]> git.0d.be Git - empathy.git/commitdiff
Handle text channels using TpSimpleHandler (#623358)
authorGuillaume Desmottes <guillaume.desmottes@collabora.co.uk>
Fri, 2 Jul 2010 11:41:00 +0000 (13:41 +0200)
committerGuillaume Desmottes <guillaume.desmottes@collabora.co.uk>
Mon, 5 Jul 2010 08:13:52 +0000 (10:13 +0200)
Also move handling code from empathy.c to empathy-chat-manager.

src/empathy-chat-manager.c
src/empathy.c

index 7c66a509bb171ea8a459ab7405f88584f64a6ca1..2de258924dc4ba0b67240e6e7ba3fea9bffa95b5 100644 (file)
  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
  */
 
+#include <telepathy-glib/telepathy-glib.h>
+
 #include <libempathy/empathy-dispatcher.h>
 
+#include "empathy-chat-window.h"
+
 #define DEBUG_FLAG EMPATHY_DEBUG_OTHER
 #include <libempathy/empathy-debug.h>
 
@@ -40,6 +44,8 @@ struct _EmpathyChatManagerPriv
 {
   /* Queue of (ChatData *) representing the closed chats */
   GQueue *queue;
+
+  TpBaseClient *handler;
 };
 
 #define GET_PRIV(o) \
@@ -87,12 +93,172 @@ chat_data_free (ChatData *data)
   g_slice_free (ChatData, data);
 }
 
+static void
+process_tp_chat (EmpathyTpChat *tp_chat,
+    TpAccount *account,
+    gint64 user_action_time)
+{
+  EmpathyChat *chat = NULL;
+  const gchar *id;
+
+  id = empathy_tp_chat_get_id (tp_chat);
+  if (!tp_str_empty (id))
+    {
+      chat = empathy_chat_window_find_chat (account, id);
+    }
+
+  if (chat != NULL)
+    {
+      empathy_chat_set_tp_chat (chat, tp_chat);
+    }
+  else
+    {
+      chat = empathy_chat_new (tp_chat);
+      /* empathy_chat_new returns a floating reference as EmpathyChat is
+       * a GtkWidget. This reference will be taken by a container
+       * (a GtkNotebook) when we'll call empathy_chat_window_present_chat */
+    }
+
+  empathy_chat_window_present_chat (chat, user_action_time);
+
+  if (empathy_tp_chat_is_invited (tp_chat, NULL))
+    {
+      /* We have been invited to the room. Add ourself as member as this
+       * channel has been approved. */
+      empathy_tp_chat_join (tp_chat);
+    }
+
+  g_object_unref (tp_chat);
+}
+
+typedef struct
+{
+  EmpathyTpChat *tp_chat;
+  TpAccount *account;
+  gint64 user_action_time;
+  gulong sig_id;
+} chat_ready_ctx;
+
+static chat_ready_ctx *
+chat_ready_ctx_new (EmpathyTpChat *tp_chat,
+    TpAccount *account,
+    gint64 user_action_time)
+{
+  chat_ready_ctx *ctx = g_slice_new0 (chat_ready_ctx);
+
+  ctx->tp_chat = g_object_ref (tp_chat);
+  ctx->account = g_object_ref (account);
+  ctx->user_action_time = user_action_time;
+  return ctx;
+}
+
+static void
+chat_ready_ctx_free (chat_ready_ctx *ctx)
+{
+  g_object_unref (ctx->tp_chat);
+  g_object_unref (ctx->account);
+
+  if (ctx->sig_id != 0)
+    g_signal_handler_disconnect (ctx->tp_chat, ctx->sig_id);
+
+  g_slice_free (chat_ready_ctx, ctx);
+}
+
+static void
+tp_chat_ready_cb (GObject *object,
+  GParamSpec *spec,
+  gpointer user_data)
+{
+  EmpathyTpChat *tp_chat = EMPATHY_TP_CHAT (object);
+  chat_ready_ctx *ctx = user_data;
+
+  if (!empathy_tp_chat_is_ready (tp_chat))
+    return;
+
+  process_tp_chat (tp_chat, ctx->account, ctx->user_action_time);
+
+  chat_ready_ctx_free (ctx);
+}
+
+static void
+handle_channels (TpSimpleHandler *handler,
+    TpAccount *account,
+    TpConnection *connection,
+    GList *channels,
+    GList *requests_satisfied,
+    gint64 user_action_time,
+    TpHandleChannelsContext *context,
+    gpointer user_data)
+{
+  GList *l;
+
+  for (l = channels; l != NULL; l = g_list_next (l))
+    {
+      TpChannel *channel = l->data;
+      EmpathyTpChat *tp_chat;
+
+      tp_chat = empathy_tp_chat_new (channel);
+
+      if (empathy_tp_chat_is_ready (tp_chat))
+        {
+          process_tp_chat (tp_chat, account, user_action_time);
+        }
+      else
+        {
+          chat_ready_ctx *ctx = chat_ready_ctx_new (tp_chat, account,
+              user_action_time);
+
+          ctx->sig_id = g_signal_connect (tp_chat, "notify::ready",
+              G_CALLBACK (tp_chat_ready_cb), ctx);
+        }
+    }
+
+  tp_handle_channels_context_accept (context);
+}
+
 static void
 empathy_chat_manager_init (EmpathyChatManager *self)
 {
   EmpathyChatManagerPriv *priv = GET_PRIV (self);
+  TpDBusDaemon *dbus;
+  GError *error = NULL;
 
   priv->queue = g_queue_new ();
+
+  dbus = tp_dbus_daemon_dup (&error);
+  if (dbus == NULL)
+    {
+      g_critical ("Failed to get D-Bus daemon: %s", error->message);
+      g_error_free (error);
+      return;
+    }
+
+  /* Text channels handler */
+  priv->handler = tp_simple_handler_new (dbus, FALSE, FALSE, "Empathy", FALSE,
+      handle_channels, self, NULL);
+
+  g_object_unref (dbus);
+
+  tp_base_client_take_handler_filter (priv->handler, tp_asv_new (
+        TP_PROP_CHANNEL_CHANNEL_TYPE, G_TYPE_STRING, TP_IFACE_CHANNEL_TYPE_TEXT,
+        TP_PROP_CHANNEL_TARGET_HANDLE_TYPE, G_TYPE_UINT, TP_HANDLE_TYPE_CONTACT,
+        NULL));
+
+  tp_base_client_take_handler_filter (priv->handler, tp_asv_new (
+        TP_PROP_CHANNEL_CHANNEL_TYPE, G_TYPE_STRING, TP_IFACE_CHANNEL_TYPE_TEXT,
+        TP_PROP_CHANNEL_TARGET_HANDLE_TYPE, G_TYPE_UINT, TP_HANDLE_TYPE_ROOM,
+        NULL));
+
+  tp_base_client_take_handler_filter (priv->handler, tp_asv_new (
+        TP_PROP_CHANNEL_CHANNEL_TYPE, G_TYPE_STRING, TP_IFACE_CHANNEL_TYPE_TEXT,
+        TP_PROP_CHANNEL_TARGET_HANDLE_TYPE, G_TYPE_UINT, TP_HANDLE_TYPE_NONE,
+        NULL));
+
+  if (!tp_base_client_register (priv->handler, &error))
+    {
+      g_critical ("Failed to register text handler: %s", error->message);
+      g_error_free (error);
+    }
 }
 
 static void
