/srv/mercurial-server/detachablepurple: e79aaa6209b7: Moved the ...

Gilles Bedel gillux at cpw.pidgin.im
Fri Jun 15 22:01:31 EDT 2012


Changeset: e79aaa6209b7ed37558c30443bf08b821a1745c0
Author:	 Gilles Bedel <gillux at cpw.pidgin.im>
Date:	 2012-03-27 20:30 +0000
Branch:	 cpw.gillux.detachablepurple
URL: http://hg.pidgin.im/srv/mercurial-server/detachablepurple/rev/e79aaa6209b7

Description:

Moved the get/set D-Bus property code to some dedicated functions
that properly handle dbus object path name to gobject references
conversion and checks wether the property is actually exported over
D-Bus. Also removed the now useless _g_variant_type_from_gvalue code
(why the hell did I need this cruft?).

diffstat:

 libpurple/pobject.c |  209 ++++++++++++++++++++++++---------------------------
 libpurple/pobject.h |   25 ++++++
 2 files changed, 123 insertions(+), 111 deletions(-)

diffs (truncated from 303 to 300 lines):

diff --git a/libpurple/pobject.c b/libpurple/pobject.c
--- a/libpurple/pobject.c
+++ b/libpurple/pobject.c
@@ -367,7 +367,85 @@
 	priv->dbus_path = g_strdup(path);
 }
 
+GVariant *
+purple_object_get_dbus_property(PurpleObject *pobj, const gchar *prop_name)
+{
+	GParamSpec *pspec;
+	GDBusPropertyInfo *prop_info;
+	GVariant *gvar;
+	GValue gval = {0, };
+	GValue gval2 = {0, };
+
+	/* Check if such a named property exists. */
+	pspec = g_object_class_find_property(G_OBJECT_GET_CLASS(G_OBJECT(pobj)),
+	                                     prop_name);
+	if (!pspec)
+		return NULL;
+
+	/* Check if we export this property over D-Bus. */
+	prop_info = g_dbus_interface_info_lookup_property
+	             (PURPLE_OBJECT_GET_CLASS(pobj)->dbus_ifaceinfo,
+	              prop_name);
+	if (!prop_info)
+		return NULL;
+
+	g_value_init(&gval, G_PARAM_SPEC_VALUE_TYPE(pspec));
+	g_object_get_property(G_OBJECT(pobj), prop_name, &gval);
+	if (G_VALUE_HOLDS_OBJECT(&gval)) {
+		/* Convert gobjects into dbus path names. */
+		g_value_init(&gval2, G_TYPE_STRING);
+		g_value_transform(&gval, &gval);
+	} else {
+		/* Regular value. */
+		g_value_init(&gval2, G_VALUE_TYPE(&gval));
+		g_value_copy(&gval, &gval2);
+	}
+	g_value_unset(&gval);
+
+	gvar = g_dbus_gvalue_to_gvariant(&gval2,
+	                                 G_VARIANT_TYPE(prop_info->signature));
+	g_value_unset(&gval2);
+	return gvar;
+}
+
 gboolean
+purple_object_set_dbus_property(PurpleObject *pobj, const gchar *prop_name,
+                                GVariant *prop_value)
+{
+	GParamSpec *pspec;
+	GDBusPropertyInfo *prop_info;
+	GValue gval = {0, };
+	GValue gval2 = {0, };
+
+	/* Check if such a named property exists. */
+	pspec = g_object_class_find_property(G_OBJECT_GET_CLASS(G_OBJECT(pobj)),
+	                                     prop_name);
+	if (!pspec)
+		return FALSE;
+
+	/* Check if we export this property over D-Bus. */
+	prop_info = g_dbus_interface_info_lookup_property
+	             (PURPLE_OBJECT_GET_CLASS(pobj)->dbus_ifaceinfo, prop_name);
+	if (!prop_info)
+		return FALSE;
+
+	g_dbus_gvariant_to_gvalue(prop_value, &gval);
+	g_value_init(&gval2, G_PARAM_SPEC_VALUE_TYPE(pspec));
+	if (G_TYPE_IS_OBJECT(G_PARAM_SPEC_VALUE_TYPE(pspec))
+	    && G_VALUE_HOLDS_STRING(&gval)) {
+		/* Convert dbus path names into gobjects. */
+		g_value_transform(&gval, &gval2);
+	} else {
+		/* Regular value. */
+		g_value_copy(&gval, &gval2);
+	}
+	g_value_unset(&gval);
+	g_object_set_property(G_OBJECT(pobj), prop_name, &gval2);
+	g_value_unset(&gval2);
+	return TRUE;
+}
+
+gboolean /* DEPRECATED! */
 purple_object_have_dbus_property(PurpleObject *pobj, const gchar *interface, const gchar *prop_name)
 {
 	GPtrArray *props;
@@ -426,43 +504,13 @@
 	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;
-}
-
+/* Forwards notify signals of exported properties over D-Bus
+ * using the PropertyChanged signal.
+ */
 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, };
 	GVariant *prop;
 	GVariant *signal_params;
 	char *object_path;
@@ -483,41 +531,23 @@
 	if (!connection)
 		return;
 
-	/* Check if we want to tell clients about this property change */
 	prop_name = g_param_spec_get_name(pspec);
