/*
* 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_channels (TpSimpleHandler *handler,
* TpAccount *account,
* TpConnection *connection,
* GList *channels,
* GList *requests_satisfied,
* gint64 user_action_time,
* GList *requests,
* TpHandleChannelsContext *context,
* gpointer user_data)
* {
* /<!-- -->* start handling the channels here *<!-- -->/
*
* tp_handle_channels_context_accept (context);
* }
*
* factory = tp_automatic_client_factory_new (dbus);
* client = tp_simple_handler_new_with_factory (factory, FALSE, FALSE,
* "MyHandler", FALSE, my_handle_channels, user_data);
* g_object_unref (factory);
*
* tp_base_client_take_handler_filter (client, 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_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
*/
/**
* TpSimpleHandlerHandleChannelsImpl:
* @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
* @channels: (element-type TelepathyGLib.Channel): a #GList of #TpChannel,
* all 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 #TpHandleChannelsContext 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 HandleChannels method.
*
* This function must call either tp_handle_channels_context_accept(),
* tp_handle_channels_context_delay() or tp_handle_channels_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
{
TpSimpleHandlerHandleChannelsImpl 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_channels (
TpBaseClient *client,
TpAccount *account,
TpConnection *connection,
GList *channels,
GList *requests_satisfied,
gint64 user_action_time,
TpHandleChannelsContext *context)
{
TpSimpleHandler *self = TP_SIMPLE_HANDLER (client);
self->priv->callback (self, account, connection, channels,
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 #TpSimpleHandlerHandleChannelsImpl callback implementing the
* HandleChannels D-Bus method.
*
* This property can't be %NULL.
*
* Since: 0.11.6
*/
param_spec = g_param_spec_pointer ("callback",
"Callback",
"Function called when HandleChannels 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 HandleChannels 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_channels = handle_channels;
}
/**
* tp_simple_handler_new:
* @dbus: a #TpDBusDaemon object, 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 HandleChannels 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 @dbus is not the result of tp_dbus_daemon_dup(), you should call
* tp_simple_handler_new_with_am() instead, so that #TpAccount,
* #TpConnection and #TpContact instances can be shared between modules.
*
* Returns: (type TelepathyGLib.SimpleHandler): a new #TpSimpleHandler
*
* Since: 0.11.6
* Deprecated: New code should use tp_simple_handler_new_with_am() instead.
*/
TpBaseClient *
tp_simple_handler_new (TpDBusDaemon *dbus,
gboolean bypass_approval,
gboolean requests,
const gchar *name,
gboolean uniquify,
TpSimpleHandlerHandleChannelsImpl callback,
gpointer user_data,
GDestroyNotify destroy)
{
return g_object_new (TP_TYPE_SIMPLE_HANDLER,
"dbus-daemon", dbus,
"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 HandleChannels 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,
TpSimpleHandlerHandleChannelsImpl callback,
gpointer user_data,
GDestroyNotify destroy)
{
return g_object_new (TP_TYPE_SIMPLE_HANDLER,
"account-manager", account_manager,
"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_factory:
* @factory: a #TpSimpleClientFactory, 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 HandleChannels 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 #TpSimpleClientFactory.
*
* Returns: (type TelepathyGLib.SimpleHandler): a new #TpSimpleHandler
*
* Since: 0.15.5
*/
TpBaseClient *
tp_simple_handler_new_with_factory (TpSimpleClientFactory *factory,
gboolean bypass_approval,
gboolean requests,
const gchar *name,
gboolean uniquify,
TpSimpleHandlerHandleChannelsImpl 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);
}