[glib/wip/settings-backend: 1/7] GSettingsBackend: simplify event handling
- From: Ryan Lortie <ryanl src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [glib/wip/settings-backend: 1/7] GSettingsBackend: simplify event handling
- Date: Fri, 30 Dec 2011 00:29:04 +0000 (UTC)
commit 6cab719206742bc314e89733f0ce5c1e4f832704
Author: Ryan Lortie <desrt desrt ca>
Date: Thu Dec 29 02:40:01 2011 -0500
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 | 260 +++++++++++++++++++++++-----------------
gio/gsettingsbackend.c | 147 +++++++++++------------
gio/gsettingsbackend.h | 66 +++++++----
gio/gsettingsbackendinternal.h | 80 +++++--------
7 files changed, 298 insertions(+), 407 deletions(-)
---
diff --git a/gio/Makefile.am b/gio/Makefile.am
index ef5869e..c70e45e 100644
--- a/gio/Makefile.am
+++ b/gio/Makefile.am
@@ -96,7 +96,6 @@ gdbus_sources = \
$(NULL)
settings_headers = \
- gsettingsbackend.h \
gsettingsschema.h \
gsettings.h
@@ -583,6 +582,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 6f3c411..b85d724 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 e91be95..3af203c 100644
--- a/gio/gio.symbols
+++ b/gio/gio.symbols
@@ -1095,6 +1095,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 5898fdd..619d5a5 100644
--- a/gio/gsettings.c
+++ b/gio/gsettings.c
@@ -295,124 +295,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)
{
- GSettings *settings = G_SETTINGS (target);
gboolean ignore_this;
- gint i;
+ guint signal_id;
- /* We used to assert here:
- *
- * settings->priv->backend == backend
- *
- * but it could be the case that a notification is queued for delivery
- * while someone calls g_settings_delay() (which changes the backend).
- *
- * 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.
- */
+ switch (type)
+ {
+ case G_SETTINGS_EVENT_CHANGE:
+ signal_id = g_settings_signals[SIGNAL_CHANGE_EVENT];
+ break;
- for (i = 0; key[i] == settings->priv->path[i]; i++);
+ case G_SETTINGS_EVENT_WRITABLE_CHANGE:
+ signal_id = g_settings_signals[SIGNAL_WRITABLE_CHANGE_EVENT];
+ break;
- if (settings->priv->path[i] == '\0' &&
- g_settings_schema_has_key (settings->priv->schema, key + i))
+ 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])
{
- GQuark quark;
+ 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);
- quark = g_quark_from_string (key + i);
- g_signal_emit (settings, g_settings_signals[SIGNAL_CHANGE_EVENT],
- 0, &quark, 1, &ignore_this);
+ return;
}
+
+ g_signal_emit (settings, signal_id, 0, quarks, n_items, &ignore_this);
}
static void
-settings_backend_path_changed (GObject *target,
- GSettingsBackend *backend,
- const gchar *path,
- gpointer origin_tag)
+g_settings_got_event (GObject *target,
+ const GSettingsEvent *event)
{
GSettings *settings = G_SETTINGS (target);
- gboolean ignore_this;
+ const gchar *prefix;
+ const gchar *path;
+ gint prefix_len;
+ gint path_len;
- if (g_str_has_prefix (settings->priv->path, path))
- g_signal_emit (settings, g_settings_signals[SIGNAL_CHANGE_EVENT],
- 0, NULL, 0, &ignore_this);
-}
+ /* The path of the GSettings always ends with '/'.
+ *
+ * For path '/a/b/', consider these prefixes:
+ *
+ * - /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
+ *
+ * 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;
-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;
+ while (*prefix && *prefix == *path)
+ {
+ prefix++;
+ path++;
+ }
+ prefix_len = strlen (prefix);
+ path_len = strlen (path);
- for (i = 0; settings->priv->path[i] &&
- settings->priv->path[i] == path[i]; i++);
+ /* 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 (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++);
+ 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.
+ */
- 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);
+ /* 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);
- /* "256 quarks ought to be enough for anybody!"
- * If this bites you, I'm sorry. Please file a bug.
- */
- g_assert (l < 256);
- }
+ else
+ {
+ GQuark *quarks;
+ gint n, i, j;
- if (l > 0)
- g_signal_emit (settings, g_settings_signals[SIGNAL_CHANGE_EVENT],
- 0, quarks, l, &ignore_this);
- }
-}
+ n = g_strv_length (event->keys);
-static void
-settings_backend_writable_changed (GObject *target,
- GSettingsBackend *backend,
- const gchar *key)
-{
- GSettings *settings = G_SETTINGS (target);
- gboolean ignore_this;
- gint i;
+ if (20 < n)
+ quarks = g_new (GQuark, n);
+ else
+ quarks = g_newa (GQuark, n);
- for (i = 0; key[i] == settings->priv->path[i]; i++);
+ j = 0;
+ for (i = 0; event->keys[i]; i++)
+ {
+ gchar *key = event->keys[i];
- 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);
-}
+ /* Check the prefix */
+ if (!g_str_has_prefix (key, path))
+ continue;
-static void
-settings_backend_path_writable_changed (GObject *target,
- GSettingsBackend *backend,
- const gchar *path)
-{
- GSettings *settings = G_SETTINGS (target);
- gboolean ignore_this;
+ /* 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 (g_str_has_prefix (settings->priv->path, path))
- g_signal_emit (settings, g_settings_signals[SIGNAL_WRITABLE_CHANGE_EVENT],
- 0, (GQuark) 0, &ignore_this);
+ if (20 < n)
+ g_free (quarks);
+ }
+ }
}
/* Properties, Construction, Destruction {{{1 */
@@ -525,14 +576,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)
{
@@ -558,7 +601,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);
@@ -1884,7 +1928,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 6075d7f..62235d4 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 e674187..f75136f 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_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_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);
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 e009b31..288b3b4 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);
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]