aboutsummaryrefslogtreecommitdiffstats
path: root/libempathy/empathy-call-handler.c
diff options
context:
space:
mode:
authorSjoerd Simons <sjoerd.simons@collabora.co.uk>2009-02-03 17:03:06 +0800
committerXavier Claessens <xclaesse@src.gnome.org>2009-02-03 17:03:06 +0800
commitf5e304dcc87509e2fb521969ef08c71cb1770758 (patch)
tree142868282e30c45f7cea6aa2f1f7c4f7e42647aa /libempathy/empathy-call-handler.c
parent72e233a357ebbc14c01bbc8fa805015d9b470fd3 (diff)
downloadgsoc2013-empathy-f5e304dcc87509e2fb521969ef08c71cb1770758.tar
gsoc2013-empathy-f5e304dcc87509e2fb521969ef08c71cb1770758.tar.gz
gsoc2013-empathy-f5e304dcc87509e2fb521969ef08c71cb1770758.tar.bz2
gsoc2013-empathy-f5e304dcc87509e2fb521969ef08c71cb1770758.tar.lz
gsoc2013-empathy-f5e304dcc87509e2fb521969ef08c71cb1770758.tar.xz
gsoc2013-empathy-f5e304dcc87509e2fb521969ef08c71cb1770758.tar.zst
gsoc2013-empathy-f5e304dcc87509e2fb521969ef08c71cb1770758.zip
Move the TpFarsight code from TpCall to CallHandler
Signed-off-by: Sjoerd Simons <sjoerd.simons@collabora.co.uk> svn path=/trunk/; revision=2387
Diffstat (limited to 'libempathy/empathy-call-handler.c')
-rw-r--r--libempathy/empathy-call-handler.c319
1 files changed, 300 insertions, 19 deletions
diff --git a/libempathy/empathy-call-handler.c b/libempathy/empathy-call-handler.c
index 2c08a8747..1fba9317a 100644
--- a/libempathy/empathy-call-handler.c
+++ b/libempathy/empathy-call-handler.c
@@ -22,36 +22,54 @@
#include <stdio.h>
#include <stdlib.h>
+#include <telepathy-glib/util.h>
+
+#include <telepathy-farsight/channel.h>
+#include <telepathy-farsight/stream.h>
+
#include "empathy-call-handler.h"
+#include "empathy-dispatcher.h"
+#include "empathy-marshal.h"
G_DEFINE_TYPE(EmpathyCallHandler, empathy_call_handler, G_TYPE_OBJECT)
-#if 0
/* signal enum */
enum
{
- LAST_SIGNAL
+ CONFERENCE_ADDED,
+ SRC_PAD_ADDED,
+ SINK_PAD_ADDED,
+ LAST_SIGNAL
};
static guint signals[LAST_SIGNAL] = {0};
-#endif
+
+enum {
+ PROP_TP_CALL = 1,
+ PROP_GST_BUS,
+ PROP_CONTACT
+};
/* private structure */
-typedef struct _EmpathyCallHandlerPrivate EmpathyCallHandlerPrivate;
+typedef struct _EmpathyCallHandlerPriv EmpathyCallHandlerPriv;
-struct _EmpathyCallHandlerPrivate
+struct _EmpathyCallHandlerPriv
{
gboolean dispose_has_run;
+ EmpathyTpCall *call;
+ EmpathyContact *contact;
+ TfChannel *tfchannel;
+ GstBus *bus;
};
-#define EMPATHY_CALL_HANDLER_GET_PRIVATE(o) \
+#define GET_PRIV(o) \
(G_TYPE_INSTANCE_GET_PRIVATE ((o), EMPATHY_TYPE_CALL_HANDLER,\
- EmpathyCallHandlerPrivate))
+ EmpathyCallHandlerPriv))
static void
empathy_call_handler_init (EmpathyCallHandler *obj)
{
- //EmpathyCallHandlerPrivate *priv = EMPATHY_CALL_HANDLER_GET_PRIVATE (obj);
+ //EmpathyCallHandlerPriv *priv = GET_PRIV (obj);
/* allocate any data required by the object here */
}
@@ -60,32 +78,125 @@ static void empathy_call_handler_dispose (GObject *object);
static void empathy_call_handler_finalize (GObject *object);
static void
-empathy_call_handler_class_init (
- EmpathyCallHandlerClass *empathy_call_handler_class)
+empathy_call_handler_set_property (GObject *object,
+ guint property_id, const GValue *value, GParamSpec *pspec)
+{
+ EmpathyCallHandlerPriv *priv = GET_PRIV (object);
+
+ switch (property_id)
+ {
+ case PROP_CONTACT:
+ priv->contact = g_value_dup_object (value);
+ break;
+ case PROP_TP_CALL:
+ priv->call = g_value_dup_object (value);
+ break;
+ case PROP_GST_BUS:
+ priv->bus = g_value_dup_object (value);
+ break;
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
+ }
+}
+
+static void
+empathy_call_handler_get_property (GObject *object,
+ guint property_id, GValue *value, GParamSpec *pspec)
+{
+ EmpathyCallHandlerPriv *priv = GET_PRIV (object);
+
+ switch (property_id)
+ {
+ case PROP_CONTACT:
+ g_value_set_object (value, priv->contact);
+ break;
+ case PROP_TP_CALL:
+ g_value_set_object (value, priv->call);
+ break;
+ case PROP_GST_BUS:
+ g_value_set_object (value, priv->bus);
+ break;
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
+ }
+}
+
+
+static void
+empathy_call_handler_class_init (EmpathyCallHandlerClass *klass)
{
- GObjectClass *object_class = G_OBJECT_CLASS (empathy_call_handler_class);
+ GObjectClass *object_class = G_OBJECT_CLASS (klass);
+ GParamSpec *param_spec;
- g_type_class_add_private (empathy_call_handler_class,
- sizeof (EmpathyCallHandlerPrivate));
+ g_type_class_add_private (klass, sizeof (EmpathyCallHandlerPriv));
+ object_class->set_property = empathy_call_handler_set_property;
+ object_class->get_property = empathy_call_handler_get_property;
object_class->dispose = empathy_call_handler_dispose;
object_class->finalize = empathy_call_handler_finalize;
+ param_spec = g_param_spec_object ("contact",
+ "contact", "The remote contact",
+ EMPATHY_TYPE_CONTACT,
+ G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS);
+ g_object_class_install_property (object_class, PROP_CONTACT, param_spec);
+
+ param_spec = g_param_spec_object ("gst-bus",
+ "gst-bus", "The gstreamer bus",
+ GST_TYPE_BUS,
+ G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS);
+ g_object_class_install_property (object_class, PROP_GST_BUS, param_spec);
+
+ param_spec = g_param_spec_object ("tp-call",
+ "tp-call", "The calls channel wrapper",
+ EMPATHY_TYPE_CONTACT,
+ G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS);
+ g_object_class_install_property (object_class, PROP_TP_CALL, param_spec);
+
+ signals[CONFERENCE_ADDED] =
+ g_signal_new ("conference-added", G_TYPE_FROM_CLASS (klass),
+ G_SIGNAL_RUN_LAST, 0, NULL, NULL,
+ g_cclosure_marshal_VOID__OBJECT,
+ G_TYPE_NONE,
+ 1, FS_TYPE_CONFERENCE);
+
+ signals[SRC_PAD_ADDED] =
+ g_signal_new ("src-pad-added", G_TYPE_FROM_CLASS (klass),
+ G_SIGNAL_RUN_LAST, 0, NULL, NULL,
+ _empathy_marshal_VOID__OBJECT_UINT,
+ G_TYPE_NONE,
+ 2, GST_TYPE_PAD, G_TYPE_UINT);
+
+ signals[SINK_PAD_ADDED] =
+ g_signal_new ("sink-pad-added", G_TYPE_FROM_CLASS (klass),
+ G_SIGNAL_RUN_LAST, 0, NULL, NULL,
+ _empathy_marshal_VOID__OBJECT_UINT,
+ G_TYPE_NONE,
+ 2, GST_TYPE_PAD, G_TYPE_UINT);
}
void
empathy_call_handler_dispose (GObject *object)
{
EmpathyCallHandler *self = EMPATHY_CALL_HANDLER (object);
- EmpathyCallHandlerPrivate *priv = EMPATHY_CALL_HANDLER_GET_PRIVATE (self);
+ EmpathyCallHandlerPriv *priv = GET_PRIV (self);
if (priv->dispose_has_run)
return;
priv->dispose_has_run = TRUE;
- /* release any references held by the object here */
+ if (priv->contact != NULL)
+ g_object_unref (priv->contact);
+
+ /* FIXME close the call ? */
+ if (priv->call != NULL)
+ g_object_unref (priv->call);
+
+ priv->call = NULL;
+
+ /* release any references held by the object here */
if (G_OBJECT_CLASS (empathy_call_handler_parent_class)->dispose)
G_OBJECT_CLASS (empathy_call_handler_parent_class)->dispose (object);
}
@@ -94,22 +205,192 @@ void
empathy_call_handler_finalize (GObject *object)
{
//EmpathyCallHandler *self = EMPATHY_CALL_HANDLER (object);
- //EmpathyCallHandlerPrivate *priv = EMPATHY_CALL_HANDLER_GET_PRIVATE (self);
+ //EmpathyCallHandlerPriv *priv = GET_PRIV (self);
/* free any data held directly by the object here */
G_OBJECT_CLASS (empathy_call_handler_parent_class)->finalize (object);
}
-
EmpathyCallHandler *
empathy_call_handler_new_for_contact (EmpathyContact *contact)
{
- return EMPATHY_CALL_HANDLER (g_object_new (EMPATHY_TYPE_CALL_HANDLER, NULL));
+ return EMPATHY_CALL_HANDLER (g_object_new (EMPATHY_TYPE_CALL_HANDLER,
+ "contact", contact, NULL));
}
EmpathyCallHandler *
empathy_call_handler_new_for_channel (EmpathyTpCall *call)
{
- return EMPATHY_CALL_HANDLER (g_object_new (EMPATHY_TYPE_CALL_HANDLER, NULL));
+ return EMPATHY_CALL_HANDLER (g_object_new (EMPATHY_TYPE_CALL_HANDLER,
+ "tp-call", call, NULL));
+}
+
+static gboolean
+empathy_call_handler_pipeline_bus_watch (GstBus *bus, GstMessage *message,
+ gpointer user_data)
+{
+ EmpathyCallHandler *handler = EMPATHY_CALL_HANDLER (user_data);
+ EmpathyCallHandlerPriv *priv = GET_PRIV (handler);
+
+ g_assert (priv->tfchannel != NULL);
+
+ tf_channel_bus_message (priv->tfchannel, message);
+
+ return TRUE;
+}
+
+static void
+empathy_call_handler_tf_channel_session_created_cb (TfChannel *tfchannel,
+ FsConference *conference, FsParticipant *participant,
+ EmpathyCallHandler *self)
+{
+ EmpathyCallHandlerPriv *priv = GET_PRIV (self);
+
+ //gst_bus_enable_essage_emission (priv->bus);
+
+ gst_bus_add_watch (priv->bus, empathy_call_handler_pipeline_bus_watch, self);
+
+ g_signal_emit (G_OBJECT (self), signals[CONFERENCE_ADDED], 0,
+ GST_ELEMENT (conference));
+}
+
+static void
+empathy_call_handler_tf_stream_src_pad_added_cb (TfStream *stream,
+ GstPad *pad, FsCodec *codec, EmpathyCallHandler *handler)
+{
+ guint media_type;
+
+ g_object_get (stream, "media-type", &media_type, NULL);
+
+ g_signal_emit (G_OBJECT (handler), signals[SRC_PAD_ADDED], 0,
+ pad, media_type);
+}
+
+
+static gboolean
+empathy_call_handler_tf_stream_request_resource_cb (TfStream *stream,
+ guint direction, EmpathyTpCall *call)
+{
+ return TRUE;
+}
+
+static void
+empathy_call_handler_tf_channel_stream_created_cb (TfChannel *tfchannel,
+ TfStream *stream, EmpathyCallHandler *handler)
+{
+ guint media_type;
+ GstPad *spad;
+
+ g_signal_connect (stream, "src-pad-added",
+ G_CALLBACK (empathy_call_handler_tf_stream_src_pad_added_cb), handler);
+ g_signal_connect (stream, "request-resource",
+ G_CALLBACK (empathy_call_handler_tf_stream_request_resource_cb),
+ handler);
+
+ g_object_get (stream, "media-type", &media_type,
+ "sink-pad", &spad, NULL);
+
+ g_signal_emit (G_OBJECT (handler), signals[SINK_PAD_ADDED], 0,
+ spad, media_type);
+
+ gst_object_unref (spad);
+}
+
+
+static void
+empathy_call_handler_request_cb (EmpathyDispatchOperation *operation,
+ const GError *error, gpointer user_data)
+{
+ EmpathyCallHandler *self = EMPATHY_CALL_HANDLER (user_data);
+ EmpathyCallHandlerPriv *priv = GET_PRIV (self);
+
+ if (error != NULL)
+ return;
+
+ priv->call = EMPATHY_TP_CALL (
+ empathy_dispatch_operation_get_channel_wrapper (operation));
+ g_object_ref (priv->call);
+
+ priv->tfchannel = tf_channel_new (
+ empathy_dispatch_operation_get_channel (operation));
+
+ /* Set up the telepathy farsight channel */
+ g_signal_connect (priv->tfchannel, "session-created",
+ G_CALLBACK (empathy_call_handler_tf_channel_session_created_cb), self);
+ g_signal_connect (priv->tfchannel, "stream-created",
+ G_CALLBACK (empathy_call_handler_tf_channel_stream_created_cb), self);
+
+ empathy_tp_call_to (priv->call, priv->contact);
+
+ empathy_dispatch_operation_claim (operation);
+}
+
+static void
+empathy_call_handler_contact_ready_cb (EmpathyContact *contact,
+ const GError *error, gpointer user_data, GObject *object)
+{
+ EmpathyCallHandler *self = EMPATHY_CALL_HANDLER (object);
+ EmpathyCallHandlerPriv *priv = GET_PRIV (self);
+ EmpathyDispatcher *dispatcher;
+ McAccount *account;
+ GStrv allowed;
+ GValue *value;
+ GHashTable *request = g_hash_table_new_full (g_str_hash, g_str_equal, NULL,
+ (GDestroyNotify) tp_g_value_slice_free);
+
+ g_assert (priv->contact != NULL);
+
+ dispatcher = empathy_dispatcher_dup_singleton ();
+ account = empathy_contact_get_account (priv->contact);
+ allowed = empathy_dispatcher_find_channel_class (dispatcher, account,
+ TP_IFACE_CHANNEL_TYPE_STREAMED_MEDIA, TP_HANDLE_TYPE_CONTACT);
+
+ if (!tp_strv_contains ((const gchar * const *)allowed,
+ TP_IFACE_CHANNEL ".TargetHandle"))
+ g_assert_not_reached ();
+
+ /* org.freedesktop.Telepathy.Channel.ChannelType */
+ value = tp_g_value_slice_new (G_TYPE_STRING);
+ g_value_set_string (value, TP_IFACE_CHANNEL_TYPE_STREAMED_MEDIA);
+ g_hash_table_insert (request, TP_IFACE_CHANNEL ".ChannelType", value);
+
+ /* org.freedesktop.Telepathy.Channel.TargetHandleType */
+ value = tp_g_value_slice_new (G_TYPE_UINT);
+ g_value_set_uint (value, TP_HANDLE_TYPE_CONTACT);
+ g_hash_table_insert (request, TP_IFACE_CHANNEL ".TargetHandleType", value);
+
+ /* org.freedesktop.Telepathy.Channel.TargetHandle*/
+ value = tp_g_value_slice_new (G_TYPE_UINT);
+ g_value_set_uint (value, empathy_contact_get_handle (priv->contact));
+ g_hash_table_insert (request, TP_IFACE_CHANNEL ".TargetHandle", value);
+
+ empathy_dispatcher_create_channel (dispatcher, account,
+ request, empathy_call_handler_request_cb, self);
+
+ g_object_unref (dispatcher);
+}
+
+void
+empathy_call_handler_start_call (EmpathyCallHandler *handler)
+{
+
+ EmpathyCallHandlerPriv *priv = GET_PRIV (handler);
+
+ g_assert (priv->contact != NULL);
+
+ empathy_contact_call_when_ready (priv->contact,
+ EMPATHY_CONTACT_READY_ID,
+ empathy_call_handler_contact_ready_cb, NULL, NULL, G_OBJECT (handler));
+}
+
+void
+empathy_call_handler_set_bus (EmpathyCallHandler *handler, GstBus *bus)
+{
+ EmpathyCallHandlerPriv *priv = GET_PRIV (handler);
+
+ g_assert (priv->bus == NULL);
+
+ priv->bus = g_object_ref (bus);
}
+