diff options
author | Sjoerd Simons <sjoerd.simons@collabora.co.uk> | 2009-08-29 07:01:47 +0800 |
---|---|---|
committer | Sjoerd Simons <sjoerd.simons@collabora.co.uk> | 2009-08-31 00:28:46 +0800 |
commit | b3acc55a8c6401de41cfc320081e1aa0be17c27a (patch) | |
tree | 26d37041c5e8fab5ace650d4d9a4421ac233d126 | |
parent | 943dbb3303c06cfa35d0d89a5765ce5430dfba69 (diff) | |
download | gsoc2013-empathy-b3acc55a8c6401de41cfc320081e1aa0be17c27a.tar gsoc2013-empathy-b3acc55a8c6401de41cfc320081e1aa0be17c27a.tar.gz gsoc2013-empathy-b3acc55a8c6401de41cfc320081e1aa0be17c27a.tar.bz2 gsoc2013-empathy-b3acc55a8c6401de41cfc320081e1aa0be17c27a.tar.lz gsoc2013-empathy-b3acc55a8c6401de41cfc320081e1aa0be17c27a.tar.xz gsoc2013-empathy-b3acc55a8c6401de41cfc320081e1aa0be17c27a.tar.zst gsoc2013-empathy-b3acc55a8c6401de41cfc320081e1aa0be17c27a.zip |
Add a simple abstraction for implementing handlers
Implement an EmpathyHandler object which can be used to easily add extra
Client.Handler heads on D-Bus.
-rw-r--r-- | libempathy/Makefile.am | 2 | ||||
-rw-r--r-- | libempathy/empathy-dispatcher.c | 215 | ||||
-rw-r--r-- | libempathy/empathy-dispatcher.h | 7 | ||||
-rw-r--r-- | libempathy/empathy-handler.c | 369 | ||||
-rw-r--r-- | libempathy/empathy-handler.h | 89 | ||||
-rw-r--r-- | src/empathy.c | 59 |
6 files changed, 615 insertions, 126 deletions
diff --git a/libempathy/Makefile.am b/libempathy/Makefile.am index ad36ede33..e45b16d81 100644 --- a/libempathy/Makefile.am +++ b/libempathy/Makefile.am @@ -45,6 +45,7 @@ libempathy_la_SOURCES = \ empathy-dispatch-operation.c \ empathy-ft-factory.c \ empathy-ft-handler.c \ + empathy-handler.c \ empathy-idle.c \ empathy-irc-network.c \ empathy-irc-network-manager.c \ @@ -100,6 +101,7 @@ libempathy_headers = \ empathy-dispatch-operation.h \ empathy-ft-factory.h \ empathy-ft-handler.h \ + empathy-handler.h \ empathy-idle.h \ empathy-irc-network.h \ empathy-irc-network-manager.h \ diff --git a/libempathy/empathy-dispatcher.c b/libempathy/empathy-dispatcher.c index c1a19f699..dfd041d6b 100644 --- a/libempathy/empathy-dispatcher.c +++ b/libempathy/empathy-dispatcher.c @@ -42,6 +42,7 @@ #include <extensions/extensions.h> #include "empathy-dispatcher.h" +#include "empathy-handler.h" #include "empathy-utils.h" #include "empathy-tube-handler.h" #include "empathy-account-manager.h" @@ -64,33 +65,33 @@ typedef struct /* channels which the dispatcher is listening "invalidated" */ GList *channels; + GPtrArray *array; + EmpathyHandler *handler; GHashTable *request_channel_class_async_ids; } EmpathyDispatcherPriv; -static void empathy_dispatcher_client_handler_iface_init (gpointer g_iface, - gpointer g_iface_data); - -G_DEFINE_TYPE_WITH_CODE (EmpathyDispatcher, - empathy_dispatcher, - G_TYPE_OBJECT, - G_IMPLEMENT_INTERFACE (TP_TYPE_SVC_DBUS_PROPERTIES, - tp_dbus_properties_mixin_iface_init); - G_IMPLEMENT_INTERFACE (TP_TYPE_SVC_CLIENT, NULL); - G_IMPLEMENT_INTERFACE (TP_TYPE_SVC_CLIENT_HANDLER, - empathy_dispatcher_client_handler_iface_init); - ); - -static const gchar *empathy_dispatcher_interfaces[] = { - TP_IFACE_CLIENT_HANDLER, - NULL -}; +static GList * +empathy_dispatcher_get_channels (EmpathyHandler *handler, + gpointer user_data); + +static gboolean +empathy_dispatcher_handle_channels (EmpathyHandler *handler, + const gchar *account_path, + const gchar *connection_path, + const GPtrArray *channels, + const GPtrArray *requests_satisfied, + guint64 timestamp, + GHashTable *handler_info, + gpointer user_data, + GError **error); + +G_DEFINE_TYPE (EmpathyDispatcher, empathy_dispatcher, G_TYPE_OBJECT); enum { PROP_INTERFACES = 1, - PROP_CHANNEL_FILTER, - PROP_CHANNELS + PROP_HANDLER, }; enum @@ -865,7 +866,7 @@ dispatcher_constructor (GType type, GObjectConstructParam *construct_params) { GObject *retval; - TpDBusDaemon *dbus; + EmpathyDispatcherPriv *priv; if (dispatcher != NULL) return g_object_ref (dispatcher); @@ -876,14 +877,15 @@ dispatcher_constructor (GType type, dispatcher = EMPATHY_DISPATCHER (retval); g_object_add_weak_pointer (retval, (gpointer) &dispatcher); - dbus = tp_dbus_daemon_dup (NULL); + priv = GET_PRIV (dispatcher); - g_assert (tp_dbus_daemon_request_name (dbus, - DISPATCHER_BUS_NAME, TRUE, NULL)); - dbus_g_connection_register_g_object (tp_get_bus (), - DISPATCHER_OBJECT_PATH, retval); + empathy_handler_set_handle_channels_func (priv->handler, + empathy_dispatcher_handle_channels, + dispatcher); - DEBUG ("Registering at '%s'", DISPATCHER_OBJECT_PATH); + empathy_handler_set_channels_func (priv->handler, + empathy_dispatcher_get_channels, + dispatcher); return retval; } @@ -936,9 +938,9 @@ dispatcher_finalize (GObject *object) } static void -dispatcher_get_property (GObject *object, +dispatcher_set_property (GObject *object, guint property_id, - GValue *value, + const GValue *value, GParamSpec *pspec) { EmpathyDispatcher *dispatcher = EMPATHY_DISPATCHER (object); @@ -946,37 +948,29 @@ dispatcher_get_property (GObject *object, switch (property_id) { - case PROP_INTERFACES: - g_value_set_boxed (value, empathy_dispatcher_interfaces); + case PROP_HANDLER: + priv->handler = g_value_dup_object (value); break; - case PROP_CHANNEL_FILTER: - { - GPtrArray *filters = g_ptr_array_new (); - GHashTable *filter = g_hash_table_new (NULL, NULL); - - g_ptr_array_add (filters, filter); - - g_value_set_boxed (value, filters); - break; - } - case PROP_CHANNELS: - { - GPtrArray *accounts; - GList *l; - - accounts = g_ptr_array_new (); - - for (l = priv->channels; l != NULL; l = g_list_next (l)) - { - TpProxy *channel = TP_PROXY (l->data); + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec); + break; + } +} - g_ptr_array_add (accounts, - g_strdup (tp_proxy_get_object_path (channel))); - } +static void +dispatcher_get_property (GObject *object, + guint property_id, + GValue *value, + GParamSpec *pspec) +{ + EmpathyDispatcher *dispatcher = EMPATHY_DISPATCHER (object); + EmpathyDispatcherPriv *priv = GET_PRIV (dispatcher); - g_value_set_boxed (value, accounts); - break; - } + switch (property_id) + { + case PROP_HANDLER: + g_value_set_object (value, priv->handler); + break; default: G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec); break; @@ -989,53 +983,18 @@ empathy_dispatcher_class_init (EmpathyDispatcherClass *klass) GObjectClass *object_class = G_OBJECT_CLASS (klass); GParamSpec *param_spec; - static TpDBusPropertiesMixinPropImpl client_props[] = { - { "Interfaces", "interfaces", NULL }, - { NULL } - }; - static TpDBusPropertiesMixinPropImpl client_handler_props[] = { - { "HandlerChannelFilter", "channel-filter", NULL }, - { "HandledChannels", "channels", NULL }, - { NULL } - }; - static TpDBusPropertiesMixinIfaceImpl prop_interfaces[] = { - { TP_IFACE_CLIENT, - tp_dbus_properties_mixin_getter_gobject_properties, - NULL, - client_props - }, - { TP_IFACE_CLIENT_HANDLER, - tp_dbus_properties_mixin_getter_gobject_properties, - NULL, - client_handler_props - }, - { NULL } - }; - object_class->finalize = dispatcher_finalize; object_class->constructor = dispatcher_constructor; object_class->get_property = dispatcher_get_property; + object_class->set_property = dispatcher_set_property; - param_spec = g_param_spec_boxed ("interfaces", "interfaces", - "Available D-Bus interfaces", - G_TYPE_STRV, - G_PARAM_READABLE | G_PARAM_STATIC_STRINGS); - g_object_class_install_property (object_class, PROP_INTERFACES, param_spec); - - param_spec = g_param_spec_boxed ("channel-filter", "channel-filter", - "Filter for channels this handles", - TP_ARRAY_TYPE_CHANNEL_CLASS_LIST, - G_PARAM_READABLE | G_PARAM_STATIC_STRINGS); - g_object_class_install_property (object_class, - PROP_CHANNEL_FILTER, param_spec); - - param_spec = g_param_spec_boxed ("channels", "channels", - "List of channels we're handling", - EMPATHY_ARRAY_TYPE_OBJECT, - G_PARAM_READABLE | G_PARAM_STATIC_STRINGS); + param_spec = g_param_spec_object ("handler", "handler", + "The main Telepathy Client Hander object", + EMPATHY_TYPE_HANDLER, + G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS | G_PARAM_CONSTRUCT_ONLY); g_object_class_install_property (object_class, - PROP_CHANNELS, param_spec); + PROP_HANDLER, param_spec); signals[OBSERVE] = g_signal_new ("observe", @@ -1069,10 +1028,6 @@ empathy_dispatcher_class_init (EmpathyDispatcherClass *klass) g_type_class_add_private (object_class, sizeof (EmpathyDispatcherPriv)); - - klass->dbus_props_class.interfaces = prop_interfaces; - tp_dbus_properties_mixin_class_init (object_class, - G_STRUCT_OFFSET (EmpathyDispatcherClass, dbus_props_class)); } static void @@ -1110,6 +1065,26 @@ empathy_dispatcher_init (EmpathyDispatcher *dispatcher) } EmpathyDispatcher * +empathy_dispatcher_new (const gchar *name, + GPtrArray *filters, + GStrv capabilities) +{ + g_assert (dispatcher == NULL); + EmpathyHandler *handler; + EmpathyDispatcher *ret; + + handler = empathy_handler_new (name, filters, capabilities); + + ret = EMPATHY_DISPATCHER ( + g_object_new (EMPATHY_TYPE_DISPATCHER, + "handler", handler, + NULL)); + g_object_unref (handler); + + return ret; +} + +EmpathyDispatcher * empathy_dispatcher_dup_singleton (void) { return EMPATHY_DISPATCHER (g_object_new (EMPATHY_TYPE_DISPATCHER, NULL)); @@ -1797,17 +1772,28 @@ empathy_dispatcher_find_requestable_channel_classes_async request, GUINT_TO_POINTER (source_id)); } -static void -empathy_dispatcher_handle_channels (TpSvcClientHandler *self, +static GList * +empathy_dispatcher_get_channels (EmpathyHandler *handler, + gpointer user_data) +{ + EmpathyDispatcher *dispatcher = EMPATHY_DISPATCHER (user_data); + EmpathyDispatcherPriv *priv = GET_PRIV (dispatcher); + + return priv->channels; +} + +static gboolean +empathy_dispatcher_handle_channels (EmpathyHandler *handler, const gchar *account_path, const gchar *connection_path, const GPtrArray *channels, const GPtrArray *requests_satisfied, guint64 timestamp, GHashTable *handler_info, - DBusGMethodInvocation *context) + gpointer user_data, + GError **error) { - EmpathyDispatcher *dispatcher = EMPATHY_DISPATCHER (self); + EmpathyDispatcher *dispatcher = EMPATHY_DISPATCHER (user_data); EmpathyDispatcherPriv *priv = GET_PRIV (dispatcher); int i; EmpathyAccount *account; @@ -1821,10 +1807,9 @@ empathy_dispatcher_handle_channels (TpSvcClientHandler *self, connection_path); if (connection == NULL) { - GError error = { TP_ERRORS, TP_ERROR_INVALID_ARGUMENT, - "Invalid connection argument" }; - dbus_g_method_return_error (context, &error); - return; + g_set_error_literal (error, TP_ERRORS, TP_ERROR_INVALID_ARGUMENT, + "Invalid connection argument"); + return FALSE; } for (i = 0; i < channels->len ; i++) @@ -1840,15 +1825,5 @@ empathy_dispatcher_handle_channels (TpSvcClientHandler *self, connection, object_path, properties); } - tp_svc_client_handler_return_from_handle_channels (context); -} - -static void -empathy_dispatcher_client_handler_iface_init (gpointer g_iface, - gpointer g_iface_data) -{ - TpSvcClientHandlerClass *klass = (TpSvcClientHandlerClass *) g_iface; - - tp_svc_client_handler_implement_handle_channels (klass, - empathy_dispatcher_handle_channels); + return TRUE; } diff --git a/libempathy/empathy-dispatcher.h b/libempathy/empathy-dispatcher.h index 41a1430fb..c4daa60fd 100644 --- a/libempathy/empathy-dispatcher.h +++ b/libempathy/empathy-dispatcher.h @@ -26,7 +26,6 @@ #include <gio/gio.h> #include <telepathy-glib/channel.h> -#include <telepathy-glib/dbus-properties-mixin.h> #include "empathy-contact.h" #include "empathy-dispatch-operation.h" @@ -52,7 +51,6 @@ struct _EmpathyDispatcher struct _EmpathyDispatcherClass { GObjectClass parent_class; - TpDBusPropertiesMixinClass dbus_props_class; }; /* Will be called when the channel is ready for dispatching. The requestor @@ -98,6 +96,11 @@ GList * empathy_dispatcher_find_requestable_channel_classes const gchar *channel_type, guint handle_type, const char *first_property_name, ...); +/* Create the dispatcher singleton */ +EmpathyDispatcher * empathy_dispatcher_new (const gchar *name, + GPtrArray *filters, + GStrv capabilities); + /* Get the dispatcher singleton */ EmpathyDispatcher * empathy_dispatcher_dup_singleton (void); diff --git a/libempathy/empathy-handler.c b/libempathy/empathy-handler.c new file mode 100644 index 000000000..649903058 --- /dev/null +++ b/libempathy/empathy-handler.c @@ -0,0 +1,369 @@ +/* + * Copyright (C) 2007-2009 Collabora Ltd. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + * + * Authors: Xavier Claessens <xclaesse@gmail.com> + * Sjoerd Simons <sjoerd.simons@collabora.co.uk> + * Cosimo Cecchi <cosimo.cecchi@collabora.co.uk> + */ + +#include <config.h> + +#include <telepathy-glib/dbus.h> +#include <telepathy-glib/proxy-subclass.h> +#include <telepathy-glib/gtypes.h> +#include <telepathy-glib/defs.h> +#include <telepathy-glib/svc-client.h> +#include <telepathy-glib/svc-generic.h> +#include <telepathy-glib/interfaces.h> + +#include "empathy-handler.h" +#include "empathy-utils.h" + +#define DEBUG_FLAG EMPATHY_DEBUG_DISPATCHER +#include <libempathy/empathy-debug.h> + +#define GET_PRIV(obj) EMPATHY_GET_PRIV (obj, EmpathyHandler) +typedef struct +{ + EmpathyHandlerHandleChannelsFunc *handle_channels; + gpointer handle_channels_user_data; + + EmpathyHandlerChannelsFunc *channels; + gpointer channels_user_data; + + gchar *name; + + GPtrArray *filters; + GStrv *capabilities; +} EmpathyHandlerPriv; + +static void empathy_handler_client_handler_iface_init (gpointer g_iface, + gpointer g_iface_data); + +G_DEFINE_TYPE_WITH_CODE (EmpathyHandler, + empathy_handler, + G_TYPE_OBJECT, + G_IMPLEMENT_INTERFACE (TP_TYPE_SVC_DBUS_PROPERTIES, + tp_dbus_properties_mixin_iface_init); + G_IMPLEMENT_INTERFACE (TP_TYPE_SVC_CLIENT, NULL); + G_IMPLEMENT_INTERFACE (TP_TYPE_SVC_CLIENT_HANDLER, + empathy_handler_client_handler_iface_init); + ); + +static const gchar *empathy_handler_interfaces[] = { + TP_IFACE_CLIENT_HANDLER, + NULL +}; + +enum +{ + PROP_INTERFACES = 1, + PROP_CHANNEL_FILTER, + PROP_CHANNELS, + PROP_CAPABILITIES, + PROP_NAME, +}; + +static GObject * +handler_constructor (GType type, + guint n_construct_params, + GObjectConstructParam *construct_params) +{ + GObject *obj = + G_OBJECT_CLASS (empathy_handler_parent_class)->constructor + (type, n_construct_params, construct_params); + EmpathyHandler *handler = EMPATHY_HANDLER (obj); + EmpathyHandlerPriv *priv = GET_PRIV (handler); + TpDBusDaemon *dbus; + gchar *busname; + gchar *object_path; + + priv = GET_PRIV (handler); + + busname = g_strdup_printf (TP_CLIENT_BUS_NAME_BASE"%s", priv->name); + object_path = g_strdup_printf (TP_CLIENT_OBJECT_PATH_BASE"%s", + priv->name); + + dbus = tp_dbus_daemon_dup (NULL); + + g_assert (tp_dbus_daemon_request_name (dbus, + busname, TRUE, NULL)); + dbus_g_connection_register_g_object (tp_get_bus (), + object_path, obj); + + DEBUG ("Registered at '%s'", object_path); + + g_free (busname); + g_free (object_path); + g_object_unref (dbus); + + return G_OBJECT (handler); +} + +static void +handler_finalize (GObject *object) +{ + EmpathyHandlerPriv *priv = GET_PRIV (object); + + if (priv->filters != NULL) + g_boxed_free (TP_ARRAY_TYPE_CHANNEL_CLASS_LIST, priv->filters); + + if (priv->capabilities != NULL) + g_boxed_free (G_TYPE_STRV, priv->capabilities); + + g_free (priv->name); +} + +static void +handler_set_property (GObject *object, + guint property_id, + const GValue *value, + GParamSpec *pspec) +{ + EmpathyHandler *handler = EMPATHY_HANDLER (object); + EmpathyHandlerPriv *priv = GET_PRIV (handler); + + switch (property_id) + { + case PROP_CHANNEL_FILTER: + priv->filters = g_value_dup_boxed (value); + break; + case PROP_CAPABILITIES: + priv->capabilities = g_value_dup_boxed (value); + break; + case PROP_NAME: + priv->name = g_value_dup_string (value); + break; + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec); + break; + } +} + +static void +handler_get_property (GObject *object, + guint property_id, + GValue *value, + GParamSpec *pspec) +{ + EmpathyHandler *self = EMPATHY_HANDLER (object); + EmpathyHandlerPriv *priv = GET_PRIV (self); + + switch (property_id) + { + case PROP_INTERFACES: + g_value_set_boxed (value, empathy_handler_interfaces); + break; + case PROP_CHANNEL_FILTER: + g_value_set_boxed (value, priv->filters); + break; + case PROP_CAPABILITIES: + g_value_set_boxed (value, priv->capabilities); + break; + case PROP_NAME: + g_value_set_string (value, priv->name); + break; + case PROP_CHANNELS: + { + GList *l, *channels = NULL; + GPtrArray *array = g_ptr_array_new (); + + if (priv->channels != NULL) + channels = priv->channels (self, priv->channels_user_data); + + for (l = channels ; l != NULL; l = g_list_next (l)) + { + TpProxy *channel = TP_PROXY (l->data); + g_ptr_array_add (array, + (gpointer) tp_proxy_get_object_path (channel)); + } + g_value_set_boxed (value, array); + g_ptr_array_free (array, TRUE); + break; + } + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec); + break; + } +} + +static void +empathy_handler_class_init (EmpathyHandlerClass *klass) +{ + GObjectClass *object_class = G_OBJECT_CLASS (klass); + GParamSpec *param_spec; + + static TpDBusPropertiesMixinPropImpl client_props[] = { + { "Interfaces", "interfaces", NULL }, + { NULL } + }; + static TpDBusPropertiesMixinPropImpl client_handler_props[] = { + { "HandlerChannelFilter", "channel-filter", NULL }, + { "HandledChannels", "channels", NULL }, + { "Capabilities", "capabilities", NULL }, + { NULL } + }; + static TpDBusPropertiesMixinIfaceImpl prop_interfaces[] = { + { TP_IFACE_CLIENT, + tp_dbus_properties_mixin_getter_gobject_properties, + NULL, + client_props + }, + { TP_IFACE_CLIENT_HANDLER, + tp_dbus_properties_mixin_getter_gobject_properties, + NULL, + client_handler_props + }, + { NULL } + }; + + object_class->finalize = handler_finalize; + object_class->constructor = handler_constructor; + + object_class->get_property = handler_get_property; + object_class->set_property = handler_set_property; + + param_spec = g_param_spec_boxed ("interfaces", "interfaces", + "Available D-Bus interfaces", + G_TYPE_STRV, + G_PARAM_READABLE | G_PARAM_STATIC_STRINGS); + g_object_class_install_property (object_class, PROP_INTERFACES, param_spec); + + param_spec = g_param_spec_boxed ("channel-filter", "channel-filter", + "Filter for channels this handles", + TP_ARRAY_TYPE_CHANNEL_CLASS_LIST, + G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS | G_PARAM_CONSTRUCT_ONLY); + g_object_class_install_property (object_class, + PROP_CHANNEL_FILTER, param_spec); + + param_spec = g_param_spec_boxed ("capabilities", "capabilities", + "Filter for channels this handles", + G_TYPE_STRV, + G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS | G_PARAM_CONSTRUCT_ONLY); + g_object_class_install_property (object_class, + PROP_CAPABILITIES, param_spec); + + param_spec = g_param_spec_boxed ("channels", "channels", + "List of channels we're handling", + EMPATHY_ARRAY_TYPE_OBJECT, + G_PARAM_READABLE | G_PARAM_STATIC_STRINGS); + g_object_class_install_property (object_class, + PROP_CHANNELS, param_spec); + + param_spec = g_param_spec_string ("name", "name", + "The local name of the handler", + NULL, + G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS | G_PARAM_CONSTRUCT_ONLY); + g_object_class_install_property (object_class, + PROP_NAME, param_spec); + + g_type_class_add_private (object_class, sizeof (EmpathyHandlerPriv)); + + klass->dbus_props_class.interfaces = prop_interfaces; + tp_dbus_properties_mixin_class_init (object_class, + G_STRUCT_OFFSET (EmpathyHandlerClass, dbus_props_class)); +} + +static void +empathy_handler_init (EmpathyHandler *handler) +{ + EmpathyHandlerPriv *priv = G_TYPE_INSTANCE_GET_PRIVATE (handler, + EMPATHY_TYPE_HANDLER, EmpathyHandlerPriv); + + handler->priv = priv; +} + +EmpathyHandler * +empathy_handler_new (const gchar *name, + GPtrArray *filters, + GStrv capabilities) +{ + return EMPATHY_HANDLER ( + g_object_new (EMPATHY_TYPE_HANDLER, + "name", name, + "channel-filter", filters, + "capabilities", capabilities, + NULL)); +} + +static void +empathy_handler_handle_channels (TpSvcClientHandler *self, + const gchar *account_path, + const gchar *connection_path, + const GPtrArray *channels, + const GPtrArray *requests_satisfied, + guint64 timestamp, + GHashTable *handler_info, + DBusGMethodInvocation *context) +{ + EmpathyHandler *handler = EMPATHY_HANDLER (self); + EmpathyHandlerPriv *priv = GET_PRIV (handler); + GError *error = NULL; + + if (!priv->handle_channels) + { + error = g_error_new_literal (TP_ERRORS, + TP_ERROR_NOT_AVAILABLE, + "No handler function setup"); + goto error; + } + + if (!priv->handle_channels (handler, account_path, connection_path, + channels, requests_satisfied, timestamp, handler_info, + priv->handle_channels_user_data, &error)) + goto error; + + tp_svc_client_handler_return_from_handle_channels (context); + return; + +error: + dbus_g_method_return_error (context, error); + g_error_free (error); +} + +static void +empathy_handler_client_handler_iface_init (gpointer g_iface, + gpointer g_iface_data) +{ + TpSvcClientHandlerClass *klass = (TpSvcClientHandlerClass *) g_iface; + + tp_svc_client_handler_implement_handle_channels (klass, + empathy_handler_handle_channels); +} + +void +empathy_handler_set_handle_channels_func (EmpathyHandler *handler, + EmpathyHandlerHandleChannelsFunc *func, + gpointer user_data) +{ + EmpathyHandlerPriv *priv = GET_PRIV (handler); + + priv->handle_channels = func; + priv->handle_channels_user_data = user_data; +} + +void +empathy_handler_set_channels_func (EmpathyHandler *handler, + EmpathyHandlerChannelsFunc *func, + gpointer user_data) +{ + EmpathyHandlerPriv *priv = GET_PRIV (handler); + + priv->channels = func; + priv->channels_user_data = user_data; +} + diff --git a/libempathy/empathy-handler.h b/libempathy/empathy-handler.h new file mode 100644 index 000000000..684ec0cc9 --- /dev/null +++ b/libempathy/empathy-handler.h @@ -0,0 +1,89 @@ +/* + * Copyright (C) 2007-2009 Collabora Ltd. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + * + * Authors: Sjoerd Simons <sjoerd.simons@collabora.co.uk> + */ + +#ifndef __EMPATHY_HANDLER_H__ +#define __EMPATHY_HANDLER_H__ + +#include <glib.h> + +#include <telepathy-glib/channel.h> +#include <telepathy-glib/dbus-properties-mixin.h> + +G_BEGIN_DECLS + +#define EMPATHY_TYPE_HANDLER (empathy_handler_get_type ()) +#define EMPATHY_HANDLER(o) (G_TYPE_CHECK_INSTANCE_CAST ((o), \ + EMPATHY_TYPE_HANDLER, EmpathyHandler)) +#define EMPATHY_HANDLER_CLASS(k) (G_TYPE_CHECK_CLASS_CAST((k), \ + EMPATHY_TYPE_HANDLER, EmpathyHandlerClass)) +#define EMPATHY_IS_HANDLER(o) (G_TYPE_CHECK_INSTANCE_TYPE ((o), \ + EMPATHY_TYPE_HANDLER)) +#define EMPATHY_IS_HANDLER_CLASS(k) (G_TYPE_CHECK_CLASS_TYPE ((k), \ + EMPATHY_TYPE_HANDLER)) +#define EMPATHY_HANDLER_GET_CLASS(o) (G_TYPE_INSTANCE_GET_CLASS ((o), \ + EMPATHY_TYPE_HANDLER, EmpathyHandlerClass)) + +GType empathy_handler_get_type (void) G_GNUC_CONST; + +typedef struct _EmpathyHandler EmpathyHandler; +typedef struct _EmpathyHandlerClass EmpathyHandlerClass; + +struct _EmpathyHandler +{ + GObject parent; + gpointer priv; +}; + +struct _EmpathyHandlerClass +{ + GObjectClass parent_class; + TpDBusPropertiesMixinClass dbus_props_class; +}; + + +EmpathyHandler * empathy_handler_new (const gchar *name, + GPtrArray *filters, + GStrv capabilities); + +typedef gboolean (EmpathyHandlerHandleChannelsFunc) (EmpathyHandler *handler, + const gchar *account_path, + const gchar *connection_path, + const GPtrArray *channels, + const GPtrArray *requests_satisfied, + guint64 timestamp, + GHashTable *handler_info, + gpointer user_data, + GError **error); + +void empathy_handler_set_handle_channels_func (EmpathyHandler *handler, + EmpathyHandlerHandleChannelsFunc *func, + gpointer user_data); + +typedef GList * (EmpathyHandlerChannelsFunc) ( + EmpathyHandler *handler, + gpointer user_data); + +void empathy_handler_set_channels_func (EmpathyHandler *handler, + EmpathyHandlerChannelsFunc func, + gpointer user_data); + +G_END_DECLS + +#endif /* __EMPATHY_HANDLER_H__ */ diff --git a/src/empathy.c b/src/empathy.c index 38fd56c54..f7017bd96 100644 --- a/src/empathy.c +++ b/src/empathy.c @@ -558,6 +558,57 @@ account_manager_ready_cb (EmpathyAccountManager *manager, } } +static EmpathyDispatcher * +setup_dispatcher (void) +{ + EmpathyDispatcher *d; + GPtrArray *filters; + struct { + const gchar *channeltype; + TpHandleType handletype; + } types[] = { + /* Text channels with handle types none, contact and room */ + { TP_IFACE_CHANNEL_TYPE_TEXT, TP_HANDLE_TYPE_NONE }, + { TP_IFACE_CHANNEL_TYPE_TEXT, TP_HANDLE_TYPE_CONTACT }, + { TP_IFACE_CHANNEL_TYPE_TEXT, TP_HANDLE_TYPE_ROOM }, + /* file transfer to contacts */ + { TP_IFACE_CHANNEL_TYPE_FILE_TRANSFER, TP_HANDLE_TYPE_CONTACT }, + /* stream media to contacts */ + { TP_IFACE_CHANNEL_TYPE_STREAMED_MEDIA, TP_HANDLE_TYPE_CONTACT }, + /* stream tubes to contacts and rooms */ + { TP_IFACE_CHANNEL_TYPE_STREAM_TUBE, TP_HANDLE_TYPE_CONTACT }, + { TP_IFACE_CHANNEL_TYPE_STREAM_TUBE, TP_HANDLE_TYPE_ROOM }, + /* d-bus tubes to contacts and rooms */ + { TP_IFACE_CHANNEL_TYPE_DBUS_TUBE, TP_HANDLE_TYPE_CONTACT }, + { TP_IFACE_CHANNEL_TYPE_DBUS_TUBE, TP_HANDLE_TYPE_ROOM }, + /* roomlists */ + { TP_IFACE_CHANNEL_TYPE_ROOM_LIST, TP_HANDLE_TYPE_NONE }, + }; + GStrv capabilities = { NULL }; + int i; + + filters = g_ptr_array_new (); + + for (i = 0 ; i < G_N_ELEMENTS (types); i++) + { + GHashTable *asv; + + asv = tp_asv_new ( + TP_IFACE_CHANNEL ".ChannelType", G_TYPE_STRING, types[i].channeltype, + TP_IFACE_CHANNEL ".TargetHandleType", G_TYPE_INT, types[i].handletype, + NULL); + + g_ptr_array_add (filters, asv); + } + + d = empathy_dispatcher_new (PACKAGE_NAME, filters, capabilities); + + g_ptr_array_foreach (filters, (GFunc) g_hash_table_destroy, NULL); + g_ptr_array_free (filters, TRUE); + + return d; +} + int main (int argc, char *argv[]) { @@ -699,6 +750,10 @@ main (int argc, char *argv[]) g_signal_connect (account_manager, "notify::ready", G_CALLBACK (account_manager_ready_cb), NULL); + /* Handle channels */ + dispatcher = setup_dispatcher (); + g_signal_connect (dispatcher, "dispatch", G_CALLBACK (dispatch_cb), NULL); + migrate_config_to_xdg_dir (); /* Setting up UI */ @@ -708,10 +763,6 @@ main (int argc, char *argv[]) g_signal_connect (unique_app, "message-received", G_CALLBACK (unique_app_message_cb), window); - /* Handle channels */ - dispatcher = empathy_dispatcher_dup_singleton (); - g_signal_connect (dispatcher, "dispatch", G_CALLBACK (dispatch_cb), NULL); - /* Logging */ log_manager = empathy_log_manager_dup_singleton (); empathy_log_manager_observe (log_manager, dispatcher); |