cpw.gillux.detachablepurple: e40bc5ea: Going multi-interface capable. Objects m...
gillux at soc.pidgin.im
gillux at soc.pidgin.im
Sun May 20 13:22:02 EDT 2012
----------------------------------------------------------------------
Revision: e40bc5ea24e2b3af38d792bcddc2db9e950ccfd4
Parent: 570b9b0ab590f28580d0d2fc0a4d341a95e62c50
Author: gillux at soc.pidgin.im
Date: 05/20/12 09:17:40
Branch: im.pidgin.cpw.gillux.detachablepurple
URL: http://d.pidgin.im/viewmtn/revision/info/e40bc5ea24e2b3af38d792bcddc2db9e950ccfd4
Changelog:
Going multi-interface capable. Objects may now hold several D-Bus interfaces.
This is the first commit of a long series to get things multi-interface. We
are going to to have one interface per class, from the PurpleObject class to
its most derived child class. Therefore we store a set of interfaces for
each class, and register each one when registering an object.
Changes against parent 570b9b0ab590f28580d0d2fc0a4d341a95e62c50
patched libpurple/pobject.c
patched libpurple/pobject.h
-------------- next part --------------
============================================================
--- libpurple/pobject.c b677d4924205565781f5b88fafb7886bc6851372
+++ libpurple/pobject.c 4103522e5b92d8e7ecd8a301730dfa841bd3f0ac
@@ -43,7 +43,7 @@ struct _PurpleObjectPrivate
gpointer ui_data;
/* The gdbus id(s) used to unregister the registered object (in daemon
context) or the registered sighandler (in client context). */
- guint dbus_reg_id;
+ GSList *dbus_reg_id;
/* The dbus interface we use for purple related methods and signals,
* e.g. im.pidgin.purple.account.
*/
@@ -293,8 +293,8 @@ gpointer purple_object_get_ui_data(Purpl
}
#ifdef HAVE_DBUS
-guint
-purple_object_get_dbus_reg_id(PurpleObject *pobj)
+GSList *
+purple_object_get_dbus_reg_ids(PurpleObject *pobj)
{
PurpleObjectPrivate *priv;
@@ -304,13 +304,15 @@ void
}
void
-purple_object_set_dbus_reg_id(PurpleObject *pobj, guint registration_id)
+purple_object_add_dbus_reg_id(PurpleObject *pobj, guint registration_id)
{
PurpleObjectPrivate *priv;
g_return_if_fail(pobj);
priv = PURPLE_OBJECT_GET_PRIVATE(pobj);
- priv->dbus_reg_id = registration_id;
+ /* TODO: unregister on exit. */
+ priv->dbus_reg_id = g_slist_append(priv->dbus_reg_id,
+ GINT_TO_POINTER(registration_id));
}
char*
@@ -827,29 +829,45 @@ purple_object_generic_dbus_set_property(
}
}
-guint
+void
purple_object_generic_dbus_register_object(gpointer object, GDBusConnection *dbus_conn)
{
PurpleObject *pobj = PURPLE_OBJECT(object);
+ PurpleObjectClass *pobjclass = PURPLE_OBJECT_GET_CLASS(object);
GError *error = NULL;
guint reg_id;
+ GDBusInterfaceInfo *ifaceinfo;
+ GType type, child;
static const GDBusInterfaceVTable interface_vtable =
{ purple_object_generic_dbus_method_handler,
purple_object_generic_dbus_get_property,
purple_object_generic_dbus_set_property };
- reg_id = g_dbus_connection_register_object
- (dbus_conn,
- purple_object_get_dbus_path(pobj),
- PURPLE_OBJECT_GET_CLASS(pobj)->dbus_ifaceinfo,
- &interface_vtable,
- object, NULL, &error);
- if (reg_id == 0) {
- purple_debug_error("dbus", "Failed to register a %s: %s\n",
- G_OBJECT_TYPE_NAME(object), error->message);
- g_error_free(error);
+ /* Step from the most derived type to PurpleObject
+ * type and retreive each associated D-Bus interface info. */
+ type = G_OBJECT_TYPE(pobj);
+ do {
+ ifaceinfo = g_datalist_id_get_data(&pobjclass->dbus_ifaceinfos,
+ g_type_qname(type));
+ if (ifaceinfo) {
+ reg_id = g_dbus_connection_register_object
+ (dbus_conn,
+ purple_object_get_dbus_path(pobj),
+ ifaceinfo,
+ &interface_vtable,
+ object, NULL, &error);
+ if (reg_id == 0) {
+ purple_debug_error("dbus",
+ "Failed to register a %s for interface %s\n",
+ G_OBJECT_TYPE_NAME(object), ifaceinfo->name);
+ } else {
+ purple_object_add_dbus_reg_id(pobj, reg_id);
+ }
+ }
+ child = type;
+ type = g_type_parent(type);
}
- return reg_id;
+ while (child != PURPLE_TYPE_OBJECT && child != 0);
}
static void
@@ -907,6 +925,14 @@ void
}
void
+purple_object_class_register_dbus_iface(PurpleObjectClass *pclass,
+ GType type,
+ GDBusInterfaceInfo *i)
+{
+ g_datalist_id_set_data(&pclass->dbus_ifaceinfos, g_type_qname(type),i);
+}
+
+void
purple_object_dbus_connect(gpointer object, GDBusConnection *dbus_conn)
{
PurpleObjectClass *pclass = PURPLE_OBJECT_GET_CLASS(object);
============================================================
--- libpurple/pobject.h 8b3f64ea8b4dd1c9d3dcebe1a5b34b9c2bd640db
+++ libpurple/pobject.h 0ba1763353e82c302094d0ec27b97f0ff4128789
@@ -57,8 +57,10 @@ struct _PurpleObjectClass
/* A data set of DBus methods (in daemon context) or signals (in client
context) names as keys and GClosures as values. */
GData *dbus_callbacks;
- /* The C structure based representation of the XML DBus interface. */
- GDBusInterfaceInfo *dbus_ifaceinfo;
+ /* A data set with GType names as keys and GDBusInterfaceInfo as
+ * values. A GDBusInterfaceInfo is a C struct-based representation
+ * of the XML DBus interface. */
+ GData *dbus_ifaceinfos;
/* Build a unique dbus path name for the object. Only the deamon can
garantee the uniqueness of a name, thus this function should only
be set in daemon mode, or possibly in client mode for well-known
@@ -88,21 +90,21 @@ gpointer purple_object_get_ui_data(Purpl
#ifdef HAVE_DBUS
/**
- * Gets the DBus registration id of the object pobj.
- * An id of zero means no registration, or a registration failed.
+ * Gets the DBus registration id list of the object pobj.
+ * There is one id per D-Bus interface.
*
- * @param pobj The PurpleObject we want to get the registration id from.
- * @return The registration id of pobj.
+ * @param pobj The PurpleObject we want to get the registration ids from.
+ * @return The registration ids of pobj.
*/
-guint purple_object_get_dbus_reg_id(PurpleObject *pobj);
+GSList* purple_object_get_dbus_reg_ids(PurpleObject *pobj);
/**
- * Sets the DBus registration id of the object pobj.
+ * Adds a D-Bus registration id of the object pobj to its list.
*
- * @param pobj The PurpleObject we want to set the registration id in.
- * @param registration_id The registration id we want to set.
+ * @param pobj The PurpleObject we want to add a registration id in.
+ * @param registration_id The registration id we want to add.
*/
-void purple_object_set_dbus_reg_id(PurpleObject *pobj, guint registration_id);
+void purple_object_add_dbus_reg_id(PurpleObject *pobj, guint registration_id);
/**
* Gets the dbus proxy. This is used in detachable sessions context only.
@@ -373,9 +375,8 @@ gboolean purple_object_generic_dbus_set_
*
* @param object An object derived from PurpleObject.
* @param dbus_conn The GDBus handle.
- * @return The registration id returned by g_dbus_connection_register_object().
*/
-guint purple_object_generic_dbus_register_object(gpointer object, GDBusConnection *dbus_conn);
+void purple_object_generic_dbus_register_object(gpointer object, GDBusConnection *dbus_conn);
/**
* Make the given object receive D-Bus signals, with the default signal
@@ -387,6 +388,17 @@ guint purple_object_generic_dbus_signal_
* @return The registration id returned by g_dbus_connection_signal_subscribe().
*/
guint purple_object_generic_dbus_signal_subscribe(gpointer object, GDBusConnection *dbus_conn);
+/**
+ * Adds an D-Bus interface definition to the pool of handled interfaces
+ * by the object class of the given type. This function should be ran by
+ * children class initialization functions.
+ *
+ * @param pclass The super-class of the class on which you add the
+ * interface definition.
+ * @param type The type of the class the interface is for.
+ * @param ifaceinfo A D-Bus interface definition.
+ */
+void purple_object_class_register_dbus_iface(PurpleObjectClass *pclass, GType type, GDBusInterfaceInfo *ifaceinfo);
/**
* Calls the on_dbus_connected function pointer on the class of object,
More information about the Commits
mailing list