/* * Simple implementation of an Handler * * Copyright © 2010 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 */ /** * SECTION: simple-handler * @title: TpSimpleHandler * @short_description: a subclass of #TpBaseClient implementing * a simple Handler * * This class makes it easier to construct a #TpSvcClient implementing the * #TpSvcClientHandler interface. * * A typical simple handler would look liks this: * |[ * static void * my_handle_channel (TpSimpleHandler *handler, * TpAccount *account, * TpConnection *connection, * TpChannel *channel, * GList *requests_satisfied, * gint64 user_action_time, * GList *requests, * TpHandleChannelContext *context, * gpointer user_data) * { * /* start handling the channel here */ * * tp_handle_channel_context_accept (context); * } * * client = tp_simple_handler_new (NULL, FALSE, FALSE, * "MyHandler", FALSE, my_handle_channel, user_data); * * tp_base_client_take_handler_filter (client, * tp_channel_filter_new_for_text_chats ()); * * tp_base_client_register (client, NULL); * ]| * * See examples/client/text-handler.c for a complete example. * * Since: 0.11.6 */ /** * TpSimpleHandler: * * Data structure representing a simple Handler implementation. * * Since: 0.11.6 */ /** * TpSimpleHandlerClass: * * The class of a #TpSimpleHandler. * * Since: 0.11.6 */ /** * TpSimpleHandlerHandleChannelImpl: * @handler: a #TpSimpleHandler instance * @account: a #TpAccount having %TP_ACCOUNT_FEATURE_CORE prepared if possible * @connection: a #TpConnection having %TP_CONNECTION_FEATURE_CORE prepared * if possible * @channel: a #TpChannel, having %TP_CHANNEL_FEATURE_CORE prepared if possible * @requests_satisfied: (element-type TelepathyGLib.ChannelRequest): a #GList of * #TpChannelRequest having their object-path defined but are not guaranteed * to be prepared. * @user_action_time: the time at which user action occurred, or one of the * special values %TP_USER_ACTION_TIME_NOT_USER_ACTION or * %TP_USER_ACTION_TIME_CURRENT_TIME * (see #TpAccountChannelRequest:user-action-time for details) * @context: a #TpHandleChannelContext representing the context of this * D-Bus call * @user_data: arbitrary user-supplied data passed to tp_simple_handler_new() * * Signature of the implementation of the HandleChannel method. * * This function must call either tp_handle_channel_context_accept(), * tp_handle_channel_context_delay() or tp_handle_channel_context_fail() * on @context before it returns. * * Since: 0.11.6 */ #include "config.h" #include "telepathy-glib/simple-handler.h" #define DEBUG_FLAG TP_DEBUG_CLIENT #include "telepathy-glib/debug-internal.h" G_DEFINE_TYPE(TpSimpleHandler, tp_simple_handler, TP_TYPE_BASE_CLIENT) enum { PROP_BYPASS_APPROVAL = 1, PROP_REQUESTS, PROP_CALLBACK, PROP_USER_DATA, PROP_DESTROY, N_PROPS }; struct _TpSimpleHandlerPrivate { TpSimpleHandlerHandleChannelImpl callback; gpointer user_data; GDestroyNotify destroy; }; static void tp_simple_handler_init (TpSimpleHandler *self) { self->priv = G_TYPE_INSTANCE_GET_PRIVATE (self, TP_TYPE_SIMPLE_HANDLER, TpSimpleHandlerPrivate); } static void tp_simple_handler_set_property (GObject *object, guint property_id, const GValue *value, GParamSpec *pspec) { TpBaseClient *base = TP_BASE_CLIENT (object); TpSimpleHandler *self = TP_SIMPLE_HANDLER (object); switch (property_id) { case PROP_BYPASS_APPROVAL: tp_base_client_set_handler_bypass_approval (base, g_value_get_boolean (value)); break; case PROP_REQUESTS: if (g_value_get_boolean (value)) tp_base_client_set_handler_request_notification (base); break; case PROP_CALLBACK: self->priv->callback = g_value_get_pointer (value); break; case PROP_USER_DATA: self->priv->user_data = g_value_get_pointer (value); break; case PROP_DESTROY: self->priv->destroy = g_value_get_pointer (value); break; default: G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec); break; } } static void tp_simple_handler_constructed (GObject *object) { TpSimpleHandler *self = TP_SIMPLE_HANDLER (object); void (*chain_up) (GObject *) = ((GObjectClass *) tp_simple_handler_parent_class)->constructed; g_assert (self->priv->callback != NULL); if (chain_up != NULL) chain_up (object); } static void tp_simple_handler_dispose (GObject *object) { TpSimpleHandler *self = TP_SIMPLE_HANDLER (object); void (*dispose) (GObject *) = G_OBJECT_CLASS (tp_simple_handler_parent_class)->dispose; if (self->priv->destroy != NULL) { self->priv->destroy (self->priv->user_data); self->priv->destroy = NULL; } if (dispose != NULL) dispose (object); } static void handle_channel ( TpBaseClient *client, TpAccount *account, TpConnection *connection, TpChannel *channel, GList *requests_satisfied, gint64 user_action_time, TpHandleChannelContext *context) { TpSimpleHandler *self = TP_SIMPLE_HANDLER (client); self->priv->callback (self, account, connection, channel, requests_satisfied, user_action_time, context, self->priv->user_data); } static void tp_simple_handler_class_init (TpSimpleHandlerClass *cls) { GObjectClass *object_class = G_OBJECT_CLASS (cls); TpBaseClientClass *base_clt_cls = TP_BASE_CLIENT_CLASS (cls); GParamSpec *param_spec; g_type_class_add_private (cls, sizeof (TpSimpleHandlerPrivate)); object_class->set_property = tp_simple_handler_set_property; object_class->constructed = tp_simple_handler_constructed; object_class->dispose = tp_simple_handler_dispose; /** * TpSimpleHandler:bypass-approval: * * The value of the Handler.BypassApproval D-Bus property. * * Since: 0.11.6 */ param_spec = g_param_spec_boolean ("bypass-approval", "bypass approval", "Handler.BypassApproval", FALSE, G_PARAM_WRITABLE | G_PARAM_CONSTRUCT_ONLY | G_PARAM_STATIC_STRINGS); g_object_class_install_property (object_class, PROP_BYPASS_APPROVAL, param_spec); /** * TpSimpleHandler:requests: * * If %TRUE, the Handler will implement the Requests interface * * Since: 0.11.6 */ param_spec = g_param_spec_boolean ("requests", "requests", "Requests", FALSE, G_PARAM_WRITABLE | G_PARAM_CONSTRUCT_ONLY | G_PARAM_STATIC_STRINGS); g_object_class_install_property (object_class, PROP_REQUESTS, param_spec); /** * TpSimpleHandler:callback: * * The #TpSimpleHandlerHandleChannelImpl callback implementing the * HandleChannel D-Bus method. * * This property can't be %NULL. * * Since: 0.11.6 */ param_spec = g_param_spec_pointer ("callback", "Callback", "Function called when HandleChannel is called", G_PARAM_WRITABLE | G_PARAM_CONSTRUCT_ONLY | G_PARAM_STATIC_STRINGS); g_object_class_install_property (object_class, PROP_CALLBACK, param_spec); /** * TpSimpleHandler:user-data: * * The user-data pointer passed to #TpSimpleHandler:callback. * * Since: 0.11.6 */ param_spec = g_param_spec_pointer ("user-data", "user data", "pointer passed as user-data when HandleChannel is called", G_PARAM_WRITABLE | G_PARAM_CONSTRUCT_ONLY | G_PARAM_STATIC_STRINGS); g_object_class_install_property (object_class, PROP_USER_DATA, param_spec); /** * TpSimpleHandler:destroy: * * The #GDestroyNotify function called to free #TpSimpleHandler:user-data * when the #TpSimpleHandler is destroyed. * * Since: 0.11.6 */ param_spec = g_param_spec_pointer ("destroy", "destroy", "function called to destroy the user-data when destroying the handler", G_PARAM_WRITABLE | G_PARAM_CONSTRUCT_ONLY | G_PARAM_STATIC_STRINGS); g_object_class_install_property (object_class, PROP_DESTROY, param_spec); base_clt_cls->handle_channel = handle_channel; } /** * tp_simple_handler_new: * @factory: a #TpClientFactory, or %NULL * @bypass_approval: the value of the Handler.BypassApproval D-Bus property * (see tp_base_client_set_handler_bypass_approval() for details) * @requests: whether this handler should implement Requests (see * tp_base_client_set_handler_request_notification() for details) * @name: the name of the Handler (see #TpBaseClient:name for details) * @uniquify: the value of the #TpBaseClient:uniquify-name property * @callback: the function called when HandleChannel is called * @user_data: arbitrary user-supplied data passed to @callback * @destroy: called with @user_data as its argument when the #TpSimpleHandler * is destroyed * * Convenient function to create a new #TpSimpleHandler instance. * * If @factory is %NULL a new #TpAutomaticClientFactory will be used. * * Returns: (type TelepathyGLib.SimpleHandler): a new #TpSimpleHandler * * Since: 0.99.1 */ TpBaseClient * tp_simple_handler_new (TpClientFactory *factory, gboolean bypass_approval, gboolean requests, const gchar *name, gboolean uniquify, TpSimpleHandlerHandleChannelImpl callback, gpointer user_data, GDestroyNotify destroy) { return g_object_new (TP_TYPE_SIMPLE_HANDLER, "factory", factory, "bypass-approval", bypass_approval, "requests", requests, "name", name, "uniquify-name", uniquify, "callback", callback, "user-data", user_data, "destroy", destroy, NULL); } /** * tp_simple_handler_new_with_am: * @account_manager: an account manager, which may not be %NULL * @bypass_approval: the value of the Handler.BypassApproval D-Bus property * (see tp_base_client_set_handler_bypass_approval() for details) * @requests: whether this handler should implement Requests (see * tp_base_client_set_handler_request_notification() for details) * @name: the name of the Handler (see #TpBaseClient:name for details) * @uniquify: the value of the #TpBaseClient:uniquify-name property * @callback: the function called when HandleChannel is called * @user_data: arbitrary user-supplied data passed to @callback * @destroy: called with @user_data as its argument when the #TpSimpleHandler * is destroyed * * Convenient function to create a new #TpSimpleHandler instance with a * specified #TpAccountManager. * * It is not necessary to prepare any features on @account_manager before * calling this function. * * Returns: (type TelepathyGLib.SimpleHandler): a new #TpSimpleHandler * * Since: 0.11.14 */ TpBaseClient * tp_simple_handler_new_with_am (TpAccountManager *account_manager, gboolean bypass_approval, gboolean requests, const gchar *name, gboolean uniquify, TpSimpleHandlerHandleChannelImpl callback, gpointer user_data, GDestroyNotify destroy) { return tp_simple_handler_new (tp_proxy_get_factory (account_manager), bypass_approval, requests, name, uniquify, callback, user_data, destroy); }