+ 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);