soc.2010.detachablepurple: dca9b57e: Added support for receiving and sending ...

gillux at soc.pidgin.im gillux at soc.pidgin.im
Thu Aug 5 00:04:07 EDT 2010


----------------------------------------------------------------------
Revision: dca9b57ebfa21805b5a8f19998066df9bbe31444
Parent:   8711547b61f3a4f2f30d6c60c102f1259c3db1db
Author:   gillux at soc.pidgin.im
Date:     08/03/10 22:56:06
Branch:   im.pidgin.soc.2010.detachablepurple
URL: http://d.pidgin.im/viewmtn/revision/info/dca9b57ebfa21805b5a8f19998066df9bbe31444

Changelog: 

Added support for receiving and sending gobject references as gobject
properties over dbus. GObject references are converted into dbus path
names and vice versa, thanks to a new GValue transformation function.

Changes against parent 8711547b61f3a4f2f30d6c60c102f1259c3db1db

  patched  libpurple/dbus-constructor.c
  patched  libpurple/pobject.c

-------------- next part --------------
============================================================
--- libpurple/pobject.c	311eb298d1c5ee2d15aed035dede13216b47c180
+++ libpurple/pobject.c	e33e2d36455066c64b2bf2366e8a2b946e4332ea
@@ -78,7 +78,6 @@ purple_object_dispose(GObject *obj)
 	g_signal_emit(pobj, signals[SIG_DESTROYING], 0);
 
 #ifdef HAVE_DBUS
-	/* Forget about the associated dbus path */
 	purple_dbus_disassoc_gobject(priv->dbus_path);
 #endif
 
@@ -112,7 +111,49 @@ purple_object_finalize(GObject *gobj)
 	parent_class->finalize(gobj);
 }
 
+/**
+ * A GValueTransform function that transforms dbus path names into
+ * local gobjects references. May be used to do this:
+ *
+ * GValue string_val = {0, };
+ * GValue gobj_val = {0, };
+ * g_value_init(&string_val, G_TYPE_STRING);
+ * g_value_init(&gobj_val,   G_TYPE_OBJECT);
+ * g_value_set_static_string(&string_val, "/im/pidgin/purple/account/foobar");
+ * g_value_transform(&string_val, &gobj_val);
+ */
 static void
+g_value_dbus_path2gobject(const GValue *src, GValue *dest)
+{
+	GObject *obj = NULL;
+	gchar *path_name;
+
+	path_name = g_value_get_string(src);
+	if (path_name && path_name[0] != '\0') {
+		obj = purple_dbus_get_gobject_by_path(path_name);
+	}
+	g_value_set_object(dest, obj);
+}
+
+/**
+ * A GValueTransform function that transforms dbus path names into
+ * local gobjects references.
+ * @see g_value_dbus_path2gobject().
+ */
+static void
+g_value_gobject2dbus_path(const GValue *src, GValue *dest)
+{
+	GObject *prop_obj;
+	char *path_name = NULL;
+
+	prop_obj = g_value_get_object(src);
+	if (prop_obj) {
+		path_name = purple_object_get_dbus_path(PURPLE_OBJECT(prop_obj));
+	}
+	g_value_set_string(dest, path_name);
+}
+
+static void
 purple_object_class_init(PurpleObjectClass *klass)
 {
 	GObjectClass *gclass = G_OBJECT_CLASS(klass);
@@ -153,6 +194,12 @@ purple_object_class_init(PurpleObjectCla
 				G_TYPE_NONE, 2, G_TYPE_STRING, G_TYPE_VALUE);
 	}
 
+	/* Register our GValue transformation function */
+	g_value_register_transform_func(G_TYPE_STRING, G_TYPE_OBJECT,
+									g_value_dbus_path2gobject);
+	g_value_register_transform_func(G_TYPE_OBJECT, G_TYPE_STRING,
+									g_value_gobject2dbus_path);
+
 	g_type_class_add_private(klass, sizeof(PurpleObjectPrivate));
 }
 
