cpw.gillux.detachablepurple: 0af33113: Moved the get/set D-Bus property code to..
gillux at soc.pidgin.im
gillux at soc.pidgin.im
Tue Mar 27 17:25:51 EDT 2012
----------------------------------------------------------------------
Revision: 0af331138cba35c79cf68e7026117af89c3aaae7
Parent: f117784967ff2fe2570a336f37396b12dfd6711f
Author: gillux at soc.pidgin.im
Date: 03/27/12 16:30:20
Branch: im.pidgin.cpw.gillux.detachablepurple
URL: http://d.pidgin.im/viewmtn/revision/info/0af331138cba35c79cf68e7026117af89c3aaae7
Changelog:
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?).
Changes against parent f117784967ff2fe2570a336f37396b12dfd6711f
patched libpurple/pobject.c
patched libpurple/pobject.h
-------------- next part --------------
============================================================
--- libpurple/pobject.c 5954781190a6a7dfc2d3fb18a4fa39b02a2ea12e
+++ libpurple/pobject.c 42939c71cd31f6e6931563e106a9d290c21aa3e6
@@ -367,7 +367,85 @@ purple_object_set_dbus_path(PurpleObject
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 @@ purple_object_notify_cb(DBusGProxy *prox
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 @@ purple_object_forward_notify_cb(GObject
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;
+ prop = purple_object_get_dbus_property(PURPLE_OBJECT(gobj), prop_name);
+ if (!prop)
+ return; /* Probably we don't export this property over D-Bus. */
- /* 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));
- 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 @@ purple_object_generic_dbus_get_property(
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 @@ purple_object_generic_dbus_set_property(
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;
}
}
============================================================
--- libpurple/pobject.h b0abc4b5af366f9308635b689022ae1679f54b82
+++ libpurple/pobject.h a45d1ca4fc67171c59b7711672e17e0e3327d34b
@@ -229,6 +229,31 @@ GClosure *purple_object_get_dbus_closure
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);
+
+/**
* A GDBusInterfaceMethodCallFunc compilant DBus method handler.
* This method handler aims to be set in a GDBusInterfaceVTable.
* In fact, it is the default method handler, set by the default
More information about the Commits
mailing list