-	ifaceinfo = PURPLE_OBJECT_GET_CLASS(gobj)->dbus_ifaceinfo;
-	if (!g_dbus_interface_info_lookup_property(ifaceinfo, prop_name))
-		return;
-
-	/* 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);
+	prop = purple_object_get_dbus_property(PURPLE_OBJECT(gobj), prop_name);
+	if (!prop)
+		return; /* Probably we don't export this property over D-Bus. */
 
 	/* 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));
-	prop = g_dbus_gvalue_to_gvariant(&prop_val2,
-	                                 _g_variant_type_from_gvalue(&prop_val2));
+	                  prop_name, G_OBJECT_TYPE_NAME(gobj));
 
 	signal_params = g_variant_new("(sv)", prop_name, prop);
 	object_path = purple_object_get_dbus_path(PURPLE_OBJECT(gobj));
+	ifaceinfo = PURPLE_OBJECT_GET_CLASS(PURPLE_OBJECT(gobj))->dbus_ifaceinfo;
 	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);
 }
 
 void
@@ -671,38 +701,14 @@
                                         GError          **error,
                                         gpointer          object)
 {
-	GVariant *ret = NULL;
-	GValue value = {0, };
-	GValue tmp   = {0, };
-	GParamSpec *pspec;
-	GDBusPropertyInfo *prop_info;
+	GVariant *prop;
 
-	pspec = g_object_class_find_property(G_OBJECT_GET_CLASS(G_OBJECT(object)),
-	                                     property_name);
-	if (!pspec)
+	prop = purple_object_get_dbus_property(PURPLE_OBJECT(object), property_name);
+	if (!prop)
 		g_set_error(error, G_DBUS_ERROR, G_DBUS_ERROR_INVALID_ARGS,
-			"No property named %s in interface %s.",
-		    property_name, interface_name);
-	else {
-		g_value_init(&value, G_PARAM_SPEC_VALUE_TYPE(pspec));
-		g_object_get_property(object, property_name, &value);
-		if (G_VALUE_HOLDS_OBJECT(&value)) {
-			/* Convert gobjects into dbus path names. */
-			g_value_init(&tmp, G_TYPE_OBJECT);
-			g_value_copy(&value, &tmp);
-			g_value_unset(&value);
-			g_value_init(&value, G_TYPE_STRING);
-			g_value_transform(&tmp, &value);
-			g_value_unset(&tmp);
-		}
-		prop_info = g_dbus_interface_info_lookup_property
-			(PURPLE_OBJECT_GET_CLASS(object)->dbus_ifaceinfo,
-			 property_name);
-		ret = g_dbus_gvalue_to_gvariant(&value,
-		                                G_VARIANT_TYPE(prop_info->signature));
-		g_value_unset(&value);
-	}
-	return ret;
+		            "No such propery '%s' on interface '%s' of object '%s'.",
+		            property_name, interface_name, object_path);
+	return prop;
 }
 
 gboolean
@@ -715,33 +721,14 @@
                                         GError          **error,
                                         gpointer          object)
 {
-	GParamSpec *pspec;
-	GValue value = {0, };
-	GValue tmp   = {0, };
-
-	pspec = g_object_class_find_property(G_OBJECT_GET_CLASS(object),
-	                                     property_name);
-	if (!pspec) {
+	if (purple_object_set_dbus_property(PURPLE_OBJECT(object),
+	                                    property_name, variant)) {
+		return TRUE;
+	} else {
 		g_set_error(error, G_DBUS_ERROR, G_DBUS_ERROR_INVALID_ARGS,
-		            "No property named %s in interface %s.",
-		            property_name, interface_name);
+		            "No such property '%s' on interface '%s' of object '%s'.",
+		            property_name, interface_name, object_path);
 		return FALSE;
-	} else {
-		g_value_init(&value, G_PARAM_SPEC_VALUE_TYPE(pspec));
-		g_dbus_gvariant_to_gvalue(variant, &value);
-		if (G_TYPE_IS_OBJECT(G_PARAM_SPEC_VALUE_TYPE(pspec))
-		    && G_VALUE_HOLDS_STRING(&value)) {
-			/* Convert dbus path names into gobjects. */
-			g_value_init(&tmp, G_TYPE_OBJECT);
-			g_value_transform(&value, &tmp);
-			g_value_unset(&value);
-			g_value_init(&value, G_TYPE_OBJECT);
-			g_value_copy(&tmp, &value);
-			g_value_unset(&tmp);
-		}
-		g_object_set_property(G_OBJECT(object), property_name, &value);
-		g_value_unset(&value);
-		return TRUE;
 	}
 }
 
diff --git a/libpurple/pobject.h b/libpurple/pobject.h
--- a/libpurple/pobject.h
+++ b/libpurple/pobject.h
@@ -229,6 +229,31 @@
                                          const char        *name);
 
 /**
+ * Gets a property exported on D-Bus. It's like directly getting the
+ * property on the object, but it also check if the property is
+ * exported on D-Bus and eventually converts object references to
+ * their dbus object path name.
+ *
+ * @param pobj The PurpleObject holding prop_name.
+ * @param prop_name The property name held by pobj.
+ * @return The property value.
+ */
+GVariant *purple_object_get_dbus_property(PurpleObject *pobj, const gchar *prop_name);
+
+/**
+ * Sets a property exported on D-Bus. It's like directly setting the
+ * property on the object, but it also check if the property is
+ * exported on D-Bus and eventually converts dbus object names to
+ * their object refereces.
+ *
+ * @param pobj The PurpleObject holding prop_name.
+ * @param prop_name The property name held by pobj.
+ * @param prop_value The property value that should be set.
+ * @return TRUE if the property has been successfully set, FALSE otherwise.
+ */
+gboolean purple_object_set_dbus_property(PurpleObject *pobj, const gchar *prop_name, GVariant *prop_value);
+
+/**



More information about the Commits mailing list