1/*
2 * Copyright © 2009, 2010 Codethink Limited
3 * Copyright © 2010 Red Hat, Inc.
4 *
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.1 of the License, or (at your option) any later version.
9 *
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.
14 *
15 * You should have received a copy of the GNU Lesser General Public
16 * License along with this library; if not, see <http://www.gnu.org/licenses/>.
17 *
18 * Authors: Ryan Lortie <desrt@desrt.ca>
19 * Matthias Clasen <mclasen@redhat.com>
20 */
21
22#include "config.h"
23
24#include "gsettingsbackendinternal.h"
25#include "gsimplepermission.h"
26#include "giomodule-priv.h"
27
28#include <string.h>
29#include <stdlib.h>
30#include <glib.h>
31#include <glibintl.h>
32
33
34typedef struct _GSettingsBackendClosure GSettingsBackendClosure;
35typedef struct _GSettingsBackendWatch GSettingsBackendWatch;
36
37struct _GSettingsBackendPrivate
38{
39 GSettingsBackendWatch *watches;
40 GMutex lock;
41};
42
43G_DEFINE_ABSTRACT_TYPE_WITH_PRIVATE (GSettingsBackend, g_settings_backend, G_TYPE_OBJECT)
44
45/* For g_settings_backend_sync_default(), we only want to actually do
46 * the sync if the backend already exists. This avoids us creating an
47 * entire GSettingsBackend in order to call a do-nothing sync()
48 * operation on it. This variable lets us avoid that.
49 */
50static gboolean g_settings_has_backend;
51
52/**
53 * SECTION:gsettingsbackend
54 * @title: GSettingsBackend
55 * @short_description: Interface for settings backend implementations
56 * @include: gio/gsettingsbackend.h
57 * @see_also: #GSettings, #GIOExtensionPoint
58 *
59 * The #GSettingsBackend interface defines a generic interface for
60 * non-strictly-typed data that is stored in a hierarchy. To implement
61 * an alternative storage backend for #GSettings, you need to implement
62 * the #GSettingsBackend interface and then make it implement the
63 * extension point #G_SETTINGS_BACKEND_EXTENSION_POINT_NAME.
64 *
65 * The interface defines methods for reading and writing values, a
66 * method for determining if writing of certain values will fail
67 * (lockdown) and a change notification mechanism.
68 *
69 * The semantics of the interface are very precisely defined and
70 * implementations must carefully adhere to the expectations of
71 * callers that are documented on each of the interface methods.
72 *
73 * Some of the #GSettingsBackend functions accept or return a #GTree.
74 * These trees always have strings as keys and #GVariant as values.
75 * g_settings_backend_create_tree() is a convenience function to create
76 * suitable trees.
77 *
78 * The #GSettingsBackend API is exported to allow third-party
79 * implementations, but does not carry the same stability guarantees
80 * as the public GIO API. For this reason, you have to define the
81 * C preprocessor symbol %G_SETTINGS_ENABLE_BACKEND before including
82 * `gio/gsettingsbackend.h`.
83 **/
84
85static gboolean
86is_key (const gchar *key)
87{
88 gint length;
89 gint i;
90
91 g_return_val_if_fail (key != NULL, FALSE);
92 g_return_val_if_fail (key[0] == '/', FALSE);
93
94 for (i = 1; key[i]; i++)
95 g_return_val_if_fail (key[i] != '/' || key[i + 1] != '/', FALSE);
96
97 length = i;
98
99 g_return_val_if_fail (key[length - 1] != '/', FALSE);
100
101 return TRUE;
102}
103
104static gboolean
105is_path (const gchar *path)
106{
107 gint length;
108 gint i;
109
110 g_return_val_if_fail (path != NULL, FALSE);
111 g_return_val_if_fail (path[0] == '/', FALSE);
112
113 for (i = 1; path[i]; i++)
114 g_return_val_if_fail (path[i] != '/' || path[i + 1] != '/', FALSE);
115
116 length = i;
117
118 g_return_val_if_fail (path[length - 1] == '/', FALSE);
119
120 return TRUE;
121}
122
123struct _GSettingsBackendWatch
124{
125 /* Always access the target via the weak reference */
126 GWeakRef target;
127 /* The pointer is only for comparison from the weak notify,
128 * at which point the target might already be close to
129 * destroyed. It's not safe to use it for anything anymore
130 * at that point */
131 GObject *target_ptr;
132 const GSettingsListenerVTable *vtable;
133 GMainContext *context;
134 GSettingsBackendWatch *next;
135};
136
137struct _GSettingsBackendClosure
138{
139 void (*function) (GObject *target,
140 GSettingsBackend *backend,
141 const gchar *name,
142 gpointer origin_tag,
143 gchar **names);
144
145 GMainContext *context;
146 GObject *target;
147 GSettingsBackend *backend;
148 gchar *name;
149 gpointer origin_tag;
150 gchar **names;
151};
152
153static void
154g_settings_backend_watch_weak_notify (gpointer data,
155 GObject *where_the_object_was)
156{
157 GSettingsBackend *backend = data;
158 GSettingsBackendWatch **ptr;
159
160 /* search and remove */
161 g_mutex_lock (mutex: &backend->priv->lock);
162 for (ptr = &backend->priv->watches; *ptr; ptr = &(*ptr)->next)
163 if ((*ptr)->target_ptr == where_the_object_was)
164 {
165 GSettingsBackendWatch *tmp = *ptr;
166
167 *ptr = tmp->next;
168 g_weak_ref_clear (weak_ref: &tmp->target);
169 g_slice_free (GSettingsBackendWatch, tmp);
170
171 g_mutex_unlock (mutex: &backend->priv->lock);
172 return;
173 }
174
175 /* we didn't find it. that shouldn't happen. */
176 g_assert_not_reached ();
177}
178
179/*< private >
180 * g_settings_backend_watch:
181 * @backend: a #GSettingsBackend
182 * @target: the GObject (typically GSettings instance) to call back to
183 * @context: (nullable): a #GMainContext, or %NULL
184 * ...: callbacks...
185 *
186 * Registers a new watch on a #GSettingsBackend.
187 *
188 * note: %NULL @context does not mean "default main context" but rather,
189 * "it is okay to dispatch in any context". If the default main context
190 * is specifically desired then it must be given.
191 *
192 * note also: if you want to get meaningful values for the @origin_tag
193 * that appears as an argument to some of the callbacks, you *must* have
194 * @context as %NULL. Otherwise, you are subject to cross-thread
195 * dispatching and whatever owned @origin_tag at the time that the event
196 * occurred may no longer own it. This is a problem if you consider that
197 * you may now be the new owner of that address and mistakenly think
198 * that the event in question originated from yourself.
199 *
200 * tl;dr: If you give a non-%NULL @context then you must ignore the
201 * value of @origin_tag given to any callbacks.
202 **/
203void
204g_settings_backend_watch (GSettingsBackend *backend,
205 const GSettingsListenerVTable *vtable,
206 GObject *target,
207 GMainContext *context)
208{
209 GSettingsBackendWatch *watch;
210
211 /* For purposes of discussion, we assume that our target is a
212 * GSettings instance.
213 *
214 * Our strategy to defend against the final reference dropping on the
215 * GSettings object in a thread other than the one that is doing the
216 * dispatching is as follows:
217 *
218 * 1) hold a strong reference on the GSettings during an outstanding
219 * dispatch. This ensures that the delivery is always possible while
220 * the GSettings object is alive, and if this was the last reference
221 * then it will be dropped from the dispatch thread.
222 *
223 * 2) hold a weak reference on the GSettings at other times. This
224 * allows us to receive early notification of pending destruction
225 * of the object. At this point, it is still safe to obtain a
226 * reference on the GObject to keep it alive, so #1 will work up
227 * to that point. After that point, we'll have been able to drop
228 * the watch from the list.
229 *
230 * Note, in particular, that it's not possible to simply have an
231 * "unwatch" function that gets called from the finalize function of
232 * the GSettings instance because, by that point it is no longer
233 * possible to keep the object alive using g_object_ref() and we would
234 * have no way of knowing this.
235 *
236 * Note also that we need to hold a reference on the main context here
237 * since the GSettings instance may be finalized before the closure runs.
238 *
239 * All access to the list holds a mutex. We have some strategies to
240 * avoid some of the pain that would be associated with that.
241 */
242
243 watch = g_slice_new (GSettingsBackendWatch);
244 watch->context = context;
245 watch->vtable = vtable;
246 g_weak_ref_init (weak_ref: &watch->target, object: target);
247 watch->target_ptr = target;
248 g_object_weak_ref (object: target, notify: g_settings_backend_watch_weak_notify, data: backend);
249
250 /* linked list prepend */
251 g_mutex_lock (mutex: &backend->priv->lock);
252 watch->next = backend->priv->watches;
253 backend->priv->watches = watch;
254 g_mutex_unlock (mutex: &backend->priv->lock);
255}
256
257void
258g_settings_backend_unwatch (GSettingsBackend *backend,
259 GObject *target)
260{
261 /* Our caller surely owns a reference on 'target', so the order of
262 * these two calls is unimportant.
263 */
264 g_object_weak_unref (object: target, notify: g_settings_backend_watch_weak_notify, data: backend);
265 g_settings_backend_watch_weak_notify (data: backend, where_the_object_was: target);
266}
267
268static gboolean
269g_settings_backend_invoke_closure (gpointer user_data)
270{
271 GSettingsBackendClosure *closure = user_data;
272
273 closure->function (closure->target, closure->backend, closure->name,
274 closure->origin_tag, closure->names);
275
276 if (closure->context)
277 g_main_context_unref (context: closure->context);
278 g_object_unref (object: closure->backend);
279 g_object_unref (object: closure->target);
280 g_strfreev (str_array: closure->names);
281 g_free (mem: closure->name);
282
283 g_slice_free (GSettingsBackendClosure, closure);
284
285 return FALSE;
286}
287
288static void
289g_settings_backend_dispatch_signal (GSettingsBackend *backend,
290 gsize function_offset,
291 const gchar *name,
292 gpointer origin_tag,
293 const gchar * const *names)
294{
295 GSettingsBackendWatch *watch;
296 GSList *closures = NULL;
297
298 /* We're in a little bit of a tricky situation here. We need to hold
299 * a lock while traversing the list, but we don't want to hold the
300 * lock while calling back into user code.
301 *
302 * We work around this by creating a bunch of GSettingsBackendClosure
303 * objects while holding the lock and dispatching them after. We
304 * never touch the list without holding the lock.
305 */
306 g_mutex_lock (mutex: &backend->priv->lock);
307 for (watch = backend->priv->watches; watch; watch = watch->next)
308 {
309 GSettingsBackendClosure *closure;
310 GObject *target = g_weak_ref_get (weak_ref: &watch->target);
311
312 /* If the target was destroyed in the meantime, just skip it here */
313 if (!target)
314 continue;
315
316 closure = g_slice_new (GSettingsBackendClosure);
317 closure->context = watch->context;
318 if (closure->context)
319 g_main_context_ref (context: closure->context);
320 closure->backend = g_object_ref (backend);
321 closure->target = g_steal_pointer (&target);
322 closure->function = G_STRUCT_MEMBER (void *, watch->vtable,
323 function_offset);
324 closure->name = g_strdup (str: name);
325 closure->origin_tag = origin_tag;
326 closure->names = g_strdupv (str_array: (gchar **) names);
327
328 closures = g_slist_prepend (list: closures, data: closure);
329 }
330 g_mutex_unlock (mutex: &backend->priv->lock);
331
332 while (closures)
333 {
334 GSettingsBackendClosure *closure = closures->data;
335
336 if (closure->context)
337 g_main_context_invoke (context: closure->context,
338 function: g_settings_backend_invoke_closure,
339 data: closure);
340 else
341 g_settings_backend_invoke_closure (user_data: closure);
342
343 closures = g_slist_delete_link (list: closures, link_: closures);
344 }
345}
346
347/**
348 * g_settings_backend_changed:
349 * @backend: a #GSettingsBackend implementation
350 * @key: the name of the key
351 * @origin_tag: the origin tag
352 *
353 * Signals that a single key has possibly changed. Backend
354 * implementations should call this if a key has possibly changed its
355 * value.
356 *
357 * @key must be a valid key (ie starting with a slash, not containing
358 * '//', and not ending with a slash).
359 *
360 * The implementation must call this function during any call to
361 * g_settings_backend_write(), before the call returns (except in the
362 * case that no keys are actually changed and it cares to detect this
363 * fact). It may not rely on the existence of a mainloop for
364 * dispatching the signal later.
365 *
366 * The implementation may call this function at any other time it likes
367 * in response to other events (such as changes occurring outside of the
368 * program). These calls may originate from a mainloop or may originate
369 * in response to any other action (including from calls to
370 * g_settings_backend_write()).
371 *
372 * In the case that this call is in response to a call to
373 * g_settings_backend_write() then @origin_tag must be set to the same
374 * value that was passed to that call.
375 *
376 * Since: 2.26
377 **/
378void
379g_settings_backend_changed (GSettingsBackend *backend,
380 const gchar *key,
381 gpointer origin_tag)
382{
383 g_return_if_fail (G_IS_SETTINGS_BACKEND (backend));
384 g_return_if_fail (is_key (key));
385
386 g_settings_backend_dispatch_signal (backend,
387 G_STRUCT_OFFSET (GSettingsListenerVTable,
388 changed),
389 name: key, origin_tag, NULL);
390}
391
392/**
393 * g_settings_backend_keys_changed:
394 * @backend: a #GSettingsBackend implementation
395 * @path: the path containing the changes
396 * @items: (array zero-terminated=1): the %NULL-terminated list of changed keys
397 * @origin_tag: the origin tag
398 *
399 * Signals that a list of keys have possibly changed. Backend
400 * implementations should call this if keys have possibly changed their
401 * values.
402 *
403 * @path must be a valid path (ie starting and ending with a slash and
404 * not containing '//'). Each string in @items must form a valid key
405 * name when @path is prefixed to it (ie: each item must not start or
406 * end with '/' and must not contain '//').
407 *
408 * The meaning of this signal is that any of the key names resulting
409 * from the contatenation of @path with each item in @items may have
410 * changed.
411 *
412 * The same rules for when notifications must occur apply as per
413 * g_settings_backend_changed(). These two calls can be used
414 * interchangeably if exactly one item has changed (although in that
415 * case g_settings_backend_changed() is definitely preferred).
416 *
417 * For efficiency reasons, the implementation should strive for @path to
418 * be as long as possible (ie: the longest common prefix of all of the
419 * keys that were changed) but this is not strictly required.
420 *
421 * Since: 2.26
422 */
423void
424g_settings_backend_keys_changed (GSettingsBackend *backend,
425 const gchar *path,
426 gchar const * const *items,
427 gpointer origin_tag)
428{
429 g_return_if_fail (G_IS_SETTINGS_BACKEND (backend));
430 g_return_if_fail (is_path (path));
431
432 /* XXX: should do stricter checking (ie: inspect each item) */
433 g_return_if_fail (items != NULL);
434
435 g_settings_backend_dispatch_signal (backend,
436 G_STRUCT_OFFSET (GSettingsListenerVTable,
437 keys_changed),
438 name: path, origin_tag, names: items);
439}
440
441/**
442 * g_settings_backend_path_changed:
443 * @backend: a #GSettingsBackend implementation
444 * @path: the path containing the changes
445 * @origin_tag: the origin tag
446 *
447 * Signals that all keys below a given path may have possibly changed.
448 * Backend implementations should call this if an entire path of keys
449 * have possibly changed their values.
450 *
451 * @path must be a valid path (ie starting and ending with a slash and
452 * not containing '//').
453 *
454 * The meaning of this signal is that any of the key which has a name
455 * starting with @path may have changed.
456 *
457 * The same rules for when notifications must occur apply as per
458 * g_settings_backend_changed(). This call might be an appropriate
459 * reasponse to a 'reset' call but implementations are also free to
460 * explicitly list the keys that were affected by that call if they can
461 * easily do so.
462 *
463 * For efficiency reasons, the implementation should strive for @path to
464 * be as long as possible (ie: the longest common prefix of all of the
465 * keys that were changed) but this is not strictly required. As an
466 * example, if this function is called with the path of "/" then every
467 * single key in the application will be notified of a possible change.
468 *
469 * Since: 2.26
470 */
471void
472g_settings_backend_path_changed (GSettingsBackend *backend,
473 const gchar *path,
474 gpointer origin_tag)
475{
476 g_return_if_fail (G_IS_SETTINGS_BACKEND (backend));
477 g_return_if_fail (is_path (path));
478
479 g_settings_backend_dispatch_signal (backend,
480 G_STRUCT_OFFSET (GSettingsListenerVTable,
481 path_changed),
482 name: path, origin_tag, NULL);
483}
484
485/**
486 * g_settings_backend_writable_changed:
487 * @backend: a #GSettingsBackend implementation
488 * @key: the name of the key
489 *
490 * Signals that the writability of a single key has possibly changed.
491 *
492 * Since GSettings performs no locking operations for itself, this call
493 * will always be made in response to external events.
494 *
495 * Since: 2.26
496 **/
497void
498g_settings_backend_writable_changed (GSettingsBackend *backend,
499 const gchar *key)
500{
501 g_return_if_fail (G_IS_SETTINGS_BACKEND (backend));
502 g_return_if_fail (is_key (key));
503
504 g_settings_backend_dispatch_signal (backend,
505 G_STRUCT_OFFSET (GSettingsListenerVTable,
506 writable_changed),
507 name: key, NULL, NULL);
508}
509
510/**
511 * g_settings_backend_path_writable_changed:
512 * @backend: a #GSettingsBackend implementation
513 * @path: the name of the path
514 *
515 * Signals that the writability of all keys below a given path may have
516 * changed.
517 *
518 * Since GSettings performs no locking operations for itself, this call
519 * will always be made in response to external events.
520 *
521 * Since: 2.26
522 **/
523void
524g_settings_backend_path_writable_changed (GSettingsBackend *backend,
525 const gchar *path)
526{
527 g_return_if_fail (G_IS_SETTINGS_BACKEND (backend));
528 g_return_if_fail (is_path (path));
529
530 g_settings_backend_dispatch_signal (backend,
531 G_STRUCT_OFFSET (GSettingsListenerVTable,
532 path_writable_changed),
533 name: path, NULL, NULL);
534}
535
536typedef struct
537{
538 const gchar **keys;
539 GVariant **values;
540 gint prefix_len;
541 gchar *prefix;
542} FlattenState;
543
544static gboolean
545g_settings_backend_flatten_one (gpointer key,
546 gpointer value,
547 gpointer user_data)
548{
549 FlattenState *state = user_data;
550 const gchar *skey = key;
551 gint i;
552
553 g_return_val_if_fail (is_key (key), TRUE);
554
555 /* calculate longest common prefix */
556 if (state->prefix == NULL)
557 {
558 gchar *last_byte;
559
560 /* first key? just take the prefix up to the last '/' */
561 state->prefix = g_strdup (str: skey);
562 last_byte = strrchr (s: state->prefix, c: '/') + 1;
563 state->prefix_len = last_byte - state->prefix;
564 *last_byte = '\0';
565 }
566 else
567 {
568 /* find the first character that does not match. we will
569 * definitely find one because the prefix ends in '/' and the key
570 * does not. also: no two keys in the tree are the same.
571 */
572 for (i = 0; state->prefix[i] == skey[i]; i++);
573
574 /* check if we need to shorten the prefix */
575 if (state->prefix[i] != '\0')
576 {
577 /* find the nearest '/', terminate after it */
578 while (state->prefix[i - 1] != '/')
579 i--;
580
581 state->prefix[i] = '\0';
582 state->prefix_len = i;
583 }
584 }
585
586
587 /* save the entire item into the array.
588 * the prefixes will be removed later.
589 */
590 *state->keys++ = key;
591
592 if (state->values)
593 *state->values++ = value;
594
595 return FALSE;
596}
597
598/**
599 * g_settings_backend_flatten_tree:
600 * @tree: a #GTree containing the changes
601 * @path: (out): the location to save the path
602 * @keys: (out) (transfer container) (array zero-terminated=1): the
603 * location to save the relative keys
604 * @values: (out) (optional) (transfer container) (array zero-terminated=1):
605 * the location to save the values, or %NULL
606 *
607 * Calculate the longest common prefix of all keys in a tree and write
608 * out an array of the key names relative to that prefix and,
609 * optionally, the value to store at each of those keys.
610 *
611 * You must free the value returned in @path, @keys and @values using
612 * g_free(). You should not attempt to free or unref the contents of
613 * @keys or @values.
614 *
615 * Since: 2.26
616 **/
617void
618g_settings_backend_flatten_tree (GTree *tree,
619 gchar **path,
620 const gchar ***keys,
621 GVariant ***values)
622{
623 FlattenState state = { 0, };
624 gsize nnodes;
625
626 nnodes = g_tree_nnodes (tree);
627
628 *keys = state.keys = g_new (const gchar *, nnodes + 1);
629 state.keys[nnodes] = NULL;
630
631 if (values != NULL)
632 {
633 *values = state.values = g_new (GVariant *, nnodes + 1);
634 state.values[nnodes] = NULL;
635 }
636
637 g_tree_foreach (tree, func: g_settings_backend_flatten_one, user_data: &state);
638 g_return_if_fail (*keys + nnodes == state.keys);
639
640 *path = state.prefix;
641 while (nnodes--)
642 *--state.keys += state.prefix_len;
643}
644
645/**
646 * g_settings_backend_changed_tree:
647 * @backend: a #GSettingsBackend implementation
648 * @tree: a #GTree containing the changes
649 * @origin_tag: the origin tag
650 *
651 * This call is a convenience wrapper. It gets the list of changes from
652 * @tree, computes the longest common prefix and calls
653 * g_settings_backend_changed().
654 *
655 * Since: 2.26
656 **/
657void
658g_settings_backend_changed_tree (GSettingsBackend *backend,
659 GTree *tree,
660 gpointer origin_tag)
661{
662 const gchar **keys;
663 gchar *path;
664
665 g_return_if_fail (G_IS_SETTINGS_BACKEND (backend));
666
667 g_settings_backend_flatten_tree (tree, path: &path, keys: &keys, NULL);
668
669#ifdef DEBUG_CHANGES
670 {
671 gint i;
672
673 g_print ("----\n");
674 g_print ("changed_tree(): prefix %s\n", path);
675 for (i = 0; keys[i]; i++)
676 g_print (" %s\n", keys[i]);
677 g_print ("----\n");
678 }
679#endif
680
681 g_settings_backend_keys_changed (backend, path, items: keys, origin_tag);
682 g_free (mem: path);
683 g_free (mem: keys);
684}
685
686/*< private >
687 * g_settings_backend_read:
688 * @backend: a #GSettingsBackend implementation
689 * @key: the key to read
690 * @expected_type: a #GVariantType
691 * @default_value: if the default value should be returned
692 *
693 * Reads a key. This call will never block.
694 *
695 * If the key exists, the value associated with it will be returned.
696 * If the key does not exist, %NULL will be returned.
697 *
698 * The returned value will be of the type given in @expected_type. If
699 * the backend stored a value of a different type then %NULL will be
700 * returned.
701 *
702 * If @default_value is %TRUE then this gets the default value from the
703 * backend (ie: the one that the backend would contain if
704 * g_settings_reset() were called).
705 *
706 * Returns: the value that was read, or %NULL
707 */
708GVariant *
709g_settings_backend_read (GSettingsBackend *backend,
710 const gchar *key,
711 const GVariantType *expected_type,
712 gboolean default_value)
713{
714 GVariant *value;
715
716 value = G_SETTINGS_BACKEND_GET_CLASS (backend)
717 ->read (backend, key, expected_type, default_value);
718
719 if (value != NULL)
720 value = g_variant_take_ref (value);
721
722 if G_UNLIKELY (value && !g_variant_is_of_type (value, expected_type))
723 {
724 g_variant_unref (value);
725 value = NULL;
726 }
727
728 return value;
729}
730
731/*< private >
732 * g_settings_backend_read_user_value:
733 * @backend: a #GSettingsBackend implementation
734 * @key: the key to read
735 * @expected_type: a #GVariantType
736 *
737 * Reads the 'user value' of a key.
738 *
739 * This is the value of the key that the user has control over and has
740 * set for themselves. Put another way: if the user did not set the
741 * value for themselves, then this will return %NULL (even if the
742 * sysadmin has provided a default value).
743 *
744 * Returns: the value that was read, or %NULL
745 */
746GVariant *
747g_settings_backend_read_user_value (GSettingsBackend *backend,
748 const gchar *key,
749 const GVariantType *expected_type)
750{
751 GVariant *value;
752
753 value = G_SETTINGS_BACKEND_GET_CLASS (backend)
754 ->read_user_value (backend, key, expected_type);
755
756 if (value != NULL)
757 value = g_variant_take_ref (value);
758
759 if G_UNLIKELY (value && !g_variant_is_of_type (value, expected_type))
760 {
761 g_variant_unref (value);
762 value = NULL;
763 }
764
765 return value;
766}
767
768/*< private >
769 * g_settings_backend_write:
770 * @backend: a #GSettingsBackend implementation
771 * @key: the name of the key
772 * @value: a #GVariant value to write to this key
773 * @origin_tag: the origin tag
774 *
775 * Writes exactly one key.
776 *
777 * This call does not fail. During this call a
778 * #GSettingsBackend::changed signal will be emitted if the value of the
779 * key has changed. The updated key value will be visible to any signal
780 * callbacks.
781 *
782 * One possible method that an implementation might deal with failures is
783 * to emit a second "changed" signal (either during this call, or later)
784 * to indicate that the affected keys have suddenly "changed back" to their
785 * old values.
786 *
787 * If @value has a floating reference, it will be sunk.
788 *
789 * Returns: %TRUE if the write succeeded, %FALSE if the key was not writable
790 */
791gboolean
792g_settings_backend_write (GSettingsBackend *backend,
793 const gchar *key,
794 GVariant *value,
795 gpointer origin_tag)
796{
797 gboolean success;
798
799 g_variant_ref_sink (value);
800 success = G_SETTINGS_BACKEND_GET_CLASS (backend)
801 ->write (backend, key, value, origin_tag);
802 g_variant_unref (value);
803
804 return success;
805}
806
807/*< private >
808 * g_settings_backend_write_tree:
809 * @backend: a #GSettingsBackend implementation
810 * @tree: a #GTree containing key-value pairs to write
811 * @origin_tag: the origin tag
812 *
813 * Writes one or more keys. This call will never block.
814 *
815 * The key of each item in the tree is the key name to write to and the
816 * value is a #GVariant to write. The proper type of #GTree for this
817 * call can be created with g_settings_backend_create_tree(). This call
818 * might take a reference to the tree; you must not modified the #GTree
819 * after passing it to this call.
820 *
821 * This call does not fail. During this call a #GSettingsBackend::changed
822 * signal will be emitted if any keys have been changed. The new values of
823 * all updated keys will be visible to any signal callbacks.
824 *
825 * One possible method that an implementation might deal with failures is
826 * to emit a second "changed" signal (either during this call, or later)
827 * to indicate that the affected keys have suddenly "changed back" to their
828 * old values.
829 */
830gboolean
831g_settings_backend_write_tree (GSettingsBackend *backend,
832 GTree *tree,
833 gpointer origin_tag)
834{
835 return G_SETTINGS_BACKEND_GET_CLASS (backend)
836 ->write_tree (backend, tree, origin_tag);
837}
838
839/*< private >
840 * g_settings_backend_reset:
841 * @backend: a #GSettingsBackend implementation
842 * @key: the name of a key
843 * @origin_tag: the origin tag
844 *
845 * "Resets" the named key to its "default" value (ie: after system-wide
846 * defaults, mandatory keys, etc. have been taken into account) or possibly
847 * unsets it.
848 */
849void
850g_settings_backend_reset (GSettingsBackend *backend,
851 const gchar *key,
852 gpointer origin_tag)
853{
854 G_SETTINGS_BACKEND_GET_CLASS (backend)
855 ->reset (backend, key, origin_tag);
856}
857
858/*< private >
859 * g_settings_backend_get_writable:
860 * @backend: a #GSettingsBackend implementation
861 * @key: the name of a key
862 *
863 * Finds out if a key is available for writing to. This is the
864 * interface through which 'lockdown' is implemented. Locked down
865 * keys will have %FALSE returned by this call.
866 *
867 * You should not write to locked-down keys, but if you do, the
868 * implementation will deal with it.
869 *
870 * Returns: %TRUE if the key is writable
871 */
872gboolean
873g_settings_backend_get_writable (GSettingsBackend *backend,
874 const gchar *key)
875{
876 return G_SETTINGS_BACKEND_GET_CLASS (backend)
877 ->get_writable (backend, key);
878}
879
880/*< private >
881 * g_settings_backend_unsubscribe:
882 * @backend: a #GSettingsBackend
883 * @name: a key or path to subscribe to
884 *
885 * Reverses the effect of a previous call to
886 * g_settings_backend_subscribe().
887 */
888void
889g_settings_backend_unsubscribe (GSettingsBackend *backend,
890 const char *name)
891{
892 G_SETTINGS_BACKEND_GET_CLASS (backend)
893 ->unsubscribe (backend, name);
894}
895
896/*< private >
897 * g_settings_backend_subscribe:
898 * @backend: a #GSettingsBackend
899 * @name: a key or path to subscribe to
900 *
901 * Requests that change signals be emitted for events on @name.
902 */
903void
904g_settings_backend_subscribe (GSettingsBackend *backend,
905 const gchar *name)
906{
907 G_SETTINGS_BACKEND_GET_CLASS (backend)
908 ->subscribe (backend, name);
909}
910
911static void
912g_settings_backend_finalize (GObject *object)
913{
914 GSettingsBackend *backend = G_SETTINGS_BACKEND (object);
915
916 g_mutex_clear (mutex: &backend->priv->lock);
917
918 G_OBJECT_CLASS (g_settings_backend_parent_class)
919 ->finalize (object);
920}
921
922static void
923ignore_subscription (GSettingsBackend *backend,
924 const gchar *key)
925{
926}
927
928static GVariant *
929g_settings_backend_real_read_user_value (GSettingsBackend *backend,
930 const gchar *key,
931 const GVariantType *expected_type)
932{
933 return g_settings_backend_read (backend, key, expected_type, FALSE);
934}
935
936static void
937g_settings_backend_init (GSettingsBackend *backend)
938{
939 backend->priv = g_settings_backend_get_instance_private (self: backend);
940 g_mutex_init (mutex: &backend->priv->lock);
941}
942
943static void
944g_settings_backend_class_init (GSettingsBackendClass *class)
945{
946 GObjectClass *gobject_class = G_OBJECT_CLASS (class);
947
948 class->subscribe = ignore_subscription;
949 class->unsubscribe = ignore_subscription;
950
951 class->read_user_value = g_settings_backend_real_read_user_value;
952
953 gobject_class->finalize = g_settings_backend_finalize;
954}
955
956static void
957g_settings_backend_variant_unref0 (gpointer data)
958{
959 if (data != NULL)
960 g_variant_unref (value: data);
961}
962
963/*< private >
964 * g_settings_backend_create_tree:
965 *
966 * This is a convenience function for creating a tree that is compatible
967 * with g_settings_backend_write(). It merely calls g_tree_new_full()
968 * with strcmp(), g_free() and g_variant_unref().
969 *
970 * Returns: a new #GTree
971 */
972GTree *
973g_settings_backend_create_tree (void)
974{
975 return g_tree_new_full (key_compare_func: (GCompareDataFunc) strcmp, NULL,
976 key_destroy_func: g_free, value_destroy_func: g_settings_backend_variant_unref0);
977}
978
979static gboolean
980g_settings_backend_verify (gpointer impl)
981{
982 GSettingsBackend *backend = impl;
983
984 if (strcmp (G_OBJECT_TYPE_NAME (backend), s2: "GMemorySettingsBackend") == 0 &&
985 g_strcmp0 (str1: g_getenv (variable: "GSETTINGS_BACKEND"), str2: "memory") != 0)
986 {
987 g_message ("Using the 'memory' GSettings backend. Your settings "
988 "will not be saved or shared with other applications.");
989 }
990
991 g_settings_has_backend = TRUE;
992 return TRUE;
993}
994
995/* We need to cache the default #GSettingsBackend for the entire process
996 * lifetime, especially if the backend is #GMemorySettingsBackend: it needs to
997 * keep the in-memory settings around even while there are no #GSettings
998 * instances alive. */
999static GSettingsBackend *settings_backend_default_singleton = NULL; /* (owned) (atomic) */
1000
1001/**
1002 * g_settings_backend_get_default:
1003 *
1004 * Returns the default #GSettingsBackend. It is possible to override
1005 * the default by setting the `GSETTINGS_BACKEND` environment variable
1006 * to the name of a settings backend.
1007 *
1008 * The user gets a reference to the backend.
1009 *
1010 * Returns: (not nullable) (transfer full): the default #GSettingsBackend,
1011 * which will be a dummy (memory) settings backend if no other settings
1012 * backend is available.
1013 *
1014 * Since: 2.28
1015 */
1016GSettingsBackend *
1017g_settings_backend_get_default (void)
1018{
1019 if (g_once_init_enter (&settings_backend_default_singleton))
1020 {
1021 GSettingsBackend *singleton;
1022
1023 singleton = _g_io_module_get_default (G_SETTINGS_BACKEND_EXTENSION_POINT_NAME,
1024 envvar: "GSETTINGS_BACKEND",
1025 verify_func: g_settings_backend_verify);
1026
1027 g_once_init_leave (&settings_backend_default_singleton, singleton);
1028 }
1029
1030 return g_object_ref (settings_backend_default_singleton);
1031}
1032
1033/*< private >
1034 * g_settings_backend_get_permission:
1035 * @backend: a #GSettingsBackend
1036 * @path: a path
1037 *
1038 * Gets the permission object associated with writing to keys below
1039 * @path on @backend.
1040 *
1041 * If this is not implemented in the backend, then a %TRUE
1042 * #GSimplePermission is returned.
1043 *
1044 * Returns: a non-%NULL #GPermission. Free with g_object_unref()
1045 */
1046GPermission *
1047g_settings_backend_get_permission (GSettingsBackend *backend,
1048 const gchar *path)
1049{
1050 GSettingsBackendClass *class = G_SETTINGS_BACKEND_GET_CLASS (backend);
1051
1052 if (class->get_permission)
1053 return class->get_permission (backend, path);
1054
1055 return g_simple_permission_new (TRUE);
1056}
1057
1058/*< private >
1059 * g_settings_backend_sync_default:
1060 *
1061 * Syncs the default backend.
1062 */
1063void
1064g_settings_backend_sync_default (void)
1065{
1066 if (g_settings_has_backend)
1067 {
1068 GSettingsBackendClass *class;
1069 GSettingsBackend *backend;
1070
1071 backend = g_settings_backend_get_default ();
1072 class = G_SETTINGS_BACKEND_GET_CLASS (backend);
1073
1074 if (class->sync)
1075 class->sync (backend);
1076
1077 g_object_unref (object: backend);
1078 }
1079}
1080

source code of gtk/subprojects/glib/gio/gsettingsbackend.c