diff options
author | Guillaume Desmottes <guillaume.desmottes@collabora.co.uk> | 2010-07-02 19:41:00 +0800 |
---|---|---|
committer | Guillaume Desmottes <guillaume.desmottes@collabora.co.uk> | 2010-07-05 16:13:52 +0800 |
commit | f178351cb959326996921f56c7a881a8a3e1e771 (patch) | |
tree | 2fc90bbf3f86e023da13b0645cf04c1119e26cbd /src | |
parent | 73845ad550f78190379cfa74a4b9e4ecefa6b241 (diff) | |
download | gsoc2013-empathy-f178351cb959326996921f56c7a881a8a3e1e771.tar gsoc2013-empathy-f178351cb959326996921f56c7a881a8a3e1e771.tar.gz gsoc2013-empathy-f178351cb959326996921f56c7a881a8a3e1e771.tar.bz2 gsoc2013-empathy-f178351cb959326996921f56c7a881a8a3e1e771.tar.lz gsoc2013-empathy-f178351cb959326996921f56c7a881a8a3e1e771.tar.xz gsoc2013-empathy-f178351cb959326996921f56c7a881a8a3e1e771.tar.zst gsoc2013-empathy-f178351cb959326996921f56c7a881a8a3e1e771.zip |
Handle text channels using TpSimpleHandler (#623358)
Also move handling code from empathy.c to empathy-chat-manager.
Diffstat (limited to 'src')
-rw-r--r-- | src/empathy-chat-manager.c | 168 | ||||
-rw-r--r-- | src/empathy.c | 47 |
2 files changed, 169 insertions, 46 deletions
diff --git a/src/empathy-chat-manager.c b/src/empathy-chat-manager.c index 7c66a509b..2de258924 100644 --- a/src/empathy-chat-manager.c +++ b/src/empathy-chat-manager.c @@ -17,8 +17,12 @@ * 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) \ @@ -88,11 +94,171 @@ chat_data_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); } diff --git a/src/empathy.c b/src/empathy.c index 7b7aa1a93..a148c9796 100644 --- a/src/empathy.c +++ b/src/empathy.c @@ -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; |