GSettings: major refactor. Add enums, range.
[platform/upstream/glib.git] / gio / gsettingsbackend.c
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 of the licence, 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, write to the
17  * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
18  * Boston, MA 02111-1307, USA.
19  *
20  * Authors: Ryan Lortie <desrt@desrt.ca>
21  *          Matthias Clasen <mclasen@redhat.com>
22  */
23
24 #include "config.h"
25
26 #include "gsettingsbackendinternal.h"
27 #include "gnullsettingsbackend.h"
28 #include "gsimplepermission.h"
29 #include "giomodule-priv.h"
30 #include "gio-marshal.h"
31
32 #include <string.h>
33 #include <stdlib.h>
34 #include <glib.h>
35 #include <glibintl.h>
36
37 #include "gioalias.h"
38
39 G_DEFINE_ABSTRACT_TYPE (GSettingsBackend, g_settings_backend, G_TYPE_OBJECT)
40
41 typedef struct _GSettingsBackendClosure GSettingsBackendClosure;
42 typedef struct _GSettingsBackendWatch   GSettingsBackendWatch;
43
44 struct _GSettingsBackendPrivate
45 {
46   GSettingsBackendWatch *watches;
47   GStaticMutex lock;
48   gchar *context;
49 };
50
51 enum
52 {
53   PROP_0,
54   PROP_CONTEXT
55 };
56
57 /**
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
63  *
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.
69  *
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.
73  *
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.
77  *
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
81  * suitable trees.
82  *
83  * <note><para>
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>
89  * </para></note>
90  **/
91
92 static gboolean
93 is_key (const gchar *key)
94 {
95   gint length;
96   gint i;
97
98   g_return_val_if_fail (key != NULL, FALSE);
99   g_return_val_if_fail (key[0] == '/', FALSE);
100
101   for (i = 1; key[i]; i++)
102     g_return_val_if_fail (key[i] != '/' || key[i + 1] != '/', FALSE);
103
104   length = i;
105
106   g_return_val_if_fail (key[length - 1] != '/', FALSE);
107
108   return TRUE;
109 }
110
111 static gboolean
112 is_path (const gchar *path)
113 {
114   gint length;
115   gint i;
116
117   g_return_val_if_fail (path != NULL, FALSE);
118   g_return_val_if_fail (path[0] == '/', FALSE);
119
120   for (i = 1; path[i]; i++)
121     g_return_val_if_fail (path[i] != '/' || path[i + 1] != '/', FALSE);
122
123   length = i;
124
125   g_return_val_if_fail (path[length - 1] == '/', FALSE);
126
127   return TRUE;
128 }
129
130 GMainContext *
131 g_settings_backend_get_active_context (void)
132 {
133   GMainContext *context;
134   GSource *source;
135
136   if ((source = g_main_current_source ()))
137     context = g_source_get_context (source);
138
139   else
140     {
141       context = g_main_context_get_thread_default ();
142
143       if (context == NULL)
144         context = g_main_context_default ();
145     }
146
147   return context;
148 }
149
150 struct _GSettingsBackendWatch
151 {
152   GObject                                 *target;
153   GMainContext                            *context;
154   GSettingsBackendChangedFunc              changed;
155   GSettingsBackendPathChangedFunc          path_changed;
156   GSettingsBackendKeysChangedFunc          keys_changed;
157   GSettingsBackendWritableChangedFunc      writable_changed;
158   GSettingsBackendPathWritableChangedFunc  path_writable_changed;
159
160   GSettingsBackendWatch                   *next;
161 };
162
163 struct _GSettingsBackendClosure
164 {
165   void (*function) (GSettingsBackend *backend,
166                     GObject          *target,
167                     const gchar      *name,
168                     gpointer          data1,
169                     gpointer          data2);
170
171   GSettingsBackend *backend;
172   GObject          *target;
173   gchar            *name;
174   gpointer          data1;
175   GBoxedFreeFunc    data1_free;
176   gpointer          data2;
177 };
178
179 static void
180 g_settings_backend_watch_weak_notify (gpointer  data,
181                                       GObject  *where_the_object_was)
182 {
183   GSettingsBackend *backend = data;
184   GSettingsBackendWatch **ptr;
185
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)
190       {
191         GSettingsBackendWatch *tmp = *ptr;
192
193         *ptr = tmp->next;
194         g_slice_free (GSettingsBackendWatch, tmp);
195
196         g_static_mutex_unlock (&backend->priv->lock);
197         return;
198       }
199
200   /* we didn't find it.  that shouldn't happen. */
201   g_assert_not_reached ();
202 }
203
204 /*< private >
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
209  * ...: callbacks...
210  *
211  * Registers a new watch on a #GSettingsBackend.
212  *
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.
216  *
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.
224  *
225  * tl;dr: If you give a non-%NULL @context then you must ignore the
226  * value of @origin_tag given to any callbacks.
227  **/
228 void
229 g_settings_backend_watch (GSettingsBackend                        *backend,
230                           GObject                                 *target,
231                           GMainContext                            *context,
232                           GSettingsBackendChangedFunc              changed,
233                           GSettingsBackendPathChangedFunc          path_changed,
234                           GSettingsBackendKeysChangedFunc          keys_changed,
235                           GSettingsBackendWritableChangedFunc      writable_changed,
236                           GSettingsBackendPathWritableChangedFunc  path_writable_changed)
237 {
238   GSettingsBackendWatch *watch;
239
240   /* For purposes of discussion, we assume that our target is a
241    * GSettings instance.
242    *
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:
246    *
247    *  1) hold a GObject reference on the GSettings during an outstanding
248    *     dispatch.  This ensures that the delivery is always possible.
249    *
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.
256    *
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.
262    *
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.
269    *
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.
272    */
273
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);
278
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;
284
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);
290 }
291
292 void
293 g_settings_backend_unwatch (GSettingsBackend *backend,
294                             GObject          *target)
295 {
296   /* Our caller surely owns a reference on 'target', so the order of
297    * these two calls is unimportant.
298    */
299   g_object_weak_unref (target, g_settings_backend_watch_weak_notify, backend);
300   g_settings_backend_watch_weak_notify (backend, target);
301 }
302
303 static gboolean
304 g_settings_backend_invoke_closure (gpointer user_data)
305 {
306   GSettingsBackendClosure *closure = user_data;
307
308   closure->function (closure->backend, closure->target, closure->name,
309                      closure->data1, closure->data2);
310
311   closure->data1_free (closure->data1);
312   g_object_unref (closure->backend);
313   g_object_unref (closure->target);
314   g_free (closure->name);
315
316   g_slice_free (GSettingsBackendClosure, closure);
317
318   return FALSE;
319 }
320
321 static gpointer
322 pointer_id (gpointer a)
323 {
324   return a;
325 }
326
327 static void
328 pointer_ignore (gpointer a)
329 {
330 }
331
332 static void
333 g_settings_backend_dispatch_signal (GSettingsBackend *backend,
334                                     gsize             function_offset,
335                                     const gchar      *name,
336                                     gpointer          data1,
337                                     GBoxedCopyFunc    data1_copy,
338                                     GBoxedFreeFunc    data1_free,
339                                     gpointer          data2)
340 {
341   GMainContext *context, *here_and_now;
342   GSettingsBackendWatch *watch;
343
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
353    * setup.
354    */
355
356   if (data1_copy == NULL)
357     data1_copy = pointer_id;
358
359   if (data1_free == NULL)
360     data1_free = pointer_ignore;
361  
362   context = g_settings_backend_get_active_context ();
363   here_and_now = g_main_context_new ();
364
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)
368     {
369       GSettingsBackendClosure *closure;
370       GSource *source;
371
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;
380
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,
385                              closure, NULL);
386
387       if (watch->context && watch->context != context)
388         g_source_attach (source, watch->context);
389       else
390         g_source_attach (source, here_and_now);
391
392       g_source_unref (source);
393     }
394   g_static_mutex_unlock (&backend->priv->lock);
395
396   while (g_main_context_iteration (here_and_now, FALSE));
397   g_main_context_unref (here_and_now);
398 }
399
400 /**
401  * g_settings_backend_changed:
402  * @backend: a #GSettingsBackend implementation
403  * @key: the name of the key
404  * @origin_tag: the origin tag
405  *
406  * Signals that a single key has possibly changed.  Backend
407  * implementations should call this if a key has possibly changed its
408  * value.
409  *
410  * @key must be a valid key (ie: starting with a slash, not containing
411  * '//', and not ending with a slash).
412  *
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.
418  *
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()).
424  *
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.
428  *
429  * Since: 2.26
430  **/
431 void
432 g_settings_backend_changed (GSettingsBackend *backend,
433                             const gchar      *key,
434                             gpointer          origin_tag)
435 {
436   g_return_if_fail (G_IS_SETTINGS_BACKEND (backend));
437   g_return_if_fail (is_key (key));
438
439   g_settings_backend_dispatch_signal (backend,
440                                       G_STRUCT_OFFSET (GSettingsBackendWatch,
441                                                        changed),
442                                       key, origin_tag, NULL, NULL, NULL);
443 }
444
445 /**
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
451  *
452  * Signals that a list of keys have possibly changed.  Backend
453  * implementations should call this if keys have possibly changed their
454  * values.
455  *
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 '//').
460  *
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
463  * changed.
464  *
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).
469  *
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.
473  *
474  * Since: 2.26
475  */
476 void
477 g_settings_backend_keys_changed (GSettingsBackend    *backend,
478                                  const gchar         *path,
479                                  gchar const * const *items,
480                                  gpointer             origin_tag)
481 {
482   g_return_if_fail (G_IS_SETTINGS_BACKEND (backend));
483   g_return_if_fail (is_path (path));
484
485   /* XXX: should do stricter checking (ie: inspect each item) */
486   g_return_if_fail (items != NULL);
487
488   g_settings_backend_dispatch_signal (backend,
489                                       G_STRUCT_OFFSET (GSettingsBackendWatch,
490                                                        keys_changed),
491                                       path, (gpointer) items,
492                                       (GBoxedCopyFunc) g_strdupv,
493                                       (GBoxedFreeFunc) g_strfreev,
494                                       origin_tag);
495 }
496
497 /**
498  * g_settings_backend_path_changed:
499  * @backend: a #GSettingsBackend implementation
500  * @path: the path containing the changes
501  * @origin_tag: the origin tag
502  *
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.
506  *
507  * @path must be a valid path (ie: starting and ending with a slash and
508  * not containing '//').
509  *
510  * The meaning of this signal is that any of the key which has a name
511  * starting with @path may have changed.
512  *
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
517  * easily do so.
518  *
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.
524  *
525  * Since: 2.26
526  */
527 void
528 g_settings_backend_path_changed (GSettingsBackend *backend,
529                                  const gchar      *path,
530                                  gpointer          origin_tag)
531 {
532   g_return_if_fail (G_IS_SETTINGS_BACKEND (backend));
533   g_return_if_fail (is_path (path));
534
535   g_settings_backend_dispatch_signal (backend,
536                                       G_STRUCT_OFFSET (GSettingsBackendWatch,
537                                                        path_changed),
538                                       path, origin_tag, NULL, NULL, NULL);
539 }
540
541 /**
542  * g_settings_backend_writable_changed:
543  * @backend: a #GSettingsBackend implementation
544  * @key: the name of the key
545  *
546  * Signals that the writability of a single key has possibly changed.
547  *
548  * Since GSettings performs no locking operations for itself, this call
549  * will always be made in response to external events.
550  *
551  * Since: 2.26
552  **/
553 void
554 g_settings_backend_writable_changed (GSettingsBackend *backend,
555                                      const gchar      *key)
556 {
557   g_return_if_fail (G_IS_SETTINGS_BACKEND (backend));
558   g_return_if_fail (is_key (key));
559
560   g_settings_backend_dispatch_signal (backend,
561                                       G_STRUCT_OFFSET (GSettingsBackendWatch,
562                                                        writable_changed),
563                                       key, NULL, NULL, NULL, NULL);
564 }
565
566 /**
567  * g_settings_backend_path_writable_changed:
568  * @backend: a #GSettingsBackend implementation
569  * @path: the name of the path
570  *
571  * Signals that the writability of all keys below a given path may have
572  * changed.
573  *
574  * Since GSettings performs no locking operations for itself, this call
575  * will always be made in response to external events.
576  *
577  * Since: 2.26
578  **/
579 void
580 g_settings_backend_path_writable_changed (GSettingsBackend *backend,
581                                           const gchar      *path)
582 {
583   g_return_if_fail (G_IS_SETTINGS_BACKEND (backend));
584   g_return_if_fail (is_path (path));
585
586   g_settings_backend_dispatch_signal (backend,
587                                       G_STRUCT_OFFSET (GSettingsBackendWatch,
588                                                        path_writable_changed),
589                                       path, NULL, NULL, NULL, NULL);
590 }
591
592 typedef struct
593 {
594   const gchar **keys;
595   GVariant **values;
596   gint prefix_len;
597   gchar *prefix;
598 } FlattenState;
599
600 static gboolean
601 g_settings_backend_flatten_one (gpointer key,
602                                 gpointer value,
603                                 gpointer user_data)
604 {
605   FlattenState *state = user_data;
606   const gchar *skey = key;
607   gint i;
608
609   g_return_val_if_fail (is_key (key), TRUE);
610
611   /* calculate longest common prefix */
612   if (state->prefix == NULL)
613     {
614       gchar *last_byte;
615
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;
620       *last_byte = '\0';
621     }
622   else
623     {
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.
627        */
628       for (i = 0; state->prefix[i] == skey[i]; i++);
629
630       /* check if we need to shorten the prefix */
631       if (state->prefix[i] != '\0')
632         {
633           /* find the nearest '/', terminate after it */
634           while (state->prefix[i - 1] != '/')
635             i--;
636
637           state->prefix[i] = '\0';
638           state->prefix_len = i;
639         }
640     }
641
642
643   /* save the entire item into the array.
644    * the prefixes will be removed later.
645    */
646   *state->keys++ = key;
647
648   if (state->values)
649     *state->values++ = value;
650
651   return FALSE;
652 }
653
654 /**
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
660  *
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.
664  *
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
667  * @keys or @values.
668  *
669  * Since: 2.26
670  **/
671 void
672 g_settings_backend_flatten_tree (GTree         *tree,
673                                  gchar        **path,
674                                  const gchar ***keys,
675                                  GVariant    ***values)
676 {
677   FlattenState state = { 0, };
678   gsize nnodes;
679
680   nnodes = g_tree_nnodes (tree);
681
682   *keys = state.keys = g_new (const gchar *, nnodes + 1);
683   state.keys[nnodes] = NULL;
684
685   if (values != NULL)
686     {
687       *values = state.values = g_new (GVariant *, nnodes + 1);
688       state.values[nnodes] = NULL;
689     }
690
691   g_tree_foreach (tree, g_settings_backend_flatten_one, &state);
692   g_return_if_fail (*keys + nnodes == state.keys);
693
694   *path = state.prefix;
695   while (nnodes--)
696     *--state.keys += state.prefix_len;
697 }
698
699 /**
700  * g_settings_backend_changed_tree:
701  * @backend: a #GSettingsBackend implementation
702  * @tree: a #GTree containing the changes
703  * @origin_tag: the origin tag
704  *
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().
708  *
709  * Since: 2.26
710  **/
711 void
712 g_settings_backend_changed_tree (GSettingsBackend *backend,
713                                  GTree            *tree,
714                                  gpointer          origin_tag)
715 {
716   GSettingsBackendWatch *watch;
717   const gchar **keys;
718   gchar *path;
719
720   g_return_if_fail (G_IS_SETTINGS_BACKEND (backend));
721
722   g_settings_backend_flatten_tree (tree, &path, &keys, NULL);
723
724   for (watch = backend->priv->watches; watch; watch = watch->next)
725     watch->keys_changed (backend, watch->target, path, keys, origin_tag);
726
727   g_free (path);
728   g_free (keys);
729 }
730
731 /*< private >
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
738  *
739  * Reads a key. This call will never block.
740  *
741  * If the key exists, the value associated with it will be returned.
742  * If the key does not exist, %NULL will be returned.
743  *
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
746  * returned.
747  *
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).
751  */
752 GVariant *
753 g_settings_backend_read (GSettingsBackend   *backend,
754                          const gchar        *key,
755                          const GVariantType *expected_type,
756                          gboolean            default_value)
757 {
758   GVariant *value;
759
760   value = G_SETTINGS_BACKEND_GET_CLASS (backend)
761     ->read (backend, key, expected_type, default_value);
762
763   if G_UNLIKELY (value && !g_variant_is_of_type (value, expected_type))
764     {
765       g_variant_unref (value);
766       value = NULL;
767     }
768
769   return value;
770 }
771
772 /*< private >
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
779  *
780  * Writes exactly one key.
781  *
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
785  * callbacks.
786  *
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
790  * old values.
791  */
792 gboolean
793 g_settings_backend_write (GSettingsBackend *backend,
794                           const gchar      *key,
795                           GVariant         *value,
796                           gpointer          origin_tag)
797 {
798   return G_SETTINGS_BACKEND_GET_CLASS (backend)
799     ->write (backend, key, value, origin_tag);
800 }
801
802 /*< private >
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
807  *
808  * Writes one or more keys.  This call will never block.
809  *
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.
815  *
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.
819  *
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
823  * old values.
824  */
825 gboolean
826 g_settings_backend_write_keys (GSettingsBackend *backend,
827                                GTree            *tree,
828                                gpointer          origin_tag)
829 {
830   return G_SETTINGS_BACKEND_GET_CLASS (backend)
831     ->write_keys (backend, tree, origin_tag);
832 }
833
834 /*< private >
835  * g_settings_backend_reset:
836  * @backend: a #GSettingsBackend implementation
837  * @key: the name of a key
838  * @origin_tag: the origin tag
839  *
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
842  * unsets it.
843  */
844 void
845 g_settings_backend_reset (GSettingsBackend *backend,
846                           const gchar      *key,
847                           gpointer          origin_tag)
848 {
849   G_SETTINGS_BACKEND_GET_CLASS (backend)
850     ->reset (backend, key, origin_tag);
851 }
852
853 /*< private >
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
858  *
859  * "Resets" the named path.  This means that every key under the path is
860  * reset.
861  */
862 void
863 g_settings_backend_reset_path (GSettingsBackend *backend,
864                                const gchar      *path,
865                                gpointer          origin_tag)
866 {
867   G_SETTINGS_BACKEND_GET_CLASS (backend)
868     ->reset_path (backend, path, origin_tag);
869 }
870
871 /*< private >
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
876  *
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.
880  *
881  * You should not write to locked-down keys, but if you do, the
882  * implementation will deal with it.
883  */
884 gboolean
885 g_settings_backend_get_writable (GSettingsBackend *backend,
886                                  const gchar      *key)
887 {
888   return G_SETTINGS_BACKEND_GET_CLASS (backend)
889     ->get_writable (backend, key);
890 }
891
892 /*< private >
893  * g_settings_backend_unsubscribe:
894  * @backend: a #GSettingsBackend
895  * @name: a key or path to subscribe to
896  *
897  * Reverses the effect of a previous call to
898  * g_settings_backend_subscribe().
899  */
900 void
901 g_settings_backend_unsubscribe (GSettingsBackend *backend,
902                                 const char       *name)
903 {
904   G_SETTINGS_BACKEND_GET_CLASS (backend)
905     ->unsubscribe (backend, name);
906 }
907
908 /*< private >
909  * g_settings_backend_subscribe:
910  * @backend: a #GSettingsBackend
911  * @name: a key or path to subscribe to
912  *
913  * Requests that change signals be emitted for events on @name.
914  */
915 void
916 g_settings_backend_subscribe (GSettingsBackend *backend,
917                               const gchar      *name)
918 {
919   G_SETTINGS_BACKEND_GET_CLASS (backend)
920     ->subscribe (backend, name);
921 }
922
923 static void
924 g_settings_backend_set_property (GObject         *object,
925                                  guint            prop_id,
926                                  const GValue    *value,
927                                  GParamSpec      *pspec)
928 {
929   GSettingsBackend *backend = G_SETTINGS_BACKEND (object);
930
931   switch (prop_id)
932     {
933     case PROP_CONTEXT:
934       backend->priv->context = g_value_dup_string (value);
935       break;
936
937     default:
938       G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
939       break;
940     }
941 }
942
943 static void
944 g_settings_backend_get_property (GObject    *object,
945                                  guint       prop_id,
946                                  GValue     *value,
947                                  GParamSpec *pspec)
948 {
949   GSettingsBackend *backend = G_SETTINGS_BACKEND (object);
950
951   switch (prop_id)
952     {
953     case PROP_CONTEXT:
954       g_value_set_string (value, backend->priv->context);
955       break;
956
957     default:
958       G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
959       break;
960     }
961 }
962
963 static void
964 g_settings_backend_finalize (GObject *object)
965 {
966   GSettingsBackend *backend = G_SETTINGS_BACKEND (object);
967
968   g_static_mutex_unlock (&backend->priv->lock);
969   g_free (backend->priv->context);
970
971   G_OBJECT_CLASS (g_settings_backend_parent_class)
972     ->finalize (object);
973 }
974
975 static void
976 ignore_subscription (GSettingsBackend *backend,
977                      const gchar      *key)
978 {
979 }
980
981 static void
982 g_settings_backend_init (GSettingsBackend *backend)
983 {
984   backend->priv = G_TYPE_INSTANCE_GET_PRIVATE (backend,
985                                                G_TYPE_SETTINGS_BACKEND,
986                                                GSettingsBackendPrivate);
987   g_static_mutex_init (&backend->priv->lock);
988 }
989
990 static void
991 g_settings_backend_class_init (GSettingsBackendClass *class)
992 {
993   GObjectClass *gobject_class = G_OBJECT_CLASS (class);
994
995   class->subscribe = ignore_subscription;
996   class->unsubscribe = ignore_subscription;
997
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;
1001
1002   g_type_class_add_private (class, sizeof (GSettingsBackendPrivate));
1003
1004   /**
1005    * GSettingsBackend:context:
1006    *
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.
1010    *
1011    * E.g. DConf supports "user", "system", "defaults" and "login"
1012    * contexts.
1013    *
1014    * If your backend supports different contexts, you should also
1015    * provide an implementation of the supports_context() class
1016    * function in #GSettingsBackendClass.
1017    */
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));
1023
1024 }
1025
1026 /*< private >
1027  * g_settings_backend_create_tree:
1028  * @returns: a new #GTree
1029  *
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().
1033  */
1034 GTree *
1035 g_settings_backend_create_tree (void)
1036 {
1037   return g_tree_new_full ((GCompareDataFunc) strcmp, NULL,
1038                           g_free, (GDestroyNotify) g_variant_unref);
1039 }
1040
1041
1042 static gpointer
1043 get_default_backend (const gchar *context)
1044 {
1045   GIOExtension *extension = NULL;
1046   GIOExtensionPoint *point;
1047   GList *extensions;
1048   const gchar *env;
1049   GType type;
1050
1051   _g_io_modules_ensure_loaded ();
1052
1053   point = g_io_extension_point_lookup (G_SETTINGS_BACKEND_EXTENSION_POINT_NAME);
1054
1055   if ((env = getenv ("GSETTINGS_BACKEND")))
1056     {
1057       extension = g_io_extension_point_get_extension_by_name (point, env);
1058
1059       if (extension == NULL)
1060         g_warning ("Can't find GSettings backend '%s' given in "
1061                    "GSETTINGS_BACKEND environment variable", env);
1062     }
1063
1064   if (extension == NULL)
1065     {
1066       extensions = g_io_extension_point_get_extensions (point);
1067
1068       if (extensions == NULL)
1069         g_error ("No GSettingsBackend implementations exist.");
1070
1071       extension = extensions->data;
1072     }
1073
1074   if (context[0] != '\0') /* (context != "") */
1075     {
1076       GSettingsBackendClass *backend_class;
1077       GTypeClass *class;
1078
1079       class = g_io_extension_ref_class (extension);
1080       backend_class = G_SETTINGS_BACKEND_CLASS (class);
1081
1082       if (backend_class->supports_context == NULL ||
1083           !backend_class->supports_context (context))
1084         {
1085           g_type_class_unref (class);
1086           return NULL;
1087         }
1088
1089       g_type_class_unref (class);
1090     }
1091
1092   type = g_io_extension_get_type (extension);
1093
1094   return g_object_new (type, "context", context, NULL);
1095 }
1096
1097 static GHashTable *g_settings_backends;
1098
1099 /*< private >
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
1104  *
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.
1108  *
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.
1112  *
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(),
1116  *
1117  * The user does not own the return value and it must not be freed.
1118  */
1119 GSettingsBackend *
1120 g_settings_backend_get_with_context (const gchar *context)
1121 {
1122   GSettingsBackend *backend;
1123
1124   g_return_val_if_fail (context != NULL, NULL);
1125
1126   _g_io_modules_ensure_extension_points_registered ();
1127
1128   if (g_settings_backends == NULL)
1129     g_settings_backends = g_hash_table_new (g_str_hash, g_str_equal);
1130
1131   backend = g_hash_table_lookup (g_settings_backends, context);
1132
1133   if (!backend)
1134     {
1135       backend = get_default_backend (context);
1136
1137       if (!backend)
1138         backend = g_null_settings_backend_new ();
1139
1140       g_hash_table_insert (g_settings_backends, g_strdup (context), backend);
1141     }
1142
1143   return g_object_ref (backend);
1144 }
1145
1146 /*< private >
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
1151  *
1152  * Determines if the given context is supported by the default
1153  * GSettingsBackend implementation.
1154  */
1155 gboolean
1156 g_settings_backend_supports_context (const gchar *context)
1157 {
1158   GSettingsBackend *backend;
1159
1160   g_return_val_if_fail (context != NULL, FALSE);
1161
1162   backend = get_default_backend (context);
1163
1164   if (backend)
1165     {
1166       g_object_unref (backend);
1167       return TRUE;
1168     }
1169
1170   return FALSE;
1171 }
1172
1173 /*< private >
1174  * g_settings_backend_get_permission:
1175  * @backend: a #GSettingsBackend
1176  * @path: a path
1177  * @returns: a non-%NULL #GPermission
1178  *
1179  * Gets the permission object associated with writing to keys below
1180  * @path on @backend.
1181  *
1182  * If this is not implemented in the backend, then a %TRUE
1183  * #GSimplePermission is returned.
1184  */
1185 GPermission *
1186 g_settings_backend_get_permission (GSettingsBackend *backend,
1187                                    const gchar      *path)
1188 {
1189   GSettingsBackendClass *class = G_SETTINGS_BACKEND_GET_CLASS (backend);
1190
1191   if (class->get_permission)
1192     return class->get_permission (backend, path);
1193
1194   return g_simple_permission_new (TRUE);
1195 }
1196
1197 /**
1198  * g_settings_backend_setup:
1199  * @context: a context string (not %NULL or "")
1200  * @backend: a #GSettingsBackend
1201  *
1202  * Sets up @backend for use with #GSettings.
1203  *
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().
1207  *
1208  * The backend must be set up before any settings objects are created
1209  * for the named context.
1210  *
1211  * It is not possible to specify a backend for the default context.
1212  *
1213  * This function takes a reference on @backend and never releases it.
1214  *
1215  * Since: 2.26
1216  **/
1217 void
1218 g_settings_backend_setup (const gchar      *context,
1219                           GSettingsBackend *backend)
1220 {
1221   g_return_if_fail (context[0] != '\0');
1222   g_return_if_fail (G_IS_SETTINGS_BACKEND (backend));
1223
1224   if (g_settings_backends == NULL)
1225     g_settings_backends = g_hash_table_new (g_str_hash, g_str_equal);
1226
1227   if (g_hash_table_lookup (g_settings_backends, context))
1228     g_error ("A GSettingsBackend already exists for context '%s'", context);
1229
1230   g_hash_table_insert (g_settings_backends,
1231                        g_strdup (context),
1232                        g_object_ref (backend));
1233 }
1234
1235 /*< private >
1236  * g_settings_backend_sync:
1237  * @backend: a #GSettingsBackend
1238  *
1239  * Syncs the backend.
1240  */
1241 void
1242 g_settings_backend_sync (GSettingsBackend *backend)
1243 {
1244   GSettingsBackendClass *class = G_SETTINGS_BACKEND_GET_CLASS (backend);
1245
1246   if (class->sync)
1247     class->sync (backend);
1248 }
1249
1250 #define __G_SETTINGS_BACKEND_C__
1251 #include "gioaliasdef.c"