]> git.0d.be Git - empathy.git/blobdiff - libempathy-gtk/empathy-new-call-dialog.c
Merge branch 'sasl'
[empathy.git] / libempathy-gtk / empathy-new-call-dialog.c
index 2437b4978359bbb1eef1b87f3b74f96f4d0d039f..ab9a86a6f7b0ce519884b9e6397aa25655aba51c 100644 (file)
@@ -31,7 +31,6 @@
 #include <libempathy/empathy-tp-contact-factory.h>
 #include <libempathy/empathy-contact-manager.h>
 #include <libempathy/empathy-call-factory.h>
-#include <libempathy/empathy-dispatcher.h>
 #include <libempathy/empathy-utils.h>
 
 #define DEBUG_FLAG EMPATHY_DEBUG_CONTACT
@@ -50,6 +49,11 @@ G_DEFINE_TYPE(EmpathyNewCallDialog, empathy_new_call_dialog,
 
 typedef struct _EmpathyNewCallDialogPriv EmpathyNewCallDialogPriv;
 
+typedef struct {
+  EmpathyAccountChooserFilterResultCallback callback;
+  gpointer                                  user_data;
+} FilterCallbackData;
+
 struct _EmpathyNewCallDialogPriv {
   GtkWidget *check_video;
 };
@@ -58,6 +62,21 @@ struct _EmpathyNewCallDialogPriv {
   (G_TYPE_INSTANCE_GET_PRIVATE ((o), EMPATHY_TYPE_NEW_CALL_DIALOG, \
     EmpathyNewCallDialogPriv))
 
+static void
+create_media_channel_cb (GObject *source,
+    GAsyncResult *result,
+    gpointer user_data)
+{
+  GError *error = NULL;
+
+  if (!tp_account_channel_request_create_channel_finish (
+        TP_ACCOUNT_CHANNEL_REQUEST (source), result, &error))
+    {
+      DEBUG ("Failed to create media channel: %s", error->message);
+      g_error_free (error);
+    }
+}
+
 /**
  * SECTION:empathy-new-call-dialog
  * @title: EmpathyNewCallDialog
@@ -69,76 +88,132 @@ struct _EmpathyNewCallDialogPriv {
  */
 
 static void
-got_contact_cb (EmpathyTpContactFactory *factory,
-    EmpathyContact *contact,
-    const GError *error,
-    gpointer user_data,
-    GObject *object)
+call_contact (TpAccount *account,
+    const gchar *contact_id,
+    gboolean video,
+    gint64 timestamp)
 {
-  EmpathyCallFactory *call_factory;
-  gboolean video = GPOINTER_TO_UINT (user_data);
-
-  if (error != NULL)
-    {
-      DEBUG ("Failed: %s", error->message);
-      return;
-    }
-
-  call_factory = empathy_call_factory_get ();
-  empathy_call_factory_new_call_with_streams (call_factory, contact, TRUE,
-      video);
+  GHashTable *request;
+  TpAccountChannelRequest *req;
+
+  request = tp_asv_new (
+      TP_PROP_CHANNEL_CHANNEL_TYPE, G_TYPE_STRING,
+        TP_IFACE_CHANNEL_TYPE_STREAMED_MEDIA,
+      TP_PROP_CHANNEL_TARGET_HANDLE_TYPE, G_TYPE_UINT, TP_HANDLE_TYPE_CONTACT,
+      TP_PROP_CHANNEL_TARGET_ID, G_TYPE_STRING, contact_id,
+      TP_PROP_CHANNEL_TYPE_STREAMED_MEDIA_INITIAL_AUDIO, G_TYPE_BOOLEAN,
+        TRUE,
+      TP_PROP_CHANNEL_TYPE_STREAMED_MEDIA_INITIAL_VIDEO, G_TYPE_BOOLEAN,
+        video,
+      NULL);
+
+  req = tp_account_channel_request_new (account, request, timestamp);
+
+  tp_account_channel_request_create_channel_async (req, NULL, NULL,
+      create_media_channel_cb, NULL);
+
+  g_object_unref (req);
 }
 
 static void
-empathy_new_call_dialog_got_response (EmpathyContactSelectorDialog *dialog,
-    TpConnection *connection,
-    const gchar *contact_id)
+empathy_new_call_dialog_response (GtkDialog *dialog, int response_id)
 {
   EmpathyNewCallDialogPriv *priv = GET_PRIV (dialog);
-  EmpathyTpContactFactory *factory;
   gboolean video;
+  TpAccount *account;
+  const gchar *contact_id;
+
+  if (response_id != GTK_RESPONSE_ACCEPT) goto out;
+
+  contact_id = empathy_contact_selector_dialog_get_selected (
+      EMPATHY_CONTACT_SELECTOR_DIALOG (dialog), NULL, &account);
+
+  if (EMP_STR_EMPTY (contact_id) || account == NULL) goto out;
 
   /* check if video is enabled now because the dialog will be destroyed once
    * we return from this function. */
   video = gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (priv->check_video));
 
-  factory = empathy_tp_contact_factory_dup_singleton (connection);
-  empathy_tp_contact_factory_get_from_id (factory, contact_id,
-      got_contact_cb, GUINT_TO_POINTER (video), NULL, NULL);
+  call_contact (account, contact_id, video, gtk_get_current_event_time ());
+
+out:
+  gtk_widget_destroy (GTK_WIDGET (dialog));
+}
+
+static void
+conn_prepared_cb (GObject *conn,
+    GAsyncResult *result,
+    gpointer user_data)
+{
+  FilterCallbackData *data = user_data;
+  GError *myerr = NULL;
+  TpCapabilities *caps;
+  GPtrArray *classes;
+  guint i;
+
+  if (!tp_proxy_prepare_finish (conn, result, &myerr))
+      goto out;
 
-  g_object_unref (factory);
+  caps = tp_connection_get_capabilities (TP_CONNECTION (conn));
+  classes = tp_capabilities_get_channel_classes (caps);
+
+  for (i = 0; i < classes->len; i++)
+    {
+      GHashTable *fixed;
+      GStrv allowed;
+      const gchar *chan_type;
+
+      tp_value_array_unpack (g_ptr_array_index (classes, i), 2,
+          &fixed, &allowed);
+
+      chan_type = tp_asv_get_string (fixed, TP_PROP_CHANNEL_CHANNEL_TYPE);
+
+      if (tp_strdiff (chan_type, TP_IFACE_CHANNEL_TYPE_STREAMED_MEDIA))
+        continue;
+
+      if (tp_asv_get_uint32 (fixed, TP_PROP_CHANNEL_TARGET_HANDLE_TYPE, NULL) !=
+          TP_HANDLE_TYPE_CONTACT)
+        continue;
+
+      data->callback (TRUE, data->user_data);
+      g_slice_free (FilterCallbackData, data);
+      return;
+    }
+
+out:
+  data->callback (FALSE, data->user_data);
+  g_slice_free (FilterCallbackData, data);
 }
 
-static gboolean
+static void
 empathy_new_call_dialog_account_filter (EmpathyContactSelectorDialog *dialog,
+    EmpathyAccountChooserFilterResultCallback callback,
+    gpointer callback_data,
     TpAccount *account)
 {
   TpConnection *connection;
-  EmpathyDispatcher *dispatcher;
-  GList *classes;
+  FilterCallbackData *cb_data;
+  GQuark features[] = { TP_CONNECTION_FEATURE_CAPABILITIES, 0 };
 
   if (tp_account_get_connection_status (account, NULL) !=
       TP_CONNECTION_STATUS_CONNECTED)
-    return FALSE;
+    {
+      callback (FALSE, callback_data);
+      return;
+    }
 
   /* check if CM supports calls */
   connection = tp_account_get_connection (account);
   if (connection == NULL)
-    return FALSE;
-
-  dispatcher = empathy_dispatcher_dup_singleton ();
-
-  classes = empathy_dispatcher_find_requestable_channel_classes
-    (dispatcher, connection, TP_IFACE_CHANNEL_TYPE_STREAMED_MEDIA,
-     TP_HANDLE_TYPE_CONTACT, NULL);
-
-  g_object_unref (dispatcher);
-
-  if (classes == NULL)
-    return FALSE;
+    {
+      callback (FALSE, callback_data);
+      return;
+    }
 
-  g_list_free (classes);
-  return TRUE;
+  cb_data = g_slice_new0 (FilterCallbackData);
+  cb_data->callback = callback;
+  cb_data->user_data = callback_data;
+  tp_proxy_prepare_async (connection, features, conn_prepared_cb, cb_data);
 }
 
 static GObject *
@@ -183,7 +258,7 @@ empathy_new_call_dialog_init (EmpathyNewCallDialog *dialog)
   gtk_widget_show (priv->check_video);
 
   /* add chat button */
-  parent->button_action = gtk_button_new_with_mnemonic (_("_Call"));
+  parent->button_action = gtk_button_new_with_mnemonic (_("C_all"));
   image = gtk_image_new_from_icon_name (EMPATHY_IMAGE_VOIP,
       GTK_ICON_SIZE_BUTTON);
   gtk_button_set_image (GTK_BUTTON (parent->button_action), image);
@@ -204,15 +279,17 @@ empathy_new_call_dialog_class_init (
   EmpathyNewCallDialogClass *class)
 {
   GObjectClass *object_class = G_OBJECT_CLASS (class);
-  EmpathyContactSelectorDialogClass *dialog_class = \
+  GtkDialogClass *dialog_class = GTK_DIALOG_CLASS (class);
+  EmpathyContactSelectorDialogClass *selector_dialog_class = \
     EMPATHY_CONTACT_SELECTOR_DIALOG_CLASS (class);
 
   g_type_class_add_private (class, sizeof (EmpathyNewCallDialogPriv));
 
   object_class->constructor = empathy_new_call_dialog_constructor;
 
-  dialog_class->got_response = empathy_new_call_dialog_got_response;
-  dialog_class->account_filter = empathy_new_call_dialog_account_filter;
+  dialog_class->response = empathy_new_call_dialog_response;
+
+  selector_dialog_class->account_filter = empathy_new_call_dialog_account_filter;
 }
 
 /**