diff options
author | Ali Abdallah <aliovx@gmail.com> | 2017-06-01 10:51:25 +0200 |
---|---|---|
committer | Ali Abdallah <aliovx@gmail.com> | 2017-06-01 10:51:25 +0200 |
commit | 90cc1974a569efee1f0298b8efb0770246c4b9f8 (patch) | |
tree | 743c02dd5e5ab1b8a5ac1efe44d3152dd3d37fa8 /xfconf | |
parent | 71d0a4140aeca07aee451f421391b151ab708cdc (diff) | |
parent | 449aeb99a5fd8990c04e4817f41a1f9834a0355c (diff) | |
download | xfconf-90cc1974a569efee1f0298b8efb0770246c4b9f8.tar.gz |
Merge branch 'gdbus-port' into master.
Diffstat (limited to 'xfconf')
-rw-r--r-- | xfconf/Makefile.am | 42 | ||||
-rwxr-xr-x | xfconf/abicheck.sh | 2 | ||||
-rw-r--r-- | xfconf/libxfconf-1.pc.in (renamed from xfconf/libxfconf-0.pc.in) | 2 | ||||
-rw-r--r-- | xfconf/xfconf-cache.c | 418 | ||||
-rw-r--r-- | xfconf/xfconf-channel.c | 138 | ||||
-rw-r--r-- | xfconf/xfconf-private.h | 7 | ||||
-rw-r--r-- | xfconf/xfconf.c | 81 |
7 files changed, 329 insertions, 361 deletions
diff --git a/xfconf/Makefile.am b/xfconf/Makefile.am index af1d3b5..51a0b1b 100644 --- a/xfconf/Makefile.am +++ b/xfconf/Makefile.am @@ -5,7 +5,7 @@ AM_CPPFLAGS = \ -DG_LOG_DOMAIN=\"xfconf\" \ $(PLATFORM_CPPFLAGS) -lib_LTLIBRARIES = libxfconf-0.la +lib_LTLIBRARIES = libxfconf-1.la libxfconfincludedir = $(includedir)/xfce4/xfconf-$(LIBXFCONF_VERSION_API)/xfconf libxfconfinclude_HEADERS = \ @@ -15,61 +15,43 @@ libxfconfinclude_HEADERS = \ xfconf-types.h \ xfconf.h -libxfconf_0_la_SOURCES = \ +libxfconf_1_la_SOURCES = \ $(libxfconfinclude_HEADERS) \ xfconf-binding.c \ xfconf-cache.c \ xfconf-cache.h \ xfconf-channel.c \ - xfconf-dbus-bindings.h \ xfconf-private.h \ xfconf.c \ $(top_srcdir)/common/xfconf-types.c -libxfconf_0_la_CFLAGS = \ +libxfconf_1_la_CFLAGS = \ $(GLIB_CFLAGS) \ - $(DBUS_CFLAGS) \ + $(GIO_CFLAGS) \ + $(GIO_UNIX_CFLAGS) \ $(GTHREAD_CFLAGS) \ - $(DBUS_GLIB_CFLAGS) \ $(PLATFORM_CFLAGS) -libxfconf_0_la_LDFLAGS = \ +libxfconf_1_la_LDFLAGS = \ -export-dynamic \ -version-info $(LIBXFCONF_VERINFO) \ -export-symbols-regex "^[^_].*" \ -no-undefined \ $(PLATFORM_LDFLAGS) -libxfconf_0_la_LIBADD = \ +libxfconf_1_la_LIBADD = \ $(top_builddir)/common/libxfconf-common.la \ $(top_builddir)/common/libxfconf-gvaluefuncs.la \ + $(top_builddir)/common/libxfconf-dbus.la \ + $(GIO_LIBS) \ + $(GIO_UNIX_LIBS) \ $(GLIB_LIBS) \ - $(GTHREAD_LIBS) \ - $(DBUS_LIBS) \ - $(DBUS_GLIB_LIBS) + $(GTHREAD_LIBS) pkgconfigdir = $(libdir)/pkgconfig -pkgconfig_DATA = libxfconf-0.pc +pkgconfig_DATA = libxfconf-1.pc -if MAINTAINER_MODE - -BUILT_SOURCES = \ - xfconf-dbus-bindings.h - -xfconf-dbus-bindings.h: $(top_srcdir)/common/xfconf-dbus.xml Makefile - $(AM_V_GEN) dbus-binding-tool --mode=glib-client $< > $(@).tmp \ - && sed -e 's/^\([[:space:]]\+GValue[[:space:]]\+[^=]\+\).*;$$/\1 = { 0, };/' <$(@).tmp >$@ \ - && rm -f $(@).tmp -# the above fixes a bug in dbus-binding-tool's output -# dbus-binding-tool doesn't initialise GValues to { 0, } properly - -CLEANFILES = \ - $(BUILT_SOURCES) \ - xfconf-dbus-bindings.h.tmp - -endif - EXTRA_DIST = \ abicheck.sh \ xfconf.symbols diff --git a/xfconf/abicheck.sh b/xfconf/abicheck.sh index 7731f9f..e6ab2ee 100755 --- a/xfconf/abicheck.sh +++ b/xfconf/abicheck.sh @@ -20,5 +20,5 @@ trap 'rm expected-abi actual-abi' EXIT ${CPP:-cpp} -DINCLUDE_INTERNAL_SYMBOLS -DINCLUDE_VARIABLES -DALL_FILES ${srcdir:-.}/xfconf.symbols | sed 's/ G_GNUC.*$//;s/ PRIVATE//;/^ *$/d;/^#/d' | sort >expected-abi -${NM:-nm} .libs/libxfconf-0.so* | awk '/ [DRTG] / {print $3}' | sort | uniq > actual-abi +${NM:-nm} .libs/libxfconf-1.so* | awk '/ [DRTG] / {print $3}' | sort | uniq > actual-abi diff -u expected-abi actual-abi diff --git a/xfconf/libxfconf-0.pc.in b/xfconf/libxfconf-1.pc.in index b424788..bfa9140 100644 --- a/xfconf/libxfconf-0.pc.in +++ b/xfconf/libxfconf-1.pc.in @@ -7,7 +7,7 @@ libxfconf_api_version=@LIBXFCONF_VERSION_API@ Name: @PACKAGE_TARNAME@ Description: Configuration library for Xfce -Requires: gobject-2.0 dbus-1 dbus-glib-1 +Requires: gio-2.0 gio-unix-2.0 Version: @PACKAGE_VERSION@ Libs: -L${libdir} -lxfconf-${libxfconf_api_version} Cflags: -I${includedir}/xfce4/xfconf-${libxfconf_api_version} diff --git a/xfconf/xfconf-cache.c b/xfconf/xfconf-cache.c index a502ff1..1923263 100644 --- a/xfconf/xfconf-cache.c +++ b/xfconf/xfconf-cache.c @@ -1,6 +1,7 @@ /* * xfconf * + * Copyright (c) 2016 Ali Abdallah <ali@xfce.org> * Copyright (c) 2009 Brian Tarricone <brian@tarricone.org> * * This library is free software; you can redistribute it and/or @@ -29,13 +30,14 @@ #include "xfconf-cache.h" #include "xfconf-channel.h" #include "xfconf-errors.h" -#include "xfconf-dbus-bindings.h" +#include "common/xfconf-gdbus-bindings.h" #include "common/xfconf-gvaluefuncs.h" #include "xfconf-private.h" #include "common/xfconf-marshal.h" #include "common/xfconf-common-private.h" -#if 0 #include "xfconf-types.h" + +#if 0 #include "xfconf.h" #include "xfconf-alias.h" #endif @@ -86,9 +88,16 @@ xfconf_cache_item_new(const GValue *value, if(G_LIKELY(steal)) { item->value = (GValue *) value; } else { + item->value = g_new0(GValue, 1); g_value_init(item->value, G_VALUE_TYPE(value)); - g_value_copy(value, item->value); + /* We need to dup the array */ + if (G_VALUE_TYPE(value) == G_TYPE_PTR_ARRAY) { + GPtrArray *arr = xfconf_dup_value_array(g_value_get_boxed(value), TRUE); + g_value_take_boxed(item->value, arr); + } else { + g_value_copy(value, item->value); + } } return item; @@ -108,8 +117,14 @@ xfconf_cache_item_update(XfconfCacheItem *item, if(value) { g_value_unset(item->value); g_value_init(item->value, G_VALUE_TYPE(value)); - g_value_copy(value, item->value); + /* We need to dup the array */ + if (G_VALUE_TYPE(value) == G_TYPE_PTR_ARRAY) { + GPtrArray *arr = xfconf_dup_value_array(g_value_get_boxed(value), TRUE); + g_value_take_boxed(item->value, arr); + } else { + g_value_copy(value, item->value); + } return TRUE; } @@ -133,12 +148,25 @@ xfconf_cache_item_free(XfconfCacheItem *item) typedef struct { gchar *property; - DBusGProxyCall *call; XfconfCacheItem *item; + + GCancellable *cancellable; + + /** + * Variant to be send on the wire + * Used in xfconf_cache_old_item_end_call + * to end an already started call + **/ + GVariant *variant; + + /* Pointer to the cache object */ + XfconfCache *cache; + } XfconfCacheOldItem; + static XfconfCacheOldItem * -xfconf_cache_old_item_new(const gchar *property) +xfconf_cache_old_item_new(XfconfCache *cache, const gchar *property) { XfconfCacheOldItem *old_item; @@ -146,6 +174,9 @@ xfconf_cache_old_item_new(const gchar *property) old_item = g_slice_new0(XfconfCacheOldItem); old_item->property = g_strdup(property); + old_item->cancellable = g_cancellable_new (); + old_item->cache = cache; + old_item->variant = NULL; return old_item; } @@ -158,10 +189,14 @@ xfconf_cache_old_item_free(XfconfCacheOldItem *old_item) /* debug check to make sure the call is properly handled before * freeing the item. it should either been cancelled or we wait for * it to finish */ - g_return_if_fail(!old_item->call); + g_return_if_fail(g_cancellable_is_cancelled(old_item->cancellable) == TRUE); + g_object_unref (old_item->cancellable); g_free(old_item->property); + if (old_item->variant) + g_variant_unref (old_item->variant); + if(old_item->item) xfconf_cache_item_free(old_item->item); @@ -173,21 +208,31 @@ xfconf_cache_old_item_end_call(gpointer key, gpointer value, gpointer user_data) { - const gchar *channel_name = user_data; - DBusGProxy *proxy = _xfconf_get_dbus_g_proxy(); GError *error = NULL; XfconfCacheOldItem *old_item = value; + GDBusProxy *gproxy = _xfconf_get_gdbus_proxy(); + const gchar *channel_name = user_data; + GVariant *variant; + + g_return_val_if_fail(g_cancellable_is_cancelled(old_item->cancellable) == FALSE, TRUE); + + variant = g_variant_new_variant (old_item->variant); - g_return_val_if_fail(old_item->call, TRUE); + g_cancellable_cancel(old_item->cancellable); - if(!dbus_g_proxy_end_call(proxy, old_item->call, &error, G_TYPE_INVALID)) { - g_warning("Failed to set property \"%s::%s\": %s", + xfconf_exported_call_set_property_sync ((XfconfExported *)gproxy, + channel_name, + old_item->property, + variant, + NULL, + &error); + + if (error) { + g_warning("Failed to set property \"%s::%s\": %s", channel_name, old_item->property, error->message); g_error_free(error); } - old_item->call = NULL; - return TRUE; } @@ -216,6 +261,8 @@ struct _XfconfCache GHashTable *pending_calls; GHashTable *old_properties; + gint g_signal_id; + #if GLIB_CHECK_VERSION (2, 32, 0) GMutex cache_lock; #else @@ -259,15 +306,11 @@ static void xfconf_cache_get_g_property(GObject *object, GParamSpec *pspec); static void xfconf_cache_finalize(GObject *obj); -static void xfconf_cache_property_changed(DBusGProxy *proxy, - const gchar *cache_name, - const gchar *property, - const GValue *value, - gpointer user_data); -static void xfconf_cache_property_removed(DBusGProxy *proxy, - const gchar *cache_name, - const gchar *property, - gpointer user_data); +static void xfconf_cache_proxy_signal_received_cb(GDBusProxy *proxy, + gchar *sender_name, + gchar *signal_name, + GVariant *parameters, + gpointer user_data); static guint signals[N_SIGS] = { 0, }; @@ -338,14 +381,10 @@ xfconf_cache_class_init(XfconfCacheClass *klass) static void xfconf_cache_init(XfconfCache *cache) { - DBusGProxy *proxy = _xfconf_get_dbus_g_proxy(); + GDBusProxy *gproxy = _xfconf_get_gdbus_proxy(); - dbus_g_proxy_connect_signal(proxy, "PropertyChanged", - G_CALLBACK(xfconf_cache_property_changed), - cache, NULL); - dbus_g_proxy_connect_signal(proxy, "PropertyRemoved", - G_CALLBACK(xfconf_cache_property_removed), - cache, NULL); + cache->g_signal_id = g_signal_connect(gproxy, "g-signal", + G_CALLBACK(xfconf_cache_proxy_signal_received_cb), cache); cache->properties = g_tree_new_full((GCompareDataFunc)strcmp, NULL, (GDestroyNotify)g_free, @@ -423,16 +462,12 @@ static void xfconf_cache_finalize(GObject *obj) { XfconfCache *cache = XFCONF_CACHE(obj); - DBusGProxy *proxy = _xfconf_get_dbus_g_proxy(); GHashTable *pending_calls; + GDBusProxy *proxy; - dbus_g_proxy_disconnect_signal(proxy, "PropertyChanged", - G_CALLBACK(xfconf_cache_property_changed), - cache); + proxy = _xfconf_get_gdbus_proxy(); - dbus_g_proxy_disconnect_signal(proxy, "PropertyRemoved", - G_CALLBACK(xfconf_cache_property_removed), - cache); + g_signal_handler_disconnect(proxy,cache->g_signal_id); /* finish pending calls (without emitting signals, therefore we set * the hash table in the cache to %NULL) */ @@ -447,6 +482,7 @@ xfconf_cache_finalize(GObject *obj) g_tree_destroy(cache->properties); g_hash_table_destroy(cache->old_properties); + #if !GLIB_CHECK_VERSION (2, 32, 0) g_mutex_free (cache->cache_lock); #endif @@ -455,77 +491,117 @@ xfconf_cache_finalize(GObject *obj) } - static void -xfconf_cache_property_changed(DBusGProxy *proxy, - const gchar *channel_name, - const gchar *property, - const GValue *value, - gpointer user_data) +xfconf_cache_handle_property_changed (XfconfCache *cache, GVariant *parameters) { - XfconfCache *cache = XFCONF_CACHE(user_data); + XfconfCacheItem *item; + const gchar *channel_name, *property; + GVariant *prop_variant; + GValue *prop_value; gboolean changed = TRUE; + if (g_variant_is_of_type(parameters, G_VARIANT_TYPE ("(ssv)"))) { + g_variant_get(parameters, "(&s&sv)", &channel_name, &property, &prop_variant); - if(strcmp(channel_name, cache->channel_name)) - return; - - /* if a call was cancelled, we still receive a property-changed from - * that value, in that case, abort the emission of the signal. we can - * detect this because the new reply is not processed yet and thus - * there is still an old_prop in the hash table */ - if(g_hash_table_lookup(cache->old_properties, property)) - return; + if(strcmp(channel_name, cache->channel_name)) { + return; + } + prop_value = xfconf_gvariant_to_gvalue (prop_variant); + + /* if a call was cancelled, we still receive a property-changed from + * that value, in that case, abort the emission of the signal. we can + * detect this because the new reply is not processed yet and thus + * there is still an old_prop in the hash table */ + if(g_hash_table_lookup(cache->old_properties, property)) + return; + + item = g_tree_lookup(cache->properties, property); + if(item) { + changed = xfconf_cache_item_update(item, prop_value); + } + else { + item = xfconf_cache_item_new(prop_value, TRUE); + g_tree_insert(cache->properties, g_strdup(property), item); + } - item = g_tree_lookup(cache->properties, property); - if(item) - changed = xfconf_cache_item_update(item, value); + if(changed) { + g_signal_emit(G_OBJECT(cache), signals[SIG_PROPERTY_CHANGED], 0, + cache->channel_name, property, prop_value); + } + g_value_unset (prop_value); + g_variant_unref(prop_variant); + } else { - item = xfconf_cache_item_new(value, FALSE); - g_tree_insert(cache->properties, g_strdup(property), item); + g_warning("property changed handler expects (ssv) type, but %s received", + g_variant_get_type_string(parameters)); } - if(changed) { - g_signal_emit(G_OBJECT(cache), signals[SIG_PROPERTY_CHANGED], 0, - cache->channel_name, property, value); - } } + static void -xfconf_cache_property_removed(DBusGProxy *proxy, - const gchar *channel_name, - const gchar *property, - gpointer user_data) +xfconf_cache_handle_property_removed (XfconfCache *cache, GVariant *parameters) { - XfconfCache *cache = XFCONF_CACHE(user_data); - GValue value = { 0, }; - if(strcmp(channel_name, cache->channel_name)) - return; + const gchar *channel_name, *property; + GValue value = G_VALUE_INIT; + if (g_variant_is_of_type(parameters, G_VARIANT_TYPE ("(ss)"))) { + g_variant_get(parameters, "(&s&s)", &channel_name, &property); - g_tree_remove(cache->properties, property); + if(strcmp(channel_name, cache->channel_name)) + return; + + g_tree_remove(cache->properties, property); + + g_signal_emit(G_OBJECT(cache), signals[SIG_PROPERTY_CHANGED], 0, + cache->channel_name, property, &value); + + } + else { + g_warning("property removed handler expects (ss) type, but %s received", + g_variant_get_type_string(parameters)); + } - g_signal_emit(G_OBJECT(cache), signals[SIG_PROPERTY_CHANGED], 0, - cache->channel_name, property, &value); } +static void +xfconf_cache_proxy_signal_received_cb(GDBusProxy *proxy, + gchar *sender_name, + gchar *signal_name, + GVariant *parameters, + gpointer user_data) +{ + XfconfCache *cache=(XfconfCache*)user_data; + + g_return_if_fail(XFCONF_IS_CACHE(cache)); + + if (g_strcmp0(signal_name, "PropertyChanged") == 0) + xfconf_cache_handle_property_changed (cache, parameters); + else if (g_strcmp0(signal_name, "PropertyRemoved") == 0) + xfconf_cache_handle_property_removed(cache, parameters); + else + g_warning ("Unhandled signal name :%s\n", signal_name); +} + static void -xfconf_cache_set_property_reply_handler(DBusGProxy *proxy, - DBusGProxyCall *call, +xfconf_cache_set_property_reply_handler(GDBusProxy *proxy, + GAsyncResult *res, gpointer user_data) { - XfconfCache *cache = user_data; + XfconfCache *cache; XfconfCacheOldItem *old_item = NULL; XfconfCacheItem *item; GError *error = NULL; - + gboolean result; + old_item = (XfconfCacheOldItem *) user_data; + cache = old_item->cache; if(!cache->pending_calls) return; xfconf_cache_mutex_lock(cache); - +/* old_item = g_hash_table_lookup(cache->pending_calls, call); if(G_UNLIKELY(!old_item)) { #ifndef NDEBUG @@ -533,11 +609,10 @@ xfconf_cache_set_property_reply_handler(DBusGProxy *proxy, #endif goto out; } - +*/ g_hash_table_remove(cache->old_properties, old_item->property); /* don't destroy old_item yet */ - g_hash_table_steal(cache->pending_calls, old_item->call); - + g_hash_table_steal(cache->pending_calls, old_item->cancellable); item = g_tree_lookup(cache->properties, old_item->property); if(G_UNLIKELY(!item)) { #ifndef NDEBUG @@ -546,15 +621,12 @@ xfconf_cache_set_property_reply_handler(DBusGProxy *proxy, goto out; } - if(!dbus_g_proxy_end_call(proxy, call, &error, G_TYPE_INVALID)) { - /* failed to set the value. reset it to the old value and send - * a prop changed signal to the channel */ + result = xfconf_exported_call_set_property_finish ((XfconfExported*)proxy, res, &error); + if (!result) { GValue empty_val = { 0, }; - g_warning("Failed to set property \"%s::%s\": %s", cache->channel_name, old_item->property, error->message); g_error_free(error); - if(old_item->item) xfconf_cache_item_update(item, old_item->item->value); else { @@ -571,8 +643,8 @@ xfconf_cache_set_property_reply_handler(DBusGProxy *proxy, xfconf_cache_mutex_lock(cache); } - /* we handled the call, so set it to %NULL */ - old_item->call = NULL; + /* we handled the call */ + g_cancellable_cancel(old_item->cancellable); if(old_item) xfconf_cache_old_item_free(old_item); @@ -624,42 +696,40 @@ xfconf_cache_new(const gchar *channel_name) NULL); } -static gboolean -xfconf_cache_prefetch_ht(gpointer key, - gpointer value, - gpointer user_data) -{ - XfconfCache *cache = XFCONF_CACHE(user_data); - XfconfCacheItem *item; - - item = xfconf_cache_item_new(value, TRUE); - g_tree_insert(cache->properties, key, item); - - return TRUE; -} - gboolean xfconf_cache_prefetch(XfconfCache *cache, const gchar *property_base, GError **error) { + GVariant *props_variant, *value; + GVariantIter *iter; + gchar *key; gboolean ret = FALSE; - GHashTable *props = NULL; - DBusGProxy *proxy = _xfconf_get_dbus_g_proxy(); + GDBusProxy *proxy = _xfconf_get_gdbus_proxy (); GError *tmp_error = NULL; g_return_val_if_fail(g_tree_nnodes(cache->properties) == 0, FALSE); xfconf_cache_mutex_lock(cache); - if(xfconf_client_get_all_properties(proxy, cache->channel_name, - property_base ? property_base : "/", - &props, &tmp_error)) + if(xfconf_exported_call_get_all_properties_sync((XfconfExported *)proxy, cache->channel_name, + property_base ? property_base : "/", + &props_variant, NULL, &tmp_error)) { - g_hash_table_foreach_steal(props, xfconf_cache_prefetch_ht, cache); - g_hash_table_destroy(props); + g_variant_get (props_variant, "a{sv}", &iter); + + while (g_variant_iter_next (iter, "{sv}", &key, &value)) + { + XfconfCacheItem *item; + + GValue *gvalue = xfconf_gvariant_to_gvalue (value); + item = xfconf_cache_item_new(gvalue, TRUE); + g_tree_insert(cache->properties, key, item); + } /* TODO: honor max entries */ ret = TRUE; + g_variant_iter_free (iter); + g_variant_unref(props_variant); } else g_propagate_error(error, tmp_error); @@ -675,22 +745,23 @@ xfconf_cache_lookup_locked(XfconfCache *cache, GError **error) { XfconfCacheItem *item = NULL; - item = g_tree_lookup(cache->properties, property); + if(!item) { - DBusGProxy *proxy = _xfconf_get_dbus_g_proxy(); - GValue tmpval = { 0, }; + GVariant *variant; + GDBusProxy *proxy = _xfconf_get_gdbus_proxy(); GError *tmp_error = NULL; - /* blocking, ugh */ - if(xfconf_client_get_property(proxy, cache->channel_name, - property, &tmpval, &tmp_error)) + if(xfconf_exported_call_get_property_sync ((XfconfExported *)proxy, cache->channel_name, + property, &variant, NULL, &tmp_error)) { - item = xfconf_cache_item_new(&tmpval, FALSE); + GValue *tmpval; + tmpval = xfconf_gvariant_to_gvalue(variant); + item = xfconf_cache_item_new(tmpval, TRUE); g_tree_insert(cache->properties, g_strdup(property), item); - g_value_unset(&tmpval); + g_variant_unref (variant); /* TODO: check tree for evictions */ - } else + } else g_propagate_error(error, tmp_error); } @@ -699,11 +770,24 @@ xfconf_cache_lookup_locked(XfconfCache *cache, if(!G_VALUE_TYPE(value)) g_value_init(value, G_VALUE_TYPE(item->value)); - if(G_VALUE_TYPE(value) == G_VALUE_TYPE(item->value)) - g_value_copy(item->value, value); - else { - if(!g_value_transform(item->value, value)) + if (G_VALUE_TYPE(item->value) == G_TYPE_PTR_ARRAY) { + if (G_VALUE_TYPE(value) != G_TYPE_PTR_ARRAY) { + g_warning("Given value is not of type G_TYPE_PTR_ARRAY"); item = NULL; + } + else { + GPtrArray *arr; + arr = xfconf_dup_value_array (g_value_get_boxed(item->value), FALSE); + g_value_take_boxed(value, arr); + } + } + else { + if(G_VALUE_TYPE(value) == G_VALUE_TYPE(item->value)) + g_value_copy(item->value, value); + else { + if(!g_value_transform(item->value, value)) + item = NULL; + } } } #if 0 @@ -739,10 +823,10 @@ xfconf_cache_set(XfconfCache *cache, const GValue *value, GError **error) { - DBusGProxy *proxy = _xfconf_get_dbus_g_proxy(); + GVariant *variant = NULL, *val = NULL; + GDBusProxy *proxy = _xfconf_get_gdbus_proxy(); XfconfCacheItem *item = NULL; XfconfCacheOldItem *old_item = NULL; - xfconf_cache_mutex_lock(cache); item = g_tree_lookup(cache->properties, property); @@ -751,33 +835,24 @@ xfconf_cache_set(XfconfCache *cache, * but i can't think of a better way yet. */ GValue tmp_val = { 0, }; GError *tmp_error = NULL; - if(!xfconf_cache_lookup_locked(cache, property, &tmp_val, &tmp_error)) { - /* this is just another example of dbus-glib's brain-deadedness. - * instead of remapping the remote error back into the local - * domain and code, it uses DBUS_GERROR as the domain, - * DBUS_GERROR_REMOTE_EXCEPTION as the code, and then "hides" - * the full string ("org.xfce.Xfconf.Error.Whatever") in - * GError::message after a NUL byte. so stupid. */ - const gchar *dbus_error_name = NULL; - - if(G_LIKELY(tmp_error->domain == DBUS_GERROR - && tmp_error->code == DBUS_GERROR_REMOTE_EXCEPTION)) - { - dbus_error_name = dbus_g_error_get_name(tmp_error); - } + gchar *dbus_error_name = NULL; + if(G_LIKELY(g_dbus_error_is_remote_error (tmp_error))) + dbus_error_name = g_dbus_error_get_remote_error (tmp_error); + if(g_strcmp0(dbus_error_name, "org.xfce.Xfconf.Error.PropertyNotFound") != 0 && g_strcmp0(dbus_error_name, "org.xfce.Xfconf.Error.ChannelNotFound") != 0) { /* this is bad... */ g_propagate_error(error, tmp_error); xfconf_cache_mutex_unlock(cache); + g_free (dbus_error_name); return FALSE; } - /* prop just doesn't exist; continue */ g_error_free(tmp_error); + g_free (dbus_error_name); } else { g_value_unset(&tmp_val); item = g_tree_lookup(cache->properties, property); @@ -791,7 +866,6 @@ xfconf_cache_set(XfconfCache *cache, return TRUE; } } - old_item = g_hash_table_lookup(cache->old_properties, property); if(old_item) { /* if we have an old item, it means that a previous set @@ -800,42 +874,50 @@ xfconf_cache_set(XfconfCache *cache, * the property. * we also steal the old_item from the pending_calls table * so there are no pending item left. */ - if(old_item->call) { - dbus_g_proxy_cancel_call(proxy, old_item->call); - g_hash_table_steal(cache->pending_calls, old_item->call); - old_item->call = NULL; + if(!g_cancellable_is_cancelled (old_item->cancellable)) { + g_cancellable_cancel(old_item->cancellable); + g_hash_table_steal(cache->pending_calls, old_item->cancellable); + g_object_unref (old_item->cancellable); + old_item->cancellable = g_cancellable_new(); } } else { - old_item = xfconf_cache_old_item_new(property); + old_item = xfconf_cache_old_item_new(cache, property); if(item) old_item->item = xfconf_cache_item_new(item->value, FALSE); g_hash_table_insert(cache->old_properties, old_item->property, old_item); } - /* can't use the generated dbus-glib binding here cuz we won't - * get the pending call pointer in the callback */ - old_item->call = dbus_g_proxy_begin_call(proxy, "SetProperty", - xfconf_cache_set_property_reply_handler, - cache, NULL, - G_TYPE_STRING, cache->channel_name, - G_TYPE_STRING, property, - G_TYPE_VALUE, value, - G_TYPE_INVALID); - g_hash_table_insert(cache->pending_calls, old_item->call, old_item); + val = xfconf_gvalue_to_gvariant (value); + if (val) { + variant = g_variant_new_variant (val); - if(item) - xfconf_cache_item_update(item, value); - else { - item = xfconf_cache_item_new(value, FALSE); - g_tree_insert(cache->properties, g_strdup(property), item); - } + xfconf_exported_call_set_property ((XfconfExported *)proxy, + cache->channel_name, + property, + variant, + old_item->cancellable, + (GAsyncReadyCallback) xfconf_cache_set_property_reply_handler, + old_item); - xfconf_cache_mutex_unlock(cache); + /* Val will be freed asynchronously */ + old_item->variant = val; - g_signal_emit(G_OBJECT(cache), signals[SIG_PROPERTY_CHANGED], 0, - cache->channel_name, property, value); + g_hash_table_insert(cache->pending_calls, old_item->cancellable, old_item); - return TRUE; + if(item) + xfconf_cache_item_update(item, value); + else { + item = xfconf_cache_item_new(value, FALSE); + g_tree_insert(cache->properties, g_strdup(property), item); + } + + xfconf_cache_mutex_unlock(cache); + g_signal_emit(G_OBJECT(cache), signals[SIG_PROPERTY_CHANGED], 0, + cache->channel_name, property, value); + + return TRUE; + } + return FALSE; } typedef struct @@ -866,7 +948,7 @@ xfconf_cache_reset(XfconfCache *cache, GError **error) { gboolean ret = FALSE; - DBusGProxy *proxy = _xfconf_get_dbus_g_proxy(); + GDBusProxy *proxy = _xfconf_get_gdbus_proxy(); #if 0 XfconfCacheOldItem *old_item = NULL; #endif @@ -903,8 +985,8 @@ xfconf_cache_reset(XfconfCache *cache, * this point if a reset is going to remove the property or reset * it to a default. so, we have to do this sync. sad. */ - ret = xfconf_client_reset_property(proxy, cache->channel_name, - property_base, recursive, error); + ret = xfconf_exported_call_reset_property_sync ((XfconfExported*)proxy, cache->channel_name, + property_base, recursive, NULL, error); if(ret) { /* here we just evict the entry from the cache if we have one. diff --git a/xfconf/xfconf-channel.c b/xfconf/xfconf-channel.c index b44b1da..9532c44 100644 --- a/xfconf/xfconf-channel.c +++ b/xfconf/xfconf-channel.c @@ -1,6 +1,7 @@ /* * xfconf * + * Copyright (c) 2016 Ali Abdallah <ali@xfce.org> * Copyright (c) 2007-2008 Brian Tarricone <bjt23@cornell.edu> * * This library is free software; you can redistribute it and/or @@ -28,7 +29,7 @@ #include "xfconf-channel.h" #include "xfconf-cache.h" -#include "xfconf-dbus-bindings.h" +#include "common/xfconf-gdbus-bindings.h" #include "common/xfconf-gvaluefuncs.h" #include "xfconf-private.h" #include "common/xfconf-marshal.h" @@ -457,47 +458,6 @@ xfconf_channel_get_internal(XfconfChannel *channel, return ret; } -static GPtrArray * -xfconf_fixup_16bit_ints(GPtrArray *arr) -{ - GPtrArray *arr_new = NULL; - guint i; - - for(i = 0; i < arr->len; ++i) { - GValue *v = g_ptr_array_index(arr, i); - - if(G_VALUE_TYPE(v) == XFCONF_TYPE_UINT16 - || G_VALUE_TYPE(v) == XFCONF_TYPE_INT16) - { - arr_new = g_ptr_array_sized_new(arr->len); - break; - } - } - - if(!arr_new) - return NULL; - - for(i = 0; i < arr->len; ++i) { - GValue *v_src, *v_dest; - - v_src = g_ptr_array_index(arr, i); - v_dest = g_new0(GValue, 1); - if(G_VALUE_TYPE(v_src) == XFCONF_TYPE_UINT16) { - g_value_init(v_dest, G_TYPE_UINT); - g_value_set_uint(v_dest, xfconf_g_value_get_uint16(v_src)); - } else if(G_VALUE_TYPE(v_src) == XFCONF_TYPE_INT16) { - g_value_init(v_dest, G_TYPE_INT); - g_value_set_int(v_dest, xfconf_g_value_get_int16(v_src)); - } else { - g_value_init(v_dest, G_VALUE_TYPE(v_src)); - g_value_copy(v_src, v_dest); - } - - g_ptr_array_add(arr_new, v_dest); - } - - return arr_new; -} static GPtrArray * xfconf_transform_array(GPtrArray *arr_src, @@ -663,13 +623,13 @@ gboolean xfconf_channel_is_property_locked(XfconfChannel *channel, const gchar *property) { - DBusGProxy *proxy = _xfconf_get_dbus_g_proxy(); + GDBusProxy *proxy = _xfconf_get_gdbus_proxy(); gboolean locked = FALSE; gchar *real_property = REAL_PROP(channel, property); ERROR_DEFINE; - - if(!xfconf_client_is_property_locked(proxy, channel->channel_name, - property, &locked, ERROR)) + + if (!xfconf_exported_call_is_property_locked_sync ((XfconfExported*)proxy, channel->channel_name, + property, &locked, NULL, ERROR)) { ERROR_CHECK; locked = FALSE; @@ -745,8 +705,9 @@ GHashTable * xfconf_channel_get_properties(XfconfChannel *channel, const gchar *property_base) { - DBusGProxy *proxy = _xfconf_get_dbus_g_proxy(); + GDBusProxy *proxy = _xfconf_get_gdbus_proxy (); GHashTable *properties = NULL; + GVariant *variant; gchar *real_property_base; ERROR_DEFINE; @@ -755,15 +716,20 @@ xfconf_channel_get_properties(XfconfChannel *channel, else real_property_base = REAL_PROP(channel, property_base); - if(!xfconf_client_get_all_properties(proxy, channel->channel_name, - real_property_base - ? real_property_base : "/", - &properties, ERROR)) + if(!xfconf_exported_call_get_all_properties_sync ((XfconfExported*)proxy, channel->channel_name, + real_property_base + ? real_property_base : "/", + &variant, NULL, ERROR)) { ERROR_CHECK; - properties = NULL; + variant = NULL; } - + + if (variant) { + properties = xfconf_gvariant_to_hash (variant); + g_variant_unref (variant); + } + if(real_property_base != property_base && real_property_base != channel->property_base) { @@ -1263,7 +1229,7 @@ xfconf_channel_get_property(XfconfChannel *channel, { /* caller wants to convert the returned value into a diff type */ - if(G_VALUE_TYPE(&val1) == XFCONF_TYPE_G_VALUE_ARRAY) { + if(G_VALUE_TYPE(&val1) == G_TYPE_PTR_ARRAY) { /* we got an array back, so let's convert each item in * the array to the target type */ GPtrArray *arr = xfconf_transform_array(g_value_get_boxed(&val1), @@ -1271,7 +1237,7 @@ xfconf_channel_get_property(XfconfChannel *channel, if(arr) { g_value_unset(value); - g_value_init(value, XFCONF_TYPE_G_VALUE_ARRAY); + g_value_init(value, G_TYPE_PTR_ARRAY); g_value_take_boxed(value, arr); } else ret = FALSE; @@ -1317,8 +1283,7 @@ xfconf_channel_set_property(XfconfChannel *channel, const gchar *property, const GValue *value) { - GValue *val, tmp_val = { 0, }; - GPtrArray *arr_new = NULL; + GValue val = { 0, }; gboolean ret; g_return_val_if_fail(XFCONF_IS_CHANNEL(channel) @@ -1328,34 +1293,11 @@ xfconf_channel_set_property(XfconfChannel *channel, || g_value_get_string(value) == NULL || g_utf8_validate(g_value_get_string(value), -1, NULL), FALSE); - - /* intercept uint16/int16 since dbus-glib doesn't know how to send - * them over the wire */ - if(G_VALUE_TYPE(value) == XFCONF_TYPE_UINT16) { - val = &tmp_val; - g_value_init(&tmp_val, G_TYPE_UINT); - g_value_set_uint(&tmp_val, xfconf_g_value_get_uint16(value)); - } else if(G_VALUE_TYPE(value) == XFCONF_TYPE_INT16) { - val = &tmp_val; - g_value_init(&tmp_val, G_TYPE_INT); - g_value_set_int(&tmp_val, xfconf_g_value_get_int16(value)); - } else if(G_VALUE_TYPE(value) == XFCONF_TYPE_G_VALUE_ARRAY) { - arr_new = xfconf_fixup_16bit_ints(g_value_get_boxed(value)); - if(arr_new) { - val = &tmp_val; - g_value_init(&tmp_val, XFCONF_TYPE_G_VALUE_ARRAY); - g_value_set_boxed(&tmp_val, arr_new); - } else - val = (GValue *)value; - } else - val = (GValue *)value; - - ret = xfconf_channel_set_internal(channel, property, val); - - if(val == &tmp_val) - g_value_unset(&tmp_val); - if(arr_new) - xfconf_array_free(arr_new); + + g_value_init(&val, G_VALUE_TYPE(value)); + g_value_copy(value, &val); + ret = xfconf_channel_set_internal(channel, property, &val); + g_value_unset(&val); return ret; } @@ -1543,22 +1485,25 @@ xfconf_channel_get_arrayv(XfconfChannel *channel, g_return_val_if_fail(XFCONF_IS_CHANNEL(channel) && property, NULL); ret = xfconf_channel_get_internal(channel, property, &val); + if(!ret) return NULL; - if(XFCONF_TYPE_G_VALUE_ARRAY != G_VALUE_TYPE(&val)) { + if(G_TYPE_PTR_ARRAY != G_VALUE_TYPE(&val)) { + g_warning ("Unexpected value type %s\n", G_VALUE_TYPE_NAME(&val)); g_value_unset(&val); return NULL; } + /** + * Arr is owned by the Gvalue in the cache + * do not free it. + **/ arr = g_value_get_boxed(&val); if(!arr->len) { g_ptr_array_free(arr, TRUE); return NULL; } - - /* FIXME: does anything with |val| leak here? */ - return arr; } @@ -1719,25 +1664,19 @@ xfconf_channel_set_arrayv(XfconfChannel *channel, const gchar *property, GPtrArray *values) { - GPtrArray *values_new = NULL; GValue val = { 0, }; gboolean ret; g_return_val_if_fail(XFCONF_IS_CHANNEL(channel) && property && values, FALSE); - values_new = xfconf_fixup_16bit_ints(values); - - g_value_init(&val, XFCONF_TYPE_G_VALUE_ARRAY); - g_value_set_static_boxed(&val, values_new ? values_new : values); + g_value_init(&val, G_TYPE_PTR_ARRAY); + g_value_set_static_boxed(&val, values); ret = xfconf_channel_set_internal(channel, property, &val); g_value_unset(&val); - if(values_new) - xfconf_array_free(values_new); - return ret; } @@ -2295,11 +2234,12 @@ out: gchar ** xfconf_list_channels(void) { - DBusGProxy *proxy = _xfconf_get_dbus_g_proxy(); + GDBusProxy *proxy = _xfconf_get_gdbus_proxy(); gchar **channels = NULL; ERROR_DEFINE; - if(!xfconf_client_list_channels(proxy, &channels, ERROR)) + if(!xfconf_exported_call_list_channels_sync ((XfconfExported*)proxy, + &channels, NULL, ERROR)) ERROR_CHECK; return channels; diff --git a/xfconf/xfconf-private.h b/xfconf/xfconf-private.h index 472a245..6dcaffa 100644 --- a/xfconf/xfconf-private.h +++ b/xfconf/xfconf-private.h @@ -21,7 +21,7 @@ #ifndef __XFCONF_PRIVATE_H__ #define __XFCONF_PRIVATE_H__ -#include <dbus/dbus-glib.h> +#include <gio/gio.h> #ifdef XFCONF_ENABLE_CHECKS @@ -49,8 +49,9 @@ typedef struct GType *member_types; } XfconfNamedStruct; -DBusGConnection *_xfconf_get_dbus_g_connection(void); -DBusGProxy *_xfconf_get_dbus_g_proxy(void); + +GDBusConnection *_xfconf_get_gdbus_connection(void); +GDBusProxy *_xfconf_get_gdbus_proxy(void); XfconfNamedStruct *_xfconf_named_struct_lookup(const gchar *struct_name); diff --git a/xfconf/xfconf.c b/xfconf/xfconf.c index 53f5825..c125571 100644 --- a/xfconf/xfconf.c +++ b/xfconf/xfconf.c @@ -26,43 +26,45 @@ #include <string.h> #endif +#include <glib.h> +#include <gio/gio.h> #include <glib-object.h> -#include <dbus/dbus-glib.h> - #include "xfconf.h" #include "common/xfconf-marshal.h" #include "xfconf-private.h" #include "common/xfconf-alias.h" static guint xfconf_refcnt = 0; -static DBusGConnection *dbus_conn = NULL; -static DBusGProxy *dbus_proxy = NULL; + +static GDBusConnection *gdbus = NULL; +static GDBusProxy *gproxy = NULL; static GHashTable *named_structs = NULL; /* private api */ -DBusGConnection * -_xfconf_get_dbus_g_connection(void) +GDBusConnection * +_xfconf_get_gdbus_connection(void) { if(!xfconf_refcnt) { g_critical("xfconf_init() must be called before attempting to use libxfconf!"); return NULL; } - return dbus_conn; + return gdbus; } -DBusGProxy * -_xfconf_get_dbus_g_proxy(void) + +GDBusProxy * +_xfconf_get_gdbus_proxy(void) { if(!xfconf_refcnt) { g_critical("xfconf_init() must be called before attempting to use libxfconf!"); return NULL; } - return dbus_proxy; + return gproxy; } XfconfNamedStruct * @@ -78,35 +80,6 @@ _xfconf_named_struct_free(XfconfNamedStruct *ns) g_slice_free(XfconfNamedStruct, ns); } - - -static void -xfconf_static_dbus_init(void) -{ - static gboolean static_dbus_inited = FALSE; - - if(!static_dbus_inited) { - dbus_g_error_domain_register(XFCONF_ERROR, "org.xfce.Xfconf.Error", - XFCONF_TYPE_ERROR); - - dbus_g_object_register_marshaller(_xfconf_marshal_VOID__STRING_STRING_BOXED, - G_TYPE_NONE, - G_TYPE_STRING, - G_TYPE_STRING, - G_TYPE_VALUE, - G_TYPE_INVALID); - dbus_g_object_register_marshaller(_xfconf_marshal_VOID__STRING_STRING, - G_TYPE_NONE, - G_TYPE_STRING, - G_TYPE_STRING, - G_TYPE_INVALID); - - static_dbus_inited = TRUE; - } -} - - - /* public api */ /** @@ -131,23 +104,19 @@ xfconf_init(GError **error) g_type_init(); #endif - xfconf_static_dbus_init(); + gdbus = g_bus_get_sync (G_BUS_TYPE_SESSION, NULL, error); - dbus_conn = dbus_g_bus_get(DBUS_BUS_SESSION, error); - if(!dbus_conn) + if (!gdbus) return FALSE; - dbus_proxy = dbus_g_proxy_new_for_name(dbus_conn, - "org.xfce.Xfconf", - "/org/xfce/Xfconf", - "org.xfce.Xfconf"); - - dbus_g_proxy_add_signal(dbus_proxy, "PropertyChanged", - G_TYPE_STRING, G_TYPE_STRING, G_TYPE_VALUE, - G_TYPE_INVALID); - dbus_g_proxy_add_signal(dbus_proxy, "PropertyRemoved", - G_TYPE_STRING, G_TYPE_STRING, - G_TYPE_INVALID); + gproxy = g_dbus_proxy_new_sync(gdbus, + G_DBUS_PROXY_FLAGS_NONE, + NULL, + "org.xfce.Xfconf", + "/org/xfce/Xfconf", + "org.xfce.Xfconf", + NULL, + NULL); ++xfconf_refcnt; return TRUE; @@ -180,12 +149,6 @@ xfconf_shutdown(void) named_structs = NULL; } - g_object_unref(G_OBJECT(dbus_proxy)); - dbus_proxy = NULL; - - dbus_g_connection_unref(dbus_conn); - dbus_conn = NULL; - --xfconf_refcnt; } |