@@ -313,19 +360,34 @@ purple_object_notify_cb(DBusGProxy *prox
 {
 	GObject *obj;
 	PurpleRunningMode mode;
+	GParamSpec *pspec;
+	GValue prop_val2 = {0, };
 
 	/* Retrieve the local gobject mirrored with the dbus path which sent
 	 * the signal */
 	obj = purple_dbus_get_gobject_by_path(dbus_g_proxy_get_path(proxy));
 	g_return_if_fail(obj != NULL);
 
+	pspec = g_object_class_find_property(G_OBJECT_GET_CLASS(obj), prop_name);
+	g_value_init(&prop_val2, G_PARAM_SPEC_VALUE_TYPE(pspec));			
+	if (G_TYPE_IS_OBJECT(G_PARAM_SPEC_VALUE_TYPE(pspec))
+		&& G_VALUE_HOLDS_STRING(prop_val)) {
+		/* Convert dbus path names into gobjects. */
+		g_value_transform(prop_val, &prop_val2);
+	} else {
+		/* Regular value. */
+		g_value_copy(prop_val, &prop_val2);
+	}
+
 	/* Update the local state of this property */
 	mode = purple_core_get_running_mode();
 	purple_core_set_running_mode(PURPLE_RUN_MIRROR_MODE);
 	purple_debug_info("dbus", "Recieved notify about property '%s' of a %s\n",
 	                  prop_name, G_OBJECT_TYPE_NAME(obj));
-	g_object_set_property(G_OBJECT(obj), prop_name, prop_val);
+
+	g_object_set_property(G_OBJECT(obj), prop_name, &prop_val2);
 	purple_core_set_running_mode(mode);
+	g_value_unset(&prop_val2);
 }
 
 static void
@@ -333,6 +395,7 @@ purple_object_forward_notify_cb(GObject 
 {
 	gchar *prop_name;
 	GValue prop_val = {0, };
+	GValue prop_val2 = {0, };
 	gchar *interface;
 
 	/* Note that this "notify" signal may occur even if the property havn't
@@ -348,13 +411,26 @@ purple_object_forward_notify_cb(GObject 
 					prop_name))
 		return;
 
-	/* Forward this property change to the clients */
+	/* Get the property. */
 	g_value_init(&prop_val, G_PARAM_SPEC_VALUE_TYPE(pspec));
 	g_object_get_property(gobj, prop_name, &prop_val);
+
+	if (G_VALUE_HOLDS_OBJECT(&prop_val)) {
+		/* Convert gobjects into dbus path names. */
+		g_value_init(&prop_val2, G_TYPE_STRING);
+		g_value_transform(&prop_val, &prop_val2);
+	} else {
+		/* Regular value. */
+		g_value_init(&prop_val2, G_VALUE_TYPE(&prop_val));
+		g_value_copy(&prop_val, &prop_val2);
+	}
+	g_value_unset(&prop_val);
+
+	/* 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_val);
-	g_value_unset(&prop_val);
+	g_signal_emit(gobj, signals[SIG_DBUS_NOTIFY], 0, prop_name, &prop_val2);
+	g_value_unset(&prop_val2);
 }
 
 void
============================================================
--- libpurple/dbus-constructor.c	b25b21916b2ba05345083e5e4dc65c5223beef96
+++ libpurple/dbus-constructor.c	517e9b8a885f8d22773f40435a685d87ba4acd03
@@ -105,6 +105,7 @@ pack_account_prop_cb(char *prop_name, Pu
 {
 	GValue prop = {0, };
 	GValue prop_val = {0, };
+	GValue prop_val2 = {0, };
 	GParamSpec *prop_spec;
 	gboolean ok;
 
@@ -121,12 +122,23 @@ pack_account_prop_cb(char *prop_name, Pu
 	/* Then get it */
 	g_object_get_property(G_OBJECT(acc), prop_name,	&prop_val);
 
+	if (G_VALUE_HOLDS_OBJECT(&prop_val)) {
+		/* Convert gobjects into dbus path names. */
+		g_value_init(&prop_val2, G_TYPE_STRING);
+		g_value_transform(&prop_val, &prop_val2);
+	} else {
+		/* Regular value. */
+		g_value_init(&prop_val2, G_VALUE_TYPE(&prop_val));
+		g_value_copy(&prop_val, &prop_val2);
+	}
+	g_value_unset(&prop_val);
+
 	/* Setup the DBus struct, with our extracted data */
 	ok = dbus_g_type_struct_set(&prop,
 				0, prop_name,
-				1, &prop_val,
+				1, &prop_val2,
 				G_MAXUINT);
-	g_value_unset(&prop_val);
+	g_value_unset(&prop_val2);
 	g_return_if_fail(ok == TRUE);
 
 	/* Finally append this fresh struct to the array */
@@ -236,6 +248,8 @@ load_account_prop_cb(GValueArray* box, P
 	char* prop_name;
 	GValue value_box = {0, };
 	GValue *prop_val;
+	GValue prop_val2 = {0, };
+	GParamSpec *pspec;
 
 	/* Each property consists of a DBUS_STRUCT_PROPERTY */
 	g_value_init(&value_box, DBUS_STRUCT_PROPERTY);
@@ -244,6 +258,17 @@ load_account_prop_cb(GValueArray* box, P
 	dbus_g_type_struct_get(&value_box, 0, &prop_name, 1, &prop_val,
 			G_MAXUINT);
 
+	pspec = g_object_class_find_property(G_OBJECT_GET_CLASS(account),
+										prop_name);
+	g_value_init(&prop_val2, G_PARAM_SPEC_VALUE_TYPE(pspec));			
+	if (G_TYPE_IS_OBJECT(G_PARAM_SPEC_VALUE_TYPE(pspec))
+		&& G_VALUE_HOLDS_STRING(prop_val)) {
+		/* Convert dbus path names into gobjects. */
+		g_value_transform(prop_val, &prop_val2);
+	} else {
+		/* Regular value. */
+		g_value_copy(prop_val, &prop_val2);
+	}
 	g_object_set_property(G_OBJECT(account), prop_name, prop_val);
 
 	g_free(prop_name);


More information about the Commits mailing list