2 * Copyright © 2009, 2010 Codethink Limited
3 * Copyright © 2010 Red Hat, Inc.
5 * This library is free software; you can redistribute it and/or
6 * modify it under the terms of the GNU Lesser General Public
7 * License as published by the Free Software Foundation; either
8 * version 2 of the licence, or (at your option) any later version.
10 * This library is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 * Lesser General Public License for more details.
15 * You should have received a copy of the GNU Lesser General Public
16 * License along with this library; if not, write to the
17 * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
18 * Boston, MA 02111-1307, USA.
20 * Authors: Ryan Lortie <desrt@desrt.ca>
21 * Matthias Clasen <mclasen@redhat.com>
26 #include "gsettingsbackendinternal.h"
27 #include "gnullsettingsbackend.h"
28 #include "gsimplepermission.h"
29 #include "giomodule-priv.h"
30 #include "gio-marshal.h"
39 G_DEFINE_ABSTRACT_TYPE (GSettingsBackend, g_settings_backend, G_TYPE_OBJECT)
41 typedef struct _GSettingsBackendClosure GSettingsBackendClosure;
42 typedef struct _GSettingsBackendWatch GSettingsBackendWatch;
44 struct _GSettingsBackendPrivate
46 GSettingsBackendWatch *watches;
58 * SECTION:gsettingsbackend
59 * @title: GSettingsBackend
60 * @short_description: an interface for settings backend implementations
61 * @include: gio/gsettingsbackend.h
62 * @see_also: #GSettings, #GIOExtensionPoint
64 * The #GSettingsBackend interface defines a generic interface for
65 * non-strictly-typed data that is stored in a hierarchy. To implement
66 * an alternative storage backend for #GSettings, you need to implement
67 * the #GSettingsBackend interface and then make it implement the
68 * extension point #G_SETTINGS_BACKEND_EXTENSION_POINT_NAME.
70 * The interface defines methods for reading and writing values, a
71 * method for determining if writing of certain values will fail
72 * (lockdown) and a change notification mechanism.
74 * The semantics of the interface are very precisely defined and
75 * implementations must carefully adhere to the expectations of
76 * callers that are documented on each of the interface methods.
78 * Some of the GSettingsBackend functions accept or return a #GTree.
79 * These trees always have strings as keys and #GVariant as values.
80 * g_settings_backend_create_tree() is a convenience function to create
84 * The #GSettingsBackend API is exported to allow third-party
85 * implementations, but does not carry the same stability guarantees
86 * as the public GIO API. For this reason, you have to define the
87 * C preprocessor symbol #G_SETTINGS_ENABLE_BACKEND before including
88 * <filename>gio/gsettingsbackend.h</filename>
93 is_key (const gchar *key)
98 g_return_val_if_fail (key != NULL, FALSE);
99 g_return_val_if_fail (key[0] == '/', FALSE);
101 for (i = 1; key[i]; i++)
102 g_return_val_if_fail (key[i] != '/' || key[i + 1] != '/', FALSE);
106 g_return_val_if_fail (key[length - 1] != '/', FALSE);
112 is_path (const gchar *path)
117 g_return_val_if_fail (path != NULL, FALSE);
118 g_return_val_if_fail (path[0] == '/', FALSE);
120 for (i = 1; path[i]; i++)
121 g_return_val_if_fail (path[i] != '/' || path[i + 1] != '/', FALSE);
125 g_return_val_if_fail (path[length - 1] == '/', FALSE);
131 g_settings_backend_get_active_context (void)
133 GMainContext *context;
136 if ((source = g_main_current_source ()))
137 context = g_source_get_context (source);
141 context = g_main_context_get_thread_default ();
144 context = g_main_context_default ();
150 struct _GSettingsBackendWatch
153 GMainContext *context;
154 GSettingsBackendChangedFunc changed;
155 GSettingsBackendPathChangedFunc path_changed;
156 GSettingsBackendKeysChangedFunc keys_changed;
157 GSettingsBackendWritableChangedFunc writable_changed;
158 GSettingsBackendPathWritableChangedFunc path_writable_changed;
160 GSettingsBackendWatch *next;
163 struct _GSettingsBackendClosure
165 void (*function) (GSettingsBackend *backend,
171 GSettingsBackend *backend;
175 GBoxedFreeFunc data1_free;
180 g_settings_backend_watch_weak_notify (gpointer data,
181 GObject *where_the_object_was)
183 GSettingsBackend *backend = data;
184 GSettingsBackendWatch **ptr;
186 /* search and remove */
187 g_static_mutex_lock (&backend->priv->lock);
188 for (ptr = &backend->priv->watches; *ptr; ptr = &(*ptr)->next)
189 if ((*ptr)->target == where_the_object_was)
191 GSettingsBackendWatch *tmp = *ptr;
194 g_slice_free (GSettingsBackendWatch, tmp);
196 g_static_mutex_unlock (&backend->priv->lock);
200 /* we didn't find it. that shouldn't happen. */
201 g_assert_not_reached ();
205 * g_settings_backend_watch:
206 * @backend: a #GSettingsBackend
207 * @target: the GObject (typically GSettings instance) to call back to
208 * @context: a #GMainContext, or %NULL
211 * Registers a new watch on a #GSettingsBackend.
213 * note: %NULL @context does not mean "default main context" but rather,
214 * "it is okay to dispatch in any context". If the default main context
215 * is specifically desired then it must be given.
217 * note also: if you want to get meaningful values for the @origin_tag
218 * that appears as an argument to some of the callbacks, you *must* have
219 * @context as %NULL. Otherwise, you are subject to cross-thread
220 * dispatching and whatever owned @origin_tag at the time that the event
221 * occured may no longer own it. This is a problem if you consider that
222 * you may now be the new owner of that address and mistakenly think
223 * that the event in question originated from yourself.
225 * tl;dr: If you give a non-%NULL @context then you must ignore the
226 * value of @origin_tag given to any callbacks.
229 g_settings_backend_watch (GSettingsBackend *backend,
231 GMainContext *context,
232 GSettingsBackendChangedFunc changed,
233 GSettingsBackendPathChangedFunc path_changed,
234 GSettingsBackendKeysChangedFunc keys_changed,
235 GSettingsBackendWritableChangedFunc writable_changed,
236 GSettingsBackendPathWritableChangedFunc path_writable_changed)
238 GSettingsBackendWatch *watch;
240 /* For purposes of discussion, we assume that our target is a
241 * GSettings instance.
243 * Our strategy to defend against the final reference dropping on the
244 * GSettings object in a thread other than the one that is doing the
245 * dispatching is as follows:
247 * 1) hold a GObject reference on the GSettings during an outstanding
248 * dispatch. This ensures that the delivery is always possible.
250 * 2) hold a weak reference on the GSettings at other times. This
251 * allows us to receive early notification of pending destruction
252 * of the object. At this point, it is still safe to obtain a
253 * reference on the GObject to keep it alive, so #1 will work up
254 * to that point. After that point, we'll have been able to drop
255 * the watch from the list.
257 * Note, in particular, that it's not possible to simply have an
258 * "unwatch" function that gets called from the finalize function of
259 * the GSettings instance because, by that point it is no longer
260 * possible to keep the object alive using g_object_ref() and we would
261 * have no way of knowing this.
263 * Note also that we do not need to hold a reference on the main
264 * context here since the GSettings instance does that for us and we
265 * will receive the weak notify long before it is dropped. We don't
266 * even need to hold it during dispatches because our reference on the
267 * GSettings will prevent the finalize from running and dropping the
268 * ref on the context.
270 * All access to the list holds a mutex. We have some strategies to
271 * avoid some of the pain that would be associated with that.
274 watch = g_slice_new (GSettingsBackendWatch);
275 watch->context = context;
276 watch->target = target;
277 g_object_weak_ref (target, g_settings_backend_watch_weak_notify, backend);
279 watch->changed = changed;
280 watch->path_changed = path_changed;
281 watch->keys_changed = keys_changed;
282 watch->writable_changed = writable_changed;
283 watch->path_writable_changed = path_writable_changed;
285 /* linked list prepend */
286 g_static_mutex_lock (&backend->priv->lock);
287 watch->next = backend->priv->watches;
288 backend->priv->watches = watch;
289 g_static_mutex_unlock (&backend->priv->lock);
293 g_settings_backend_unwatch (GSettingsBackend *backend,
296 /* Our caller surely owns a reference on 'target', so the order of
297 * these two calls is unimportant.
299 g_object_weak_unref (target, g_settings_backend_watch_weak_notify, backend);
300 g_settings_backend_watch_weak_notify (backend, target);
304 g_settings_backend_invoke_closure (gpointer user_data)
306 GSettingsBackendClosure *closure = user_data;
308 closure->function (closure->backend, closure->target, closure->name,
309 closure->data1, closure->data2);
311 closure->data1_free (closure->data1);
312 g_object_unref (closure->backend);
313 g_object_unref (closure->target);
314 g_free (closure->name);
316 g_slice_free (GSettingsBackendClosure, closure);
322 pointer_id (gpointer a)
328 pointer_ignore (gpointer a)
333 g_settings_backend_dispatch_signal (GSettingsBackend *backend,
334 gsize function_offset,
337 GBoxedCopyFunc data1_copy,
338 GBoxedFreeFunc data1_free,
341 GMainContext *context, *here_and_now;
342 GSettingsBackendWatch *watch;
344 /* We need to hold the mutex here (to prevent a node from being
345 * deleted as we are traversing the list). Since we should not
346 * re-enter user code while holding this mutex, we create a
347 * one-time-use GMainContext and populate it with the events that we
348 * would have called directly. We dispatch these events after
349 * releasing the lock. Note that the GObject reference is acquired on
350 * the target while holding the mutex and the mutex needs to be held
351 * as part of the destruction of any GSettings instance (via the weak
352 * reference handling). This is the key to the safety of the whole
356 if (data1_copy == NULL)
357 data1_copy = pointer_id;
359 if (data1_free == NULL)
360 data1_free = pointer_ignore;
362 context = g_settings_backend_get_active_context ();
363 here_and_now = g_main_context_new ();
365 /* traverse the (immutable while holding lock) list */
366 g_static_mutex_lock (&backend->priv->lock);
367 for (watch = backend->priv->watches; watch; watch = watch->next)
369 GSettingsBackendClosure *closure;
372 closure = g_slice_new (GSettingsBackendClosure);
373 closure->backend = g_object_ref (backend);
374 closure->target = g_object_ref (watch->target);
375 closure->function = G_STRUCT_MEMBER (void *, watch, function_offset);
376 closure->name = g_strdup (name);
377 closure->data1 = data1_copy (data1);
378 closure->data1_free = data1_free;
379 closure->data2 = data2;
381 source = g_idle_source_new ();
382 g_source_set_priority (source, G_PRIORITY_DEFAULT);
383 g_source_set_callback (source,
384 g_settings_backend_invoke_closure,
387 if (watch->context && watch->context != context)
388 g_source_attach (source, watch->context);
390 g_source_attach (source, here_and_now);
392 g_source_unref (source);
394 g_static_mutex_unlock (&backend->priv->lock);
396 while (g_main_context_iteration (here_and_now, FALSE));
397 g_main_context_unref (here_and_now);
401 * g_settings_backend_changed:
402 * @backend: a #GSettingsBackend implementation
403 * @key: the name of the key
404 * @origin_tag: the origin tag
406 * Signals that a single key has possibly changed. Backend
407 * implementations should call this if a key has possibly changed its
410 * @key must be a valid key (ie: starting with a slash, not containing
411 * '//', and not ending with a slash).
413 * The implementation must call this function during any call to
414 * g_settings_backend_write(), before the call returns (except in the
415 * case that no keys are actually changed and it cares to detect this
416 * fact). It may not rely on the existence of a mainloop for
417 * dispatching the signal later.
419 * The implementation may call this function at any other time it likes
420 * in response to other events (such as changes occuring outside of the
421 * program). These calls may originate from a mainloop or may originate
422 * in response to any other action (including from calls to
423 * g_settings_backend_write()).
425 * In the case that this call is in response to a call to
426 * g_settings_backend_write() then @origin_tag must be set to the same
427 * value that was passed to that call.
432 g_settings_backend_changed (GSettingsBackend *backend,
436 g_return_if_fail (G_IS_SETTINGS_BACKEND (backend));
437 g_return_if_fail (is_key (key));
439 g_settings_backend_dispatch_signal (backend,
440 G_STRUCT_OFFSET (GSettingsBackendWatch,
442 key, origin_tag, NULL, NULL, NULL);
446 * g_settings_backend_keys_changed:
447 * @backend: a #GSettingsBackend implementation
448 * @path: the path containing the changes
449 * @items: the %NULL-terminated list of changed keys
450 * @origin_tag: the origin tag
452 * Signals that a list of keys have possibly changed. Backend
453 * implementations should call this if keys have possibly changed their
456 * @path must be a valid path (ie: starting and ending with a slash and
457 * not containing '//'). Each string in @items must form a valid key
458 * name when @path is prefixed to it (ie: each item must not start or
459 * end with '/' and must not contain '//').
461 * The meaning of this signal is that any of the key names resulting
462 * from the contatenation of @path with each item in @items may have
465 * The same rules for when notifications must occur apply as per
466 * g_settings_backend_changed(). These two calls can be used
467 * interchangeably if exactly one item has changed (although in that
468 * case g_settings_backend_changed() is definitely preferred).
470 * For efficiency reasons, the implementation should strive for @path to
471 * be as long as possible (ie: the longest common prefix of all of the
472 * keys that were changed) but this is not strictly required.
477 g_settings_backend_keys_changed (GSettingsBackend *backend,
479 gchar const * const *items,
482 g_return_if_fail (G_IS_SETTINGS_BACKEND (backend));
483 g_return_if_fail (is_path (path));
485 /* XXX: should do stricter checking (ie: inspect each item) */
486 g_return_if_fail (items != NULL);
488 g_settings_backend_dispatch_signal (backend,
489 G_STRUCT_OFFSET (GSettingsBackendWatch,
491 path, (gpointer) items,
492 (GBoxedCopyFunc) g_strdupv,
493 (GBoxedFreeFunc) g_strfreev,
498 * g_settings_backend_path_changed:
499 * @backend: a #GSettingsBackend implementation
500 * @path: the path containing the changes
501 * @origin_tag: the origin tag
503 * Signals that all keys below a given path may have possibly changed.
504 * Backend implementations should call this if an entire path of keys
505 * have possibly changed their values.
507 * @path must be a valid path (ie: starting and ending with a slash and
508 * not containing '//').
510 * The meaning of this signal is that any of the key which has a name
511 * starting with @path may have changed.
513 * The same rules for when notifications must occur apply as per
514 * g_settings_backend_changed(). This call might be an appropriate
515 * reasponse to a 'reset' call but implementations are also free to
516 * explicitly list the keys that were affected by that call if they can
519 * For efficiency reasons, the implementation should strive for @path to
520 * be as long as possible (ie: the longest common prefix of all of the
521 * keys that were changed) but this is not strictly required. As an
522 * example, if this function is called with the path of "/" then every
523 * single key in the application will be notified of a possible change.
528 g_settings_backend_path_changed (GSettingsBackend *backend,
532 g_return_if_fail (G_IS_SETTINGS_BACKEND (backend));
533 g_return_if_fail (is_path (path));
535 g_settings_backend_dispatch_signal (backend,
536 G_STRUCT_OFFSET (GSettingsBackendWatch,
538 path, origin_tag, NULL, NULL, NULL);
542 * g_settings_backend_writable_changed:
543 * @backend: a #GSettingsBackend implementation
544 * @key: the name of the key
546 * Signals that the writability of a single key has possibly changed.
548 * Since GSettings performs no locking operations for itself, this call
549 * will always be made in response to external events.
554 g_settings_backend_writable_changed (GSettingsBackend *backend,
557 g_return_if_fail (G_IS_SETTINGS_BACKEND (backend));
558 g_return_if_fail (is_key (key));
560 g_settings_backend_dispatch_signal (backend,
561 G_STRUCT_OFFSET (GSettingsBackendWatch,
563 key, NULL, NULL, NULL, NULL);
567 * g_settings_backend_path_writable_changed:
568 * @backend: a #GSettingsBackend implementation
569 * @path: the name of the path
571 * Signals that the writability of all keys below a given path may have
574 * Since GSettings performs no locking operations for itself, this call
575 * will always be made in response to external events.
580 g_settings_backend_path_writable_changed (GSettingsBackend *backend,
583 g_return_if_fail (G_IS_SETTINGS_BACKEND (backend));
584 g_return_if_fail (is_path (path));
586 g_settings_backend_dispatch_signal (backend,
587 G_STRUCT_OFFSET (GSettingsBackendWatch,
588 path_writable_changed),
589 path, NULL, NULL, NULL, NULL);
601 g_settings_backend_flatten_one (gpointer key,
605 FlattenState *state = user_data;
606 const gchar *skey = key;
609 g_return_val_if_fail (is_key (key), TRUE);
611 /* calculate longest common prefix */
612 if (state->prefix == NULL)
616 /* first key? just take the prefix up to the last '/' */
617 state->prefix = g_strdup (skey);
618 last_byte = strrchr (state->prefix, '/') + 1;
619 state->prefix_len = last_byte - state->prefix;
624 /* find the first character that does not match. we will
625 * definitely find one because the prefix ends in '/' and the key
626 * does not. also: no two keys in the tree are the same.
628 for (i = 0; state->prefix[i] == skey[i]; i++);
630 /* check if we need to shorten the prefix */
631 if (state->prefix[i] != '\0')
633 /* find the nearest '/', terminate after it */
634 while (state->prefix[i - 1] != '/')
637 state->prefix[i] = '\0';
638 state->prefix_len = i;
643 /* save the entire item into the array.
644 * the prefixes will be removed later.
646 *state->keys++ = key;
649 *state->values++ = value;
655 * g_settings_backend_flatten_tree:
656 * @tree: a #GTree containing the changes
657 * @path: the location to save the path
658 * @keys: the location to save the relative keys
659 * @values: the location to save the values, or %NULL
661 * Calculate the longest common prefix of all keys in a tree and write
662 * out an array of the key names relative to that prefix and,
663 * optionally, the value to store at each of those keys.
665 * You must free the value returned in @path, @keys and @values using
666 * g_free(). You should not attempt to free or unref the contents of
672 g_settings_backend_flatten_tree (GTree *tree,
677 FlattenState state = { 0, };
680 nnodes = g_tree_nnodes (tree);
682 *keys = state.keys = g_new (const gchar *, nnodes + 1);
683 state.keys[nnodes] = NULL;
687 *values = state.values = g_new (GVariant *, nnodes + 1);
688 state.values[nnodes] = NULL;
691 g_tree_foreach (tree, g_settings_backend_flatten_one, &state);
692 g_return_if_fail (*keys + nnodes == state.keys);
694 *path = state.prefix;
696 *--state.keys += state.prefix_len;
700 * g_settings_backend_changed_tree:
701 * @backend: a #GSettingsBackend implementation
702 * @tree: a #GTree containing the changes
703 * @origin_tag: the origin tag
705 * This call is a convenience wrapper. It gets the list of changes from
706 * @tree, computes the longest common prefix and calls
707 * g_settings_backend_changed().
712 g_settings_backend_changed_tree (GSettingsBackend *backend,
716 GSettingsBackendWatch *watch;
720 g_return_if_fail (G_IS_SETTINGS_BACKEND (backend));
722 g_settings_backend_flatten_tree (tree, &path, &keys, NULL);
724 for (watch = backend->priv->watches; watch; watch = watch->next)
725 watch->keys_changed (backend, watch->target, path, keys, origin_tag);
732 * g_settings_backend_read:
733 * @backend: a #GSettingsBackend implementation
734 * @key: the key to read
735 * @expected_type: a #GVariantType
736 * @default_value: if the default value should be returned
737 * @returns: the value that was read, or %NULL
739 * Reads a key. This call will never block.
741 * If the key exists, the value associated with it will be returned.
742 * If the key does not exist, %NULL will be returned.
744 * The returned value will be of the type given in @expected_type. If
745 * the backend stored a value of a different type then %NULL will be
748 * If @default_value is %TRUE then this gets the default value from the
749 * backend (ie: the one that the backend would contain if
750 * g_settings_reset() were called).
753 g_settings_backend_read (GSettingsBackend *backend,
755 const GVariantType *expected_type,
756 gboolean default_value)
760 value = G_SETTINGS_BACKEND_GET_CLASS (backend)
761 ->read (backend, key, expected_type, default_value);
763 if G_UNLIKELY (value && !g_variant_is_of_type (value, expected_type))
765 g_variant_unref (value);
773 * g_settings_backend_write:
774 * @backend: a #GSettingsBackend implementation
775 * @key: the name of the key
776 * @value: a #GVariant value to write to this key
777 * @origin_tag: the origin tag
778 * @returns: %TRUE if the write succeeded, %FALSE if the key was not writable
780 * Writes exactly one key.
782 * This call does not fail. During this call a
783 * #GSettingsBackend::changed signal will be emitted if the value of the
784 * key has changed. The updated key value will be visible to any signal
787 * One possible method that an implementation might deal with failures is
788 * to emit a second "changed" signal (either during this call, or later)
789 * to indicate that the affected keys have suddenly "changed back" to their
793 g_settings_backend_write (GSettingsBackend *backend,
798 return G_SETTINGS_BACKEND_GET_CLASS (backend)
799 ->write (backend, key, value, origin_tag);
803 * g_settings_backend_write_keys:
804 * @backend: a #GSettingsBackend implementation
805 * @values: a #GTree containing key-value pairs to write
806 * @origin_tag: the origin tag
808 * Writes one or more keys. This call will never block.
810 * The key of each item in the tree is the key name to write to and the
811 * value is a #GVariant to write. The proper type of #GTree for this
812 * call can be created with g_settings_backend_create_tree(). This call
813 * might take a reference to the tree; you must not modified the #GTree
814 * after passing it to this call.
816 * This call does not fail. During this call a #GSettingsBackend::changed
817 * signal will be emitted if any keys have been changed. The new values of
818 * all updated keys will be visible to any signal callbacks.
820 * One possible method that an implementation might deal with failures is
821 * to emit a second "changed" signal (either during this call, or later)
822 * to indicate that the affected keys have suddenly "changed back" to their
826 g_settings_backend_write_keys (GSettingsBackend *backend,
830 return G_SETTINGS_BACKEND_GET_CLASS (backend)
831 ->write_keys (backend, tree, origin_tag);
835 * g_settings_backend_reset:
836 * @backend: a #GSettingsBackend implementation
837 * @key: the name of a key
838 * @origin_tag: the origin tag
840 * "Resets" the named key to its "default" value (ie: after system-wide
841 * defaults, mandatory keys, etc. have been taken into account) or possibly
845 g_settings_backend_reset (GSettingsBackend *backend,
849 G_SETTINGS_BACKEND_GET_CLASS (backend)
850 ->reset (backend, key, origin_tag);
854 * g_settings_backend_reset_path:
855 * @backend: a #GSettingsBackend implementation
856 * @name: the name of a key or path
857 * @origin_tag: the origin tag
859 * "Resets" the named path. This means that every key under the path is
863 g_settings_backend_reset_path (GSettingsBackend *backend,
867 G_SETTINGS_BACKEND_GET_CLASS (backend)
868 ->reset_path (backend, path, origin_tag);
872 * g_settings_backend_get_writable:
873 * @backend: a #GSettingsBackend implementation
874 * @key: the name of a key
875 * @returns: %TRUE if the key is writable
877 * Finds out if a key is available for writing to. This is the
878 * interface through which 'lockdown' is implemented. Locked down
879 * keys will have %FALSE returned by this call.
881 * You should not write to locked-down keys, but if you do, the
882 * implementation will deal with it.
885 g_settings_backend_get_writable (GSettingsBackend *backend,
888 return G_SETTINGS_BACKEND_GET_CLASS (backend)
889 ->get_writable (backend, key);
893 * g_settings_backend_unsubscribe:
894 * @backend: a #GSettingsBackend
895 * @name: a key or path to subscribe to
897 * Reverses the effect of a previous call to
898 * g_settings_backend_subscribe().
901 g_settings_backend_unsubscribe (GSettingsBackend *backend,
904 G_SETTINGS_BACKEND_GET_CLASS (backend)
905 ->unsubscribe (backend, name);
909 * g_settings_backend_subscribe:
910 * @backend: a #GSettingsBackend
911 * @name: a key or path to subscribe to
913 * Requests that change signals be emitted for events on @name.
916 g_settings_backend_subscribe (GSettingsBackend *backend,
919 G_SETTINGS_BACKEND_GET_CLASS (backend)
920 ->subscribe (backend, name);
924 g_settings_backend_set_property (GObject *object,
929 GSettingsBackend *backend = G_SETTINGS_BACKEND (object);
934 backend->priv->context = g_value_dup_string (value);
938 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
944 g_settings_backend_get_property (GObject *object,
949 GSettingsBackend *backend = G_SETTINGS_BACKEND (object);
954 g_value_set_string (value, backend->priv->context);
958 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
964 g_settings_backend_finalize (GObject *object)
966 GSettingsBackend *backend = G_SETTINGS_BACKEND (object);
968 g_static_mutex_unlock (&backend->priv->lock);
969 g_free (backend->priv->context);
971 G_OBJECT_CLASS (g_settings_backend_parent_class)
976 ignore_subscription (GSettingsBackend *backend,
982 g_settings_backend_init (GSettingsBackend *backend)
984 backend->priv = G_TYPE_INSTANCE_GET_PRIVATE (backend,
985 G_TYPE_SETTINGS_BACKEND,
986 GSettingsBackendPrivate);
987 g_static_mutex_init (&backend->priv->lock);
991 g_settings_backend_class_init (GSettingsBackendClass *class)
993 GObjectClass *gobject_class = G_OBJECT_CLASS (class);
995 class->subscribe = ignore_subscription;
996 class->unsubscribe = ignore_subscription;
998 gobject_class->get_property = g_settings_backend_get_property;
999 gobject_class->set_property = g_settings_backend_set_property;
1000 gobject_class->finalize = g_settings_backend_finalize;
1002 g_type_class_add_private (class, sizeof (GSettingsBackendPrivate));
1005 * GSettingsBackend:context:
1007 * The "context" property gives a hint to the backend as to
1008 * what storage to use. It is up to the implementation to make
1009 * use of this information.
1011 * E.g. DConf supports "user", "system", "defaults" and "login"
1014 * If your backend supports different contexts, you should also
1015 * provide an implementation of the supports_context() class
1016 * function in #GSettingsBackendClass.
1018 g_object_class_install_property (gobject_class, PROP_CONTEXT,
1019 g_param_spec_string ("context", P_("Context"),
1020 P_("An identifier to decide which storage to use"),
1021 "", G_PARAM_READWRITE |
1022 G_PARAM_CONSTRUCT_ONLY | G_PARAM_STATIC_STRINGS));
1027 * g_settings_backend_create_tree:
1028 * @returns: a new #GTree
1030 * This is a convenience function for creating a tree that is compatible
1031 * with g_settings_backend_write(). It merely calls g_tree_new_full()
1032 * with strcmp(), g_free() and g_variant_unref().
1035 g_settings_backend_create_tree (void)
1037 return g_tree_new_full ((GCompareDataFunc) strcmp, NULL,
1038 g_free, (GDestroyNotify) g_variant_unref);
1043 get_default_backend (const gchar *context)
1045 GIOExtension *extension = NULL;
1046 GIOExtensionPoint *point;
1051 _g_io_modules_ensure_loaded ();
1053 point = g_io_extension_point_lookup (G_SETTINGS_BACKEND_EXTENSION_POINT_NAME);
1055 if ((env = getenv ("GSETTINGS_BACKEND")))
1057 extension = g_io_extension_point_get_extension_by_name (point, env);
1059 if (extension == NULL)
1060 g_warning ("Can't find GSettings backend '%s' given in "
1061 "GSETTINGS_BACKEND environment variable", env);
1064 if (extension == NULL)
1066 extensions = g_io_extension_point_get_extensions (point);
1068 if (extensions == NULL)
1069 g_error ("No GSettingsBackend implementations exist.");
1071 extension = extensions->data;
1074 if (context[0] != '\0') /* (context != "") */
1076 GSettingsBackendClass *backend_class;
1079 class = g_io_extension_ref_class (extension);
1080 backend_class = G_SETTINGS_BACKEND_CLASS (class);
1082 if (backend_class->supports_context == NULL ||
1083 !backend_class->supports_context (context))
1085 g_type_class_unref (class);
1089 g_type_class_unref (class);
1092 type = g_io_extension_get_type (extension);
1094 return g_object_new (type, "context", context, NULL);
1097 static GHashTable *g_settings_backends;
1100 * g_settings_backend_get_with_context:
1101 * @context: a context that might be used by the backend to determine
1102 * which storage to use, or %NULL to use the default storage
1103 * @returns: the default #GSettingsBackend
1105 * Returns the default #GSettingsBackend. It is possible to override
1106 * the default by setting the <envar>GSETTINGS_BACKEND</envar>
1107 * environment variable to the name of a settings backend.
1109 * The @context parameter can be used to indicate that a different
1110 * than the default storage is desired. E.g. the DConf backend lets
1111 * you use "user", "system", "defaults" and "login" as contexts.
1113 * If @context is not supported by the implementation, this function
1114 * returns an instance of the #GSettingsMemoryBackend.
1115 * See g_settings_backend_supports_context(),
1117 * The user does not own the return value and it must not be freed.
1120 g_settings_backend_get_with_context (const gchar *context)
1122 GSettingsBackend *backend;
1124 g_return_val_if_fail (context != NULL, NULL);
1126 _g_io_modules_ensure_extension_points_registered ();
1128 if (g_settings_backends == NULL)
1129 g_settings_backends = g_hash_table_new (g_str_hash, g_str_equal);
1131 backend = g_hash_table_lookup (g_settings_backends, context);
1135 backend = get_default_backend (context);
1138 backend = g_null_settings_backend_new ();
1140 g_hash_table_insert (g_settings_backends, g_strdup (context), backend);
1143 return g_object_ref (backend);
1147 * g_settings_backend_supports_context:
1148 * @context: a context string that might be passed to
1149 * g_settings_backend_new_with_context()
1150 * @returns: #TRUE if @context is supported
1152 * Determines if the given context is supported by the default
1153 * GSettingsBackend implementation.
1156 g_settings_backend_supports_context (const gchar *context)
1158 GSettingsBackend *backend;
1160 g_return_val_if_fail (context != NULL, FALSE);
1162 backend = get_default_backend (context);
1166 g_object_unref (backend);
1174 * g_settings_backend_get_permission:
1175 * @backend: a #GSettingsBackend
1177 * @returns: a non-%NULL #GPermission
1179 * Gets the permission object associated with writing to keys below
1180 * @path on @backend.
1182 * If this is not implemented in the backend, then a %TRUE
1183 * #GSimplePermission is returned.
1186 g_settings_backend_get_permission (GSettingsBackend *backend,
1189 GSettingsBackendClass *class = G_SETTINGS_BACKEND_GET_CLASS (backend);
1191 if (class->get_permission)
1192 return class->get_permission (backend, path);
1194 return g_simple_permission_new (TRUE);
1198 * g_settings_backend_setup:
1199 * @context: a context string (not %NULL or "")
1200 * @backend: a #GSettingsBackend
1202 * Sets up @backend for use with #GSettings.
1204 * If you create a #GSettings with its context property set to @context
1205 * then it will use the backend given to this function. See
1206 * g_settings_new_with_context().
1208 * The backend must be set up before any settings objects are created
1209 * for the named context.
1211 * It is not possible to specify a backend for the default context.
1213 * This function takes a reference on @backend and never releases it.
1218 g_settings_backend_setup (const gchar *context,
1219 GSettingsBackend *backend)
1221 g_return_if_fail (context[0] != '\0');
1222 g_return_if_fail (G_IS_SETTINGS_BACKEND (backend));
1224 if (g_settings_backends == NULL)
1225 g_settings_backends = g_hash_table_new (g_str_hash, g_str_equal);
1227 if (g_hash_table_lookup (g_settings_backends, context))
1228 g_error ("A GSettingsBackend already exists for context '%s'", context);
1230 g_hash_table_insert (g_settings_backends,
1232 g_object_ref (backend));
1236 * g_settings_backend_sync:
1237 * @backend: a #GSettingsBackend
1239 * Syncs the backend.
1242 g_settings_backend_sync (GSettingsBackend *backend)
1244 GSettingsBackendClass *class = G_SETTINGS_BACKEND_GET_CLASS (backend);
1247 class->sync (backend);
1250 #define __G_SETTINGS_BACKEND_C__
1251 #include "gioaliasdef.c"