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