From acd4439e6fdbc80edc39fe366ba6faec44193195 Mon Sep 17 00:00:00 2001 From: Ryan Lortie Date: Thu, 29 Dec 2011 02:40:01 -0500 Subject: [PATCH] GSettingsBackend: simplify event handling Drop the 'vtable' business and switch to a single callback that takes a new GSettingsEvent structure. This patch temporarily regresses delayed settings: if a key set within a delayed settings backend becomes non-writable, it is no longer removed from the changeset. --- gio/Makefile.am | 2 +- gio/gdelayedsettingsbackend.c | 149 +------------------ gio/gio.symbols | 1 + gio/gsettings.c | 258 +++++++++++++++++++-------------- gio/gsettingsbackend.c | 147 +++++++++---------- gio/gsettingsbackend.h | 64 +++++--- gio/gsettingsbackendinternal.h | 80 ++++------ 7 files changed, 296 insertions(+), 405 deletions(-) diff --git a/gio/Makefile.am b/gio/Makefile.am index 20bcd8161..08eb7b2e3 100644 --- a/gio/Makefile.am +++ b/gio/Makefile.am @@ -111,7 +111,6 @@ gdbus-daemon-generated.h gdbus-daemon-generated.c: $(srcdir)/dbus-daemon.xml $(s $(NULL) settings_headers = \ - gsettingsbackend.h \ gsettingsschema.h \ gsettings.h @@ -624,6 +623,7 @@ gio_headers = \ gioincludedir=$(includedir)/glib-2.0/gio/ gioinclude_HEADERS = \ + gsettingsbackend.h \ $(gio_headers) \ gioenumtypes.h diff --git a/gio/gdelayedsettingsbackend.c b/gio/gdelayedsettingsbackend.c index 6f3c41197..b85d7240d 100644 --- a/gio/gdelayedsettingsbackend.c +++ b/gio/gdelayedsettingsbackend.c @@ -264,146 +264,14 @@ g_delayed_settings_backend_revert (GDelayedSettingsBackend *delayed) } } -/* change notification */ static void -delayed_backend_changed (GObject *target, - GSettingsBackend *backend, - const gchar *key, - gpointer origin_tag) +g_delayed_settings_got_event (GObject *target, + const GSettingsEvent *event) { GDelayedSettingsBackend *delayed = G_DELAYED_SETTINGS_BACKEND (target); - if (origin_tag != delayed->priv) - g_settings_backend_changed (G_SETTINGS_BACKEND (delayed), - key, origin_tag); -} - -static void -delayed_backend_keys_changed (GObject *target, - GSettingsBackend *backend, - const gchar *path, - const gchar * const *items, - gpointer origin_tag) -{ - GDelayedSettingsBackend *delayed = G_DELAYED_SETTINGS_BACKEND (target); - - if (origin_tag != delayed->priv) - g_settings_backend_keys_changed (G_SETTINGS_BACKEND (delayed), - path, items, origin_tag); -} - -static void -delayed_backend_path_changed (GObject *target, - GSettingsBackend *backend, - const gchar *path, - gpointer origin_tag) -{ - GDelayedSettingsBackend *delayed = G_DELAYED_SETTINGS_BACKEND (target); - - if (origin_tag != delayed->priv) - g_settings_backend_path_changed (G_SETTINGS_BACKEND (delayed), - path, origin_tag); -} - -static void -delayed_backend_writable_changed (GObject *target, - GSettingsBackend *backend, - const gchar *key) -{ - GDelayedSettingsBackend *delayed = G_DELAYED_SETTINGS_BACKEND (target); - gboolean last_one = FALSE; - - g_mutex_lock (&delayed->priv->lock); - - if (g_tree_lookup (delayed->priv->delayed, key) != NULL && - !g_settings_backend_get_writable (delayed->priv->backend, key)) - { - /* drop the key from our changeset if it just became read-only. - * no need to signal since the writable change below implies it. - * - * note that the item in the tree may very well be set to NULL in - * the case that the user stored a reset. we intentionally don't - * drop the key in this case since a reset will always succeed - * (even against a non-writable key). - */ - g_tree_remove (delayed->priv->delayed, key); - - /* if that was the only key... */ - last_one = g_tree_nnodes (delayed->priv->delayed) == 0; - } - - g_mutex_unlock (&delayed->priv->lock); - - if (last_one) - g_delayed_settings_backend_notify_unapplied (delayed); - - g_settings_backend_writable_changed (G_SETTINGS_BACKEND (delayed), key); -} - -/* slow method until we get foreach-with-remove in GTree - */ -typedef struct -{ - const gchar *path; - const gchar **keys; - gsize index; -} CheckPrefixState; - -static gboolean -check_prefix (gpointer key, - gpointer value, - gpointer data) -{ - CheckPrefixState *state = data; - - if (g_str_has_prefix (key, state->path)) - state->keys[state->index++] = key; - - return FALSE; -} - -static void -delayed_backend_path_writable_changed (GObject *target, - GSettingsBackend *backend, - const gchar *path) -{ - GDelayedSettingsBackend *delayed = G_DELAYED_SETTINGS_BACKEND (target); - gboolean last_one = FALSE; - gsize n_keys; - - g_mutex_lock (&delayed->priv->lock); - - n_keys = g_tree_nnodes (delayed->priv->delayed); - - if (n_keys > 0) - { - CheckPrefixState state = { path, g_new (const gchar *, n_keys) }; - gsize i; - - /* collect a list of possibly-affected keys (ie: matching the path) */ - g_tree_foreach (delayed->priv->delayed, check_prefix, &state); - - /* drop the keys that have been affected. - * - * don't drop 'reset' keys (see above) */ - for (i = 0; i < state.index; i++) - if (g_tree_lookup (delayed->priv->delayed, state.keys[i]) != NULL && - !g_settings_backend_get_writable (delayed->priv->backend, - state.keys[i])) - g_tree_remove (delayed->priv->delayed, state.keys[i]); - - g_free (state.keys); - - last_one = g_tree_nnodes (delayed->priv->delayed) == 0; - } - - g_mutex_unlock (&delayed->priv->lock); - - if (last_one) - g_delayed_settings_backend_notify_unapplied (delayed); - - g_settings_backend_path_writable_changed (G_SETTINGS_BACKEND (delayed), - path); + if (event->origin_tag != delayed->priv) + g_settings_backend_report_event (G_SETTINGS_BACKEND (delayed), event); } static void @@ -470,13 +338,6 @@ g_delayed_settings_backend_new (GSettingsBackend *backend, gpointer owner, GMainContext *owner_context) { - static GSettingsListenerVTable vtable = { - delayed_backend_changed, - delayed_backend_path_changed, - delayed_backend_keys_changed, - delayed_backend_writable_changed, - delayed_backend_path_writable_changed - }; GDelayedSettingsBackend *delayed; delayed = g_object_new (G_TYPE_DELAYED_SETTINGS_BACKEND, NULL); @@ -487,7 +348,7 @@ g_delayed_settings_backend_new (GSettingsBackend *backend, g_object_weak_ref (owner, g_delayed_settings_backend_disown, delayed); g_settings_backend_watch (delayed->priv->backend, - &vtable, G_OBJECT (delayed), NULL); + g_delayed_settings_got_event, G_OBJECT (delayed), NULL); return delayed; } diff --git a/gio/gio.symbols b/gio/gio.symbols index 6db9bbd2d..3c7cc0ca2 100644 --- a/gio/gio.symbols +++ b/gio/gio.symbols @@ -1132,6 +1132,7 @@ g_file_descriptor_based_get_type g_file_descriptor_based_get_fd #endif g_settings_backend_get_type +g_settings_backend_report_event g_settings_backend_changed g_settings_backend_flatten_tree g_settings_backend_keys_changed diff --git a/gio/gsettings.c b/gio/gsettings.c index a6ee776c2..f0f5c1d55 100644 --- a/gio/gsettings.c +++ b/gio/gsettings.c @@ -316,124 +316,175 @@ g_settings_real_writable_change_event (GSettings *settings, } static void -settings_backend_changed (GObject *target, - GSettingsBackend *backend, - const gchar *key, - gpointer origin_tag) +g_settings_emit_signal (GSettings *settings, + GSettingsEventType type, + const GQuark *quarks, + gint n_items) +{ + gboolean ignore_this; + guint signal_id; + + switch (type) + { + case G_SETTINGS_EVENT_CHANGE: + signal_id = g_settings_signals[SIGNAL_CHANGE_EVENT]; + break; + + case G_SETTINGS_EVENT_WRITABLE_CHANGE: + signal_id = g_settings_signals[SIGNAL_WRITABLE_CHANGE_EVENT]; + break; + + default: + g_assert_not_reached (); + } + + /* writable-change-event signals are emitted in a different way */ + if (signal_id == g_settings_signals[SIGNAL_WRITABLE_CHANGE_EVENT]) + { + if (n_items > 0) + { + gint i; + + for (i = 0; i < n_items; i++) + g_signal_emit (settings, signal_id, 0, quarks[i], &ignore_this); + } + else + g_signal_emit (settings, signal_id, 0, (GQuark) 0, &ignore_this); + + return; + } + + g_signal_emit (settings, signal_id, 0, quarks, n_items, &ignore_this); +} + +static void +g_settings_got_event (GObject *target, + const GSettingsEvent *event) { GSettings *settings = G_SETTINGS (target); - gboolean ignore_this; - gint i; + const gchar *prefix; + const gchar *path; + gint prefix_len; + gint path_len; - /* We used to assert here: + /* The path of the GSettings always ends with '/'. * - * settings->priv->backend == backend + * For path '/a/b/', consider these prefixes: * - * but it could be the case that a notification is queued for delivery - * while someone calls g_settings_delay() (which changes the backend). + * - /x/ does not match + * - /a/b/ want to match -- this is us directly + * - /a/ want to match -- this may impact us + * - /a/b/c want to match -- 'c' may be a key + * - /a/b/c/ does not match * - * Since the delay backend would just pass that straight through - * anyway, it doesn't make sense to try to detect this case. - * Therefore, we just accept it. + * We can quickly determine if we are in a 'want to match' situation + * by fast-forwarding the common part of the GSettings path and the + * event prefix. */ + path = settings->priv->path; + prefix = event->prefix; - for (i = 0; key[i] == settings->priv->path[i]; i++); - - if (settings->priv->path[i] == '\0' && - g_settings_schema_has_key (settings->priv->schema, key + i)) + while (*prefix && *prefix == *path) { - GQuark quark; - - quark = g_quark_from_string (key + i); - g_signal_emit (settings, g_settings_signals[SIGNAL_CHANGE_EVENT], - 0, &quark, 1, &ignore_this); + prefix++; + path++; } -} + prefix_len = strlen (prefix); + path_len = strlen (path); -static void -settings_backend_path_changed (GObject *target, - GSettingsBackend *backend, - const gchar *path, - gpointer origin_tag) -{ - GSettings *settings = G_SETTINGS (target); - gboolean ignore_this; + /* If after removing the common prefix, we are left with characters in + * both then it is clear that we are in a non-matching situation. + */ + if (prefix_len && path_len) + return; - if (g_str_has_prefix (settings->priv->path, path)) - g_signal_emit (settings, g_settings_signals[SIGNAL_CHANGE_EVENT], - 0, NULL, 0, &ignore_this); -} - -static void -settings_backend_keys_changed (GObject *target, - GSettingsBackend *backend, - const gchar *path, - const gchar * const *items, - gpointer origin_tag) -{ - GSettings *settings = G_SETTINGS (target); - gboolean ignore_this; - gint i; - - for (i = 0; settings->priv->path[i] && - settings->priv->path[i] == path[i]; i++); - - if (path[i] == '\0') + if (prefix_len) { - GQuark quarks[256]; - gint j, l = 0; + /* If part of the prefix is remaining then the only possibility is + * that we are emitting a change notification for a single key + * belonging to this settings object. The remainder of that + * prefix (after stripping our path) is exactly the name of that + * key. + * + * Necessarily, this key must not contain a slash in any part of + * it. This is a somewhat common case, so we explicitly check + * that before attempting to do a lookup of the key. + */ + if (strchr (prefix, '/')) + return; - for (j = 0; items[j]; j++) - { - const gchar *item = items[j]; - gint k; + /* If the prefix doesn't end with a slash (as we just verified) + * then it had better be the case that the keys array is empty. + * We don't bother verifying that, though. + * + * We just check if the prefix is the name of one of our keys. + */ + if (g_settings_schema_has_key (settings->priv->schema, prefix)) + { + GQuark quark; - for (k = 0; item[k] == settings->priv->path[i + k]; k++); - - if (settings->priv->path[i + k] == '\0' && - g_settings_schema_has_key (settings->priv->schema, item + k)) - quarks[l++] = g_quark_from_string (item + k); - - /* "256 quarks ought to be enough for anybody!" - * If this bites you, I'm sorry. Please file a bug. - */ - g_assert (l < 256); - } - - if (l > 0) - g_signal_emit (settings, g_settings_signals[SIGNAL_CHANGE_EVENT], - 0, quarks, l, &ignore_this); + quark = g_quark_from_string (prefix); + g_settings_emit_signal (settings, event->type, &quark, 1); + } } -} + else + { + /* The entire prefix is consumed. This means that the prefix + * ended with a slash and matched our path. + * + * We may still have some remaining part of the path, however. If + * that is true, we need to verify that each item in the keys + * array has this component as a prefix. + */ -static void -settings_backend_writable_changed (GObject *target, - GSettingsBackend *backend, - const gchar *key) -{ - GSettings *settings = G_SETTINGS (target); - gboolean ignore_this; - gint i; + /* If the key array is empty then all items under this path have + * changed. We don't care about any remaining part of our path in + * this case since everything has changed. + */ + if (event->keys[0] == NULL) + g_settings_emit_signal (settings, event->type, NULL, 0); - for (i = 0; key[i] == settings->priv->path[i]; i++); + else + { + GQuark *quarks; + gint n, i, j; - if (settings->priv->path[i] == '\0' && - g_settings_schema_has_key (settings->priv->schema, key + i)) - g_signal_emit (settings, g_settings_signals[SIGNAL_WRITABLE_CHANGE_EVENT], - 0, g_quark_from_string (key + i), &ignore_this); -} + n = g_strv_length (event->keys); -static void -settings_backend_path_writable_changed (GObject *target, - GSettingsBackend *backend, - const gchar *path) -{ - GSettings *settings = G_SETTINGS (target); - gboolean ignore_this; + if (20 < n) + quarks = g_new (GQuark, n); + else + quarks = g_newa (GQuark, n); - if (g_str_has_prefix (settings->priv->path, path)) - g_signal_emit (settings, g_settings_signals[SIGNAL_WRITABLE_CHANGE_EVENT], - 0, (GQuark) 0, &ignore_this); + j = 0; + for (i = 0; event->keys[i]; i++) + { + gchar *key = event->keys[i]; + + /* Check the prefix */ + if (!g_str_has_prefix (key, path)) + continue; + + /* Remove that component from the key */ + key += path_len; + + /* Do the slash check as above, and for the same reason */ + if (strchr (key, '/')) + continue; + + /* Check if it's actually a key */ + if (g_settings_schema_has_key (settings->priv->schema, key)) + quarks[j++] = g_quark_from_string (key); + } + + /* Only signal if we actually had a match. */ + if (j > 0) + g_settings_emit_signal (settings, event->type, quarks, j); + + if (20 < n) + g_free (quarks); + } + } } /* Properties, Construction, Destruction {{{1 */ @@ -546,14 +597,6 @@ g_settings_get_property (GObject *object, } } -static const GSettingsListenerVTable listener_vtable = { - settings_backend_changed, - settings_backend_path_changed, - settings_backend_keys_changed, - settings_backend_writable_changed, - settings_backend_path_writable_changed -}; - static void g_settings_constructed (GObject *object) { @@ -579,7 +622,8 @@ g_settings_constructed (GObject *object) settings->priv->backend = g_settings_backend_get_default (); g_settings_backend_watch (settings->priv->backend, - &listener_vtable, G_OBJECT (settings), + g_settings_got_event, + G_OBJECT (settings), settings->priv->main_context); g_settings_backend_subscribe (settings->priv->backend, settings->priv->path); @@ -1907,7 +1951,7 @@ g_settings_delay (GSettings *settings) settings->priv->backend = G_SETTINGS_BACKEND (settings->priv->delayed); g_settings_backend_watch (settings->priv->backend, - &listener_vtable, G_OBJECT (settings), + g_settings_got_event, G_OBJECT (settings), settings->priv->main_context); g_object_notify (G_OBJECT (settings), "delay-apply"); diff --git a/gio/gsettingsbackend.c b/gio/gsettingsbackend.c index c89531ad3..76485a5a2 100644 --- a/gio/gsettingsbackend.c +++ b/gio/gsettingsbackend.c @@ -126,26 +126,18 @@ is_path (const gchar *path) struct _GSettingsBackendWatch { - GObject *target; - const GSettingsListenerVTable *vtable; - GMainContext *context; - GSettingsBackendWatch *next; + GObject *target; + GSettingsEventFunc function; + GMainContext *context; + GSettingsBackendWatch *next; }; struct _GSettingsBackendClosure { - void (*function) (GObject *target, - GSettingsBackend *backend, - const gchar *name, - gpointer data1, - gpointer data2); - - GSettingsBackend *backend; - GObject *target; - gchar *name; - gpointer data1; - GBoxedFreeFunc data1_free; - gpointer data2; + GSettingsEventFunc function; + GSettingsBackend *backend; + GObject *target; + GSettingsEvent event; }; static void @@ -198,10 +190,10 @@ g_settings_backend_watch_weak_notify (gpointer data, * value of @origin_tag given to any callbacks. **/ void -g_settings_backend_watch (GSettingsBackend *backend, - const GSettingsListenerVTable *vtable, - GObject *target, - GMainContext *context) +g_settings_backend_watch (GSettingsBackend *backend, + GSettingsEventFunc callback, + GObject *target, + GMainContext *context) { GSettingsBackendWatch *watch; @@ -241,7 +233,7 @@ g_settings_backend_watch (GSettingsBackend *backend, watch = g_slice_new (GSettingsBackendWatch); watch->context = context; - watch->vtable = vtable; + watch->function = callback; watch->target = target; g_object_weak_ref (target, g_settings_backend_watch_weak_notify, backend); @@ -268,47 +260,24 @@ g_settings_backend_invoke_closure (gpointer user_data) { GSettingsBackendClosure *closure = user_data; - closure->function (closure->target, closure->backend, closure->name, - closure->data1, closure->data2); + closure->function (closure->target, &closure->event); - closure->data1_free (closure->data1); g_object_unref (closure->backend); g_object_unref (closure->target); - g_free (closure->name); + g_strfreev (closure->event.keys); + g_free (closure->event.prefix); g_slice_free (GSettingsBackendClosure, closure); return FALSE; } -static gpointer -pointer_id (gpointer a) -{ - return a; -} - -static void -pointer_ignore (gpointer a) -{ -} - -static void -g_settings_backend_dispatch_signal (GSettingsBackend *backend, - gsize function_offset, - const gchar *name, - gpointer data1, - GBoxedCopyFunc data1_copy, - GBoxedFreeFunc data1_free, - gpointer data2) +void +g_settings_backend_report_event (GSettingsBackend *backend, + const GSettingsEvent *event) { GSettingsBackendWatch *suffix, *watch, *next; - if (data1_copy == NULL) - data1_copy = pointer_id; - - if (data1_free == NULL) - data1_free = pointer_ignore; - /* We're in a little bit of a tricky situation here. We need to hold * a lock while traversing the list, but we don't want to hold the * lock while calling back into user code. @@ -337,12 +306,11 @@ g_settings_backend_dispatch_signal (GSettingsBackend *backend, closure = g_slice_new (GSettingsBackendClosure); closure->backend = g_object_ref (backend); closure->target = watch->target; /* we took our ref above */ - closure->function = G_STRUCT_MEMBER (void *, watch->vtable, - function_offset); - closure->name = g_strdup (name); - closure->data1 = data1_copy (data1); - closure->data1_free = data1_free; - closure->data2 = data2; + closure->function = watch->function; + closure->event.type = event->type; + closure->event.prefix = g_strdup (event->prefix); + closure->event.keys = g_strdupv (event->keys); + closure->event.origin_tag = event->origin_tag; /* we do this here because 'watch' may not live to the end of this * iteration of the loop (since we may unref the target below). @@ -394,13 +362,18 @@ g_settings_backend_changed (GSettingsBackend *backend, const gchar *key, gpointer origin_tag) { + GSettingsEvent event; + gchar *null = NULL; + g_return_if_fail (G_IS_SETTINGS_BACKEND (backend)); g_return_if_fail (is_key (key)); - g_settings_backend_dispatch_signal (backend, - G_STRUCT_OFFSET (GSettingsListenerVTable, - changed), - key, origin_tag, NULL, NULL, NULL); + event.type = G_SETTINGS_EVENT_CHANGE; + event.prefix = (gchar *) key; + event.keys = &null; + event.origin_tag = origin_tag; + + g_settings_backend_report_event (backend, &event); } /** @@ -440,19 +413,20 @@ g_settings_backend_keys_changed (GSettingsBackend *backend, gchar const * const *items, gpointer origin_tag) { + GSettingsEvent event; + g_return_if_fail (G_IS_SETTINGS_BACKEND (backend)); g_return_if_fail (is_path (path)); /* XXX: should do stricter checking (ie: inspect each item) */ g_return_if_fail (items != NULL); - g_settings_backend_dispatch_signal (backend, - G_STRUCT_OFFSET (GSettingsListenerVTable, - keys_changed), - path, (gpointer) items, - (GBoxedCopyFunc) g_strdupv, - (GBoxedFreeFunc) g_strfreev, - origin_tag); + event.type = G_SETTINGS_EVENT_CHANGE; + event.prefix = (gchar *) path; + event.keys = (gchar **) items; + event.origin_tag = origin_tag; + + g_settings_backend_report_event (backend, &event); } /** @@ -490,13 +464,18 @@ g_settings_backend_path_changed (GSettingsBackend *backend, const gchar *path, gpointer origin_tag) { + GSettingsEvent event; + gchar *null = NULL; + g_return_if_fail (G_IS_SETTINGS_BACKEND (backend)); g_return_if_fail (is_path (path)); - g_settings_backend_dispatch_signal (backend, - G_STRUCT_OFFSET (GSettingsListenerVTable, - path_changed), - path, origin_tag, NULL, NULL, NULL); + event.type = G_SETTINGS_EVENT_CHANGE; + event.prefix = (gchar *) path; + event.keys = &null; + event.origin_tag = origin_tag; + + g_settings_backend_report_event (backend, &event); } /** @@ -515,13 +494,18 @@ void g_settings_backend_writable_changed (GSettingsBackend *backend, const gchar *key) { + GSettingsEvent event; + gchar *null = NULL; + g_return_if_fail (G_IS_SETTINGS_BACKEND (backend)); g_return_if_fail (is_key (key)); - g_settings_backend_dispatch_signal (backend, - G_STRUCT_OFFSET (GSettingsListenerVTable, - writable_changed), - key, NULL, NULL, NULL, NULL); + event.type = G_SETTINGS_EVENT_WRITABLE_CHANGE; + event.prefix = (gchar *) key; + event.keys = &null; + event.origin_tag = NULL; + + g_settings_backend_report_event (backend, &event); } /** @@ -541,13 +525,18 @@ void g_settings_backend_path_writable_changed (GSettingsBackend *backend, const gchar *path) { + GSettingsEvent event; + gchar *null = NULL; + g_return_if_fail (G_IS_SETTINGS_BACKEND (backend)); g_return_if_fail (is_path (path)); - g_settings_backend_dispatch_signal (backend, - G_STRUCT_OFFSET (GSettingsListenerVTable, - path_writable_changed), - path, NULL, NULL, NULL, NULL); + event.type = G_SETTINGS_EVENT_WRITABLE_CHANGE; + event.prefix = (gchar *) path; + event.keys = &null; + event.origin_tag = NULL; + + g_settings_backend_report_event (backend, &event); } typedef struct diff --git a/gio/gsettingsbackend.h b/gio/gsettingsbackend.h index e67418734..f75136fa3 100644 --- a/gio/gsettingsbackend.h +++ b/gio/gsettingsbackend.h @@ -104,36 +104,52 @@ struct _GSettingsBackend GSettingsBackendPrivate *priv; }; +typedef enum +{ + G_SETTINGS_EVENT_CHANGE, + G_SETTINGS_EVENT_WRITABLE_CHANGE +} GSettingsEventType; + +typedef struct +{ + GSettingsEventType type; + gchar *prefix; + gchar **keys; + gpointer origin_tag; +} GSettingsEvent; + GType g_settings_backend_get_type (void); -void g_settings_backend_changed (GSettingsBackend *backend, - const gchar *key, - gpointer origin_tag); -void g_settings_backend_path_changed (GSettingsBackend *backend, - const gchar *path, - gpointer origin_tag); -void g_settings_backend_flatten_tree (GTree *tree, - gchar **path, - const gchar ***keys, - GVariant ***values); -void g_settings_backend_keys_changed (GSettingsBackend *backend, - const gchar *path, - gchar const * const *items, - gpointer origin_tag); +void g_settings_backend_report_event (GSettingsBackend *backend, + const GSettingsEvent *event); +void g_settings_backend_changed (GSettingsBackend *backend, + const gchar *key, + gpointer origin_tag); +void g_settings_backend_path_changed (GSettingsBackend *backend, + const gchar *path, + gpointer origin_tag); +void g_settings_backend_flatten_tree (GTree *tree, + gchar **path, + const gchar ***keys, + GVariant ***values); +void g_settings_backend_keys_changed (GSettingsBackend *backend, + const gchar *path, + gchar const * const *items, + gpointer origin_tag); -void g_settings_backend_path_writable_changed (GSettingsBackend *backend, - const gchar *path); -void g_settings_backend_writable_changed (GSettingsBackend *backend, - const gchar *key); -void g_settings_backend_changed_tree (GSettingsBackend *backend, - GTree *tree, - gpointer origin_tag); +void g_settings_backend_path_writable_changed (GSettingsBackend *backend, + const gchar *path); +void g_settings_backend_writable_changed (GSettingsBackend *backend, + const gchar *key); +void g_settings_backend_changed_tree (GSettingsBackend *backend, + GTree *tree, + gpointer origin_tag); GSettingsBackend * g_settings_backend_get_default (void); -GSettingsBackend * g_keyfile_settings_backend_new (const gchar *filename, - const gchar *root_path, - const gchar *root_group); +GSettingsBackend * g_keyfile_settings_backend_new (const gchar *filename, + const gchar *root_path, + const gchar *root_group); GSettingsBackend * g_null_settings_backend_new (void); diff --git a/gio/gsettingsbackendinternal.h b/gio/gsettingsbackendinternal.h index 368c54b61..2b2d8f25a 100644 --- a/gio/gsettingsbackendinternal.h +++ b/gio/gsettingsbackendinternal.h @@ -26,71 +26,51 @@ #include "gsettingsbackend.h" -typedef struct -{ - void (* changed) (GObject *target, - GSettingsBackend *backend, - const gchar *key, - gpointer origin_tag); - void (* path_changed) (GObject *target, - GSettingsBackend *backend, - const gchar *path, - gpointer origin_tag); - void (* keys_changed) (GObject *target, - GSettingsBackend *backend, - const gchar *prefix, - const gchar * const *names, - gpointer origin_tag); - void (* writable_changed) (GObject *target, - GSettingsBackend *backend, - const gchar *key); - void (* path_writable_changed) (GObject *target, - GSettingsBackend *backend, - const gchar *path); -} GSettingsListenerVTable; +typedef void (* GSettingsEventFunc) (GObject *target, + const GSettingsEvent *event); G_GNUC_INTERNAL -void g_settings_backend_watch (GSettingsBackend *backend, - const GSettingsListenerVTable *vtable, - GObject *target, - GMainContext *context); +void g_settings_backend_watch (GSettingsBackend *backend, + GSettingsEventFunc callback, + GObject *target, + GMainContext *context); G_GNUC_INTERNAL -void g_settings_backend_unwatch (GSettingsBackend *backend, - GObject *target); +void g_settings_backend_unwatch (GSettingsBackend *backend, + GObject *target); G_GNUC_INTERNAL GTree * g_settings_backend_create_tree (void); G_GNUC_INTERNAL -GVariant * g_settings_backend_read (GSettingsBackend *backend, - const gchar *key, - const GVariantType *expected_type, - gboolean default_value); +GVariant * g_settings_backend_read (GSettingsBackend *backend, + const gchar *key, + const GVariantType *expected_type, + gboolean default_value); G_GNUC_INTERNAL -gboolean g_settings_backend_write (GSettingsBackend *backend, - const gchar *key, - GVariant *value, - gpointer origin_tag); +gboolean g_settings_backend_write (GSettingsBackend *backend, + const gchar *key, + GVariant *value, + gpointer origin_tag); G_GNUC_INTERNAL -gboolean g_settings_backend_write_tree (GSettingsBackend *backend, - GTree *tree, - gpointer origin_tag); +gboolean g_settings_backend_write_tree (GSettingsBackend *backend, + GTree *tree, + gpointer origin_tag); G_GNUC_INTERNAL -void g_settings_backend_reset (GSettingsBackend *backend, - const gchar *key, - gpointer origin_tag); +void g_settings_backend_reset (GSettingsBackend *backend, + const gchar *key, + gpointer origin_tag); G_GNUC_INTERNAL -gboolean g_settings_backend_get_writable (GSettingsBackend *backend, - const char *key); +gboolean g_settings_backend_get_writable (GSettingsBackend *backend, + const char *key); G_GNUC_INTERNAL -void g_settings_backend_unsubscribe (GSettingsBackend *backend, - const char *name); +void g_settings_backend_unsubscribe (GSettingsBackend *backend, + const char *name); G_GNUC_INTERNAL -void g_settings_backend_subscribe (GSettingsBackend *backend, - const char *name); +void g_settings_backend_subscribe (GSettingsBackend *backend, + const char *name); G_GNUC_INTERNAL -GPermission * g_settings_backend_get_permission (GSettingsBackend *backend, - const gchar *path); +GPermission * g_settings_backend_get_permission (GSettingsBackend *backend, + const gchar *path); G_GNUC_INTERNAL void g_settings_backend_sync_default (void);