diff options
author | Xavier Claessens <xavier.claessens@collabora.com> | 2014-04-10 23:21:53 -0400 |
---|---|---|
committer | Simon McVittie <simon.mcvittie@collabora.co.uk> | 2014-04-17 14:22:29 +0100 |
commit | 69584cd0059d60401ded4f634107a9fb093a830b (patch) | |
tree | 03fc889ca8562c959ec04a0864de892afc75f39b | |
parent | 0787479d7ce2236e346d633d01b9ff64ac214a1a (diff) |
TpPresenceMixin: Convert it to a GInterface
It is much easier to use, and should be introspectable
-rw-r--r-- | docs/reference/telepathy-glib/telepathy-glib-sections.txt | 24 | ||||
-rw-r--r-- | examples/cm/call/conn.c | 63 | ||||
-rw-r--r-- | examples/cm/call/conn.h | 2 | ||||
-rw-r--r-- | examples/cm/contactlist/conn.c | 50 | ||||
-rw-r--r-- | examples/cm/contactlist/conn.h | 2 | ||||
-rw-r--r-- | telepathy-glib/base-connection-internal.h | 67 | ||||
-rw-r--r-- | telepathy-glib/base-connection.c | 63 | ||||
-rw-r--r-- | telepathy-glib/presence-mixin.c | 476 | ||||
-rw-r--r-- | telepathy-glib/presence-mixin.h | 105 | ||||
-rw-r--r-- | telepathy-glib/versions/main-1.0.abi | 7 | ||||
-rw-r--r-- | tests/lib/contacts-conn.c | 52 | ||||
-rw-r--r-- | tests/lib/contacts-conn.h | 3 |
12 files changed, 321 insertions, 593 deletions
diff --git a/docs/reference/telepathy-glib/telepathy-glib-sections.txt b/docs/reference/telepathy-glib/telepathy-glib-sections.txt index 220235765..03e4559bf 100644 --- a/docs/reference/telepathy-glib/telepathy-glib-sections.txt +++ b/docs/reference/telepathy-glib/telepathy-glib-sections.txt @@ -1682,28 +1682,16 @@ TpPresenceStatus tp_presence_status_new tp_presence_status_free <TITLE>TpPresenceMixin</TITLE> -TpPresenceMixin -TpPresenceMixinClass -tp_presence_mixin_class_init -tp_presence_mixin_init -tp_presence_mixin_finalize +TpPresenceMixinInterface tp_presence_mixin_emit_presence_update tp_presence_mixin_emit_one_presence_update -tp_presence_mixin_fill_contact_attributes -<SUBSECTION Private> -TP_PRESENCE_MIXIN_CLASS_OFFSET_QUARK -TP_PRESENCE_MIXIN_CLASS_OFFSET -TP_PRESENCE_MIXIN_OFFSET_QUARK -TP_PRESENCE_MIXIN_OFFSET -tp_presence_mixin_class_get_offset_quark -tp_presence_mixin_get_offset_quark -TpPresenceMixinPrivate -TpPresenceMixinClassPrivate -<SUBSECTION Standard> -TP_PRESENCE_MIXIN_CLASS -TP_PRESENCE_MIXIN +<SUBSECTION Standard> +TP_TYPE_PRESENCE_MIXIN +TP_IS_PRESENCE_MIXIN +TP_PRESENCE_MIXIN_GET_INTERFACE TpPresenceStatusSpecPrivate tp_presence_status_spec_get_type +tp_presence_mixin_get_type </SECTION> <SECTION> diff --git a/examples/cm/call/conn.c b/examples/cm/call/conn.c index 8c7c50a33..3d1c1d3c5 100644 --- a/examples/cm/call/conn.c +++ b/examples/cm/call/conn.c @@ -31,8 +31,12 @@ #include "call-manager.h" #include "protocol.h" -G_DEFINE_TYPE (ExampleCallConnection, example_call_connection, - TP_TYPE_BASE_CONNECTION) +static void init_presence (gpointer g_iface, + gpointer iface_data); + +G_DEFINE_TYPE_WITH_CODE (ExampleCallConnection, example_call_connection, + TP_TYPE_BASE_CONNECTION, + G_IMPLEMENT_INTERFACE (TP_TYPE_PRESENCE_MIXIN, init_presence)) enum { @@ -206,35 +210,18 @@ shut_down (TpBaseConnection *conn) tp_base_connection_finish_shutdown (conn); } -static void -constructed (GObject *object) -{ - void (*chain_up) (GObject *) = - G_OBJECT_CLASS (example_call_connection_parent_class)->constructed; - - if (chain_up != NULL) - chain_up (object); - - tp_presence_mixin_init (object, - G_STRUCT_OFFSET (ExampleCallConnection, presence_mixin)); -} - static gboolean -status_available (GObject *object, +status_available (TpBaseConnection *base, guint index_) { - TpBaseConnection *base = TP_BASE_CONNECTION (object); - return tp_base_connection_check_connected (base, NULL); } static TpPresenceStatus * -get_contact_status (GObject *object, +get_contact_status (TpBaseConnection *base, TpHandle contact) { - ExampleCallConnection *self = - EXAMPLE_CALL_CONNECTION (object); - TpBaseConnection *base = TP_BASE_CONNECTION (object); + ExampleCallConnection *self = EXAMPLE_CALL_CONNECTION (base); ExampleCallPresence presence; const gchar *message; @@ -256,13 +243,11 @@ get_contact_status (GObject *object, } static gboolean -set_own_status (GObject *object, +set_own_status (TpBaseConnection *base, const TpPresenceStatus *status, GError **error) { - ExampleCallConnection *self = - EXAMPLE_CALL_CONNECTION (object); - TpBaseConnection *base = TP_BASE_CONNECTION (object); + ExampleCallConnection *self = EXAMPLE_CALL_CONNECTION (base); GHashTable *presences; if (status->index == EXAMPLE_CALL_PRESENCE_AWAY) @@ -290,7 +275,7 @@ set_own_status (GObject *object, g_hash_table_insert (presences, GUINT_TO_POINTER (tp_base_connection_get_self_handle (base)), (gpointer) status); - tp_presence_mixin_emit_presence_update (object, presences); + tp_presence_mixin_emit_presence_update (base, presences); g_hash_table_unref (presences); if (!self->priv->away) @@ -324,17 +309,15 @@ example_call_connection_get_possible_interfaces (void) } static void -example_call_connection_fill_contact_attributes (TpBaseConnection *conn, - const gchar *dbus_interface, - TpHandle contact, - GVariantDict *attributes) +init_presence (gpointer g_iface, + gpointer iface_data) { - if (tp_presence_mixin_fill_contact_attributes (G_OBJECT (conn), - dbus_interface, contact, attributes)) - return; + TpPresenceMixinInterface *iface = g_iface; - ((TpBaseConnectionClass *) example_call_connection_parent_class)-> - fill_contact_attributes (conn, dbus_interface, contact, attributes); + iface->status_available = status_available; + iface->get_contact_status = get_contact_status; + iface->set_own_status = set_own_status; + iface->statuses = presence_statuses; } static void @@ -347,7 +330,6 @@ example_call_connection_class_init ( object_class->get_property = get_property; object_class->set_property = set_property; - object_class->constructed = constructed; object_class->finalize = finalize; g_type_class_add_private (klass, sizeof (ExampleCallConnectionPrivate)); @@ -357,8 +339,6 @@ example_call_connection_class_init ( base_class->create_channel_managers = create_channel_managers; base_class->start_connecting = start_connecting; base_class->shut_down = shut_down; - base_class->fill_contact_attributes = - example_call_connection_fill_contact_attributes; param_spec = g_param_spec_string ("account", "Account name", "The username of this user", NULL, @@ -377,9 +357,4 @@ example_call_connection_class_init ( signals[SIGNAL_AVAILABLE] = g_signal_new ("available", G_TYPE_FROM_CLASS (klass), G_SIGNAL_RUN_LAST, 0, NULL, NULL, NULL, G_TYPE_NONE, 1, G_TYPE_STRING); - - tp_presence_mixin_class_init (object_class, - G_STRUCT_OFFSET (ExampleCallConnectionClass, presence_mixin), - status_available, get_contact_status, set_own_status, - presence_statuses); } diff --git a/examples/cm/call/conn.h b/examples/cm/call/conn.h index 56a252602..bb2404df8 100644 --- a/examples/cm/call/conn.h +++ b/examples/cm/call/conn.h @@ -27,14 +27,12 @@ typedef struct _ExampleCallConnectionClassPrivate struct _ExampleCallConnectionClass { TpBaseConnectionClass parent_class; - TpPresenceMixinClass presence_mixin; ExampleCallConnectionClassPrivate *priv; }; struct _ExampleCallConnection { TpBaseConnection parent; - TpPresenceMixin presence_mixin; ExampleCallConnectionPrivate *priv; }; diff --git a/examples/cm/contactlist/conn.c b/examples/cm/contactlist/conn.c index 0bcda0271..307ccdc87 100644 --- a/examples/cm/contactlist/conn.c +++ b/examples/cm/contactlist/conn.c @@ -22,12 +22,14 @@ #include "protocol.h" static void init_aliasing (gpointer, gpointer); +static void init_presence (gpointer, gpointer); G_DEFINE_TYPE_WITH_CODE (ExampleContactListConnection, example_contact_list_connection, TP_TYPE_BASE_CONNECTION, G_IMPLEMENT_INTERFACE (TP_TYPE_SVC_CONNECTION_INTERFACE_ALIASING1, init_aliasing) + G_IMPLEMENT_INTERFACE (TP_TYPE_PRESENCE_MIXIN, init_presence) ) enum @@ -175,8 +177,7 @@ presence_updated_cb (ExampleContactList *contact_list, status = tp_presence_status_new ( example_contact_list_get_presence (contact_list, contact), NULL); - tp_presence_mixin_emit_one_presence_update ((GObject *) self, - contact, status); + tp_presence_mixin_emit_one_presence_update (base, contact, status); tp_presence_status_free (status); } @@ -244,10 +245,6 @@ example_contact_list_connection_fill_contact_attributes (TpBaseConnection *conn, dbus_interface, contact, attributes)) return; - if (tp_presence_mixin_fill_contact_attributes (G_OBJECT (conn), - dbus_interface, contact, attributes)) - return; - ((TpBaseConnectionClass *) example_contact_list_connection_parent_class)-> fill_contact_attributes (conn, dbus_interface, contact, attributes); } @@ -275,9 +272,6 @@ constructed (GObject *object) g_signal_connect (self->priv->contact_list, "presence-updated", G_CALLBACK (presence_updated_cb), self); - tp_presence_mixin_init (object, - G_STRUCT_OFFSET (ExampleContactListConnection, presence_mixin)); - iface = tp_svc_interface_skeleton_new (skel, TP_TYPE_SVC_CONNECTION_INTERFACE_ALIASING1); g_dbus_object_skeleton_add_interface (skel, iface); @@ -285,21 +279,17 @@ constructed (GObject *object) } static gboolean -status_available (GObject *object, - guint index_) +status_available (TpBaseConnection *base, + guint index_) { - TpBaseConnection *base = TP_BASE_CONNECTION (object); - return tp_base_connection_check_connected (base, NULL); } static TpPresenceStatus * -get_contact_status (GObject *object, +get_contact_status (TpBaseConnection *base, TpHandle contact) { - ExampleContactListConnection *self = - EXAMPLE_CONTACT_LIST_CONNECTION (object); - TpBaseConnection *base = TP_BASE_CONNECTION (object); + ExampleContactListConnection *self = EXAMPLE_CONTACT_LIST_CONNECTION (base); ExampleContactListPresence presence; /* we get our own status from the connection, and everyone else's status @@ -319,13 +309,11 @@ get_contact_status (GObject *object, } static gboolean -set_own_status (GObject *object, +set_own_status (TpBaseConnection *base, const TpPresenceStatus *status, GError **error) { - ExampleContactListConnection *self = - EXAMPLE_CONTACT_LIST_CONNECTION (object); - TpBaseConnection *base = TP_BASE_CONNECTION (object); + ExampleContactListConnection *self = EXAMPLE_CONTACT_LIST_CONNECTION (base); GHashTable *presences; if (status->index == EXAMPLE_CONTACT_LIST_PRESENCE_AWAY) @@ -348,11 +336,24 @@ set_own_status (GObject *object, g_hash_table_insert (presences, GUINT_TO_POINTER (tp_base_connection_get_self_handle (base)), (gpointer) status); - tp_presence_mixin_emit_presence_update (object, presences); + tp_presence_mixin_emit_presence_update (base, presences); g_hash_table_unref (presences); return TRUE; } +static void +init_presence (gpointer g_iface, + gpointer iface_data) +{ + TpPresenceMixinInterface *iface = g_iface; + + iface->status_available = status_available; + iface->get_contact_status = get_contact_status; + iface->set_own_status = set_own_status; + iface->statuses = example_contact_list_presence_statuses (); +} + + static const gchar *interfaces_always_present[] = { TP_IFACE_CONNECTION_INTERFACE_ALIASING1, TP_IFACE_CONNECTION_INTERFACE_CONTACT_LIST1, @@ -439,11 +440,6 @@ example_contact_list_connection_class_init ( g_object_class_install_property (object_class, PROP_SIMULATION_DELAY, param_spec); - tp_presence_mixin_class_init (object_class, - G_STRUCT_OFFSET (ExampleContactListConnectionClass, presence_mixin), - status_available, get_contact_status, set_own_status, - example_contact_list_presence_statuses ()); - klass->properties_mixin.interfaces = prop_interfaces; tp_dbus_properties_mixin_class_init (object_class, G_STRUCT_OFFSET (ExampleContactListConnectionClass, properties_mixin)); diff --git a/examples/cm/contactlist/conn.h b/examples/cm/contactlist/conn.h index b54524564..6bfa53a20 100644 --- a/examples/cm/contactlist/conn.h +++ b/examples/cm/contactlist/conn.h @@ -25,13 +25,11 @@ typedef struct _ExampleContactListConnectionPrivate struct _ExampleContactListConnectionClass { TpBaseConnectionClass parent_class; - TpPresenceMixinClass presence_mixin; TpDBusPropertiesMixinClass properties_mixin; }; struct _ExampleContactListConnection { TpBaseConnection parent; - TpPresenceMixin presence_mixin; ExampleContactListConnectionPrivate *priv; }; diff --git a/telepathy-glib/base-connection-internal.h b/telepathy-glib/base-connection-internal.h index 64fba2517..2c572ec77 100644 --- a/telepathy-glib/base-connection-internal.h +++ b/telepathy-glib/base-connection-internal.h @@ -22,10 +22,70 @@ #ifndef __TP_BASE_CONNECTION_INTERNAL_H__ #define __TP_BASE_CONNECTION_INTERNAL_H__ +#include <telepathy-glib/_gdbus/Connection.h> +#include <telepathy-glib/_gdbus/Connection_Interface_Presence1.h> +#include <telepathy-glib/_gdbus/Connection_Interface_Requests.h> + #include <telepathy-glib/base-connection.h> G_BEGIN_DECLS +struct _TpBaseConnectionPrivate +{ + gchar *bus_name; + gchar *object_path; + + TpConnectionStatus status; + + TpHandle self_handle; + const gchar *self_id; + + /* Telepathy properties */ + gchar *protocol; + + /* if TRUE, the object has gone away */ + gboolean dispose_has_run; + /* array of (TpChannelManager *) */ + GPtrArray *channel_managers; + /* array of reffed (TpChannelManagerRequest *) */ + GPtrArray *channel_requests; + + TpHandleRepoIface *handles[TP_NUM_ENTITY_TYPES]; + + /* Created in constructed, this is an array of static strings which + * represent the interfaces on this connection. + * + * Note that this is a GArray of gchar*, not a GPtrArray, + * so that we can use GArray's convenient auto-null-termination. */ + GArray *interfaces; + + /* Array of GDBusMethodInvocation * representing Disconnect calls. + * If NULL and we are in a state != DISCONNECTED, then we have not started + * shutting down yet. + * If NULL and we are in state DISCONNECTED, then we have finished shutting + * down. + * If not NULL, we are trying to shut down (and must be in state + * DISCONNECTED). */ + GPtrArray *disconnect_requests; + + GDBusConnection *dbus_connection; + /* TRUE after constructor() returns */ + gboolean been_constructed; + /* TRUE if on D-Bus */ + gboolean been_registered; + + /* g_strdup (unique name) => owned ClientData struct */ + GHashTable *clients; + /* GQuark iface => number of clients interested */ + GHashTable *interests; + + gchar *account_path_suffix; + + _TpGDBusConnection *connection_skeleton; + _TpGDBusConnectionInterfaceRequests *requests_skeleton; + _TpGDBusConnectionInterfacePresence1 *presence_skeleton; +}; + void _tp_base_connection_set_handle_repo (TpBaseConnection *self, TpEntityType entity_type, TpHandleRepoIface *handle_repo); @@ -39,6 +99,13 @@ GVariant *_tp_base_connection_dup_contact_attributes_hash ( const gchar * const *interfaces, const gchar * const *assumed_interfaces); +/* TpPresenceMixin */ +void _tp_presence_mixin_init (TpBaseConnection *self); +gboolean _tp_presence_mixin_fill_contact_attributes (TpBaseConnection *self, + const gchar *dbus_interface, + TpHandle contact, + GVariantDict *attributes); + G_END_DECLS #endif diff --git a/telepathy-glib/base-connection.c b/telepathy-glib/base-connection.c index 886cb74bc..9ac6fbe63 100644 --- a/telepathy-glib/base-connection.c +++ b/telepathy-glib/base-connection.c @@ -217,9 +217,6 @@ #include <telepathy-glib/util.h> #include <telepathy-glib/value-array.h> -#include <telepathy-glib/_gdbus/Connection.h> -#include <telepathy-glib/_gdbus/Connection_Interface_Requests.h> - #define DEBUG_FLAG TP_DEBUG_CONNECTION #include "telepathy-glib/debug-internal.h" #include "telepathy-glib/variant-util-internal.h" @@ -277,54 +274,6 @@ channel_request_cancel (gpointer data, _tp_channel_manager_request_cancel (request); } -struct _TpBaseConnectionPrivate -{ - gchar *bus_name; - gchar *object_path; - - TpConnectionStatus status; - - TpHandle self_handle; - const gchar *self_id; - - /* Telepathy properties */ - gchar *protocol; - - /* if TRUE, the object has gone away */ - gboolean dispose_has_run; - /* array of (TpChannelManager *) */ - GPtrArray *channel_managers; - /* array of reffed (TpChannelManagerRequest *) */ - GPtrArray *channel_requests; - - TpHandleRepoIface *handles[TP_NUM_ENTITY_TYPES]; - - /* Array of GDBusMethodInvocation * representing Disconnect calls. - * If NULL and we are in a state != DISCONNECTED, then we have not started - * shutting down yet. - * If NULL and we are in state DISCONNECTED, then we have finished shutting - * down. - * If not NULL, we are trying to shut down (and must be in state - * DISCONNECTED). */ - GPtrArray *disconnect_requests; - - GDBusConnection *dbus_connection; - /* TRUE after constructor() returns */ - gboolean been_constructed; - /* TRUE if on D-Bus */ - gboolean been_registered; - - /* g_strdup (unique name) => owned ClientData struct */ - GHashTable *clients; - /* GQuark iface => number of clients interested */ - GHashTable *interests; - - gchar *account_path_suffix; - - _TpGDBusConnection *connection_skeleton; - _TpGDBusConnectionInterfaceRequests *requests_skeleton; -}; - typedef struct { /* GQuark iface => count */ @@ -495,6 +444,7 @@ tp_base_connection_dispose (GObject *object) g_clear_object (&self->priv->connection_skeleton); g_clear_object (&self->priv->requests_skeleton); + g_clear_object (&self->priv->presence_skeleton); if (G_OBJECT_CLASS (tp_base_connection_parent_class)->dispose) G_OBJECT_CLASS (tp_base_connection_parent_class)->dispose (object); @@ -823,6 +773,11 @@ tp_base_connection_constructed (GObject *object) G_CALLBACK (tp_base_connection_interface_changed_cb), GINT_TO_POINTER (-1)); + if (TP_IS_PRESENCE_MIXIN (self)) + { + _tp_presence_mixin_init (self); + } + /* We don't have any interfaces yet (except for Connection and Requests) * so it's OK that the default for _TpGDBusConnection:interfaces is NULL. */ } @@ -971,6 +926,10 @@ _tp_base_connection_fill_contact_attributes (TpBaseConnection *self, { const gchar *tmp; + if (_tp_presence_mixin_fill_contact_attributes (self, dbus_interface, contact, + attributes)) + return; + if (tp_strdiff (dbus_interface, TP_IFACE_CONNECTION)) { DEBUG ("contact #%u: interface '%s' unhandled", contact, dbus_interface); @@ -1067,7 +1026,7 @@ tp_base_connection_class_init (TpBaseConnectionClass *klass) * * If this property is %NULL or omitted during construction, the object will * automatically attempt to connect to the session bus with - * g_bus_get_sync() just after it is constructed; if this fails, this + * g_bus_get_sync() just after it is ; if this fails, this * property will remain %NULL, and tp_base_connection_register() will fail. * * Since: 0.99.10 diff --git a/telepathy-glib/presence-mixin.c b/telepathy-glib/presence-mixin.c index 6720eab4e..792b0d224 100644 --- a/telepathy-glib/presence-mixin.c +++ b/telepathy-glib/presence-mixin.c @@ -20,53 +20,14 @@ /** * SECTION:presence-mixin - * @title: TpPresenceMixin - * @short_description: a mixin implementation of the Presence connection - * interface - * - * This mixin can be added to a #TpBaseConnection subclass to implement the - * Presence interface. - * - * To use the presence mixin, include a #TpPresenceMixinClass somewhere in your - * class structure and a #TpPresenceMixin somewhere in your instance structure, - * and call tp_presence_mixin_class_init() from your class_init function, - * tp_presence_mixin_init() from your init function or constructor, and - * tp_presence_mixin_finalize() from your dispose or finalize function. - * - * <section> - * <title>Implementing Presence</title> - * <para> - * Since 0.7.13 this mixin supports the entire Presence interface. - * You can implement #TpSvcConnectionInterfacePresence1 as follows: - * <itemizedlist> - * <listitem> - * <para>in the #TpBaseConnectionClass.fill_contact_attributes - * implementation, call tp_presence_mixin_fill_contact_attributes() - * and do not chain up if it returns %TRUE: - * </para> - * |[ - * // ... - * if (!tp_strdiff (dbus_interface, MY_IFACE_CONNECTION_INTERFACE_HATS)) - * { - * // ... fill in Hats attributes ... - * return; - * } - * - * if (tp_presence_mixin_fill_contact_attributes (G_OBJECT (self), - * dbus_interface, contact, attributes)) - * { - * return; - * } - * - * ((TpBaseConnectionClass *) my_connection_parent_class)-> - * fill_contact_attributes (self, dbus_interface, contact, attributes); - * ]| - * </listitem> - * </itemizedlist> - * </para> - * </section> - * - * Since: 0.5.13 + * @title: TpPresenceMixinInterface + * @short_description: an interface that can be implemented on #TpBaseConnection + * subclasses to add support for presence. + * + * #TpBaseConnection subclasses can implement this interface to implement the + * corresponding DBus interface. + * + * Since: 0.UNRELEASED */ /** @@ -98,17 +59,15 @@ /** * TpPresenceMixinStatusAvailableFunc: - * @obj: An instance of a #TpBaseConnection subclass implementing the presence - * interface with this mixin + * @self: A #TpBaseConnection implemeting #TpPresenceMixinInterface * @which: An index into the array of #TpPresenceStatusSpec provided to * tp_presence_mixin_class_init() * * Signature of a callback to be used to determine if a given presence - * status can be set on the connection. Most users of this mixin do not need to - * supply an implementation of this callback: the value of + * status can be set on the connection. Most users of this interface do not need + * to supply an implementation of this callback: the value of * #TpPresenceStatusSpec.self is enough to determine whether this is a - * user-settable presence, so %NULL should be passed to - * tp_presence_mixin_class_init() for this callback. + * user-settable presence. * * One place where this callback may be needed is on XMPP: not all server * implementation support the user becoming invisible. So an XMPP @@ -123,7 +82,7 @@ /** * TpPresenceMixinGetContactStatusFunc: - * @obj: An object with this mixin. + * @self: A #TpBaseConnection implemeting #TpPresenceMixinInterface * @contact: A #TpHandle of type %TP_ENTITY_TYPE_CONTACT * * Return the contact's status @@ -133,7 +92,7 @@ /** * TpPresenceMixinSetOwnStatusFunc: - * @obj: An object with this mixin. + * @self: A #TpBaseConnection implemeting #TpPresenceMixinInterface * @status: The status to set, or NULL for whatever the protocol defines as a * "default" status * @error: Used to return a Telepathy D-Bus error if %FALSE is returned @@ -151,7 +110,7 @@ /** * TpPresenceMixinGetMaximumStatusMessageLengthFunc: - * @obj: An object with this mixin. + * @self: A #TpBaseConnection implemeting #TpPresenceMixinInterface * * Signature of a callback used to determine the maximum length of status * messages. If this callback is provided and returns non-zero, the @@ -164,46 +123,24 @@ */ /** - * TpPresenceMixinClass: - * @status_available: The status-available function that was passed to - * tp_presence_mixin_class_init() - * @get_contact_status: The get-contact-status function that was passed to - * tp_presence_mixin_class_init() - * @set_own_status: The set-own-status function that was passed to - * tp_presence_mixin_class_init() - * @statuses: The presence statuses array that was passed to - * tp_presence_mixin_class_init() + * TpPresenceMixinInterface: + * @parent: the parent interface + * @status_available: A callback to be used to determine if a given presence + * status can be set on a particular connection. Should usually be %NULL, to + * consider all statuses with #TpPresenceStatusSpec.self set to %TRUE to be + * settable. + * @get_contact_status: A callback to be used get the current presence status + * for contacts. This is used in implementations of various D-Bus methods and + * hence must be provided. + * @set_own_status: A callback to be used to commit changes to the user's own + * presence status to the server. This is used in implementations of various + * D-Bus methods and hence must be provided. * @get_maximum_status_message_length: The callback used to discover the - * the limit for status messages length, if any. Since: 0.14.5 - * - * Structure to be included in the class structure of objects that - * use this mixin. Initialize it with tp_presence_mixin_class_init(). - * - * If the protocol imposes a limit on the length of status messages, one should - * implement @get_maximum_status_message_length. If this callback is not - * implemented, it is assumed that there is no limit. The callback function - * should be set after calling tp_presence_mixin_class_init(), like so: - * - * |[ - * TpPresenceMixinClass *mixin_class; - * - * tp_presence_mixin_class_init ((GObjectClass *) klass, - * G_STRUCT_OFFSET (SomeObjectClass, presence_mixin)); - * mixin_class = TP_PRESENCE_MIXIN_CLASS (klass); - * mixin_class->get_maximum_status_message_length = - * some_object_get_maximum_status_message_length; - * ]| - * - * All other fields should be considered read-only. - */ - -/** - * TpPresenceMixin: - * - * Structure to be included in the instance structure of objects that - * use this mixin. Initialize it with tp_presence_mixin_init(). + * the limit for status messages length, if any. + * @statuses: An array of #TpPresenceStatusSpec structures representing all + * presence statuses supported by the protocol, terminated by a NULL name. * - * There are no public fields. + * The interface vtable for a %TP_TYPE_PRESENCE_MIXIN. */ #include "config.h" @@ -213,8 +150,6 @@ #include <dbus/dbus-glib.h> #include <string.h> -#include <telepathy-glib/_gdbus/Connection_Interface_Presence1.h> - #include <telepathy-glib/base-connection.h> #include <telepathy-glib/dbus-properties-mixin.h> #include <telepathy-glib/enums.h> @@ -228,6 +163,7 @@ #define DEBUG_FLAG TP_DEBUG_PRESENCE #include "debug-internal.h" +#include "base-connection-internal.h" struct _TpPresenceMixinPrivate { @@ -283,110 +219,57 @@ tp_presence_status_free (TpPresenceStatus *status) g_slice_free (TpPresenceStatus, status); } +G_DEFINE_INTERFACE (TpPresenceMixin, tp_presence_mixin, TP_TYPE_BASE_CONNECTION) -/** - * tp_presence_mixin_class_get_offset_quark: (skip) - * - * <!--no documentation beyond Returns: needed--> - * - * Returns: the quark used for storing mixin offset on a GObjectClass - */ -GQuark -tp_presence_mixin_class_get_offset_quark () +static void update_statuses_property (TpBaseConnection *self); +static void update_max_status_message_len_property (TpBaseConnection *self); +static gboolean tp_presence_mixin_set_presence ( + _TpGDBusConnectionInterfacePresence1 *skeleton, + GDBusMethodInvocation *context, + const gchar *status, + const gchar *message, + TpBaseConnection *self); + +static void +tp_presence_mixin_default_init (TpPresenceMixinInterface *iface) { - static GQuark offset_quark = 0; - if (!offset_quark) - offset_quark = g_quark_from_static_string ("TpPresenceMixinClassOffsetQuark"); - return offset_quark; } -/** - * tp_presence_mixin_get_offset_quark: (skip) - * - * <!--no documentation beyond Returns: needed--> - * - * Returns: the quark used for storing mixin offset on a GObject - */ -GQuark -tp_presence_mixin_get_offset_quark () +static void +connection_status_changed_cb (TpBaseConnection *self, + TpConnectionStatus status, + TpConnectionStatusReason reason, + gpointer user_data) { - static GQuark offset_quark = 0; - if (!offset_quark) - offset_quark = g_quark_from_static_string ("TpPresenceMixinOffsetQuark"); - return offset_quark; + if (status == TP_CONNECTION_STATUS_CONNECTED) + { + update_statuses_property (self); + update_max_status_message_len_property (self); + } } -/** - * tp_presence_mixin_class_init: (skip) - * @obj_cls: The class of the implementation that uses this mixin - * @offset: The byte offset of the TpPresenceMixinClass within the class - * structure - * @status_available: A callback to be used to determine if a given presence - * status can be set on a particular connection. Should usually be %NULL, to - * consider all statuses with #TpPresenceStatusSpec.self set to %TRUE to be - * settable. - * @get_contact_status: A callback to be used get the current presence status - * for contacts. This is used in implementations of various D-Bus methods and - * hence must be provided. - * @set_own_status: A callback to be used to commit changes to the user's own - * presence status to the server. This is used in implementations of various - * D-Bus methods and hence must be provided. - * @statuses: An array of #TpPresenceStatusSpec structures representing all - * presence statuses supported by the protocol, terminated by a NULL name. - * - * Initialize the presence mixin. Should be called from the implementation's - * class_init function like so: - * - * <informalexample><programlisting> - * tp_presence_mixin_class_init ((GObjectClass *) klass, - * G_STRUCT_OFFSET (SomeObjectClass, - * presence_mixin)); - * </programlisting></informalexample> - */ - void -tp_presence_mixin_class_init (GObjectClass *obj_cls, - glong offset, - TpPresenceMixinStatusAvailableFunc status_available, - TpPresenceMixinGetContactStatusFunc get_contact_status, - TpPresenceMixinSetOwnStatusFunc set_own_status, - const TpPresenceStatusSpec *statuses) +_tp_presence_mixin_init (TpBaseConnection *self) { - TpPresenceMixinClass *mixin_cls; + TpPresenceMixinInterface *iface = TP_PRESENCE_MIXIN_GET_INTERFACE (self); guint i; - DEBUG ("called."); - - g_assert (get_contact_status != NULL); - g_assert (set_own_status != NULL); - g_assert (statuses != NULL); + g_assert (iface->get_contact_status != NULL); + g_assert (iface->set_own_status != NULL); + g_assert (iface->statuses != NULL); - g_assert (G_IS_OBJECT_CLASS (obj_cls)); - - g_type_set_qdata (G_OBJECT_CLASS_TYPE (obj_cls), - TP_PRESENCE_MIXIN_CLASS_OFFSET_QUARK, - GINT_TO_POINTER (offset)); - - mixin_cls = TP_PRESENCE_MIXIN_CLASS (obj_cls); - - mixin_cls->status_available = status_available; - mixin_cls->get_contact_status = get_contact_status; - mixin_cls->set_own_status = set_own_status; - mixin_cls->statuses = statuses; - mixin_cls->get_maximum_status_message_length = NULL; - - for (i = 0; statuses[i].name != NULL; i++) + for (i = 0; iface->statuses[i].name != NULL; i++) { - if (statuses[i].self) + if (iface->statuses[i].self) { - switch (statuses[i].presence_type) + switch (iface->statuses[i].presence_type) { case TP_CONNECTION_PRESENCE_TYPE_OFFLINE: case TP_CONNECTION_PRESENCE_TYPE_UNKNOWN: case TP_CONNECTION_PRESENCE_TYPE_ERROR: WARNING ("Status \"%s\" of type %u should not be available " - "to set on yourself", statuses[i].name, - statuses[i].presence_type); + "to set on yourself", iface->statuses[i].name, + iface->statuses[i].presence_type); break; default: @@ -394,99 +277,26 @@ tp_presence_mixin_class_init (GObjectClass *obj_cls, } } } -} - -static void update_statuses_property (TpPresenceMixin *self, - GObject *object); -static void update_max_status_message_len_property (TpPresenceMixin *self, - GObject *object); -static gboolean tp_presence_mixin_set_presence ( - _TpGDBusConnectionInterfacePresence1 *skeleton, - GDBusMethodInvocation *context, - const gchar *status, - const gchar *message, - GObject *obj); - -static void -connection_status_changed_cb (GObject *object, - TpConnectionStatus status, - TpConnectionStatusReason reason, - TpPresenceMixin *self) -{ - if (status == TP_CONNECTION_STATUS_CONNECTED) - { - update_statuses_property (self, object); - update_max_status_message_len_property (self, object); - } -} - -/** - * tp_presence_mixin_init: (skip) - * @obj: An instance of the implementation that uses this mixin - * @offset: The byte offset of the TpPresenceMixin within the object structure - * - * Initialize the presence mixin. Should be called from the implementation's - * instance init function like so: - * - * <informalexample><programlisting> - * tp_presence_mixin_init ((GObject *) self, - * G_STRUCT_OFFSET (SomeObject, presence_mixin)); - * </programlisting></informalexample> - * - * Since 0.99.1 @obj must be a #TpBaseConnection subclass. - */ -void -tp_presence_mixin_init (GObject *obj, - glong offset) -{ - TpPresenceMixin *self; - - DEBUG ("called."); - g_assert (TP_IS_BASE_CONNECTION (obj)); + self->priv->presence_skeleton = + _tp_gdbus_connection_interface_presence1_skeleton_new (); - g_type_set_qdata (G_OBJECT_TYPE (obj), - TP_PRESENCE_MIXIN_OFFSET_QUARK, - GINT_TO_POINTER (offset)); - - self = TP_PRESENCE_MIXIN (obj); - self->priv = g_slice_new0 (TpPresenceMixinPrivate); - - self->priv->skeleton = _tp_gdbus_connection_interface_presence1_skeleton_new (); - g_signal_connect_object (self->priv->skeleton, "handle-set-presence", - G_CALLBACK (tp_presence_mixin_set_presence), obj, 0); + g_signal_connect_object (self->priv->presence_skeleton, "handle-set-presence", + G_CALLBACK (tp_presence_mixin_set_presence), self, 0); /* Set the initial properties values, we'll update them once CONNECTED */ - update_max_status_message_len_property (self, obj); - update_statuses_property (self, obj); - g_signal_connect (obj, "status-changed", - G_CALLBACK (connection_status_changed_cb), self); - - g_dbus_object_skeleton_add_interface (G_DBUS_OBJECT_SKELETON (obj), - G_DBUS_INTERFACE_SKELETON (self->priv->skeleton)); -} - -/** - * tp_presence_mixin_finalize: (skip) - * @obj: An object with this mixin. - * - * Free resources held by the presence mixin. - */ -void -tp_presence_mixin_finalize (GObject *obj) -{ - TpPresenceMixin *self = TP_PRESENCE_MIXIN (obj); - - DEBUG ("%p", obj); + update_max_status_message_len_property (self); + update_statuses_property (self); + g_signal_connect (self, "status-changed", + G_CALLBACK (connection_status_changed_cb), NULL); - g_object_unref (self->priv->skeleton); - - g_slice_free (TpPresenceMixinPrivate, self->priv); + g_dbus_object_skeleton_add_interface (G_DBUS_OBJECT_SKELETON (self), + G_DBUS_INTERFACE_SKELETON (self->priv->presence_skeleton)); } /** * tp_presence_mixin_emit_presence_update: (skip) - * @obj: A connection object with this mixin + * @self: A #TpBaseConnection implemeting #TpPresenceMixinInterface * @contact_presences: A mapping of contact handles to #TpPresenceStatus * structures with the presence data to emit * @@ -495,33 +305,29 @@ tp_presence_mixin_finalize (GObject *obj) * #tp_presence_mixin_emit_one_presence_update. */ void -tp_presence_mixin_emit_presence_update (GObject *obj, +tp_presence_mixin_emit_presence_update (TpBaseConnection *self, GHashTable *contact_statuses) { - TpPresenceMixin *self = TP_PRESENCE_MIXIN (obj); - TpPresenceMixinClass *mixin_cls = - TP_PRESENCE_MIXIN_CLASS (G_OBJECT_GET_CLASS (obj)); + TpPresenceMixinInterface *iface = TP_PRESENCE_MIXIN_GET_INTERFACE (self); DEBUG ("called."); _tp_gdbus_connection_interface_presence1_emit_presences_changed ( - self->priv->skeleton, - construct_presence_hash (mixin_cls->statuses, contact_statuses)); + self->priv->presence_skeleton, + construct_presence_hash (iface->statuses, contact_statuses)); } - /** - * tp_presence_mixin_emit_one_presence_update: (skip) - * @obj: A connection object with this mixin + * tp_presence_mixin_emit_one_presence_update: + * @self: A #TpBaseConnection implemeting #TpPresenceMixinInterface * @handle: The handle of the contact to emit the signal for * @status: The new status to emit * * Emit a presence update signal for a single contact. This method is - * just a convenience wrapper around - * #tp_presence_mixin_emit_presence_update. + * just a convenience wrapper around tp_presence_mixin_emit_presence_update(). */ void -tp_presence_mixin_emit_one_presence_update (GObject *obj, +tp_presence_mixin_emit_one_presence_update (TpBaseConnection *self, TpHandle handle, const TpPresenceStatus *status) { @@ -532,38 +338,38 @@ tp_presence_mixin_emit_one_presence_update (GObject *obj, contact_statuses = g_hash_table_new (NULL, NULL); g_hash_table_insert (contact_statuses, GUINT_TO_POINTER (handle), (gpointer) status); - tp_presence_mixin_emit_presence_update (obj, contact_statuses); + tp_presence_mixin_emit_presence_update (self, contact_statuses); g_hash_table_unref (contact_statuses); } static gboolean -check_status_available (GObject *object, - TpPresenceMixinClass *mixin_cls, - guint i, - GError **error, - gboolean for_self) +check_status_available (TpBaseConnection *self, + TpPresenceMixinInterface *iface, + guint i, + GError **error, + gboolean for_self) { if (for_self) { - if (!mixin_cls->statuses[i].self) + if (!iface->statuses[i].self) { g_set_error (error, TP_ERROR, TP_ERROR_INVALID_ARGUMENT, "cannot set status '%s' on yourself", - mixin_cls->statuses[i].name); + iface->statuses[i].name); return FALSE; } /* never allow OFFLINE, UNKNOWN or ERROR - if the CM says they're * OK to set on yourself, then it's wrong */ - switch (mixin_cls->statuses[i].presence_type) + switch (iface->statuses[i].presence_type) { case TP_CONNECTION_PRESENCE_TYPE_OFFLINE: case TP_CONNECTION_PRESENCE_TYPE_UNKNOWN: case TP_CONNECTION_PRESENCE_TYPE_ERROR: g_set_error (error, TP_ERROR, TP_ERROR_INVALID_ARGUMENT, "cannot set offline/unknown/error status '%s' on yourself", - mixin_cls->statuses[i].name); + iface->statuses[i].name); return FALSE; default: @@ -571,14 +377,13 @@ check_status_available (GObject *object, } } - if (mixin_cls->status_available - && !mixin_cls->status_available (object, i)) + if (iface->status_available != NULL && !iface->status_available (self, i)) { DEBUG ("requested status %s is not available", - mixin_cls->statuses[i].name); + iface->statuses[i].name); g_set_error (error, TP_ERROR, TP_ERROR_NOT_AVAILABLE, "requested status '%s' is not available on this connection", - mixin_cls->statuses[i].name); + iface->statuses[i].name); return FALSE; } @@ -586,24 +391,25 @@ check_status_available (GObject *object, } static int -check_for_status (GObject *object, const gchar *status, GError **error) +check_for_status (TpBaseConnection *self, + const gchar *status, + GError **error) { - TpPresenceMixinClass *mixin_cls = - TP_PRESENCE_MIXIN_CLASS (G_OBJECT_GET_CLASS (object)); + TpPresenceMixinInterface *iface = TP_PRESENCE_MIXIN_GET_INTERFACE (self); int i; - for (i = 0; mixin_cls->statuses[i].name != NULL; i++) + for (i = 0; iface->statuses[i].name != NULL; i++) { - if (!tp_strdiff (mixin_cls->statuses[i].name, status)) + if (!tp_strdiff (iface->statuses[i].name, status)) break; } - if (mixin_cls->statuses[i].name != NULL) + if (iface->statuses[i].name != NULL) { DEBUG ("Found status \"%s\", checking if it's available...", (const gchar *) status); - if (!check_status_available (object, mixin_cls, i, error, TRUE)) + if (!check_status_available (self, iface, i, error, TRUE)) return -1; } else @@ -618,80 +424,66 @@ check_for_status (GObject *object, const gchar *status, GError **error) } static void -update_statuses_property (TpPresenceMixin *self, - GObject *object) +update_statuses_property (TpBaseConnection *self) { - TpPresenceMixinClass *mixin_cls = - TP_PRESENCE_MIXIN_CLASS (G_OBJECT_GET_CLASS (object)); + TpPresenceMixinInterface *iface = TP_PRESENCE_MIXIN_GET_INTERFACE (self); GVariantBuilder builder; int i; g_variant_builder_init (&builder, G_VARIANT_TYPE ("a{s(ubb)}")); - for (i = 0; mixin_cls->statuses[i].name != NULL; i++) + for (i = 0; iface->statuses[i].name != NULL; i++) { gboolean message; /* we include statuses here even if they're not available * to set on yourself */ - if (!check_status_available (object, mixin_cls, i, NULL, FALSE)) + if (!check_status_available (self, iface, i, NULL, FALSE)) continue; message = tp_presence_status_spec_has_message ( - &mixin_cls->statuses[i]); + &iface->statuses[i]); g_variant_builder_add (&builder, "{s(ubb)}", - mixin_cls->statuses[i].name, - mixin_cls->statuses[i].presence_type, - mixin_cls->statuses[i].self, + iface->statuses[i].name, + iface->statuses[i].presence_type, + iface->statuses[i].self, message); } - _tp_gdbus_connection_interface_presence1_set_statuses (self->priv->skeleton, + _tp_gdbus_connection_interface_presence1_set_statuses ( + self->priv->presence_skeleton, g_variant_builder_end (&builder)); } static void -update_max_status_message_len_property (TpPresenceMixin *self, - GObject *object) +update_max_status_message_len_property (TpBaseConnection *self) { - TpPresenceMixinClass *mixin_cls = - TP_PRESENCE_MIXIN_CLASS (G_OBJECT_GET_CLASS (object)); + TpPresenceMixinInterface *iface = TP_PRESENCE_MIXIN_GET_INTERFACE (self); guint max_status_message_length = 0; - if (mixin_cls->get_maximum_status_message_length != NULL) - max_status_message_length = - mixin_cls->get_maximum_status_message_length (object); + if (iface->get_maximum_status_message_length != NULL) + max_status_message_length = iface->get_maximum_status_message_length (self); _tp_gdbus_connection_interface_presence1_set_maximum_status_message_length ( - self->priv->skeleton, max_status_message_length); + self->priv->presence_skeleton, max_status_message_length); } -/* - * tp_presence_mixin_set_presence: - * - * Implements D-Bus method SetPresence - * on interface im.telepathy.v1.Connection.Interface.Presence - * - * @context: The D-Bus invocation context to use to return values - * or throw an error. - */ static gboolean tp_presence_mixin_set_presence ( _TpGDBusConnectionInterfacePresence1 *skeleton, GDBusMethodInvocation *context, const gchar *status, const gchar *message, - GObject *obj) + TpBaseConnection *self) { - TpPresenceMixinClass *mixin_cls = - TP_PRESENCE_MIXIN_CLASS (G_OBJECT_GET_CLASS (obj)); + TpPresenceMixinInterface *iface = TP_PRESENCE_MIXIN_GET_INTERFACE (self); TpPresenceStatus status_to_set = { 0, }; int s; GError *error = NULL; DEBUG ("called."); - s = check_for_status (obj, status, &error); + s = check_for_status (self, status, &error); if (s == -1) goto out; @@ -701,7 +493,7 @@ tp_presence_mixin_set_presence ( status_to_set.index = s; status_to_set.message = g_strdup (message); - mixin_cls->set_own_status (obj, &status_to_set, &error); + iface->set_own_status (self, &status_to_set, &error); g_free (status_to_set.message); @@ -763,33 +555,19 @@ construct_presence_hash (const TpPresenceStatusSpec *supported_statuses, return g_variant_builder_end (&builder); } -/** - * tp_presence_mixin_fill_contact_attributes: - * @obj: an object with a #TpPresenceMixin - * @dbus_interface: a D-Bus interface - * @contact: a contact - * @attributes: used to return attributes - * - * If @dbus_interface is an interface that is relevant for this - * object, fill @attributes with the attributes for @contact - * and return %TRUE. - * - * Returns: %TRUE if @dbus_interface was recognised - */ gboolean -tp_presence_mixin_fill_contact_attributes (GObject *obj, +_tp_presence_mixin_fill_contact_attributes (TpBaseConnection *self, const gchar *dbus_interface, TpHandle contact, GVariantDict *attributes) { - TpPresenceMixinClass *mixin_cls = - TP_PRESENCE_MIXIN_CLASS (G_OBJECT_GET_CLASS (obj)); + TpPresenceMixinInterface *iface = TP_PRESENCE_MIXIN_GET_INTERFACE (self); TpPresenceStatus *status; if (tp_strdiff (dbus_interface, TP_IFACE_CONNECTION_INTERFACE_PRESENCE1)) return FALSE; - status = mixin_cls->get_contact_status (obj, contact); + status = iface->get_contact_status (self, contact); if (status == NULL) { @@ -799,7 +577,7 @@ tp_presence_mixin_fill_contact_attributes (GObject *obj, { g_variant_dict_insert_value (attributes, TP_TOKEN_CONNECTION_INTERFACE_PRESENCE1_PRESENCE, - construct_presence_variant (status, mixin_cls->statuses)); + construct_presence_variant (status, iface->statuses)); tp_presence_status_free (status); } return TRUE; diff --git a/telepathy-glib/presence-mixin.h b/telepathy-glib/presence-mixin.h index ac14c0279..ed4483487 100644 --- a/telepathy-glib/presence-mixin.h +++ b/telepathy-glib/presence-mixin.h @@ -32,6 +32,8 @@ G_BEGIN_DECLS +/* -- TpPresenceStatusSpec -- */ + typedef struct _TpPresenceStatusSpec TpPresenceStatusSpec; typedef struct _TpPresenceStatusSpecPrivate TpPresenceStatusSpecPrivate; @@ -78,6 +80,9 @@ TpPresenceStatusSpec *tp_presence_status_spec_copy ( _TP_AVAILABLE_IN_1_0 void tp_presence_status_spec_free (TpPresenceStatusSpec *self); +/* -- TpPresenceStatus -- */ + + typedef struct _TpPresenceStatus TpPresenceStatus; struct _TpPresenceStatus { @@ -92,82 +97,56 @@ TpPresenceStatus *tp_presence_status_new (guint which, const gchar *message) G_GNUC_WARN_UNUSED_RESULT; void tp_presence_status_free (TpPresenceStatus *status); -typedef gboolean (*TpPresenceMixinStatusAvailableFunc) (GObject *obj, - guint which); +/* -- TpPresenceMixinInterface -- */ -typedef TpPresenceStatus *(*TpPresenceMixinGetContactStatusFunc) (GObject *obj, - TpHandle contact); +#define TP_TYPE_PRESENCE_MIXIN \ + (tp_presence_mixin_get_type ()) -typedef gboolean (*TpPresenceMixinSetOwnStatusFunc) (GObject *obj, - const TpPresenceStatus *status, GError **error); +#define TP_IS_PRESENCE_MIXIN(obj) \ + (G_TYPE_CHECK_INSTANCE_TYPE ((obj), \ + TP_TYPE_PRESENCE_MIXIN)) -typedef guint (*TpPresenceMixinGetMaximumStatusMessageLengthFunc) ( - GObject *obj); +#define TP_PRESENCE_MIXIN_GET_INTERFACE(obj) \ + (G_TYPE_INSTANCE_GET_INTERFACE ((obj), \ + TP_TYPE_PRESENCE_MIXIN, TpPresenceMixinInterface)) -typedef struct _TpPresenceMixinClass TpPresenceMixinClass; -typedef struct _TpPresenceMixinClassPrivate TpPresenceMixinClassPrivate; -typedef struct _TpPresenceMixin TpPresenceMixin; -typedef struct _TpPresenceMixinPrivate TpPresenceMixinPrivate; +typedef struct _TpPresenceMixinInterface TpPresenceMixinInterface; +/* For some reason g-i wants that name */ +typedef struct _TpPresenceMixinInterface TpPresenceMixin; -struct _TpPresenceMixinClass { - TpPresenceMixinStatusAvailableFunc status_available; - TpPresenceMixinGetContactStatusFunc get_contact_status; - TpPresenceMixinSetOwnStatusFunc set_own_status; +typedef gboolean (*TpPresenceMixinStatusAvailableFunc) (TpBaseConnection *self, + guint which); - const TpPresenceStatusSpec *statuses; +typedef TpPresenceStatus *(*TpPresenceMixinGetContactStatusFunc) ( + TpBaseConnection *self, + TpHandle contact); - /*<private>*/ - TpPresenceMixinClassPrivate *priv; +typedef gboolean (*TpPresenceMixinSetOwnStatusFunc) (TpBaseConnection *self, + const TpPresenceStatus *status, + GError **error); - /*<public>*/ - TpPresenceMixinGetMaximumStatusMessageLengthFunc get_maximum_status_message_length; +typedef guint (*TpPresenceMixinGetMaximumStatusMessageLengthFunc) ( + TpBaseConnection *self); - /*<private>*/ - GCallback _future[10]; -}; +struct _TpPresenceMixinInterface { + GTypeInterface parent; -struct _TpPresenceMixin { - /*<private>*/ - TpPresenceMixinPrivate *priv; + TpPresenceMixinStatusAvailableFunc status_available; + TpPresenceMixinGetContactStatusFunc get_contact_status; + TpPresenceMixinSetOwnStatusFunc set_own_status; + TpPresenceMixinGetMaximumStatusMessageLengthFunc + get_maximum_status_message_length; + + const TpPresenceStatusSpec *statuses; }; -/* TYPE MACROS */ -#define TP_PRESENCE_MIXIN_CLASS_OFFSET_QUARK \ - (tp_presence_mixin_class_get_offset_quark ()) -#define TP_PRESENCE_MIXIN_CLASS_OFFSET(o) \ - tp_mixin_class_get_offset (o, TP_PRESENCE_MIXIN_CLASS_OFFSET_QUARK) -#define TP_PRESENCE_MIXIN_CLASS(o) \ - ((TpPresenceMixinClass *) tp_mixin_offset_cast (o, \ - TP_PRESENCE_MIXIN_CLASS_OFFSET (o))) - -#define TP_PRESENCE_MIXIN_OFFSET_QUARK (tp_presence_mixin_get_offset_quark ()) -#define TP_PRESENCE_MIXIN_OFFSET(o) \ - tp_mixin_instance_get_offset (o, TP_PRESENCE_MIXIN_OFFSET_QUARK) -#define TP_PRESENCE_MIXIN(o) \ - ((TpPresenceMixin *) tp_mixin_offset_cast (o, TP_PRESENCE_MIXIN_OFFSET (o))) - -GQuark tp_presence_mixin_class_get_offset_quark (void); -GQuark tp_presence_mixin_get_offset_quark (void); - -void tp_presence_mixin_class_init (GObjectClass *obj_cls, glong offset, - TpPresenceMixinStatusAvailableFunc status_available, - TpPresenceMixinGetContactStatusFunc get_contact_status, - TpPresenceMixinSetOwnStatusFunc set_own_status, - const TpPresenceStatusSpec *statuses); - -void tp_presence_mixin_init (GObject *obj, glong offset); -void tp_presence_mixin_finalize (GObject *obj); - -void tp_presence_mixin_emit_presence_update (GObject *obj, - GHashTable *contact_presences); -void tp_presence_mixin_emit_one_presence_update (GObject *obj, - TpHandle handle, const TpPresenceStatus *status); +GType tp_presence_mixin_get_type (void) G_GNUC_CONST; -_TP_AVAILABLE_IN_1_0 -gboolean tp_presence_mixin_fill_contact_attributes (GObject *obj, - const gchar *dbus_interface, - TpHandle contact, - GVariantDict *attributes); +void tp_presence_mixin_emit_presence_update (TpBaseConnection *self, + GHashTable *contact_presences); +void tp_presence_mixin_emit_one_presence_update (TpBaseConnection *self, + TpHandle handle, + const TpPresenceStatus *status); G_END_DECLS diff --git a/telepathy-glib/versions/main-1.0.abi b/telepathy-glib/versions/main-1.0.abi index b090554be..896f53d87 100644 --- a/telepathy-glib/versions/main-1.0.abi +++ b/telepathy-glib/versions/main-1.0.abi @@ -988,14 +988,9 @@ tp_observe_channel_context_fail tp_observe_channel_context_get_requests tp_observe_channel_context_get_type tp_observe_channel_context_is_recovering -tp_presence_mixin_class_get_offset_quark -tp_presence_mixin_class_init tp_presence_mixin_emit_one_presence_update tp_presence_mixin_emit_presence_update -tp_presence_mixin_fill_contact_attributes -tp_presence_mixin_finalize -tp_presence_mixin_get_offset_quark -tp_presence_mixin_init +tp_presence_mixin_get_type tp_presence_status_free tp_presence_status_new tp_presence_status_spec_can_set_on_self diff --git a/tests/lib/contacts-conn.c b/tests/lib/contacts-conn.c index a2562cb00..539c9bb8f 100644 --- a/tests/lib/contacts-conn.c +++ b/tests/lib/contacts-conn.c @@ -24,12 +24,14 @@ static void init_aliasing (gpointer, gpointer); static void init_avatars (gpointer, gpointer); static void init_contact_info (gpointer, gpointer); +static void init_presence (gpointer, gpointer); static void conn_avatars_properties_getter (GObject *object, GQuark interface, GQuark name, GValue *value, gpointer getter_data); G_DEFINE_TYPE_WITH_CODE (TpTestsContactsConnection, tp_tests_contacts_connection, TP_TESTS_TYPE_SIMPLE_CONNECTION, + G_IMPLEMENT_INTERFACE (TP_TYPE_PRESENCE_MIXIN, init_presence) G_IMPLEMENT_INTERFACE (TP_TYPE_SVC_CONNECTION_INTERFACE_ALIASING1, init_aliasing); G_IMPLEMENT_INTERFACE (TP_TYPE_SVC_CONNECTION_INTERFACE_AVATARS1, @@ -296,10 +298,6 @@ tp_tests_contacts_connection_fill_contact_attributes (TpBaseConnection *base, dbus_interface, contact, attributes)) return; - if (tp_presence_mixin_fill_contact_attributes (G_OBJECT (self), - dbus_interface, contact, attributes)) - return; - ((TpBaseConnectionClass *) tp_tests_contacts_connection_parent_class)-> fill_contact_attributes (base, dbus_interface, contact, attributes); } @@ -414,9 +412,6 @@ constructed (GObject *object) self->priv->list_manager = g_object_new (TP_TESTS_TYPE_CONTACT_LIST_MANAGER, "connection", self, NULL); - - tp_presence_mixin_init (object, - G_STRUCT_OFFSET (TpTestsContactsConnection, presence_mixin)); } /* Must match TpTestsContactsConnectionPresenceStatusIndex in the .h */ @@ -431,19 +426,17 @@ static const TpPresenceStatusSpec my_statuses[] = { }; static gboolean -my_status_available (GObject *object, - guint index) +my_status_available (TpBaseConnection *base, + guint index) { - TpBaseConnection *base = TP_BASE_CONNECTION (object); - return tp_base_connection_check_connected (base, NULL); } static TpPresenceStatus * -my_get_contact_status (GObject *object, +my_get_contact_status (TpBaseConnection *base_conn, TpHandle contact) { - TpTestsContactsConnection *self = TP_TESTS_CONTACTS_CONNECTION (object); + TpTestsContactsConnection *self = TP_TESTS_CONTACTS_CONNECTION (base_conn); gpointer key = GUINT_TO_POINTER (contact); TpTestsContactsConnectionPresenceStatusIndex index; const gchar *presence_message; @@ -457,28 +450,42 @@ my_get_contact_status (GObject *object, } static gboolean -my_set_own_status (GObject *object, +my_set_own_status (TpBaseConnection *base_conn, const TpPresenceStatus *status, GError **error) { - TpBaseConnection *base_conn = TP_BASE_CONNECTION (object); TpTestsContactsConnectionPresenceStatusIndex index = status->index; const gchar *message = status->message; TpHandle self_handle; self_handle = tp_base_connection_get_self_handle (base_conn); - tp_tests_contacts_connection_change_presences (TP_TESTS_CONTACTS_CONNECTION (object), + tp_tests_contacts_connection_change_presences ( + TP_TESTS_CONTACTS_CONNECTION (base_conn), 1, &self_handle, &index, &message); return TRUE; } static guint -my_get_maximum_status_message_length_cb (GObject *obj) +my_get_maximum_status_message_length_cb (TpBaseConnection *base_conn) { return 512; } +static void +init_presence (gpointer g_iface, + gpointer iface_data) +{ + TpPresenceMixinInterface *iface = g_iface; + + iface->status_available = my_status_available; + iface->get_contact_status = my_get_contact_status; + iface->set_own_status = my_set_own_status; + iface->statuses = my_statuses; + iface->get_maximum_status_message_length = + my_get_maximum_status_message_length_cb; +} + static GPtrArray * create_channel_managers (TpBaseConnection *conn) { @@ -514,7 +521,6 @@ tp_tests_contacts_connection_class_init (TpTestsContactsConnectionClass *klass) TpBaseConnectionClass *base_class = (TpBaseConnectionClass *) klass; GObjectClass *object_class = (GObjectClass *) klass; - TpPresenceMixinClass *mixin_class; static TpDBusPropertiesMixinPropImpl aliasing_props[] = { { "AliasFlags", GUINT_TO_POINTER (ALIASING_DP_ALIAS_FLAGS), NULL }, { NULL } @@ -547,14 +553,6 @@ tp_tests_contacts_connection_class_init (TpTestsContactsConnectionClass *klass) base_class->fill_contact_attributes = tp_tests_contacts_connection_fill_contact_attributes; - tp_presence_mixin_class_init (object_class, - G_STRUCT_OFFSET (TpTestsContactsConnectionClass, presence_mixin), - my_status_available, my_get_contact_status, - my_set_own_status, my_statuses); - mixin_class = TP_PRESENCE_MIXIN_CLASS(klass); - mixin_class->get_maximum_status_message_length = - my_get_maximum_status_message_length_cb; - klass->properties_class.interfaces = prop_interfaces; tp_dbus_properties_mixin_class_init (object_class, G_STRUCT_OFFSET (TpTestsContactsConnectionClass, properties_class)); @@ -628,7 +626,7 @@ tp_tests_contacts_connection_change_presences ( messages[i])); } - tp_presence_mixin_emit_presence_update ((GObject *) self, + tp_presence_mixin_emit_presence_update ((TpBaseConnection *) self, presences); g_hash_table_unref (presences); } diff --git a/tests/lib/contacts-conn.h b/tests/lib/contacts-conn.h index aaa826e2e..2d77c4eed 100644 --- a/tests/lib/contacts-conn.h +++ b/tests/lib/contacts-conn.h @@ -27,15 +27,12 @@ typedef struct _TpTestsContactsConnectionPrivate TpTestsContactsConnectionPrivat struct _TpTestsContactsConnectionClass { TpTestsSimpleConnectionClass parent_class; - TpPresenceMixinClass presence_mixin; TpDBusPropertiesMixinClass properties_class; }; struct _TpTestsContactsConnection { TpTestsSimpleConnection parent; - TpPresenceMixin presence_mixin; - TpTestsContactsConnectionPrivate *priv; }; |