@@ -108,6 +274,8 @@ empathy_chat_manager_finalize (GObject *object)
       priv->queue = NULL;
     }
 
+  tp_clear_object (&priv->handler);
+
   G_OBJECT_CLASS (empathy_chat_manager_parent_class)->finalize (object);
 }
 
index 7b7aa1a93159359f42b3185d2744aa9c27322984..a148c97965f06ba9a342c1503cc94a4c4ef2277f 100644 (file)
@@ -67,7 +67,6 @@
 #include "empathy-accounts-dialog.h"
 #include "empathy-chat-manager.h"
 #include "empathy-status-icon.h"
-#include "empathy-chat-window.h"
 #include "empathy-ft-manager.h"
 
 #include "extensions/extensions.h"
@@ -91,51 +90,7 @@ dispatch_cb (EmpathyDispatcher *dispatcher,
 
   channel_type = empathy_dispatch_operation_get_channel_type_id (operation);
 
-  if (channel_type == TP_IFACE_QUARK_CHANNEL_TYPE_TEXT)
-    {
-      EmpathyTpChat *tp_chat;
-      EmpathyChat   *chat = NULL;
-      const gchar   *id;
-
-      tp_chat = EMPATHY_TP_CHAT
-        (empathy_dispatch_operation_get_channel_wrapper (operation));
-
-      id = empathy_tp_chat_get_id (tp_chat);
-      if (!EMP_STR_EMPTY (id))
-        {
-          TpConnection *connection;
-          TpAccount *account;
-
-          connection = empathy_tp_chat_get_connection (tp_chat);
-          account = empathy_get_account_for_connection (connection);
-          chat = empathy_chat_window_find_chat (account, id);
-        }
-
-      if (chat)
-        {
-          empathy_chat_set_tp_chat (chat, tp_chat);
-        }
-      else
-        {
-          chat = empathy_chat_new (tp_chat);
-          /* empathy_chat_new returns a floating reference as EmpathyChat is
-           * a GtkWidget. This reference will be taken by a container
-           * (a GtkNotebook) when we'll call empathy_chat_window_present_chat */
-        }
-
-      empathy_chat_window_present_chat (chat,
-          empathy_dispatch_operation_get_user_action_time (operation));
-
-      if (empathy_tp_chat_is_invited (tp_chat, NULL))
-        {
-          /* We have been invited to the room. Add ourself as member as this
-           * channel has been approved. */
-          empathy_tp_chat_join (tp_chat);
-        }
-
-      empathy_dispatch_operation_claim (operation);
-    }
-  else if (channel_type == TP_IFACE_QUARK_CHANNEL_TYPE_FILE_TRANSFER)
+  if (channel_type == TP_IFACE_QUARK_CHANNEL_TYPE_FILE_TRANSFER)
     {
       EmpathyFTFactory *factory;