soc.2010.detachablepurple: 11dfbe58: Added a mechanism to send a dbus signal ...

gillux at soc.pidgin.im gillux at soc.pidgin.im
Sat Jul 17 10:38:08 EDT 2010


----------------------------------------------------------------------
Revision: 11dfbe583683cd073529aed0719494003cbd4914
Parent:   b5d57c238c9e8ba5c9ef084e6e9e251bb6539177
Author:   gillux at soc.pidgin.im
Date:     07/17/10 10:22:25
Branch:   im.pidgin.soc.2010.detachablepurple
URL: http://d.pidgin.im/viewmtn/revision/info/11dfbe583683cd073529aed0719494003cbd4914

Changelog: 

Added a mechanism to send a dbus signal when the "notify" glib signal happens
on a property we export on dbus. This is the daemon part of the "daemon to
client properties updates".

Changes against parent b5d57c238c9e8ba5c9ef084e6e9e251bb6539177

  patched  libpurple/dbus-prototypes/account.xml
  patched  libpurple/pobject.c

-------------- next part --------------
============================================================
--- libpurple/pobject.c	739d68f1dc9151b6bfd0e63c57ff81431adeca58
+++ libpurple/pobject.c	536c0e526dacea76fa9f61acb9e18175c440f239
@@ -22,6 +22,7 @@
 #include "internal.h"
 #include "core.h"
 #include "dbus-maybe.h"
+#include "marshallers.h"
 #include "pobject.h"
 
 #ifdef HAVE_DBUS
@@ -58,6 +59,7 @@ enum
 	SIG_NEW,
 	SIG_DESTROYING,
 	SIG_DESTROYED,
+	SIG_DBUS_NOTIFY,
 	SIG_LAST
 };
 
@@ -138,6 +140,17 @@ purple_object_class_init(PurpleObjectCla
 				0, 0, NULL, NULL,
 				g_cclosure_marshal_VOID__VOID, G_TYPE_NONE, 0);
 
+	if (purple_core_is_daemon_mode()) {
+		/* Signals to propagate infos from the daemon to the clients */
+		signals[SIG_DBUS_NOTIFY] =
+			g_signal_new("d_bus_notify",
+				G_OBJECT_CLASS_TYPE(klass),
+				G_SIGNAL_RUN_LAST,
+				0, NULL, NULL,
+				purple_smarshal_VOID__STRING_BOXED,
+				G_TYPE_NONE, 2, G_TYPE_STRING, G_TYPE_VALUE);
+	}
+
 	g_type_class_add_private(klass, sizeof(PurpleObjectPrivate));
 }
 
@@ -268,6 +281,56 @@ purple_object_set_dbus_path(PurpleObject
 	priv->dbus_path = g_strdup(path);
 }
 
+gboolean
+purple_object_have_dbus_property(PurpleObject *pobj, const gchar *interface, const gchar *prop_name)
+{
+	GPtrArray *props;
+	int i;
+	gboolean exported_prop = FALSE;
+
+	/* Let's see if we export this property on dbus */
+	props = purple_object_get_dbus_props(G_OBJECT_TYPE(pobj), interface);
+	for (i = 0; i < props->len; i++) {
+		if (purple_strequal(prop_name, props->pdata[i])) {
+			exported_prop = TRUE;
+			break;
+		}
+	}
+	g_ptr_array_foreach(props, (GFunc)g_free, NULL);
+	g_ptr_array_free(props, TRUE);
+
+	return exported_prop;
+}
+
+static void
+purple_object_forward_notify_cb(GObject *gobj, GParamSpec *pspec, gpointer user_data)
+{
+	gchar *prop_name;
+	GValue prop_val = {0, };
+	gchar *interface;
+
+	/* 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
+	 * a heavy cost as we send this on dbus. This would be great if we could
+	 * avoid it.
+	 */
+
+	/* 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))
+		return;
+
+	/* Forward this property change to the clients */
+	g_value_init(&prop_val, G_PARAM_SPEC_VALUE_TYPE(pspec));
+	g_object_get_property(gobj, prop_name, &prop_val);
+	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_val);
+	g_value_unset(&prop_val);
+}
+
 void
 purple_object_install_dbus_infos(PurpleObject *pobj, char *dbus_interface, char *dbus_path)
 {
@@ -310,6 +373,13 @@ purple_object_install_dbus_infos(PurpleO
 
 		/* Remember the purple interface */
 		purple_object_set_dbus_obj_interface(pobj, dbus_interface);
+
+		/* Register the callback that forwards the "notify" signal
+		 * (a property changed) to the remote clients
+		 */
+		g_signal_connect(pobj, "notify",
+		                 G_CALLBACK(purple_object_forward_notify_cb),
+		                 NULL);
 	}
 #endif	
 }
============================================================
--- libpurple/dbus-prototypes/account.xml	4a4a315f59542cb0bde564c1cd87c07ac432247e
+++ libpurple/dbus-prototypes/account.xml	a096ee777496d0beb19a884c70ed83e62f39914b
@@ -11,5 +11,10 @@
 		<property type="b" name="check-mail"      access="readwrite" />
 
 		<method name="Connect" />
+
+		<signal name="DBusNotify">
+			<arg type="s" name="property-name" />
+			<arg type="v" name="property-value" />
+		</signal>
 	</interface>
 </node>


More information about the Commits mailing list