summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorXavier Claessens <xavier.claessens@collabora.com>2014-04-10 23:21:53 -0400
committerSimon McVittie <simon.mcvittie@collabora.co.uk>2014-04-17 14:22:29 +0100
commit69584cd0059d60401ded4f634107a9fb093a830b (patch)
tree03fc889ca8562c959ec04a0864de892afc75f39b
parent0787479d7ce2236e346d633d01b9ff64ac214a1a (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.txt24
-rw-r--r--examples/cm/call/conn.c63
-rw-r--r--examples/cm/call/conn.h2
-rw-r--r--examples/cm/contactlist/conn.c50
-rw-r--r--examples/cm/contactlist/conn.h2
-rw-r--r--telepathy-glib/base-connection-internal.h67
-rw-r--r--telepathy-glib/base-connection.c63
-rw-r--r--telepathy-glib/presence-mixin.c476
-rw-r--r--telepathy-glib/presence-mixin.h105
-rw-r--r--telepathy-glib/versions/main-1.0.abi7
-rw-r--r--tests/lib/contacts-conn.c52
-rw-r--r--tests/lib/contacts-conn.h3
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;
};