/srv/mercurial-server/detachablepurple: b2166962d9f9: Updated th...
Gilles Bedel
gillux at cpw.pidgin.im
Fri Jun 15 22:01:30 EDT 2012
Changeset: b2166962d9f9b3e93309acde1be476b7bc96ad16
Author: Gilles Bedel <gillux at cpw.pidgin.im>
Date: 2011-05-27 02:07 +0000
Branch: cpw.gillux.detachablepurple
URL: http://hg.pidgin.im/srv/mercurial-server/detachablepurple/rev/b2166962d9f9
Description:
Updated the code that propagates object property changes,
to match the new gdbus library. Still only used by
PurpleAccounts and only from daemon to clients.
diffstat:
libpurple/dbus/account.c | 2 +
libpurple/pobject.c | 72 ++++++++++++++++++++++++++++++++++++++++++++---
libpurple/pobject.h | 11 +++++++
3 files changed, 80 insertions(+), 5 deletions(-)
diffs (144 lines):
diff --git a/libpurple/dbus/account.c b/libpurple/dbus/account.c
--- a/libpurple/dbus/account.c
+++ b/libpurple/dbus/account.c
@@ -227,6 +227,8 @@
purple_object_set_dbus_path(PURPLE_OBJECT(account), dbus_path);
g_free(dbus_path);
+ purple_object_dbus_bind_notify(PURPLE_OBJECT(account));
+
if (purple_core_is_remote_mode() || purple_core_is_mirror_mode()) {
/* For clients connect our wrapper sighandlers */
proxy = purple_object_get_dbus_obj_proxy(PURPLE_OBJECT(account));
diff --git a/libpurple/pobject.c b/libpurple/pobject.c
--- a/libpurple/pobject.c
+++ b/libpurple/pobject.c
@@ -425,13 +425,48 @@
g_value_unset(&prop_val2);
}
+/* Helps purple_object_forward_notify_cb() below.
+ This should be handled by glib somehow, but for the moment
+ it lacks type-independant gvalue/gvariant conversion tools. */
+typedef struct {
+ GType gtype;
+ const GVariantType *gvariant;
+} gtype_gvariant;
+const GVariantType*
+_g_variant_type_from_gvalue(GValue *value)
+{
+ static gtype_gvariant conversion_table[] =
+ { { G_TYPE_BOOLEAN, G_VARIANT_TYPE_BOOLEAN },
+ { G_TYPE_CHAR, G_VARIANT_TYPE_BYTE },
+ { G_TYPE_UCHAR, G_VARIANT_TYPE_BYTE },
+ { G_TYPE_INT, G_VARIANT_TYPE_INT32 },
+ { G_TYPE_UINT, G_VARIANT_TYPE_UINT32 },
+ { G_TYPE_INT64, G_VARIANT_TYPE_INT64 },
+ { G_TYPE_UINT64, G_VARIANT_TYPE_UINT64 },
+ { G_TYPE_DOUBLE, G_VARIANT_TYPE_DOUBLE },
+ { G_TYPE_STRING, G_VARIANT_TYPE_STRING },
+ { G_TYPE_VARIANT, G_VARIANT_TYPE_VARIANT },
+ { 0, NULL } };
+ gtype_gvariant *iter = conversion_table;
+ while (iter) {
+ if (G_VALUE_TYPE(value) == iter->gtype)
+ return iter->gvariant;
+ iter++;
+ }
+ return NULL;
+}
+
static void
purple_object_forward_notify_cb(GObject *gobj, GParamSpec *pspec, gpointer user_data)
{
gchar *prop_name;
GValue prop_val = {0, };
GValue prop_val2 = {0, };
- gchar *interface;
+ GVariant *prop;
+ GVariant *signal_params;
+ char *object_path;
+ GDBusInterfaceInfo *ifaceinfo;
+ GDBusConnection *connection;
/* Note that this "notify" signal may occur even if the property havn't
* changed (when one sets it to its previous value). This can constitute
@@ -439,11 +474,18 @@
* avoid it.
*/
+ /* Check if we are on DBus. Not having a connection can happen
+ during purple initialization, when object properties are
+ modified whereas the bus name is not acquired yet.
+ Not a problem at all. */
+ connection = purple_gdbus_get_connection();
+ if (!connection)
+ return;
+
/* Check if we want to tell clients about this property change */
- interface = purple_object_get_dbus_obj_interface(PURPLE_OBJECT(gobj));
prop_name = g_param_spec_get_name(pspec);
- if (!purple_object_have_dbus_property(PURPLE_OBJECT(gobj), interface,
- prop_name))
+ ifaceinfo = PURPLE_OBJECT_GET_CLASS(gobj)->dbus_ifaceinfo;
+ if (!g_dbus_interface_info_lookup_property(ifaceinfo, prop_name))
return;
/* Get the property. */
@@ -464,7 +506,16 @@
/* Forward this property change to the clients */
purple_debug_info("dbus", "Sending notify about property '%s' of a %s\n",
prop_name, G_OBJECT_TYPE_NAME(gobj));
- g_signal_emit(gobj, signals[SIG_DBUS_NOTIFY], 0, prop_name, &prop_val2);
+ prop = g_dbus_gvalue_to_gvariant(&prop_val2,
+ _g_variant_type_from_gvalue(&prop_val2));
+
+ signal_params = g_variant_new("(sv)", prop_name, prop);
+ object_path = purple_object_get_dbus_path(PURPLE_OBJECT(gobj));
+ g_dbus_connection_emit_signal(connection, NULL,
+ object_path, ifaceinfo->name,
+ "PropertyChanged", signal_params, NULL);
+ g_variant_unref(prop);
+ g_variant_unref(signal_params);
g_value_unset(&prop_val2);
}
@@ -534,6 +585,17 @@
}
void
+purple_object_dbus_bind_notify(PurpleObject *pobj)
+{
+ if (purple_core_is_remote_mode() || purple_core_is_mirror_mode()) {
+ /* TODO */
+ } else if (purple_core_is_daemon_mode())
+ g_signal_connect(pobj, "notify",
+ G_CALLBACK(purple_object_forward_notify_cb),
+ NULL);
+}
+
+void
purple_object_bind_dbus_method(PurpleObjectClass *klass,
const char *method_name,
GCallback func)
diff --git a/libpurple/pobject.h b/libpurple/pobject.h
--- a/libpurple/pobject.h
+++ b/libpurple/pobject.h
@@ -204,6 +204,17 @@
GCallback func);
/**
+ * Makes the relevant object properties changes to be transmitted over DBus.
+ * "Relevant" properties are the one listed in the matching XML file of the
+ * PurpleObject subclass, e.g. account.xml. In client context, it binds a
+ * DBus signal handler that receives properties changes. In daemon context,
+ * it propagates the properties changes with a DBus signal.
+ *
+ * @param pobj The PurpleObject we want to bind notifications for.
+ */
+void purple_object_dbus_bind_notify(PurpleObject *pobj);
+
+/**
* Gets the GClosure created to handle the call of the DBus method
* named method_name.
*
More information about the Commits
mailing list