Merge remote branch 'gvdb/master'
[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 hint
736  * @returns: the value that was read, or %NULL
737  *
738  * Reads a key. This call will never block.
739  *
740  * If the key exists, the value associated with it will be returned.
741  * If the key does not exist, %NULL will be returned.
742  *
743  * If @expected_type is given, it serves as a type hint to the backend.
744  * If you expect a key of a certain type then you should give
745  * @expected_type to increase your chances of getting it.  Some backends
746  * may ignore this argument and return values of a different type; it is
747  * mostly used by backends that don't store strong type information.
748  */
749 GVariant *
750 g_settings_backend_read (GSettingsBackend   *backend,
751                          const gchar        *key,
752                          const GVariantType *expected_type,
753                          gboolean            default_value)
754 {
755   return G_SETTINGS_BACKEND_GET_CLASS (backend)
756     ->read (backend, key, expected_type, default_value);
757 }
758
759 /*< private >
760  * g_settings_backend_write:
761  * @backend: a #GSettingsBackend implementation
762  * @key: the name of the key
763  * @value: a #GVariant value to write to this key
764  * @origin_tag: the origin tag
765  * @returns: %TRUE if the write succeeded, %FALSE if the key was not writable
766  *
767  * Writes exactly one key.
768  *
769  * This call does not fail.  During this call a
770  * #GSettingsBackend::changed signal will be emitted if the value of the
771  * key has changed.  The updated key value will be visible to any signal
772  * callbacks.
773  *
774  * One possible method that an implementation might deal with failures is
775  * to emit a second "changed" signal (either during this call, or later)
776  * to indicate that the affected keys have suddenly "changed back" to their
777  * old values.
778  */
779 gboolean
780 g_settings_backend_write (GSettingsBackend *backend,
781                           const gchar      *key,
782                           GVariant         *value,
783                           gpointer          origin_tag)
784 {
785   return G_SETTINGS_BACKEND_GET_CLASS (backend)
786     ->write (backend, key, value, origin_tag);
787 }
788
789 /*< private >
790  * g_settings_backend_write_keys:
791  * @backend: a #GSettingsBackend implementation
792  * @values: a #GTree containing key-value pairs to write
793  * @origin_tag: the origin tag
794  *
795  * Writes one or more keys.  This call will never block.
796  *
797  * The key of each item in the tree is the key name to write to and the
798  * value is a #GVariant to write.  The proper type of #GTree for this
799  * call can be created with g_settings_backend_create_tree().  This call
800  * might take a reference to the tree; you must not modified the #GTree
801  * after passing it to this call.
802  *
803  * This call does not fail.  During this call a #GSettingsBackend::changed
804  * signal will be emitted if any keys have been changed.  The new values of
805  * all updated keys will be visible to any signal callbacks.
806  *
807  * One possible method that an implementation might deal with failures is
808  * to emit a second "changed" signal (either during this call, or later)
809  * to indicate that the affected keys have suddenly "changed back" to their
810  * old values.
811  */
812 gboolean
813 g_settings_backend_write_keys (GSettingsBackend *backend,
814                                GTree            *tree,
815                                gpointer          origin_tag)
816 {
817   return G_SETTINGS_BACKEND_GET_CLASS (backend)
818     ->write_keys (backend, tree, origin_tag);
819 }
820
821 /*< private >
822  * g_settings_backend_reset:
823  * @backend: a #GSettingsBackend implementation
824  * @key: the name of a key
825  * @origin_tag: the origin tag
826  *
827  * "Resets" the named key to its "default" value (ie: after system-wide
828  * defaults, mandatory keys, etc. have been taken into account) or possibly
829  * unsets it.
830  */
831 void
832 g_settings_backend_reset (GSettingsBackend *backend,
833                           const gchar      *key,
834                           gpointer          origin_tag)
835 {
836   G_SETTINGS_BACKEND_GET_CLASS (backend)
837     ->reset (backend, key, origin_tag);
838 }
839
840 /*< private >
841  * g_settings_backend_reset_path:
842  * @backend: a #GSettingsBackend implementation
843  * @name: the name of a key or path
844  * @origin_tag: the origin tag
845  *
846  * "Resets" the named path.  This means that every key under the path is
847  * reset.
848  */
849 void
850 g_settings_backend_reset_path (GSettingsBackend *backend,
851                                const gchar      *path,
852                                gpointer          origin_tag)
853 {
854   G_SETTINGS_BACKEND_GET_CLASS (backend)
855     ->reset_path (backend, path, 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  * @returns: %TRUE if the key is writable
863  *
864  * Finds out if a key is available for writing to.  This is the
865  * interface through which 'lockdown' is implemented.  Locked down
866  * keys will have %FALSE returned by this call.
867  *
868  * You should not write to locked-down keys, but if you do, the
869  * implementation will deal with it.
870  */
871 gboolean
872 g_settings_backend_get_writable (GSettingsBackend *backend,
873                                  const gchar      *key)
874 {
875   return G_SETTINGS_BACKEND_GET_CLASS (backend)
876     ->get_writable (backend, key);
877 }
878
879 /*< private >
880  * g_settings_backend_unsubscribe:
881  * @backend: a #GSettingsBackend
882  * @name: a key or path to subscribe to
883  *
884  * Reverses the effect of a previous call to
885  * g_settings_backend_subscribe().
886  */
887 void
888 g_settings_backend_unsubscribe (GSettingsBackend *backend,
889                                 const char       *name)
890 {
891   G_SETTINGS_BACKEND_GET_CLASS (backend)
892     ->unsubscribe (backend, name);
893 }
894
895 /*< private >
896  * g_settings_backend_subscribe:
897  * @backend: a #GSettingsBackend
898  * @name: a key or path to subscribe to
899  *
900  * Requests that change signals be emitted for events on @name.
901  */
902 void
903 g_settings_backend_subscribe (GSettingsBackend *backend,
904                               const gchar      *name)
905 {
906   G_SETTINGS_BACKEND_GET_CLASS (backend)
907     ->subscribe (backend, name);
908 }
909
910 static void
911 g_settings_backend_set_property (GObject         *object,
912                                  guint            prop_id,
913                                  const GValue    *value,
914                                  GParamSpec      *pspec)
915 {
916   GSettingsBackend *backend = G_SETTINGS_BACKEND (object);
917
918   switch (prop_id)
919     {
920     case PROP_CONTEXT:
921       backend->priv->context = g_value_dup_string (value);
922       break;
923
924     default:
925       G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
926       break;
927     }
928 }
929
930 static void
931 g_settings_backend_get_property (GObject    *object,
932                                  guint       prop_id,
933                                  GValue     *value,
934                                  GParamSpec *pspec)
935 {
936   GSettingsBackend *backend = G_SETTINGS_BACKEND (object);
937
938   switch (prop_id)
939     {
940     case PROP_CONTEXT:
941       g_value_set_string (value, backend->priv->context);
942       break;
943
944     default:
945       G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
946       break;
947     }
948 }
949
950 static void
951 g_settings_backend_finalize (GObject *object)
952 {
953   GSettingsBackend *backend = G_SETTINGS_BACKEND (object);
954
955   g_static_mutex_unlock (&backend->priv->lock);
956   g_free (backend->priv->context);
957
958   G_OBJECT_CLASS (g_settings_backend_parent_class)
959     ->finalize (object);
960 }
961
962 static void
963 ignore_subscription (GSettingsBackend *backend,
964                      const gchar      *key)
965 {
966 }
967
968 static void
969 g_settings_backend_init (GSettingsBackend *backend)
970 {
971   backend->priv = G_TYPE_INSTANCE_GET_PRIVATE (backend,
972                                                G_TYPE_SETTINGS_BACKEND,
973                                                GSettingsBackendPrivate);
974   g_static_mutex_init (&backend->priv->lock);
975 }
976
977 static void
978 g_settings_backend_class_init (GSettingsBackendClass *class)
979 {
980   GObjectClass *gobject_class = G_OBJECT_CLASS (class);
981
982   class->subscribe = ignore_subscription;
983   class->unsubscribe = ignore_subscription;
984
985   gobject_class->get_property = g_settings_backend_get_property;
986   gobject_class->set_property = g_settings_backend_set_property;
987   gobject_class->finalize = g_settings_backend_finalize;
988
989   g_type_class_add_private (class, sizeof (GSettingsBackendPrivate));
990
991   /**
992    * GSettingsBackend:context:
993    *
994    * The "context" property gives a hint to the backend as to
995    * what storage to use. It is up to the implementation to make
996    * use of this information.
997    *
998    * E.g. DConf supports "user", "system", "defaults" and "login"
999    * contexts.
1000    *
1001    * If your backend supports different contexts, you should also
1002    * provide an implementation of the supports_context() class
1003    * function in #GSettingsBackendClass.
1004    */
1005   g_object_class_install_property (gobject_class, PROP_CONTEXT,
1006     g_param_spec_string ("context", P_("Context"),
1007                          P_("An identifier to decide which storage to use"),
1008                          "", G_PARAM_READWRITE |
1009                          G_PARAM_CONSTRUCT_ONLY | G_PARAM_STATIC_STRINGS));
1010
1011 }
1012
1013 /*< private >
1014  * g_settings_backend_create_tree:
1015  * @returns: a new #GTree
1016  *
1017  * This is a convenience function for creating a tree that is compatible
1018  * with g_settings_backend_write().  It merely calls g_tree_new_full()
1019  * with strcmp(), g_free() and g_variant_unref().
1020  */
1021 GTree *
1022 g_settings_backend_create_tree (void)
1023 {
1024   return g_tree_new_full ((GCompareDataFunc) strcmp, NULL,
1025                           g_free, (GDestroyNotify) g_variant_unref);
1026 }
1027
1028
1029 static gpointer
1030 get_default_backend (const gchar *context)
1031 {
1032   GIOExtension *extension = NULL;
1033   GIOExtensionPoint *point;
1034   GList *extensions;
1035   const gchar *env;
1036   GType type;
1037
1038   _g_io_modules_ensure_loaded ();
1039
1040   point = g_io_extension_point_lookup (G_SETTINGS_BACKEND_EXTENSION_POINT_NAME);
1041
1042   if ((env = getenv ("GSETTINGS_BACKEND")))
1043     {
1044       extension = g_io_extension_point_get_extension_by_name (point, env);
1045
1046       if (extension == NULL)
1047         g_warning ("Can't find GSettings backend '%s' given in "
1048                    "GSETTINGS_BACKEND environment variable", env);
1049     }
1050
1051   if (extension == NULL)
1052     {
1053       extensions = g_io_extension_point_get_extensions (point);
1054
1055       if (extensions == NULL)
1056         g_error ("No GSettingsBackend implementations exist.");
1057
1058       extension = extensions->data;
1059     }
1060
1061   if (context[0] != '\0') /* (context != "") */
1062     {
1063       GSettingsBackendClass *backend_class;
1064       GTypeClass *class;
1065
1066       class = g_io_extension_ref_class (extension);
1067       backend_class = G_SETTINGS_BACKEND_CLASS (class);
1068
1069       if (backend_class->supports_context == NULL ||
1070           !backend_class->supports_context (context))
1071         {
1072           g_type_class_unref (class);
1073           return NULL;
1074         }
1075
1076       g_type_class_unref (class);
1077     }
1078
1079   type = g_io_extension_get_type (extension);
1080
1081   return g_object_new (type, "context", context, NULL);
1082 }
1083
1084 static GHashTable *g_settings_backends;
1085
1086 /*< private >
1087  * g_settings_backend_get_with_context:
1088  * @context: a context that might be used by the backend to determine
1089  *     which storage to use, or %NULL to use the default storage
1090  * @returns: the default #GSettingsBackend
1091  *
1092  * Returns the default #GSettingsBackend. It is possible to override
1093  * the default by setting the <envar>GSETTINGS_BACKEND</envar>
1094  * environment variable to the name of a settings backend.
1095  *
1096  * The @context parameter can be used to indicate that a different
1097  * than the default storage is desired. E.g. the DConf backend lets
1098  * you use "user", "system", "defaults" and "login" as contexts.
1099  *
1100  * If @context is not supported by the implementation, this function
1101  * returns an instance of the #GSettingsMemoryBackend.
1102  * See g_settings_backend_supports_context(),
1103  *
1104  * The user does not own the return value and it must not be freed.
1105  */
1106 GSettingsBackend *
1107 g_settings_backend_get_with_context (const gchar *context)
1108 {
1109   GSettingsBackend *backend;
1110
1111   g_return_val_if_fail (context != NULL, NULL);
1112
1113   _g_io_modules_ensure_extension_points_registered ();
1114
1115   if (g_settings_backends == NULL)
1116     g_settings_backends = g_hash_table_new (g_str_hash, g_str_equal);
1117
1118   backend = g_hash_table_lookup (g_settings_backends, context);
1119
1120   if (!backend)
1121     {
1122       backend = get_default_backend (context);
1123
1124       if (!backend)
1125         backend = g_null_settings_backend_new ();
1126
1127       g_hash_table_insert (g_settings_backends, g_strdup (context), backend);
1128     }
1129
1130   return g_object_ref (backend);
1131 }
1132
1133 /*< private >
1134  * g_settings_backend_supports_context:
1135  * @context: a context string that might be passed to
1136  *     g_settings_backend_new_with_context()
1137  * @returns: #TRUE if @context is supported
1138  *
1139  * Determines if the given context is supported by the default
1140  * GSettingsBackend implementation.
1141  */
1142 gboolean
1143 g_settings_backend_supports_context (const gchar *context)
1144 {
1145   GSettingsBackend *backend;
1146
1147   g_return_val_if_fail (context != NULL, FALSE);
1148
1149   backend = get_default_backend (context);
1150
1151   if (backend)
1152     {
1153       g_object_unref (backend);
1154       return TRUE;
1155     }
1156
1157   return FALSE;
1158 }
1159
1160 /*< private >
1161  * g_settings_backend_get_permission:
1162  * @backend: a #GSettingsBackend
1163  * @path: a path
1164  * @returns: a non-%NULL #GPermission
1165  *
1166  * Gets the permission object associated with writing to keys below
1167  * @path on @backend.
1168  *
1169  * If this is not implemented in the backend, then a %TRUE
1170  * #GSimplePermission is returned.
1171  */
1172 GPermission *
1173 g_settings_backend_get_permission (GSettingsBackend *backend,
1174                                    const gchar      *path)
1175 {
1176   GSettingsBackendClass *class = G_SETTINGS_BACKEND_GET_CLASS (backend);
1177
1178   if (class->get_permission)
1179     return class->get_permission (backend, path);
1180
1181   return g_simple_permission_new (TRUE);
1182 }
1183
1184 /**
1185  * g_settings_backend_setup:
1186  * @context: a context string (not %NULL or "")
1187  * @backend: a #GSettingsBackend
1188  *
1189  * Sets up @backend for use with #GSettings.
1190  *
1191  * If you create a #GSettings with its context property set to @context
1192  * then it will use the backend given to this function.  See
1193  * g_settings_new_with_context().
1194  *
1195  * The backend must be set up before any settings objects are created
1196  * for the named context.
1197  *
1198  * It is not possible to specify a backend for the default context.
1199  *
1200  * This function takes a reference on @backend and never releases it.
1201  *
1202  * Since: 2.26
1203  **/
1204 void
1205 g_settings_backend_setup (const gchar      *context,
1206                           GSettingsBackend *backend)
1207 {
1208   g_return_if_fail (context[0] != '\0');
1209   g_return_if_fail (G_IS_SETTINGS_BACKEND (backend));
1210
1211   if (g_settings_backends == NULL)
1212     g_settings_backends = g_hash_table_new (g_str_hash, g_str_equal);
1213
1214   if (g_hash_table_lookup (g_settings_backends, context))
1215     g_error ("A GSettingsBackend already exists for context '%s'", context);
1216
1217   g_hash_table_insert (g_settings_backends,
1218                        g_strdup (context),
1219                        g_object_ref (backend));
1220 }
1221
1222 #define __G_SETTINGS_BACKEND_C__
1223 #include "gioaliasdef.c"