• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright © 2009, 2010 Codethink Limited
3  *
4  * This library is free software; you can redistribute it and/or
5  * modify it under the terms of the GNU Lesser General Public
6  * License as published by the Free Software Foundation; either
7  * version 2.1 of the License, or (at your option) any later version.
8  *
9  * This library is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
12  * Lesser General Public License for more details.
13  *
14  * You should have received a copy of the GNU Lesser General Public
15  * License along with this library; if not, see <http://www.gnu.org/licenses/>.
16  *
17  * Author: Ryan Lortie <desrt@desrt.ca>
18  */
19 
20 /* Prelude {{{1 */
21 #include "config.h"
22 
23 #include <glib.h>
24 #include <glibintl.h>
25 
26 #include "gsettings.h"
27 
28 #include "gdelayedsettingsbackend.h"
29 #include "gsettingsbackendinternal.h"
30 #include "gsettings-mapping.h"
31 #include "gsettingsschema-internal.h"
32 #include "gaction.h"
33 #include "gmarshal-internal.h"
34 
35 #include "strinfo.c"
36 
37 /**
38  * SECTION:gsettings
39  * @short_description: High-level API for application settings
40  * @include: gio/gio.h
41  *
42  * The #GSettings class provides a convenient API for storing and retrieving
43  * application settings.
44  *
45  * Reads and writes can be considered to be non-blocking.  Reading
46  * settings with #GSettings is typically extremely fast: on
47  * approximately the same order of magnitude (but slower than) a
48  * #GHashTable lookup.  Writing settings is also extremely fast in terms
49  * of time to return to your application, but can be extremely expensive
50  * for other threads and other processes.  Many settings backends
51  * (including dconf) have lazy initialisation which means in the common
52  * case of the user using their computer without modifying any settings
53  * a lot of work can be avoided.  For dconf, the D-Bus service doesn't
54  * even need to be started in this case.  For this reason, you should
55  * only ever modify #GSettings keys in response to explicit user action.
56  * Particular care should be paid to ensure that modifications are not
57  * made during startup -- for example, when setting the initial value
58  * of preferences widgets.  The built-in g_settings_bind() functionality
59  * is careful not to write settings in response to notify signals as a
60  * result of modifications that it makes to widgets.
61  *
62  * When creating a GSettings instance, you have to specify a schema
63  * that describes the keys in your settings and their types and default
64  * values, as well as some other information.
65  *
66  * Normally, a schema has a fixed path that determines where the settings
67  * are stored in the conceptual global tree of settings. However, schemas
68  * can also be '[relocatable][gsettings-relocatable]', i.e. not equipped with
69  * a fixed path. This is
70  * useful e.g. when the schema describes an 'account', and you want to be
71  * able to store a arbitrary number of accounts.
72  *
73  * Paths must start with and end with a forward slash character ('/')
74  * and must not contain two sequential slash characters.  Paths should
75  * be chosen based on a domain name associated with the program or
76  * library to which the settings belong.  Examples of paths are
77  * "/org/gtk/settings/file-chooser/" and "/ca/desrt/dconf-editor/".
78  * Paths should not start with "/apps/", "/desktop/" or "/system/" as
79  * they often did in GConf.
80  *
81  * Unlike other configuration systems (like GConf), GSettings does not
82  * restrict keys to basic types like strings and numbers. GSettings stores
83  * values as #GVariant, and allows any #GVariantType for keys. Key names
84  * are restricted to lowercase characters, numbers and '-'. Furthermore,
85  * the names must begin with a lowercase character, must not end
86  * with a '-', and must not contain consecutive dashes.
87  *
88  * Similar to GConf, the default values in GSettings schemas can be
89  * localized, but the localized values are stored in gettext catalogs
90  * and looked up with the domain that is specified in the
91  * `gettext-domain` attribute of the <schemalist> or <schema>
92  * elements and the category that is specified in the `l10n` attribute of
93  * the <default> element. The string which is translated includes all text in
94  * the <default> element, including any surrounding quotation marks.
95  *
96  * The `l10n` attribute must be set to `messages` or `time`, and sets the
97  * [locale category for
98  * translation](https://www.gnu.org/software/gettext/manual/html_node/Aspects.html#index-locale-categories-1).
99  * The `messages` category should be used by default; use `time` for
100  * translatable date or time formats. A translation comment can be added as an
101  * XML comment immediately above the <default> element — it is recommended to
102  * add these comments to aid translators understand the meaning and
103  * implications of the default value. An optional translation `context`
104  * attribute can be set on the <default> element to disambiguate multiple
105  * defaults which use the same string.
106  *
107  * For example:
108  * |[
109  *  <!-- Translators: A list of words which are not allowed to be typed, in
110  *       GVariant serialization syntax.
111  *       See: https://developer.gnome.org/glib/stable/gvariant-text.html -->
112  *  <default l10n='messages' context='Banned words'>['bad', 'words']</default>
113  * ]|
114  *
115  * Translations of default values must remain syntactically valid serialized
116  * #GVariants (e.g. retaining any surrounding quotation marks) or runtime
117  * errors will occur.
118  *
119  * GSettings uses schemas in a compact binary form that is created
120  * by the [glib-compile-schemas][glib-compile-schemas]
121  * utility. The input is a schema description in an XML format.
122  *
123  * A DTD for the gschema XML format can be found here:
124  * [gschema.dtd](https://git.gnome.org/browse/glib/tree/gio/gschema.dtd)
125  *
126  * The [glib-compile-schemas][glib-compile-schemas] tool expects schema
127  * files to have the extension `.gschema.xml`.
128  *
129  * At runtime, schemas are identified by their id (as specified in the
130  * id attribute of the <schema> element). The convention for schema
131  * ids is to use a dotted name, similar in style to a D-Bus bus name,
132  * e.g. "org.gnome.SessionManager". In particular, if the settings are
133  * for a specific service that owns a D-Bus bus name, the D-Bus bus name
134  * and schema id should match. For schemas which deal with settings not
135  * associated with one named application, the id should not use
136  * StudlyCaps, e.g. "org.gnome.font-rendering".
137  *
138  * In addition to #GVariant types, keys can have types that have
139  * enumerated types. These can be described by a <choice>,
140  * <enum> or <flags> element, as seen in the
141  * [example][schema-enumerated]. The underlying type of such a key
142  * is string, but you can use g_settings_get_enum(), g_settings_set_enum(),
143  * g_settings_get_flags(), g_settings_set_flags() access the numeric values
144  * corresponding to the string value of enum and flags keys.
145  *
146  * An example for default value:
147  * |[
148  * <schemalist>
149  *   <schema id="org.gtk.Test" path="/org/gtk/Test/" gettext-domain="test">
150  *
151  *     <key name="greeting" type="s">
152  *       <default l10n="messages">"Hello, earthlings"</default>
153  *       <summary>A greeting</summary>
154  *       <description>
155  *         Greeting of the invading martians
156  *       </description>
157  *     </key>
158  *
159  *     <key name="box" type="(ii)">
160  *       <default>(20,30)</default>
161  *     </key>
162  *
163  *     <key name="empty-string" type="s">
164  *       <default>""</default>
165  *       <summary>Empty strings have to be provided in GVariant form</summary>
166  *     </key>
167  *
168  *   </schema>
169  * </schemalist>
170  * ]|
171  *
172  * An example for ranges, choices and enumerated types:
173  * |[
174  * <schemalist>
175  *
176  *   <enum id="org.gtk.Test.myenum">
177  *     <value nick="first" value="1"/>
178  *     <value nick="second" value="2"/>
179  *   </enum>
180  *
181  *   <flags id="org.gtk.Test.myflags">
182  *     <value nick="flag1" value="1"/>
183  *     <value nick="flag2" value="2"/>
184  *     <value nick="flag3" value="4"/>
185  *   </flags>
186  *
187  *   <schema id="org.gtk.Test">
188  *
189  *     <key name="key-with-range" type="i">
190  *       <range min="1" max="100"/>
191  *       <default>10</default>
192  *     </key>
193  *
194  *     <key name="key-with-choices" type="s">
195  *       <choices>
196  *         <choice value='Elisabeth'/>
197  *         <choice value='Annabeth'/>
198  *         <choice value='Joe'/>
199  *       </choices>
200  *       <aliases>
201  *         <alias value='Anna' target='Annabeth'/>
202  *         <alias value='Beth' target='Elisabeth'/>
203  *       </aliases>
204  *       <default>'Joe'</default>
205  *     </key>
206  *
207  *     <key name='enumerated-key' enum='org.gtk.Test.myenum'>
208  *       <default>'first'</default>
209  *     </key>
210  *
211  *     <key name='flags-key' flags='org.gtk.Test.myflags'>
212  *       <default>["flag1","flag2"]</default>
213  *     </key>
214  *   </schema>
215  * </schemalist>
216  * ]|
217  *
218  * ## Vendor overrides
219  *
220  * Default values are defined in the schemas that get installed by
221  * an application. Sometimes, it is necessary for a vendor or distributor
222  * to adjust these defaults. Since patching the XML source for the schema
223  * is inconvenient and error-prone,
224  * [glib-compile-schemas][glib-compile-schemas] reads so-called vendor
225  * override' files. These are keyfiles in the same directory as the XML
226  * schema sources which can override default values. The schema id serves
227  * as the group name in the key file, and the values are expected in
228  * serialized GVariant form, as in the following example:
229  * |[
230  *     [org.gtk.Example]
231  *     key1='string'
232  *     key2=1.5
233  * ]|
234  *
235  * glib-compile-schemas expects schema files to have the extension
236  * `.gschema.override`.
237  *
238  * ## Binding
239  *
240  * A very convenient feature of GSettings lets you bind #GObject properties
241  * directly to settings, using g_settings_bind(). Once a GObject property
242  * has been bound to a setting, changes on either side are automatically
243  * propagated to the other side. GSettings handles details like mapping
244  * between GObject and GVariant types, and preventing infinite cycles.
245  *
246  * This makes it very easy to hook up a preferences dialog to the
247  * underlying settings. To make this even more convenient, GSettings
248  * looks for a boolean property with the name "sensitivity" and
249  * automatically binds it to the writability of the bound setting.
250  * If this 'magic' gets in the way, it can be suppressed with the
251  * #G_SETTINGS_BIND_NO_SENSITIVITY flag.
252  *
253  * ## Relocatable schemas # {#gsettings-relocatable}
254  *
255  * A relocatable schema is one with no `path` attribute specified on its
256  * <schema> element. By using g_settings_new_with_path(), a #GSettings object
257  * can be instantiated for a relocatable schema, assigning a path to the
258  * instance. Paths passed to g_settings_new_with_path() will typically be
259  * constructed dynamically from a constant prefix plus some form of instance
260  * identifier; but they must still be valid GSettings paths. Paths could also
261  * be constant and used with a globally installed schema originating from a
262  * dependency library.
263  *
264  * For example, a relocatable schema could be used to store geometry information
265  * for different windows in an application. If the schema ID was
266  * `org.foo.MyApp.Window`, it could be instantiated for paths
267  * `/org/foo/MyApp/main/`, `/org/foo/MyApp/document-1/`,
268  * `/org/foo/MyApp/document-2/`, etc. If any of the paths are well-known
269  * they can be specified as <child> elements in the parent schema, e.g.:
270  * |[
271  * <schema id="org.foo.MyApp" path="/org/foo/MyApp/">
272  *   <child name="main" schema="org.foo.MyApp.Window"/>
273  * </schema>
274  * ]|
275  *
276  * ## Build system integration # {#gsettings-build-system}
277  *
278  * GSettings comes with autotools integration to simplify compiling and
279  * installing schemas. To add GSettings support to an application, add the
280  * following to your `configure.ac`:
281  * |[
282  * GLIB_GSETTINGS
283  * ]|
284  *
285  * In the appropriate `Makefile.am`, use the following snippet to compile and
286  * install the named schema:
287  * |[
288  * gsettings_SCHEMAS = org.foo.MyApp.gschema.xml
289  * EXTRA_DIST = $(gsettings_SCHEMAS)
290  *
291  * @GSETTINGS_RULES@
292  * ]|
293  *
294  * No changes are needed to the build system to mark a schema XML file for
295  * translation. Assuming it sets the `gettext-domain` attribute, a schema may
296  * be marked for translation by adding it to `POTFILES.in`, assuming gettext
297  * 0.19 is in use (the preferred method for translation):
298  * |[
299  * data/org.foo.MyApp.gschema.xml
300  * ]|
301  *
302  * Alternatively, if intltool 0.50.1 is in use:
303  * |[
304  * [type: gettext/gsettings]data/org.foo.MyApp.gschema.xml
305  * ]|
306  *
307  * GSettings will use gettext to look up translations for the <summary> and
308  * <description> elements, and also any <default> elements which have a `l10n`
309  * attribute set. Translations must not be included in the `.gschema.xml` file
310  * by the build system, for example by using intltool XML rules with a
311  * `.gschema.xml.in` template.
312  *
313  * If an enumerated type defined in a C header file is to be used in a GSettings
314  * schema, it can either be defined manually using an <enum> element in the
315  * schema XML, or it can be extracted automatically from the C header. This
316  * approach is preferred, as it ensures the two representations are always
317  * synchronised. To do so, add the following to the relevant `Makefile.am`:
318  * |[
319  * gsettings_ENUM_NAMESPACE = org.foo.MyApp
320  * gsettings_ENUM_FILES = my-app-enums.h my-app-misc.h
321  * ]|
322  *
323  * `gsettings_ENUM_NAMESPACE` specifies the schema namespace for the enum files,
324  * which are specified in `gsettings_ENUM_FILES`. This will generate a
325  * `org.foo.MyApp.enums.xml` file containing the extracted enums, which will be
326  * automatically included in the schema compilation, install and uninstall
327  * rules. It should not be committed to version control or included in
328  * `EXTRA_DIST`.
329  */
330 
331 /**
332  * GSettings:
333  *
334  * #GSettings is an opaque data structure and can only be accessed
335  * using the following functions.
336  **/
337 
338 struct _GSettingsPrivate
339 {
340   /* where the signals go... */
341   GMainContext *main_context;
342 
343   GSettingsBackend *backend;
344   GSettingsSchema *schema;
345   gchar *path;
346 
347   GDelayedSettingsBackend *delayed;
348 };
349 
350 enum
351 {
352   PROP_0,
353   PROP_SCHEMA,
354   PROP_SCHEMA_ID,
355   PROP_BACKEND,
356   PROP_PATH,
357   PROP_HAS_UNAPPLIED,
358   PROP_DELAY_APPLY
359 };
360 
361 enum
362 {
363   SIGNAL_WRITABLE_CHANGE_EVENT,
364   SIGNAL_WRITABLE_CHANGED,
365   SIGNAL_CHANGE_EVENT,
366   SIGNAL_CHANGED,
367   N_SIGNALS
368 };
369 
370 static guint g_settings_signals[N_SIGNALS];
371 
G_DEFINE_TYPE_WITH_PRIVATE(GSettings,g_settings,G_TYPE_OBJECT)372 G_DEFINE_TYPE_WITH_PRIVATE (GSettings, g_settings, G_TYPE_OBJECT)
373 
374 /* Signals {{{1 */
375 static gboolean
376 g_settings_real_change_event (GSettings    *settings,
377                               const GQuark *keys,
378                               gint          n_keys)
379 {
380   gint i;
381 
382   if (keys == NULL)
383     keys = g_settings_schema_list (settings->priv->schema, &n_keys);
384 
385   for (i = 0; i < n_keys; i++)
386     {
387       const gchar *key = g_quark_to_string (keys[i]);
388 
389       if (g_str_has_suffix (key, "/"))
390         continue;
391 
392       g_signal_emit (settings, g_settings_signals[SIGNAL_CHANGED], keys[i], key);
393     }
394 
395   return FALSE;
396 }
397 
398 static gboolean
g_settings_real_writable_change_event(GSettings * settings,GQuark key)399 g_settings_real_writable_change_event (GSettings *settings,
400                                        GQuark     key)
401 {
402   const GQuark *keys = &key;
403   gint n_keys = 1;
404   gint i;
405 
406   if (key == 0)
407     keys = g_settings_schema_list (settings->priv->schema, &n_keys);
408 
409   for (i = 0; i < n_keys; i++)
410     {
411       const gchar *key = g_quark_to_string (keys[i]);
412 
413       if (g_str_has_suffix (key, "/"))
414         continue;
415 
416       g_signal_emit (settings, g_settings_signals[SIGNAL_WRITABLE_CHANGED], keys[i], key);
417     }
418 
419   return FALSE;
420 }
421 
422 static void
settings_backend_changed(GObject * target,GSettingsBackend * backend,const gchar * key,gpointer origin_tag)423 settings_backend_changed (GObject             *target,
424                           GSettingsBackend    *backend,
425                           const gchar         *key,
426                           gpointer             origin_tag)
427 {
428   GSettings *settings = G_SETTINGS (target);
429   gboolean ignore_this;
430   gint i;
431 
432   /* We used to assert here:
433    *
434    *   settings->priv->backend == backend
435    *
436    * but it could be the case that a notification is queued for delivery
437    * while someone calls g_settings_delay() (which changes the backend).
438    *
439    * Since the delay backend would just pass that straight through
440    * anyway, it doesn't make sense to try to detect this case.
441    * Therefore, we just accept it.
442    */
443 
444   for (i = 0; key[i] == settings->priv->path[i]; i++);
445 
446   if (settings->priv->path[i] == '\0' &&
447       g_settings_schema_has_key (settings->priv->schema, key + i))
448     {
449       GQuark quark;
450 
451       quark = g_quark_from_string (key + i);
452       g_signal_emit (settings, g_settings_signals[SIGNAL_CHANGE_EVENT],
453                      0, &quark, 1, &ignore_this);
454     }
455 }
456 
457 static void
settings_backend_path_changed(GObject * target,GSettingsBackend * backend,const gchar * path,gpointer origin_tag)458 settings_backend_path_changed (GObject          *target,
459                                GSettingsBackend *backend,
460                                const gchar      *path,
461                                gpointer          origin_tag)
462 {
463   GSettings *settings = G_SETTINGS (target);
464   gboolean ignore_this;
465 
466   if (g_str_has_prefix (settings->priv->path, path))
467     g_signal_emit (settings, g_settings_signals[SIGNAL_CHANGE_EVENT],
468                    0, NULL, 0, &ignore_this);
469 }
470 
471 static void
settings_backend_keys_changed(GObject * target,GSettingsBackend * backend,const gchar * path,gpointer origin_tag,const gchar * const * items)472 settings_backend_keys_changed (GObject             *target,
473                                GSettingsBackend    *backend,
474                                const gchar         *path,
475                                gpointer             origin_tag,
476                                const gchar * const *items)
477 {
478   GSettings *settings = G_SETTINGS (target);
479   gboolean ignore_this;
480   gint i;
481 
482   for (i = 0; settings->priv->path[i] &&
483               settings->priv->path[i] == path[i]; i++);
484 
485   if (path[i] == '\0')
486     {
487       GQuark quarks[256];
488       gint j, l = 0;
489 
490       for (j = 0; items[j]; j++)
491          {
492            const gchar *item = items[j];
493            gint k;
494 
495            for (k = 0; item[k] == settings->priv->path[i + k]; k++);
496 
497            if (settings->priv->path[i + k] == '\0' &&
498                g_settings_schema_has_key (settings->priv->schema, item + k))
499              quarks[l++] = g_quark_from_string (item + k);
500 
501            /* "256 quarks ought to be enough for anybody!"
502             * If this bites you, I'm sorry.  Please file a bug.
503             */
504            g_assert (l < 256);
505          }
506 
507       if (l > 0)
508         g_signal_emit (settings, g_settings_signals[SIGNAL_CHANGE_EVENT],
509                        0, quarks, l, &ignore_this);
510     }
511 }
512 
513 static void
settings_backend_writable_changed(GObject * target,GSettingsBackend * backend,const gchar * key)514 settings_backend_writable_changed (GObject          *target,
515                                    GSettingsBackend *backend,
516                                    const gchar      *key)
517 {
518   GSettings *settings = G_SETTINGS (target);
519   gboolean ignore_this;
520   gint i;
521 
522   for (i = 0; key[i] == settings->priv->path[i]; i++);
523 
524   if (settings->priv->path[i] == '\0' &&
525       g_settings_schema_has_key (settings->priv->schema, key + i))
526     g_signal_emit (settings, g_settings_signals[SIGNAL_WRITABLE_CHANGE_EVENT],
527                    0, g_quark_from_string (key + i), &ignore_this);
528 }
529 
530 static void
settings_backend_path_writable_changed(GObject * target,GSettingsBackend * backend,const gchar * path)531 settings_backend_path_writable_changed (GObject          *target,
532                                         GSettingsBackend *backend,
533                                         const gchar      *path)
534 {
535   GSettings *settings = G_SETTINGS (target);
536   gboolean ignore_this;
537 
538   if (g_str_has_prefix (settings->priv->path, path))
539     g_signal_emit (settings, g_settings_signals[SIGNAL_WRITABLE_CHANGE_EVENT],
540                    0, (GQuark) 0, &ignore_this);
541 }
542 
543 /* Properties, Construction, Destruction {{{1 */
544 static void
g_settings_set_property(GObject * object,guint prop_id,const GValue * value,GParamSpec * pspec)545 g_settings_set_property (GObject      *object,
546                          guint         prop_id,
547                          const GValue *value,
548                          GParamSpec   *pspec)
549 {
550   GSettings *settings = G_SETTINGS (object);
551 
552   switch (prop_id)
553     {
554     case PROP_SCHEMA:
555       {
556         GSettingsSchema *schema;
557 
558         schema = g_value_dup_boxed (value);
559 
560         /* we receive a set_property() call for "settings-schema" even
561          * if it was not specified (ie: with NULL value).  ->schema
562          * could already be set at this point (ie: via "schema-id").
563          * check for NULL to avoid clobbering the existing value.
564          */
565         if (schema != NULL)
566           {
567             g_assert (settings->priv->schema == NULL);
568             settings->priv->schema = schema;
569           }
570       }
571       break;
572 
573     case PROP_SCHEMA_ID:
574       {
575         const gchar *schema_id;
576 
577         schema_id = g_value_get_string (value);
578 
579         /* we receive a set_property() call for both "schema" and
580          * "schema-id", even if they are not set.  Hopefully only one of
581          * them is non-NULL.
582          */
583         if (schema_id != NULL)
584           {
585             GSettingsSchemaSource *default_source;
586 
587             g_assert (settings->priv->schema == NULL);
588             default_source = g_settings_schema_source_get_default ();
589 
590             if (default_source == NULL)
591               g_error ("No GSettings schemas are installed on the system");
592 
593             settings->priv->schema = g_settings_schema_source_lookup (default_source, schema_id, TRUE);
594 
595             if (settings->priv->schema == NULL)
596               g_error ("Settings schema '%s' is not installed", schema_id);
597           }
598       }
599       break;
600 
601     case PROP_PATH:
602       settings->priv->path = g_value_dup_string (value);
603       break;
604 
605     case PROP_BACKEND:
606       settings->priv->backend = g_value_dup_object (value);
607       break;
608 
609     default:
610       g_assert_not_reached ();
611     }
612 }
613 
614 static void
g_settings_get_property(GObject * object,guint prop_id,GValue * value,GParamSpec * pspec)615 g_settings_get_property (GObject    *object,
616                          guint       prop_id,
617                          GValue     *value,
618                          GParamSpec *pspec)
619 {
620   GSettings *settings = G_SETTINGS (object);
621 
622   switch (prop_id)
623     {
624     case PROP_SCHEMA:
625       g_value_set_boxed (value, settings->priv->schema);
626       break;
627 
628      case PROP_SCHEMA_ID:
629       g_value_set_string (value, g_settings_schema_get_id (settings->priv->schema));
630       break;
631 
632      case PROP_BACKEND:
633       g_value_set_object (value, settings->priv->backend);
634       break;
635 
636      case PROP_PATH:
637       g_value_set_string (value, settings->priv->path);
638       break;
639 
640      case PROP_HAS_UNAPPLIED:
641       g_value_set_boolean (value, g_settings_get_has_unapplied (settings));
642       break;
643 
644      case PROP_DELAY_APPLY:
645       g_value_set_boolean (value, settings->priv->delayed != NULL);
646       break;
647 
648      default:
649       g_assert_not_reached ();
650     }
651 }
652 
653 static const GSettingsListenerVTable listener_vtable = {
654   settings_backend_changed,
655   settings_backend_path_changed,
656   settings_backend_keys_changed,
657   settings_backend_writable_changed,
658   settings_backend_path_writable_changed
659 };
660 
661 static void
g_settings_constructed(GObject * object)662 g_settings_constructed (GObject *object)
663 {
664   GSettings *settings = G_SETTINGS (object);
665   const gchar *schema_path;
666 
667   schema_path = g_settings_schema_get_path (settings->priv->schema);
668 
669   if (settings->priv->path && schema_path && strcmp (settings->priv->path, schema_path) != 0)
670     g_error ("settings object created with schema '%s' and path '%s', but path '%s' is specified by schema",
671              g_settings_schema_get_id (settings->priv->schema), settings->priv->path, schema_path);
672 
673   if (settings->priv->path == NULL)
674     {
675       if (schema_path == NULL)
676         g_error ("attempting to create schema '%s' without a path",
677                  g_settings_schema_get_id (settings->priv->schema));
678 
679       settings->priv->path = g_strdup (schema_path);
680     }
681 
682   if (settings->priv->backend == NULL)
683     settings->priv->backend = g_settings_backend_get_default ();
684 
685   g_settings_backend_watch (settings->priv->backend,
686                             &listener_vtable, G_OBJECT (settings),
687                             settings->priv->main_context);
688   g_settings_backend_subscribe (settings->priv->backend,
689                                 settings->priv->path);
690 }
691 
692 static void
g_settings_finalize(GObject * object)693 g_settings_finalize (GObject *object)
694 {
695   GSettings *settings = G_SETTINGS (object);
696 
697   g_settings_backend_unsubscribe (settings->priv->backend,
698                                   settings->priv->path);
699   g_main_context_unref (settings->priv->main_context);
700   g_object_unref (settings->priv->backend);
701   g_settings_schema_unref (settings->priv->schema);
702   g_free (settings->priv->path);
703 
704   G_OBJECT_CLASS (g_settings_parent_class)->finalize (object);
705 }
706 
707 static void
g_settings_init(GSettings * settings)708 g_settings_init (GSettings *settings)
709 {
710   settings->priv = g_settings_get_instance_private (settings);
711   settings->priv->main_context = g_main_context_ref_thread_default ();
712 }
713 
714 static void
g_settings_class_init(GSettingsClass * class)715 g_settings_class_init (GSettingsClass *class)
716 {
717   GObjectClass *object_class = G_OBJECT_CLASS (class);
718 
719   class->writable_change_event = g_settings_real_writable_change_event;
720   class->change_event = g_settings_real_change_event;
721 
722   object_class->set_property = g_settings_set_property;
723   object_class->get_property = g_settings_get_property;
724   object_class->constructed = g_settings_constructed;
725   object_class->finalize = g_settings_finalize;
726 
727   /**
728    * GSettings::changed:
729    * @settings: the object on which the signal was emitted
730    * @key: the name of the key that changed
731    *
732    * The "changed" signal is emitted when a key has potentially changed.
733    * You should call one of the g_settings_get() calls to check the new
734    * value.
735    *
736    * This signal supports detailed connections.  You can connect to the
737    * detailed signal "changed::x" in order to only receive callbacks
738    * when key "x" changes.
739    *
740    * Note that @settings only emits this signal if you have read @key at
741    * least once while a signal handler was already connected for @key.
742    */
743   g_settings_signals[SIGNAL_CHANGED] =
744     g_signal_new (I_("changed"), G_TYPE_SETTINGS,
745                   G_SIGNAL_RUN_LAST | G_SIGNAL_DETAILED,
746                   G_STRUCT_OFFSET (GSettingsClass, changed),
747                   NULL, NULL, NULL, G_TYPE_NONE,
748                   1, G_TYPE_STRING | G_SIGNAL_TYPE_STATIC_SCOPE);
749 
750   /**
751    * GSettings::change-event:
752    * @settings: the object on which the signal was emitted
753    * @keys: (array length=n_keys) (element-type GQuark) (nullable):
754    *        an array of #GQuarks for the changed keys, or %NULL
755    * @n_keys: the length of the @keys array, or 0
756    *
757    * The "change-event" signal is emitted once per change event that
758    * affects this settings object.  You should connect to this signal
759    * only if you are interested in viewing groups of changes before they
760    * are split out into multiple emissions of the "changed" signal.
761    * For most use cases it is more appropriate to use the "changed" signal.
762    *
763    * In the event that the change event applies to one or more specified
764    * keys, @keys will be an array of #GQuark of length @n_keys.  In the
765    * event that the change event applies to the #GSettings object as a
766    * whole (ie: potentially every key has been changed) then @keys will
767    * be %NULL and @n_keys will be 0.
768    *
769    * The default handler for this signal invokes the "changed" signal
770    * for each affected key.  If any other connected handler returns
771    * %TRUE then this default functionality will be suppressed.
772    *
773    * Returns: %TRUE to stop other handlers from being invoked for the
774    *          event. FALSE to propagate the event further.
775    */
776   g_settings_signals[SIGNAL_CHANGE_EVENT] =
777     g_signal_new (I_("change-event"), G_TYPE_SETTINGS,
778                   G_SIGNAL_RUN_LAST,
779                   G_STRUCT_OFFSET (GSettingsClass, change_event),
780                   g_signal_accumulator_true_handled, NULL,
781                   _g_cclosure_marshal_BOOLEAN__POINTER_INT,
782                   G_TYPE_BOOLEAN, 2, G_TYPE_POINTER, G_TYPE_INT);
783   g_signal_set_va_marshaller (g_settings_signals[SIGNAL_CHANGE_EVENT],
784                               G_TYPE_FROM_CLASS (class),
785                               _g_cclosure_marshal_BOOLEAN__POINTER_INTv);
786 
787   /**
788    * GSettings::writable-changed:
789    * @settings: the object on which the signal was emitted
790    * @key: the key
791    *
792    * The "writable-changed" signal is emitted when the writability of a
793    * key has potentially changed.  You should call
794    * g_settings_is_writable() in order to determine the new status.
795    *
796    * This signal supports detailed connections.  You can connect to the
797    * detailed signal "writable-changed::x" in order to only receive
798    * callbacks when the writability of "x" changes.
799    */
800   g_settings_signals[SIGNAL_WRITABLE_CHANGED] =
801     g_signal_new (I_("writable-changed"), G_TYPE_SETTINGS,
802                   G_SIGNAL_RUN_LAST | G_SIGNAL_DETAILED,
803                   G_STRUCT_OFFSET (GSettingsClass, writable_changed),
804                   NULL, NULL, NULL, G_TYPE_NONE,
805                   1, G_TYPE_STRING | G_SIGNAL_TYPE_STATIC_SCOPE);
806 
807   /**
808    * GSettings::writable-change-event:
809    * @settings: the object on which the signal was emitted
810    * @key: the quark of the key, or 0
811    *
812    * The "writable-change-event" signal is emitted once per writability
813    * change event that affects this settings object.  You should connect
814    * to this signal if you are interested in viewing groups of changes
815    * before they are split out into multiple emissions of the
816    * "writable-changed" signal.  For most use cases it is more
817    * appropriate to use the "writable-changed" signal.
818    *
819    * In the event that the writability change applies only to a single
820    * key, @key will be set to the #GQuark for that key.  In the event
821    * that the writability change affects the entire settings object,
822    * @key will be 0.
823    *
824    * The default handler for this signal invokes the "writable-changed"
825    * and "changed" signals for each affected key.  This is done because
826    * changes in writability might also imply changes in value (if for
827    * example, a new mandatory setting is introduced).  If any other
828    * connected handler returns %TRUE then this default functionality
829    * will be suppressed.
830    *
831    * Returns: %TRUE to stop other handlers from being invoked for the
832    *          event. FALSE to propagate the event further.
833    */
834   g_settings_signals[SIGNAL_WRITABLE_CHANGE_EVENT] =
835     g_signal_new (I_("writable-change-event"), G_TYPE_SETTINGS,
836                   G_SIGNAL_RUN_LAST,
837                   G_STRUCT_OFFSET (GSettingsClass, writable_change_event),
838                   g_signal_accumulator_true_handled, NULL,
839                   _g_cclosure_marshal_BOOLEAN__UINT,
840                   G_TYPE_BOOLEAN, 1, G_TYPE_UINT);
841   g_signal_set_va_marshaller (g_settings_signals[SIGNAL_WRITABLE_CHANGE_EVENT],
842                               G_TYPE_FROM_CLASS (class),
843                               _g_cclosure_marshal_BOOLEAN__UINTv);
844 
845   /**
846    * GSettings:backend:
847    *
848    * The name of the context that the settings are stored in.
849    */
850   g_object_class_install_property (object_class, PROP_BACKEND,
851     g_param_spec_object ("backend",
852                          P_("GSettingsBackend"),
853                          P_("The GSettingsBackend for this settings object"),
854                          G_TYPE_SETTINGS_BACKEND, G_PARAM_CONSTRUCT_ONLY |
855                          G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
856 
857   /**
858    * GSettings:settings-schema:
859    *
860    * The #GSettingsSchema describing the types of keys for this
861    * #GSettings object.
862    *
863    * Ideally, this property would be called 'schema'.  #GSettingsSchema
864    * has only existed since version 2.32, however, and before then the
865    * 'schema' property was used to refer to the ID of the schema rather
866    * than the schema itself.  Take care.
867    */
868   g_object_class_install_property (object_class, PROP_SCHEMA,
869     g_param_spec_boxed ("settings-schema",
870                         P_("schema"),
871                         P_("The GSettingsSchema for this settings object"),
872                         G_TYPE_SETTINGS_SCHEMA,
873                         G_PARAM_CONSTRUCT_ONLY |
874                         G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
875 
876   /**
877    * GSettings:schema:
878    *
879    * The name of the schema that describes the types of keys
880    * for this #GSettings object.
881    *
882    * The type of this property is *not* #GSettingsSchema.
883    * #GSettingsSchema has only existed since version 2.32 and
884    * unfortunately this name was used in previous versions to refer to
885    * the schema ID rather than the schema itself.  Take care to use the
886    * 'settings-schema' property if you wish to pass in a
887    * #GSettingsSchema.
888    *
889    * Deprecated:2.32:Use the 'schema-id' property instead.  In a future
890    * version, this property may instead refer to a #GSettingsSchema.
891    */
892   g_object_class_install_property (object_class, PROP_SCHEMA_ID,
893     g_param_spec_string ("schema",
894                          P_("Schema name"),
895                          P_("The name of the schema for this settings object"),
896                          NULL,
897                          G_PARAM_CONSTRUCT_ONLY |
898                          G_PARAM_DEPRECATED | G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
899 
900   /**
901    * GSettings:schema-id:
902    *
903    * The name of the schema that describes the types of keys
904    * for this #GSettings object.
905    */
906   g_object_class_install_property (object_class, PROP_SCHEMA_ID,
907     g_param_spec_string ("schema-id",
908                          P_("Schema name"),
909                          P_("The name of the schema for this settings object"),
910                          NULL,
911                          G_PARAM_CONSTRUCT_ONLY |
912                          G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
913 
914    /**
915     * GSettings:path:
916     *
917     * The path within the backend where the settings are stored.
918     */
919    g_object_class_install_property (object_class, PROP_PATH,
920      g_param_spec_string ("path",
921                           P_("Base path"),
922                           P_("The path within the backend where the settings are"),
923                           NULL,
924                           G_PARAM_CONSTRUCT_ONLY |
925                           G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
926 
927    /**
928     * GSettings:has-unapplied:
929     *
930     * If this property is %TRUE, the #GSettings object has outstanding
931     * changes that will be applied when g_settings_apply() is called.
932     */
933    g_object_class_install_property (object_class, PROP_HAS_UNAPPLIED,
934      g_param_spec_boolean ("has-unapplied",
935                            P_("Has unapplied changes"),
936                            P_("TRUE if there are outstanding changes to apply()"),
937                            FALSE,
938                            G_PARAM_READABLE | G_PARAM_STATIC_STRINGS));
939 
940    /**
941     * GSettings:delay-apply:
942     *
943     * Whether the #GSettings object is in 'delay-apply' mode. See
944     * g_settings_delay() for details.
945     *
946     * Since: 2.28
947     */
948    g_object_class_install_property (object_class, PROP_DELAY_APPLY,
949      g_param_spec_boolean ("delay-apply",
950                            P_("Delay-apply mode"),
951                            P_("Whether this settings object is in “delay-apply” mode"),
952                            FALSE,
953                            G_PARAM_READABLE | G_PARAM_STATIC_STRINGS));
954 }
955 
956 /* Construction (new, new_with_path, etc.) {{{1 */
957 /**
958  * g_settings_new:
959  * @schema_id: the id of the schema
960  *
961  * Creates a new #GSettings object with the schema specified by
962  * @schema_id.
963  *
964  * Signals on the newly created #GSettings object will be dispatched
965  * via the thread-default #GMainContext in effect at the time of the
966  * call to g_settings_new().  The new #GSettings will hold a reference
967  * on the context.  See g_main_context_push_thread_default().
968  *
969  * Returns: a new #GSettings object
970  *
971  * Since: 2.26
972  */
973 GSettings *
g_settings_new(const gchar * schema_id)974 g_settings_new (const gchar *schema_id)
975 {
976   g_return_val_if_fail (schema_id != NULL, NULL);
977 
978   return g_object_new (G_TYPE_SETTINGS,
979                        "schema-id", schema_id,
980                        NULL);
981 }
982 
983 static gboolean
path_is_valid(const gchar * path)984 path_is_valid (const gchar *path)
985 {
986   if (!path)
987     return FALSE;
988 
989   if (path[0] != '/')
990     return FALSE;
991 
992   if (!g_str_has_suffix (path, "/"))
993     return FALSE;
994 
995   return strstr (path, "//") == NULL;
996 }
997 
998 /**
999  * g_settings_new_with_path:
1000  * @schema_id: the id of the schema
1001  * @path: the path to use
1002  *
1003  * Creates a new #GSettings object with the relocatable schema specified
1004  * by @schema_id and a given path.
1005  *
1006  * You only need to do this if you want to directly create a settings
1007  * object with a schema that doesn't have a specified path of its own.
1008  * That's quite rare.
1009  *
1010  * It is a programmer error to call this function for a schema that
1011  * has an explicitly specified path.
1012  *
1013  * It is a programmer error if @path is not a valid path.  A valid path
1014  * begins and ends with '/' and does not contain two consecutive '/'
1015  * characters.
1016  *
1017  * Returns: a new #GSettings object
1018  *
1019  * Since: 2.26
1020  */
1021 GSettings *
g_settings_new_with_path(const gchar * schema_id,const gchar * path)1022 g_settings_new_with_path (const gchar *schema_id,
1023                           const gchar *path)
1024 {
1025   g_return_val_if_fail (schema_id != NULL, NULL);
1026   g_return_val_if_fail (path_is_valid (path), NULL);
1027 
1028   return g_object_new (G_TYPE_SETTINGS,
1029                        "schema-id", schema_id,
1030                        "path", path,
1031                        NULL);
1032 }
1033 
1034 /**
1035  * g_settings_new_with_backend:
1036  * @schema_id: the id of the schema
1037  * @backend: the #GSettingsBackend to use
1038  *
1039  * Creates a new #GSettings object with the schema specified by
1040  * @schema_id and a given #GSettingsBackend.
1041  *
1042  * Creating a #GSettings object with a different backend allows accessing
1043  * settings from a database other than the usual one. For example, it may make
1044  * sense to pass a backend corresponding to the "defaults" settings database on
1045  * the system to get a settings object that modifies the system default
1046  * settings instead of the settings for this user.
1047  *
1048  * Returns: a new #GSettings object
1049  *
1050  * Since: 2.26
1051  */
1052 GSettings *
g_settings_new_with_backend(const gchar * schema_id,GSettingsBackend * backend)1053 g_settings_new_with_backend (const gchar      *schema_id,
1054                              GSettingsBackend *backend)
1055 {
1056   g_return_val_if_fail (schema_id != NULL, NULL);
1057   g_return_val_if_fail (G_IS_SETTINGS_BACKEND (backend), NULL);
1058 
1059   return g_object_new (G_TYPE_SETTINGS,
1060                        "schema-id", schema_id,
1061                        "backend", backend,
1062                        NULL);
1063 }
1064 
1065 /**
1066  * g_settings_new_with_backend_and_path:
1067  * @schema_id: the id of the schema
1068  * @backend: the #GSettingsBackend to use
1069  * @path: the path to use
1070  *
1071  * Creates a new #GSettings object with the schema specified by
1072  * @schema_id and a given #GSettingsBackend and path.
1073  *
1074  * This is a mix of g_settings_new_with_backend() and
1075  * g_settings_new_with_path().
1076  *
1077  * Returns: a new #GSettings object
1078  *
1079  * Since: 2.26
1080  */
1081 GSettings *
g_settings_new_with_backend_and_path(const gchar * schema_id,GSettingsBackend * backend,const gchar * path)1082 g_settings_new_with_backend_and_path (const gchar      *schema_id,
1083                                       GSettingsBackend *backend,
1084                                       const gchar      *path)
1085 {
1086   g_return_val_if_fail (schema_id != NULL, NULL);
1087   g_return_val_if_fail (G_IS_SETTINGS_BACKEND (backend), NULL);
1088   g_return_val_if_fail (path_is_valid (path), NULL);
1089 
1090   return g_object_new (G_TYPE_SETTINGS,
1091                        "schema-id", schema_id,
1092                        "backend", backend,
1093                        "path", path,
1094                        NULL);
1095 }
1096 
1097 /**
1098  * g_settings_new_full:
1099  * @schema: a #GSettingsSchema
1100  * @backend: (nullable): a #GSettingsBackend
1101  * @path: (nullable): the path to use
1102  *
1103  * Creates a new #GSettings object with a given schema, backend and
1104  * path.
1105  *
1106  * It should be extremely rare that you ever want to use this function.
1107  * It is made available for advanced use-cases (such as plugin systems
1108  * that want to provide access to schemas loaded from custom locations,
1109  * etc).
1110  *
1111  * At the most basic level, a #GSettings object is a pure composition of
1112  * 4 things: a #GSettingsSchema, a #GSettingsBackend, a path within that
1113  * backend, and a #GMainContext to which signals are dispatched.
1114  *
1115  * This constructor therefore gives you full control over constructing
1116  * #GSettings instances.  The first 3 parameters are given directly as
1117  * @schema, @backend and @path, and the main context is taken from the
1118  * thread-default (as per g_settings_new()).
1119  *
1120  * If @backend is %NULL then the default backend is used.
1121  *
1122  * If @path is %NULL then the path from the schema is used.  It is an
1123  * error if @path is %NULL and the schema has no path of its own or if
1124  * @path is non-%NULL and not equal to the path that the schema does
1125  * have.
1126  *
1127  * Returns: a new #GSettings object
1128  *
1129  * Since: 2.32
1130  */
1131 GSettings *
g_settings_new_full(GSettingsSchema * schema,GSettingsBackend * backend,const gchar * path)1132 g_settings_new_full (GSettingsSchema  *schema,
1133                      GSettingsBackend *backend,
1134                      const gchar      *path)
1135 {
1136   g_return_val_if_fail (schema != NULL, NULL);
1137   g_return_val_if_fail (backend == NULL || G_IS_SETTINGS_BACKEND (backend), NULL);
1138   g_return_val_if_fail (path == NULL || path_is_valid (path), NULL);
1139 
1140   return g_object_new (G_TYPE_SETTINGS,
1141                        "settings-schema", schema,
1142                        "backend", backend,
1143                        "path", path,
1144                        NULL);
1145 }
1146 
1147 /* Internal read/write utilities {{{1 */
1148 
1149 /* @value will be sunk */
1150 static gboolean
g_settings_write_to_backend(GSettings * settings,GSettingsSchemaKey * key,GVariant * value)1151 g_settings_write_to_backend (GSettings          *settings,
1152                              GSettingsSchemaKey *key,
1153                              GVariant           *value)
1154 {
1155   gboolean success;
1156   gchar *path;
1157 
1158   path = g_strconcat (settings->priv->path, key->name, NULL);
1159   success = g_settings_backend_write (settings->priv->backend, path, value, NULL);
1160   g_free (path);
1161 
1162   return success;
1163 }
1164 
1165 static GVariant *
g_settings_read_from_backend(GSettings * settings,GSettingsSchemaKey * key,gboolean user_value_only,gboolean default_value)1166 g_settings_read_from_backend (GSettings          *settings,
1167                               GSettingsSchemaKey *key,
1168                               gboolean            user_value_only,
1169                               gboolean            default_value)
1170 {
1171   GVariant *value;
1172   GVariant *fixup;
1173   gchar *path;
1174 
1175   path = g_strconcat (settings->priv->path, key->name, NULL);
1176   if (user_value_only)
1177     value = g_settings_backend_read_user_value (settings->priv->backend, path, key->type);
1178   else
1179     value = g_settings_backend_read (settings->priv->backend, path, key->type, default_value);
1180   g_free (path);
1181 
1182   if (value != NULL)
1183     {
1184       fixup = g_settings_schema_key_range_fixup (key, value);
1185       g_variant_unref (value);
1186     }
1187   else
1188     fixup = NULL;
1189 
1190   return fixup;
1191 }
1192 
1193 /* Public Get/Set API {{{1 (get, get_value, set, set_value, get_mapped) */
1194 /**
1195  * g_settings_get_value:
1196  * @settings: a #GSettings object
1197  * @key: the key to get the value for
1198  *
1199  * Gets the value that is stored in @settings for @key.
1200  *
1201  * It is a programmer error to give a @key that isn't contained in the
1202  * schema for @settings.
1203  *
1204  * Returns: a new #GVariant
1205  *
1206  * Since: 2.26
1207  */
1208 GVariant *
g_settings_get_value(GSettings * settings,const gchar * key)1209 g_settings_get_value (GSettings   *settings,
1210                       const gchar *key)
1211 {
1212   GSettingsSchemaKey skey;
1213   GVariant *value;
1214 
1215   g_return_val_if_fail (G_IS_SETTINGS (settings), NULL);
1216   g_return_val_if_fail (key != NULL, NULL);
1217 
1218   g_settings_schema_key_init (&skey, settings->priv->schema, key);
1219   value = g_settings_read_from_backend (settings, &skey, FALSE, FALSE);
1220 
1221   if (value == NULL)
1222     value = g_settings_schema_key_get_default_value (&skey);
1223 
1224   g_settings_schema_key_clear (&skey);
1225 
1226   return value;
1227 }
1228 
1229 /**
1230  * g_settings_get_user_value:
1231  * @settings: a #GSettings object
1232  * @key: the key to get the user value for
1233  *
1234  * Checks the "user value" of a key, if there is one.
1235  *
1236  * The user value of a key is the last value that was set by the user.
1237  *
1238  * After calling g_settings_reset() this function should always return
1239  * %NULL (assuming something is not wrong with the system
1240  * configuration).
1241  *
1242  * It is possible that g_settings_get_value() will return a different
1243  * value than this function.  This can happen in the case that the user
1244  * set a value for a key that was subsequently locked down by the system
1245  * administrator -- this function will return the user's old value.
1246  *
1247  * This function may be useful for adding a "reset" option to a UI or
1248  * for providing indication that a particular value has been changed.
1249  *
1250  * It is a programmer error to give a @key that isn't contained in the
1251  * schema for @settings.
1252  *
1253  * Returns: (nullable) (transfer full): the user's value, if set
1254  *
1255  * Since: 2.40
1256  **/
1257 GVariant *
g_settings_get_user_value(GSettings * settings,const gchar * key)1258 g_settings_get_user_value (GSettings   *settings,
1259                            const gchar *key)
1260 {
1261   GSettingsSchemaKey skey;
1262   GVariant *value;
1263 
1264   g_return_val_if_fail (G_IS_SETTINGS (settings), NULL);
1265   g_return_val_if_fail (key != NULL, NULL);
1266 
1267   g_settings_schema_key_init (&skey, settings->priv->schema, key);
1268   value = g_settings_read_from_backend (settings, &skey, TRUE, FALSE);
1269   g_settings_schema_key_clear (&skey);
1270 
1271   return value;
1272 }
1273 
1274 /**
1275  * g_settings_get_default_value:
1276  * @settings: a #GSettings object
1277  * @key: the key to get the default value for
1278  *
1279  * Gets the "default value" of a key.
1280  *
1281  * This is the value that would be read if g_settings_reset() were to be
1282  * called on the key.
1283  *
1284  * Note that this may be a different value than returned by
1285  * g_settings_schema_key_get_default_value() if the system administrator
1286  * has provided a default value.
1287  *
1288  * Comparing the return values of g_settings_get_default_value() and
1289  * g_settings_get_value() is not sufficient for determining if a value
1290  * has been set because the user may have explicitly set the value to
1291  * something that happens to be equal to the default.  The difference
1292  * here is that if the default changes in the future, the user's key
1293  * will still be set.
1294  *
1295  * This function may be useful for adding an indication to a UI of what
1296  * the default value was before the user set it.
1297  *
1298  * It is a programmer error to give a @key that isn't contained in the
1299  * schema for @settings.
1300  *
1301  * Returns: (nullable) (transfer full): the default value
1302  *
1303  * Since: 2.40
1304  **/
1305 GVariant *
g_settings_get_default_value(GSettings * settings,const gchar * key)1306 g_settings_get_default_value (GSettings   *settings,
1307                               const gchar *key)
1308 {
1309   GSettingsSchemaKey skey;
1310   GVariant *value;
1311 
1312   g_return_val_if_fail (G_IS_SETTINGS (settings), NULL);
1313   g_return_val_if_fail (key != NULL, NULL);
1314 
1315   g_settings_schema_key_init (&skey, settings->priv->schema, key);
1316   value = g_settings_read_from_backend (settings, &skey, FALSE, TRUE);
1317 
1318   if (value == NULL)
1319     value = g_settings_schema_key_get_default_value (&skey);
1320 
1321   g_settings_schema_key_clear (&skey);
1322 
1323   return value;
1324 }
1325 
1326 /**
1327  * g_settings_get_enum:
1328  * @settings: a #GSettings object
1329  * @key: the key to get the value for
1330  *
1331  * Gets the value that is stored in @settings for @key and converts it
1332  * to the enum value that it represents.
1333  *
1334  * In order to use this function the type of the value must be a string
1335  * and it must be marked in the schema file as an enumerated type.
1336  *
1337  * It is a programmer error to give a @key that isn't contained in the
1338  * schema for @settings or is not marked as an enumerated type.
1339  *
1340  * If the value stored in the configuration database is not a valid
1341  * value for the enumerated type then this function will return the
1342  * default value.
1343  *
1344  * Returns: the enum value
1345  *
1346  * Since: 2.26
1347  **/
1348 gint
g_settings_get_enum(GSettings * settings,const gchar * key)1349 g_settings_get_enum (GSettings   *settings,
1350                      const gchar *key)
1351 {
1352   GSettingsSchemaKey skey;
1353   GVariant *value;
1354   gint result;
1355 
1356   g_return_val_if_fail (G_IS_SETTINGS (settings), -1);
1357   g_return_val_if_fail (key != NULL, -1);
1358 
1359   g_settings_schema_key_init (&skey, settings->priv->schema, key);
1360 
1361   if (!skey.is_enum)
1362     {
1363       g_critical ("g_settings_get_enum() called on key '%s' which is not "
1364                   "associated with an enumerated type", skey.name);
1365       g_settings_schema_key_clear (&skey);
1366       return -1;
1367     }
1368 
1369   value = g_settings_read_from_backend (settings, &skey, FALSE, FALSE);
1370 
1371   if (value == NULL)
1372     value = g_settings_schema_key_get_default_value (&skey);
1373 
1374   result = g_settings_schema_key_to_enum (&skey, value);
1375   g_settings_schema_key_clear (&skey);
1376   g_variant_unref (value);
1377 
1378   return result;
1379 }
1380 
1381 /**
1382  * g_settings_set_enum:
1383  * @settings: a #GSettings object
1384  * @key: a key, within @settings
1385  * @value: an enumerated value
1386  *
1387  * Looks up the enumerated type nick for @value and writes it to @key,
1388  * within @settings.
1389  *
1390  * It is a programmer error to give a @key that isn't contained in the
1391  * schema for @settings or is not marked as an enumerated type, or for
1392  * @value not to be a valid value for the named type.
1393  *
1394  * After performing the write, accessing @key directly with
1395  * g_settings_get_string() will return the 'nick' associated with
1396  * @value.
1397  *
1398  * Returns: %TRUE, if the set succeeds
1399  **/
1400 gboolean
g_settings_set_enum(GSettings * settings,const gchar * key,gint value)1401 g_settings_set_enum (GSettings   *settings,
1402                      const gchar *key,
1403                      gint         value)
1404 {
1405   GSettingsSchemaKey skey;
1406   GVariant *variant;
1407   gboolean success;
1408 
1409   g_return_val_if_fail (G_IS_SETTINGS (settings), FALSE);
1410   g_return_val_if_fail (key != NULL, FALSE);
1411 
1412   g_settings_schema_key_init (&skey, settings->priv->schema, key);
1413 
1414   if (!skey.is_enum)
1415     {
1416       g_critical ("g_settings_set_enum() called on key '%s' which is not "
1417                   "associated with an enumerated type", skey.name);
1418       return FALSE;
1419     }
1420 
1421   if (!(variant = g_settings_schema_key_from_enum (&skey, value)))
1422     {
1423       g_critical ("g_settings_set_enum(): invalid enum value %d for key '%s' "
1424                   "in schema '%s'.  Doing nothing.", value, skey.name,
1425                   g_settings_schema_get_id (skey.schema));
1426       g_settings_schema_key_clear (&skey);
1427       return FALSE;
1428     }
1429 
1430   success = g_settings_write_to_backend (settings, &skey, g_steal_pointer (&variant));
1431   g_settings_schema_key_clear (&skey);
1432 
1433   return success;
1434 }
1435 
1436 /**
1437  * g_settings_get_flags:
1438  * @settings: a #GSettings object
1439  * @key: the key to get the value for
1440  *
1441  * Gets the value that is stored in @settings for @key and converts it
1442  * to the flags value that it represents.
1443  *
1444  * In order to use this function the type of the value must be an array
1445  * of strings and it must be marked in the schema file as a flags type.
1446  *
1447  * It is a programmer error to give a @key that isn't contained in the
1448  * schema for @settings or is not marked as a flags type.
1449  *
1450  * If the value stored in the configuration database is not a valid
1451  * value for the flags type then this function will return the default
1452  * value.
1453  *
1454  * Returns: the flags value
1455  *
1456  * Since: 2.26
1457  **/
1458 guint
g_settings_get_flags(GSettings * settings,const gchar * key)1459 g_settings_get_flags (GSettings   *settings,
1460                       const gchar *key)
1461 {
1462   GSettingsSchemaKey skey;
1463   GVariant *value;
1464   guint result;
1465 
1466   g_return_val_if_fail (G_IS_SETTINGS (settings), -1);
1467   g_return_val_if_fail (key != NULL, -1);
1468 
1469   g_settings_schema_key_init (&skey, settings->priv->schema, key);
1470 
1471   if (!skey.is_flags)
1472     {
1473       g_critical ("g_settings_get_flags() called on key '%s' which is not "
1474                   "associated with a flags type", skey.name);
1475       g_settings_schema_key_clear (&skey);
1476       return -1;
1477     }
1478 
1479   value = g_settings_read_from_backend (settings, &skey, FALSE, FALSE);
1480 
1481   if (value == NULL)
1482     value = g_settings_schema_key_get_default_value (&skey);
1483 
1484   result = g_settings_schema_key_to_flags (&skey, value);
1485   g_settings_schema_key_clear (&skey);
1486   g_variant_unref (value);
1487 
1488   return result;
1489 }
1490 
1491 /**
1492  * g_settings_set_flags:
1493  * @settings: a #GSettings object
1494  * @key: a key, within @settings
1495  * @value: a flags value
1496  *
1497  * Looks up the flags type nicks for the bits specified by @value, puts
1498  * them in an array of strings and writes the array to @key, within
1499  * @settings.
1500  *
1501  * It is a programmer error to give a @key that isn't contained in the
1502  * schema for @settings or is not marked as a flags type, or for @value
1503  * to contain any bits that are not value for the named type.
1504  *
1505  * After performing the write, accessing @key directly with
1506  * g_settings_get_strv() will return an array of 'nicks'; one for each
1507  * bit in @value.
1508  *
1509  * Returns: %TRUE, if the set succeeds
1510  **/
1511 gboolean
g_settings_set_flags(GSettings * settings,const gchar * key,guint value)1512 g_settings_set_flags (GSettings   *settings,
1513                       const gchar *key,
1514                       guint        value)
1515 {
1516   GSettingsSchemaKey skey;
1517   GVariant *variant;
1518   gboolean success;
1519 
1520   g_return_val_if_fail (G_IS_SETTINGS (settings), FALSE);
1521   g_return_val_if_fail (key != NULL, FALSE);
1522 
1523   g_settings_schema_key_init (&skey, settings->priv->schema, key);
1524 
1525   if (!skey.is_flags)
1526     {
1527       g_critical ("g_settings_set_flags() called on key '%s' which is not "
1528                   "associated with a flags type", skey.name);
1529       return FALSE;
1530     }
1531 
1532   if (!(variant = g_settings_schema_key_from_flags (&skey, value)))
1533     {
1534       g_critical ("g_settings_set_flags(): invalid flags value 0x%08x "
1535                   "for key '%s' in schema '%s'.  Doing nothing.",
1536                   value, skey.name, g_settings_schema_get_id (skey.schema));
1537       g_settings_schema_key_clear (&skey);
1538       return FALSE;
1539     }
1540 
1541   success = g_settings_write_to_backend (settings, &skey, g_steal_pointer (&variant));
1542   g_settings_schema_key_clear (&skey);
1543 
1544   return success;
1545 }
1546 
1547 /**
1548  * g_settings_set_value:
1549  * @settings: a #GSettings object
1550  * @key: the name of the key to set
1551  * @value: a #GVariant of the correct type
1552  *
1553  * Sets @key in @settings to @value.
1554  *
1555  * It is a programmer error to give a @key that isn't contained in the
1556  * schema for @settings or for @value to have the incorrect type, per
1557  * the schema.
1558  *
1559  * If @value is floating then this function consumes the reference.
1560  *
1561  * Returns: %TRUE if setting the key succeeded,
1562  *     %FALSE if the key was not writable
1563  *
1564  * Since: 2.26
1565  **/
1566 gboolean
g_settings_set_value(GSettings * settings,const gchar * key,GVariant * value)1567 g_settings_set_value (GSettings   *settings,
1568                       const gchar *key,
1569                       GVariant    *value)
1570 {
1571   GSettingsSchemaKey skey;
1572   gboolean success;
1573 
1574   g_return_val_if_fail (G_IS_SETTINGS (settings), FALSE);
1575   g_return_val_if_fail (key != NULL, FALSE);
1576 
1577   g_variant_ref_sink (value);
1578   g_settings_schema_key_init (&skey, settings->priv->schema, key);
1579 
1580   if (!g_settings_schema_key_type_check (&skey, value))
1581     {
1582       g_critical ("g_settings_set_value: key '%s' in '%s' expects type '%s', but a GVariant of type '%s' was given",
1583                   key,
1584                   g_settings_schema_get_id (settings->priv->schema),
1585                   g_variant_type_peek_string (skey.type),
1586                   g_variant_get_type_string (value));
1587       success = FALSE;
1588     }
1589   else if (!g_settings_schema_key_range_check (&skey, value))
1590     {
1591       g_warning ("g_settings_set_value: value for key '%s' in schema '%s' "
1592                  "is outside of valid range",
1593                  key,
1594                  g_settings_schema_get_id (settings->priv->schema));
1595       success = FALSE;
1596     }
1597   else
1598     {
1599       success = g_settings_write_to_backend (settings, &skey, value);
1600     }
1601 
1602   g_settings_schema_key_clear (&skey);
1603   g_variant_unref (value);
1604 
1605   return success;
1606 }
1607 
1608 /**
1609  * g_settings_get:
1610  * @settings: a #GSettings object
1611  * @key: the key to get the value for
1612  * @format: a #GVariant format string
1613  * @...: arguments as per @format
1614  *
1615  * Gets the value that is stored at @key in @settings.
1616  *
1617  * A convenience function that combines g_settings_get_value() with
1618  * g_variant_get().
1619  *
1620  * It is a programmer error to give a @key that isn't contained in the
1621  * schema for @settings or for the #GVariantType of @format to mismatch
1622  * the type given in the schema.
1623  *
1624  * Since: 2.26
1625  */
1626 void
g_settings_get(GSettings * settings,const gchar * key,const gchar * format,...)1627 g_settings_get (GSettings   *settings,
1628                 const gchar *key,
1629                 const gchar *format,
1630                 ...)
1631 {
1632   GVariant *value;
1633   va_list ap;
1634 
1635   value = g_settings_get_value (settings, key);
1636 
1637   if (strchr (format, '&'))
1638     {
1639       g_critical ("%s: the format string may not contain '&' (key '%s' from schema '%s'). "
1640                   "This call will probably stop working with a future version of glib.",
1641                   G_STRFUNC, key, g_settings_schema_get_id (settings->priv->schema));
1642     }
1643 
1644   va_start (ap, format);
1645   g_variant_get_va (value, format, NULL, &ap);
1646   va_end (ap);
1647 
1648   g_variant_unref (value);
1649 }
1650 
1651 /**
1652  * g_settings_set:
1653  * @settings: a #GSettings object
1654  * @key: the name of the key to set
1655  * @format: a #GVariant format string
1656  * @...: arguments as per @format
1657  *
1658  * Sets @key in @settings to @value.
1659  *
1660  * A convenience function that combines g_settings_set_value() with
1661  * g_variant_new().
1662  *
1663  * It is a programmer error to give a @key that isn't contained in the
1664  * schema for @settings or for the #GVariantType of @format to mismatch
1665  * the type given in the schema.
1666  *
1667  * Returns: %TRUE if setting the key succeeded,
1668  *     %FALSE if the key was not writable
1669  *
1670  * Since: 2.26
1671  */
1672 gboolean
g_settings_set(GSettings * settings,const gchar * key,const gchar * format,...)1673 g_settings_set (GSettings   *settings,
1674                 const gchar *key,
1675                 const gchar *format,
1676                 ...)
1677 {
1678   GVariant *value;
1679   va_list ap;
1680 
1681   va_start (ap, format);
1682   value = g_variant_new_va (format, NULL, &ap);
1683   va_end (ap);
1684 
1685   return g_settings_set_value (settings, key, g_steal_pointer (&value));
1686 }
1687 
1688 /**
1689  * g_settings_get_mapped:
1690  * @settings: a #GSettings object
1691  * @key: the key to get the value for
1692  * @mapping: (scope call): the function to map the value in the
1693  *           settings database to the value used by the application
1694  * @user_data: user data for @mapping
1695  *
1696  * Gets the value that is stored at @key in @settings, subject to
1697  * application-level validation/mapping.
1698  *
1699  * You should use this function when the application needs to perform
1700  * some processing on the value of the key (for example, parsing).  The
1701  * @mapping function performs that processing.  If the function
1702  * indicates that the processing was unsuccessful (due to a parse error,
1703  * for example) then the mapping is tried again with another value.
1704  *
1705  * This allows a robust 'fall back to defaults' behaviour to be
1706  * implemented somewhat automatically.
1707  *
1708  * The first value that is tried is the user's setting for the key.  If
1709  * the mapping function fails to map this value, other values may be
1710  * tried in an unspecified order (system or site defaults, translated
1711  * schema default values, untranslated schema default values, etc).
1712  *
1713  * If the mapping function fails for all possible values, one additional
1714  * attempt is made: the mapping function is called with a %NULL value.
1715  * If the mapping function still indicates failure at this point then
1716  * the application will be aborted.
1717  *
1718  * The result parameter for the @mapping function is pointed to a
1719  * #gpointer which is initially set to %NULL.  The same pointer is given
1720  * to each invocation of @mapping.  The final value of that #gpointer is
1721  * what is returned by this function.  %NULL is valid; it is returned
1722  * just as any other value would be.
1723  *
1724  * Returns: (transfer full): the result, which may be %NULL
1725  **/
1726 gpointer
g_settings_get_mapped(GSettings * settings,const gchar * key,GSettingsGetMapping mapping,gpointer user_data)1727 g_settings_get_mapped (GSettings           *settings,
1728                        const gchar         *key,
1729                        GSettingsGetMapping  mapping,
1730                        gpointer             user_data)
1731 {
1732   gpointer result = NULL;
1733   GSettingsSchemaKey skey;
1734   GVariant *value;
1735   gboolean okay;
1736 
1737   g_return_val_if_fail (G_IS_SETTINGS (settings), NULL);
1738   g_return_val_if_fail (key != NULL, NULL);
1739   g_return_val_if_fail (mapping != NULL, NULL);
1740 
1741   g_settings_schema_key_init (&skey, settings->priv->schema, key);
1742 
1743   if ((value = g_settings_read_from_backend (settings, &skey, FALSE, FALSE)))
1744     {
1745       okay = mapping (value, &result, user_data);
1746       g_variant_unref (value);
1747       if (okay) goto okay;
1748     }
1749 
1750   if ((value = g_settings_schema_key_get_translated_default (&skey)))
1751     {
1752       okay = mapping (value, &result, user_data);
1753       g_variant_unref (value);
1754       if (okay) goto okay;
1755     }
1756 
1757   if ((value = g_settings_schema_key_get_per_desktop_default (&skey)))
1758     {
1759       okay = mapping (value, &result, user_data);
1760       g_variant_unref (value);
1761       if (okay) goto okay;
1762     }
1763 
1764   if (mapping (skey.default_value, &result, user_data))
1765     goto okay;
1766 
1767   if (!mapping (NULL, &result, user_data))
1768     g_error ("The mapping function given to g_settings_get_mapped() for key "
1769              "'%s' in schema '%s' returned FALSE when given a NULL value.",
1770              key, g_settings_schema_get_id (settings->priv->schema));
1771 
1772  okay:
1773   g_settings_schema_key_clear (&skey);
1774 
1775   return result;
1776 }
1777 
1778 /* Convenience API (get, set_string, int, double, boolean, strv) {{{1 */
1779 /**
1780  * g_settings_get_string:
1781  * @settings: a #GSettings object
1782  * @key: the key to get the value for
1783  *
1784  * Gets the value that is stored at @key in @settings.
1785  *
1786  * A convenience variant of g_settings_get() for strings.
1787  *
1788  * It is a programmer error to give a @key that isn't specified as
1789  * having a string type in the schema for @settings.
1790  *
1791  * Returns: a newly-allocated string
1792  *
1793  * Since: 2.26
1794  */
1795 gchar *
g_settings_get_string(GSettings * settings,const gchar * key)1796 g_settings_get_string (GSettings   *settings,
1797                        const gchar *key)
1798 {
1799   GVariant *value;
1800   gchar *result;
1801 
1802   value = g_settings_get_value (settings, key);
1803   result = g_variant_dup_string (value, NULL);
1804   g_variant_unref (value);
1805 
1806   return result;
1807 }
1808 
1809 /**
1810  * g_settings_set_string:
1811  * @settings: a #GSettings object
1812  * @key: the name of the key to set
1813  * @value: the value to set it to
1814  *
1815  * Sets @key in @settings to @value.
1816  *
1817  * A convenience variant of g_settings_set() for strings.
1818  *
1819  * It is a programmer error to give a @key that isn't specified as
1820  * having a string type in the schema for @settings.
1821  *
1822  * Returns: %TRUE if setting the key succeeded,
1823  *     %FALSE if the key was not writable
1824  *
1825  * Since: 2.26
1826  */
1827 gboolean
g_settings_set_string(GSettings * settings,const gchar * key,const gchar * value)1828 g_settings_set_string (GSettings   *settings,
1829                        const gchar *key,
1830                        const gchar *value)
1831 {
1832   return g_settings_set_value (settings, key, g_variant_new_string (value));
1833 }
1834 
1835 /**
1836  * g_settings_get_int:
1837  * @settings: a #GSettings object
1838  * @key: the key to get the value for
1839  *
1840  * Gets the value that is stored at @key in @settings.
1841  *
1842  * A convenience variant of g_settings_get() for 32-bit integers.
1843  *
1844  * It is a programmer error to give a @key that isn't specified as
1845  * having a int32 type in the schema for @settings.
1846  *
1847  * Returns: an integer
1848  *
1849  * Since: 2.26
1850  */
1851 gint
g_settings_get_int(GSettings * settings,const gchar * key)1852 g_settings_get_int (GSettings   *settings,
1853                     const gchar *key)
1854 {
1855   GVariant *value;
1856   gint result;
1857 
1858   value = g_settings_get_value (settings, key);
1859   result = g_variant_get_int32 (value);
1860   g_variant_unref (value);
1861 
1862   return result;
1863 }
1864 
1865 /**
1866  * g_settings_set_int:
1867  * @settings: a #GSettings object
1868  * @key: the name of the key to set
1869  * @value: the value to set it to
1870  *
1871  * Sets @key in @settings to @value.
1872  *
1873  * A convenience variant of g_settings_set() for 32-bit integers.
1874  *
1875  * It is a programmer error to give a @key that isn't specified as
1876  * having a int32 type in the schema for @settings.
1877  *
1878  * Returns: %TRUE if setting the key succeeded,
1879  *     %FALSE if the key was not writable
1880  *
1881  * Since: 2.26
1882  */
1883 gboolean
g_settings_set_int(GSettings * settings,const gchar * key,gint value)1884 g_settings_set_int (GSettings   *settings,
1885                     const gchar *key,
1886                     gint         value)
1887 {
1888   return g_settings_set_value (settings, key, g_variant_new_int32 (value));
1889 }
1890 
1891 /**
1892  * g_settings_get_int64:
1893  * @settings: a #GSettings object
1894  * @key: the key to get the value for
1895  *
1896  * Gets the value that is stored at @key in @settings.
1897  *
1898  * A convenience variant of g_settings_get() for 64-bit integers.
1899  *
1900  * It is a programmer error to give a @key that isn't specified as
1901  * having a int64 type in the schema for @settings.
1902  *
1903  * Returns: a 64-bit integer
1904  *
1905  * Since: 2.50
1906  */
1907 gint64
g_settings_get_int64(GSettings * settings,const gchar * key)1908 g_settings_get_int64 (GSettings   *settings,
1909                       const gchar *key)
1910 {
1911   GVariant *value;
1912   gint64 result;
1913 
1914   value = g_settings_get_value (settings, key);
1915   result = g_variant_get_int64 (value);
1916   g_variant_unref (value);
1917 
1918   return result;
1919 }
1920 
1921 /**
1922  * g_settings_set_int64:
1923  * @settings: a #GSettings object
1924  * @key: the name of the key to set
1925  * @value: the value to set it to
1926  *
1927  * Sets @key in @settings to @value.
1928  *
1929  * A convenience variant of g_settings_set() for 64-bit integers.
1930  *
1931  * It is a programmer error to give a @key that isn't specified as
1932  * having a int64 type in the schema for @settings.
1933  *
1934  * Returns: %TRUE if setting the key succeeded,
1935  *     %FALSE if the key was not writable
1936  *
1937  * Since: 2.50
1938  */
1939 gboolean
g_settings_set_int64(GSettings * settings,const gchar * key,gint64 value)1940 g_settings_set_int64 (GSettings   *settings,
1941                       const gchar *key,
1942                       gint64       value)
1943 {
1944   return g_settings_set_value (settings, key, g_variant_new_int64 (value));
1945 }
1946 
1947 /**
1948  * g_settings_get_uint:
1949  * @settings: a #GSettings object
1950  * @key: the key to get the value for
1951  *
1952  * Gets the value that is stored at @key in @settings.
1953  *
1954  * A convenience variant of g_settings_get() for 32-bit unsigned
1955  * integers.
1956  *
1957  * It is a programmer error to give a @key that isn't specified as
1958  * having a uint32 type in the schema for @settings.
1959  *
1960  * Returns: an unsigned integer
1961  *
1962  * Since: 2.30
1963  */
1964 guint
g_settings_get_uint(GSettings * settings,const gchar * key)1965 g_settings_get_uint (GSettings   *settings,
1966                      const gchar *key)
1967 {
1968   GVariant *value;
1969   guint result;
1970 
1971   value = g_settings_get_value (settings, key);
1972   result = g_variant_get_uint32 (value);
1973   g_variant_unref (value);
1974 
1975   return result;
1976 }
1977 
1978 /**
1979  * g_settings_set_uint:
1980  * @settings: a #GSettings object
1981  * @key: the name of the key to set
1982  * @value: the value to set it to
1983  *
1984  * Sets @key in @settings to @value.
1985  *
1986  * A convenience variant of g_settings_set() for 32-bit unsigned
1987  * integers.
1988  *
1989  * It is a programmer error to give a @key that isn't specified as
1990  * having a uint32 type in the schema for @settings.
1991  *
1992  * Returns: %TRUE if setting the key succeeded,
1993  *     %FALSE if the key was not writable
1994  *
1995  * Since: 2.30
1996  */
1997 gboolean
g_settings_set_uint(GSettings * settings,const gchar * key,guint value)1998 g_settings_set_uint (GSettings   *settings,
1999                      const gchar *key,
2000                      guint        value)
2001 {
2002   return g_settings_set_value (settings, key, g_variant_new_uint32 (value));
2003 }
2004 
2005 /**
2006  * g_settings_get_uint64:
2007  * @settings: a #GSettings object
2008  * @key: the key to get the value for
2009  *
2010  * Gets the value that is stored at @key in @settings.
2011  *
2012  * A convenience variant of g_settings_get() for 64-bit unsigned
2013  * integers.
2014  *
2015  * It is a programmer error to give a @key that isn't specified as
2016  * having a uint64 type in the schema for @settings.
2017  *
2018  * Returns: a 64-bit unsigned integer
2019  *
2020  * Since: 2.50
2021  */
2022 guint64
g_settings_get_uint64(GSettings * settings,const gchar * key)2023 g_settings_get_uint64 (GSettings   *settings,
2024                        const gchar *key)
2025 {
2026   GVariant *value;
2027   guint64 result;
2028 
2029   value = g_settings_get_value (settings, key);
2030   result = g_variant_get_uint64 (value);
2031   g_variant_unref (value);
2032 
2033   return result;
2034 }
2035 
2036 /**
2037  * g_settings_set_uint64:
2038  * @settings: a #GSettings object
2039  * @key: the name of the key to set
2040  * @value: the value to set it to
2041  *
2042  * Sets @key in @settings to @value.
2043  *
2044  * A convenience variant of g_settings_set() for 64-bit unsigned
2045  * integers.
2046  *
2047  * It is a programmer error to give a @key that isn't specified as
2048  * having a uint64 type in the schema for @settings.
2049  *
2050  * Returns: %TRUE if setting the key succeeded,
2051  *     %FALSE if the key was not writable
2052  *
2053  * Since: 2.50
2054  */
2055 gboolean
g_settings_set_uint64(GSettings * settings,const gchar * key,guint64 value)2056 g_settings_set_uint64 (GSettings   *settings,
2057                        const gchar *key,
2058                        guint64      value)
2059 {
2060   return g_settings_set_value (settings, key, g_variant_new_uint64 (value));
2061 }
2062 
2063 /**
2064  * g_settings_get_double:
2065  * @settings: a #GSettings object
2066  * @key: the key to get the value for
2067  *
2068  * Gets the value that is stored at @key in @settings.
2069  *
2070  * A convenience variant of g_settings_get() for doubles.
2071  *
2072  * It is a programmer error to give a @key that isn't specified as
2073  * having a 'double' type in the schema for @settings.
2074  *
2075  * Returns: a double
2076  *
2077  * Since: 2.26
2078  */
2079 gdouble
g_settings_get_double(GSettings * settings,const gchar * key)2080 g_settings_get_double (GSettings   *settings,
2081                        const gchar *key)
2082 {
2083   GVariant *value;
2084   gdouble result;
2085 
2086   value = g_settings_get_value (settings, key);
2087   result = g_variant_get_double (value);
2088   g_variant_unref (value);
2089 
2090   return result;
2091 }
2092 
2093 /**
2094  * g_settings_set_double:
2095  * @settings: a #GSettings object
2096  * @key: the name of the key to set
2097  * @value: the value to set it to
2098  *
2099  * Sets @key in @settings to @value.
2100  *
2101  * A convenience variant of g_settings_set() for doubles.
2102  *
2103  * It is a programmer error to give a @key that isn't specified as
2104  * having a 'double' type in the schema for @settings.
2105  *
2106  * Returns: %TRUE if setting the key succeeded,
2107  *     %FALSE if the key was not writable
2108  *
2109  * Since: 2.26
2110  */
2111 gboolean
g_settings_set_double(GSettings * settings,const gchar * key,gdouble value)2112 g_settings_set_double (GSettings   *settings,
2113                        const gchar *key,
2114                        gdouble      value)
2115 {
2116   return g_settings_set_value (settings, key, g_variant_new_double (value));
2117 }
2118 
2119 /**
2120  * g_settings_get_boolean:
2121  * @settings: a #GSettings object
2122  * @key: the key to get the value for
2123  *
2124  * Gets the value that is stored at @key in @settings.
2125  *
2126  * A convenience variant of g_settings_get() for booleans.
2127  *
2128  * It is a programmer error to give a @key that isn't specified as
2129  * having a boolean type in the schema for @settings.
2130  *
2131  * Returns: a boolean
2132  *
2133  * Since: 2.26
2134  */
2135 gboolean
g_settings_get_boolean(GSettings * settings,const gchar * key)2136 g_settings_get_boolean (GSettings  *settings,
2137                        const gchar *key)
2138 {
2139   GVariant *value;
2140   gboolean result;
2141 
2142   value = g_settings_get_value (settings, key);
2143   result = g_variant_get_boolean (value);
2144   g_variant_unref (value);
2145 
2146   return result;
2147 }
2148 
2149 /**
2150  * g_settings_set_boolean:
2151  * @settings: a #GSettings object
2152  * @key: the name of the key to set
2153  * @value: the value to set it to
2154  *
2155  * Sets @key in @settings to @value.
2156  *
2157  * A convenience variant of g_settings_set() for booleans.
2158  *
2159  * It is a programmer error to give a @key that isn't specified as
2160  * having a boolean type in the schema for @settings.
2161  *
2162  * Returns: %TRUE if setting the key succeeded,
2163  *     %FALSE if the key was not writable
2164  *
2165  * Since: 2.26
2166  */
2167 gboolean
g_settings_set_boolean(GSettings * settings,const gchar * key,gboolean value)2168 g_settings_set_boolean (GSettings  *settings,
2169                        const gchar *key,
2170                        gboolean     value)
2171 {
2172   return g_settings_set_value (settings, key, g_variant_new_boolean (value));
2173 }
2174 
2175 /**
2176  * g_settings_get_strv:
2177  * @settings: a #GSettings object
2178  * @key: the key to get the value for
2179  *
2180  * A convenience variant of g_settings_get() for string arrays.
2181  *
2182  * It is a programmer error to give a @key that isn't specified as
2183  * having an array of strings type in the schema for @settings.
2184  *
2185  * Returns: (array zero-terminated=1) (transfer full): a
2186  * newly-allocated, %NULL-terminated array of strings, the value that
2187  * is stored at @key in @settings.
2188  *
2189  * Since: 2.26
2190  */
2191 gchar **
g_settings_get_strv(GSettings * settings,const gchar * key)2192 g_settings_get_strv (GSettings   *settings,
2193                      const gchar *key)
2194 {
2195   GVariant *value;
2196   gchar **result;
2197 
2198   value = g_settings_get_value (settings, key);
2199   result = g_variant_dup_strv (value, NULL);
2200   g_variant_unref (value);
2201 
2202   return result;
2203 }
2204 
2205 /**
2206  * g_settings_set_strv:
2207  * @settings: a #GSettings object
2208  * @key: the name of the key to set
2209  * @value: (nullable) (array zero-terminated=1): the value to set it to, or %NULL
2210  *
2211  * Sets @key in @settings to @value.
2212  *
2213  * A convenience variant of g_settings_set() for string arrays.  If
2214  * @value is %NULL, then @key is set to be the empty array.
2215  *
2216  * It is a programmer error to give a @key that isn't specified as
2217  * having an array of strings type in the schema for @settings.
2218  *
2219  * Returns: %TRUE if setting the key succeeded,
2220  *     %FALSE if the key was not writable
2221  *
2222  * Since: 2.26
2223  */
2224 gboolean
g_settings_set_strv(GSettings * settings,const gchar * key,const gchar * const * value)2225 g_settings_set_strv (GSettings           *settings,
2226                      const gchar         *key,
2227                      const gchar * const *value)
2228 {
2229   GVariant *array;
2230 
2231   if (value != NULL)
2232     array = g_variant_new_strv (value, -1);
2233   else
2234     array = g_variant_new_strv (NULL, 0);
2235 
2236   return g_settings_set_value (settings, key, array);
2237 }
2238 
2239 /* Delayed apply (delay, apply, revert, get_has_unapplied) {{{1 */
2240 /**
2241  * g_settings_delay:
2242  * @settings: a #GSettings object
2243  *
2244  * Changes the #GSettings object into 'delay-apply' mode. In this
2245  * mode, changes to @settings are not immediately propagated to the
2246  * backend, but kept locally until g_settings_apply() is called.
2247  *
2248  * Since: 2.26
2249  */
2250 void
g_settings_delay(GSettings * settings)2251 g_settings_delay (GSettings *settings)
2252 {
2253   g_return_if_fail (G_IS_SETTINGS (settings));
2254 
2255   if (settings->priv->delayed)
2256     return;
2257 
2258   settings->priv->delayed =
2259     g_delayed_settings_backend_new (settings->priv->backend,
2260                                     settings,
2261                                     settings->priv->main_context);
2262   g_settings_backend_unwatch (settings->priv->backend, G_OBJECT (settings));
2263   g_object_unref (settings->priv->backend);
2264 
2265   settings->priv->backend = G_SETTINGS_BACKEND (settings->priv->delayed);
2266   g_settings_backend_watch (settings->priv->backend,
2267                             &listener_vtable, G_OBJECT (settings),
2268                             settings->priv->main_context);
2269 
2270   g_object_notify (G_OBJECT (settings), "delay-apply");
2271 }
2272 
2273 /**
2274  * g_settings_apply:
2275  * @settings: a #GSettings instance
2276  *
2277  * Applies any changes that have been made to the settings.  This
2278  * function does nothing unless @settings is in 'delay-apply' mode;
2279  * see g_settings_delay().  In the normal case settings are always
2280  * applied immediately.
2281  **/
2282 void
g_settings_apply(GSettings * settings)2283 g_settings_apply (GSettings *settings)
2284 {
2285   if (settings->priv->delayed)
2286     {
2287       GDelayedSettingsBackend *delayed;
2288 
2289       delayed = G_DELAYED_SETTINGS_BACKEND (settings->priv->backend);
2290       g_delayed_settings_backend_apply (delayed);
2291     }
2292 }
2293 
2294 /**
2295  * g_settings_revert:
2296  * @settings: a #GSettings instance
2297  *
2298  * Reverts all non-applied changes to the settings.  This function
2299  * does nothing unless @settings is in 'delay-apply' mode; see
2300  * g_settings_delay().  In the normal case settings are always applied
2301  * immediately.
2302  *
2303  * Change notifications will be emitted for affected keys.
2304  **/
2305 void
g_settings_revert(GSettings * settings)2306 g_settings_revert (GSettings *settings)
2307 {
2308   if (settings->priv->delayed)
2309     {
2310       GDelayedSettingsBackend *delayed;
2311 
2312       delayed = G_DELAYED_SETTINGS_BACKEND (settings->priv->backend);
2313       g_delayed_settings_backend_revert (delayed);
2314     }
2315 }
2316 
2317 /**
2318  * g_settings_get_has_unapplied:
2319  * @settings: a #GSettings object
2320  *
2321  * Returns whether the #GSettings object has any unapplied
2322  * changes.  This can only be the case if it is in 'delayed-apply' mode.
2323  *
2324  * Returns: %TRUE if @settings has unapplied changes
2325  *
2326  * Since: 2.26
2327  */
2328 gboolean
g_settings_get_has_unapplied(GSettings * settings)2329 g_settings_get_has_unapplied (GSettings *settings)
2330 {
2331   g_return_val_if_fail (G_IS_SETTINGS (settings), FALSE);
2332 
2333   return settings->priv->delayed &&
2334          g_delayed_settings_backend_get_has_unapplied (
2335            G_DELAYED_SETTINGS_BACKEND (settings->priv->backend));
2336 }
2337 
2338 /* Extra API (reset, sync, get_child, is_writable, list_*, ranges) {{{1 */
2339 /**
2340  * g_settings_reset:
2341  * @settings: a #GSettings object
2342  * @key: the name of a key
2343  *
2344  * Resets @key to its default value.
2345  *
2346  * This call resets the key, as much as possible, to its default value.
2347  * That might be the value specified in the schema or the one set by the
2348  * administrator.
2349  **/
2350 void
g_settings_reset(GSettings * settings,const gchar * key)2351 g_settings_reset (GSettings *settings,
2352                   const gchar *key)
2353 {
2354   gchar *path;
2355 
2356   g_return_if_fail (G_IS_SETTINGS (settings));
2357   g_return_if_fail (key != NULL);
2358 
2359   path = g_strconcat (settings->priv->path, key, NULL);
2360   g_settings_backend_reset (settings->priv->backend, path, NULL);
2361   g_free (path);
2362 }
2363 
2364 /**
2365  * g_settings_sync:
2366  *
2367  * Ensures that all pending operations are complete for the default backend.
2368  *
2369  * Writes made to a #GSettings are handled asynchronously.  For this
2370  * reason, it is very unlikely that the changes have it to disk by the
2371  * time g_settings_set() returns.
2372  *
2373  * This call will block until all of the writes have made it to the
2374  * backend.  Since the mainloop is not running, no change notifications
2375  * will be dispatched during this call (but some may be queued by the
2376  * time the call is done).
2377  **/
2378 void
g_settings_sync(void)2379 g_settings_sync (void)
2380 {
2381   g_settings_backend_sync_default ();
2382 }
2383 
2384 /**
2385  * g_settings_is_writable:
2386  * @settings: a #GSettings object
2387  * @name: the name of a key
2388  *
2389  * Finds out if a key can be written or not
2390  *
2391  * Returns: %TRUE if the key @name is writable
2392  *
2393  * Since: 2.26
2394  */
2395 gboolean
g_settings_is_writable(GSettings * settings,const gchar * name)2396 g_settings_is_writable (GSettings   *settings,
2397                         const gchar *name)
2398 {
2399   gboolean writable;
2400   gchar *path;
2401 
2402   g_return_val_if_fail (G_IS_SETTINGS (settings), FALSE);
2403 
2404   path = g_strconcat (settings->priv->path, name, NULL);
2405   writable = g_settings_backend_get_writable (settings->priv->backend, path);
2406   g_free (path);
2407 
2408   return writable;
2409 }
2410 
2411 /**
2412  * g_settings_get_child:
2413  * @settings: a #GSettings object
2414  * @name: the name of the child schema
2415  *
2416  * Creates a child settings object which has a base path of
2417  * `base-path/@name`, where `base-path` is the base path of
2418  * @settings.
2419  *
2420  * The schema for the child settings object must have been declared
2421  * in the schema of @settings using a <child> element.
2422  *
2423  * Returns: (transfer full): a 'child' settings object
2424  *
2425  * Since: 2.26
2426  */
2427 GSettings *
g_settings_get_child(GSettings * settings,const gchar * name)2428 g_settings_get_child (GSettings   *settings,
2429                       const gchar *name)
2430 {
2431   const gchar *child_schema;
2432   gchar *child_path;
2433   gchar *child_name;
2434   GSettings *child;
2435 
2436   g_return_val_if_fail (G_IS_SETTINGS (settings), NULL);
2437 
2438   child_name = g_strconcat (name, "/", NULL);
2439   child_schema = g_settings_schema_get_string (settings->priv->schema,
2440                                                child_name);
2441   if (child_schema == NULL)
2442     g_error ("Schema '%s' has no child '%s'",
2443              g_settings_schema_get_id (settings->priv->schema), name);
2444 
2445   child_path = g_strconcat (settings->priv->path, child_name, NULL);
2446   child = g_object_new (G_TYPE_SETTINGS,
2447                         "backend", settings->priv->backend,
2448                         "schema-id", child_schema,
2449                         "path", child_path,
2450                         NULL);
2451   g_free (child_path);
2452   g_free (child_name);
2453 
2454   return child;
2455 }
2456 
2457 /**
2458  * g_settings_list_keys:
2459  * @settings: a #GSettings object
2460  *
2461  * Introspects the list of keys on @settings.
2462  *
2463  * You should probably not be calling this function from "normal" code
2464  * (since you should already know what keys are in your schema).  This
2465  * function is intended for introspection reasons.
2466  *
2467  * You should free the return value with g_strfreev() when you are done
2468  * with it.
2469  *
2470  * Returns: (transfer full) (element-type utf8): a list of the keys on
2471  *    @settings, in no defined order
2472  * Deprecated: 2.46: Use g_settings_schema_list_keys instead().
2473  */
2474 gchar **
g_settings_list_keys(GSettings * settings)2475 g_settings_list_keys (GSettings *settings)
2476 {
2477   return g_settings_schema_list_keys (settings->priv->schema);
2478 }
2479 
2480 /**
2481  * g_settings_list_children:
2482  * @settings: a #GSettings object
2483  *
2484  * Gets the list of children on @settings.
2485  *
2486  * The list is exactly the list of strings for which it is not an error
2487  * to call g_settings_get_child().
2488  *
2489  * There is little reason to call this function from "normal" code, since
2490  * you should already know what children are in your schema. This function
2491  * may still be useful there for introspection reasons, however.
2492  *
2493  * You should free the return value with g_strfreev() when you are done
2494  * with it.
2495  *
2496  * Returns: (transfer full) (element-type utf8): a list of the children on
2497  *    @settings, in no defined order
2498  */
2499 gchar **
g_settings_list_children(GSettings * settings)2500 g_settings_list_children (GSettings *settings)
2501 {
2502   return g_settings_schema_list_children (settings->priv->schema);
2503 }
2504 
2505 /**
2506  * g_settings_get_range:
2507  * @settings: a #GSettings
2508  * @key: the key to query the range of
2509  *
2510  * Queries the range of a key.
2511  *
2512  * Since: 2.28
2513  *
2514  * Deprecated:2.40:Use g_settings_schema_key_get_range() instead.
2515  **/
2516 GVariant *
g_settings_get_range(GSettings * settings,const gchar * key)2517 g_settings_get_range (GSettings   *settings,
2518                       const gchar *key)
2519 {
2520   GSettingsSchemaKey skey;
2521   GVariant *range;
2522 
2523   g_settings_schema_key_init (&skey, settings->priv->schema, key);
2524   range = g_settings_schema_key_get_range (&skey);
2525   g_settings_schema_key_clear (&skey);
2526 
2527   return range;
2528 }
2529 
2530 /**
2531  * g_settings_range_check:
2532  * @settings: a #GSettings
2533  * @key: the key to check
2534  * @value: the value to check
2535  *
2536  * Checks if the given @value is of the correct type and within the
2537  * permitted range for @key.
2538  *
2539  * Returns: %TRUE if @value is valid for @key
2540  *
2541  * Since: 2.28
2542  *
2543  * Deprecated:2.40:Use g_settings_schema_key_range_check() instead.
2544  **/
2545 gboolean
g_settings_range_check(GSettings * settings,const gchar * key,GVariant * value)2546 g_settings_range_check (GSettings   *settings,
2547                         const gchar *key,
2548                         GVariant    *value)
2549 {
2550   GSettingsSchemaKey skey;
2551   gboolean good;
2552 
2553   g_settings_schema_key_init (&skey, settings->priv->schema, key);
2554   good = g_settings_schema_key_range_check (&skey, value);
2555   g_settings_schema_key_clear (&skey);
2556 
2557   return good;
2558 }
2559 
2560 /* Binding {{{1 */
2561 typedef struct
2562 {
2563   GSettingsSchemaKey key;
2564   GSettings *settings;
2565   GObject *object;
2566 
2567   GSettingsBindGetMapping get_mapping;
2568   GSettingsBindSetMapping set_mapping;
2569   gpointer user_data;
2570   GDestroyNotify destroy;
2571 
2572   guint writable_handler_id;
2573   guint property_handler_id;
2574   const GParamSpec *property;
2575   guint key_handler_id;
2576 
2577   /* prevent recursion */
2578   gboolean running;
2579 } GSettingsBinding;
2580 
2581 static void
g_settings_binding_free(gpointer data)2582 g_settings_binding_free (gpointer data)
2583 {
2584   GSettingsBinding *binding = data;
2585 
2586   g_assert (!binding->running);
2587 
2588   if (binding->writable_handler_id)
2589     g_signal_handler_disconnect (binding->settings,
2590                                  binding->writable_handler_id);
2591 
2592   if (binding->key_handler_id)
2593     g_signal_handler_disconnect (binding->settings,
2594                                  binding->key_handler_id);
2595 
2596   if (g_signal_handler_is_connected (binding->object,
2597                                      binding->property_handler_id))
2598   g_signal_handler_disconnect (binding->object,
2599                                binding->property_handler_id);
2600 
2601   g_settings_schema_key_clear (&binding->key);
2602 
2603   if (binding->destroy)
2604     binding->destroy (binding->user_data);
2605 
2606   g_object_unref (binding->settings);
2607 
2608   g_slice_free (GSettingsBinding, binding);
2609 }
2610 
2611 static GQuark
g_settings_binding_quark(const char * property)2612 g_settings_binding_quark (const char *property)
2613 {
2614   GQuark quark;
2615   gchar *tmp;
2616 
2617   tmp = g_strdup_printf ("gsettingsbinding-%s", property);
2618   quark = g_quark_from_string (tmp);
2619   g_free (tmp);
2620 
2621   return quark;
2622 }
2623 
2624 static void
g_settings_binding_key_changed(GSettings * settings,const gchar * key,gpointer user_data)2625 g_settings_binding_key_changed (GSettings   *settings,
2626                                 const gchar *key,
2627                                 gpointer     user_data)
2628 {
2629   GSettingsBinding *binding = user_data;
2630   GValue value = G_VALUE_INIT;
2631   GVariant *variant;
2632 
2633   g_assert (settings == binding->settings);
2634   g_assert (key == binding->key.name);
2635 
2636   if (binding->running)
2637     return;
2638 
2639   binding->running = TRUE;
2640 
2641   g_value_init (&value, binding->property->value_type);
2642 
2643   variant = g_settings_read_from_backend (binding->settings, &binding->key, FALSE, FALSE);
2644   if (variant && !binding->get_mapping (&value, variant, binding->user_data))
2645     {
2646       /* silently ignore errors in the user's config database */
2647       g_variant_unref (variant);
2648       variant = NULL;
2649     }
2650 
2651   if (variant == NULL)
2652     {
2653       variant = g_settings_schema_key_get_translated_default (&binding->key);
2654       if (variant &&
2655           !binding->get_mapping (&value, variant, binding->user_data))
2656         {
2657           /* flag translation errors with a warning */
2658           g_warning ("Translated default '%s' for key '%s' in schema '%s' "
2659                      "was rejected by the binding mapping function",
2660                      binding->key.unparsed, binding->key.name,
2661                      g_settings_schema_get_id (binding->key.schema));
2662           g_variant_unref (variant);
2663           variant = NULL;
2664         }
2665     }
2666 
2667   if (variant == NULL)
2668     {
2669       variant = g_settings_schema_key_get_per_desktop_default (&binding->key);
2670       if (variant &&
2671           !binding->get_mapping (&value, variant, binding->user_data))
2672         {
2673           g_error ("Per-desktop default value for key '%s' in schema '%s' "
2674                    "was rejected by the binding mapping function.",
2675                    binding->key.name, g_settings_schema_get_id (binding->key.schema));
2676           g_variant_unref (variant);
2677           variant = NULL;
2678         }
2679     }
2680 
2681   if (variant == NULL)
2682     {
2683       variant = g_variant_ref (binding->key.default_value);
2684       if (!binding->get_mapping (&value, variant, binding->user_data))
2685         g_error ("The schema default value for key '%s' in schema '%s' "
2686                  "was rejected by the binding mapping function.",
2687                  binding->key.name, g_settings_schema_get_id (binding->key.schema));
2688     }
2689 
2690   g_object_set_property (binding->object, binding->property->name, &value);
2691   g_variant_unref (variant);
2692   g_value_unset (&value);
2693 
2694   binding->running = FALSE;
2695 }
2696 
2697 static void
g_settings_binding_property_changed(GObject * object,const GParamSpec * pspec,gpointer user_data)2698 g_settings_binding_property_changed (GObject          *object,
2699                                      const GParamSpec *pspec,
2700                                      gpointer          user_data)
2701 {
2702   GSettingsBinding *binding = user_data;
2703   GValue value = G_VALUE_INIT;
2704   GVariant *variant;
2705   gboolean valid = TRUE;
2706 
2707   g_assert (object == binding->object);
2708   g_assert (pspec == binding->property);
2709 
2710   if (binding->running)
2711     return;
2712 
2713   binding->running = TRUE;
2714 
2715   g_value_init (&value, pspec->value_type);
2716   g_object_get_property (object, pspec->name, &value);
2717   if ((variant = binding->set_mapping (&value, binding->key.type,
2718                                        binding->user_data)))
2719     {
2720       g_variant_take_ref (variant);
2721 
2722       if (!g_settings_schema_key_type_check (&binding->key, variant))
2723         {
2724           gchar *type_str;
2725           type_str = g_variant_type_dup_string (binding->key.type);
2726           g_critical ("binding mapping function for key '%s' returned "
2727                       "GVariant of type '%s' when type '%s' was requested",
2728                       binding->key.name, g_variant_get_type_string (variant),
2729                       type_str);
2730           g_free (type_str);
2731           valid = FALSE;
2732         }
2733 
2734       if (valid && !g_settings_schema_key_range_check (&binding->key, variant))
2735         {
2736           gchar *variant_str;
2737           variant_str = g_variant_print (variant, TRUE);
2738           g_critical ("GObject property '%s' on a '%s' object is out of "
2739                       "schema-specified range for key '%s' of '%s': %s",
2740                       binding->property->name, g_type_name (binding->property->owner_type),
2741                       binding->key.name, g_settings_schema_get_id (binding->key.schema),
2742                       variant_str);
2743           g_free (variant_str);
2744           valid = FALSE;
2745         }
2746 
2747       if (valid)
2748         {
2749           g_settings_write_to_backend (binding->settings, &binding->key, variant);
2750         }
2751       g_variant_unref (variant);
2752     }
2753   g_value_unset (&value);
2754 
2755   binding->running = FALSE;
2756 }
2757 
2758 static gboolean
g_settings_bind_invert_boolean_get_mapping(GValue * value,GVariant * variant,gpointer user_data)2759 g_settings_bind_invert_boolean_get_mapping (GValue   *value,
2760                                             GVariant *variant,
2761                                             gpointer  user_data)
2762 {
2763   g_value_set_boolean (value, !g_variant_get_boolean (variant));
2764   return TRUE;
2765 }
2766 
2767 static GVariant *
g_settings_bind_invert_boolean_set_mapping(const GValue * value,const GVariantType * expected_type,gpointer user_data)2768 g_settings_bind_invert_boolean_set_mapping (const GValue       *value,
2769                                             const GVariantType *expected_type,
2770                                             gpointer            user_data)
2771 {
2772   return g_variant_new_boolean (!g_value_get_boolean (value));
2773 }
2774 
2775 /**
2776  * g_settings_bind:
2777  * @settings: a #GSettings object
2778  * @key: the key to bind
2779  * @object: (type GObject.Object): a #GObject
2780  * @property: the name of the property to bind
2781  * @flags: flags for the binding
2782  *
2783  * Create a binding between the @key in the @settings object
2784  * and the property @property of @object.
2785  *
2786  * The binding uses the default GIO mapping functions to map
2787  * between the settings and property values. These functions
2788  * handle booleans, numeric types and string types in a
2789  * straightforward way. Use g_settings_bind_with_mapping() if
2790  * you need a custom mapping, or map between types that are not
2791  * supported by the default mapping functions.
2792  *
2793  * Unless the @flags include %G_SETTINGS_BIND_NO_SENSITIVITY, this
2794  * function also establishes a binding between the writability of
2795  * @key and the "sensitive" property of @object (if @object has
2796  * a boolean property by that name). See g_settings_bind_writable()
2797  * for more details about writable bindings.
2798  *
2799  * Note that the lifecycle of the binding is tied to @object,
2800  * and that you can have only one binding per object property.
2801  * If you bind the same property twice on the same object, the second
2802  * binding overrides the first one.
2803  *
2804  * Since: 2.26
2805  */
2806 void
g_settings_bind(GSettings * settings,const gchar * key,gpointer object,const gchar * property,GSettingsBindFlags flags)2807 g_settings_bind (GSettings          *settings,
2808                  const gchar        *key,
2809                  gpointer            object,
2810                  const gchar        *property,
2811                  GSettingsBindFlags  flags)
2812 {
2813   GSettingsBindGetMapping get_mapping = NULL;
2814   GSettingsBindSetMapping set_mapping = NULL;
2815 
2816   if (flags & G_SETTINGS_BIND_INVERT_BOOLEAN)
2817     {
2818       get_mapping = g_settings_bind_invert_boolean_get_mapping;
2819       set_mapping = g_settings_bind_invert_boolean_set_mapping;
2820 
2821       /* can't pass this flag to g_settings_bind_with_mapping() */
2822       flags &= ~G_SETTINGS_BIND_INVERT_BOOLEAN;
2823     }
2824 
2825   g_settings_bind_with_mapping (settings, key, object, property, flags,
2826                                 get_mapping, set_mapping, NULL, NULL);
2827 }
2828 
2829 /**
2830  * g_settings_bind_with_mapping: (skip)
2831  * @settings: a #GSettings object
2832  * @key: the key to bind
2833  * @object: (type GObject.Object): a #GObject
2834  * @property: the name of the property to bind
2835  * @flags: flags for the binding
2836  * @get_mapping: a function that gets called to convert values
2837  *     from @settings to @object, or %NULL to use the default GIO mapping
2838  * @set_mapping: a function that gets called to convert values
2839  *     from @object to @settings, or %NULL to use the default GIO mapping
2840  * @user_data: data that gets passed to @get_mapping and @set_mapping
2841  * @destroy: #GDestroyNotify function for @user_data
2842  *
2843  * Create a binding between the @key in the @settings object
2844  * and the property @property of @object.
2845  *
2846  * The binding uses the provided mapping functions to map between
2847  * settings and property values.
2848  *
2849  * Note that the lifecycle of the binding is tied to @object,
2850  * and that you can have only one binding per object property.
2851  * If you bind the same property twice on the same object, the second
2852  * binding overrides the first one.
2853  *
2854  * Since: 2.26
2855  */
2856 void
g_settings_bind_with_mapping(GSettings * settings,const gchar * key,gpointer object,const gchar * property,GSettingsBindFlags flags,GSettingsBindGetMapping get_mapping,GSettingsBindSetMapping set_mapping,gpointer user_data,GDestroyNotify destroy)2857 g_settings_bind_with_mapping (GSettings               *settings,
2858                               const gchar             *key,
2859                               gpointer                 object,
2860                               const gchar             *property,
2861                               GSettingsBindFlags       flags,
2862                               GSettingsBindGetMapping  get_mapping,
2863                               GSettingsBindSetMapping  set_mapping,
2864                               gpointer                 user_data,
2865                               GDestroyNotify           destroy)
2866 {
2867   GSettingsBinding *binding;
2868   GObjectClass *objectclass;
2869   gchar *detailed_signal;
2870   GQuark binding_quark;
2871 
2872   g_return_if_fail (G_IS_SETTINGS (settings));
2873   g_return_if_fail (key != NULL);
2874   g_return_if_fail (G_IS_OBJECT (object));
2875   g_return_if_fail (property != NULL);
2876   g_return_if_fail (~flags & G_SETTINGS_BIND_INVERT_BOOLEAN);
2877 
2878   objectclass = G_OBJECT_GET_CLASS (object);
2879 
2880   binding = g_slice_new0 (GSettingsBinding);
2881   g_settings_schema_key_init (&binding->key, settings->priv->schema, key);
2882   binding->settings = g_object_ref (settings);
2883   binding->object = object;
2884   binding->property = g_object_class_find_property (objectclass, property);
2885   binding->user_data = user_data;
2886   binding->destroy = destroy;
2887   binding->get_mapping = get_mapping ? get_mapping : g_settings_get_mapping;
2888   binding->set_mapping = set_mapping ? set_mapping : g_settings_set_mapping;
2889 
2890   if (!(flags & (G_SETTINGS_BIND_GET | G_SETTINGS_BIND_SET)))
2891     flags |= G_SETTINGS_BIND_GET | G_SETTINGS_BIND_SET;
2892 
2893   if (binding->property == NULL)
2894     {
2895       g_critical ("g_settings_bind: no property '%s' on class '%s'",
2896                   property, G_OBJECT_TYPE_NAME (object));
2897       return;
2898     }
2899 
2900   if ((flags & G_SETTINGS_BIND_GET) &&
2901       (binding->property->flags & G_PARAM_WRITABLE) == 0)
2902     {
2903       g_critical ("g_settings_bind: property '%s' on class '%s' is not "
2904                   "writable", binding->property->name, G_OBJECT_TYPE_NAME (object));
2905       return;
2906     }
2907   if ((flags & G_SETTINGS_BIND_SET) &&
2908       (binding->property->flags & G_PARAM_READABLE) == 0)
2909     {
2910       g_critical ("g_settings_bind: property '%s' on class '%s' is not "
2911                   "readable", binding->property->name, G_OBJECT_TYPE_NAME (object));
2912       return;
2913     }
2914 
2915   if (get_mapping == g_settings_bind_invert_boolean_get_mapping)
2916     {
2917       /* g_settings_bind_invert_boolean_get_mapping() is a private
2918        * function, so if we are here it means that g_settings_bind() was
2919        * called with G_SETTINGS_BIND_INVERT_BOOLEAN.
2920        *
2921        * Ensure that both sides are boolean.
2922        */
2923 
2924       if (binding->property->value_type != G_TYPE_BOOLEAN)
2925         {
2926           g_critical ("g_settings_bind: G_SETTINGS_BIND_INVERT_BOOLEAN "
2927                       "was specified, but property '%s' on type '%s' has "
2928                       "type '%s'", binding->property->name, G_OBJECT_TYPE_NAME (object),
2929                       g_type_name ((binding->property->value_type)));
2930           return;
2931         }
2932 
2933       if (!g_variant_type_equal (binding->key.type, G_VARIANT_TYPE_BOOLEAN))
2934         {
2935           gchar *type_string = g_variant_type_dup_string (binding->key.type);
2936           g_critical ("g_settings_bind: G_SETTINGS_BIND_INVERT_BOOLEAN "
2937                       "was specified, but key '%s' on schema '%s' has "
2938                       "type '%s'", key, g_settings_schema_get_id (settings->priv->schema),
2939                       type_string);
2940           g_free (type_string);
2941           return;
2942         }
2943 
2944     }
2945 
2946   else if (((get_mapping == NULL && (flags & G_SETTINGS_BIND_GET)) ||
2947             (set_mapping == NULL && (flags & G_SETTINGS_BIND_SET))) &&
2948            !g_settings_mapping_is_compatible (binding->property->value_type,
2949                                               binding->key.type))
2950     {
2951       gchar *type_string = g_variant_type_dup_string (binding->key.type);
2952       g_critical ("g_settings_bind: property '%s' on class '%s' has type "
2953                   "'%s' which is not compatible with type '%s' of key '%s' "
2954                   "on schema '%s'", binding->property->name, G_OBJECT_TYPE_NAME (object),
2955                   g_type_name (binding->property->value_type),
2956                   type_string, key,
2957                   g_settings_schema_get_id (settings->priv->schema));
2958       g_free (type_string);
2959       return;
2960     }
2961 
2962   if ((flags & G_SETTINGS_BIND_SET) &&
2963       (~flags & G_SETTINGS_BIND_NO_SENSITIVITY))
2964     {
2965       GParamSpec *sensitive;
2966 
2967       sensitive = g_object_class_find_property (objectclass, "sensitive");
2968 
2969       if (sensitive && sensitive->value_type == G_TYPE_BOOLEAN &&
2970           (sensitive->flags & G_PARAM_WRITABLE))
2971         g_settings_bind_writable (settings, binding->key.name, object, "sensitive", FALSE);
2972     }
2973 
2974   if (flags & G_SETTINGS_BIND_SET)
2975     {
2976       detailed_signal = g_strdup_printf ("notify::%s", binding->property->name);
2977       binding->property_handler_id =
2978         g_signal_connect (object, detailed_signal,
2979                           G_CALLBACK (g_settings_binding_property_changed),
2980                           binding);
2981       g_free (detailed_signal);
2982 
2983       if (~flags & G_SETTINGS_BIND_GET)
2984         g_settings_binding_property_changed (object,
2985                                              binding->property,
2986                                              binding);
2987     }
2988 
2989   if (flags & G_SETTINGS_BIND_GET)
2990     {
2991       if (~flags & G_SETTINGS_BIND_GET_NO_CHANGES)
2992         {
2993           detailed_signal = g_strdup_printf ("changed::%s", key);
2994           binding->key_handler_id =
2995             g_signal_connect (settings, detailed_signal,
2996                               G_CALLBACK (g_settings_binding_key_changed),
2997                               binding);
2998           g_free (detailed_signal);
2999         }
3000 
3001       g_settings_binding_key_changed (settings, binding->key.name, binding);
3002     }
3003 
3004   binding_quark = g_settings_binding_quark (binding->property->name);
3005   g_object_set_qdata_full (object, binding_quark,
3006                            binding, g_settings_binding_free);
3007 }
3008 
3009 /* Writability binding {{{1 */
3010 typedef struct
3011 {
3012   GSettings *settings;
3013   gpointer object;
3014   const gchar *key;
3015   const gchar *property;
3016   gboolean inverted;
3017   gulong handler_id;
3018 } GSettingsWritableBinding;
3019 
3020 static void
g_settings_writable_binding_free(gpointer data)3021 g_settings_writable_binding_free (gpointer data)
3022 {
3023   GSettingsWritableBinding *binding = data;
3024 
3025   g_signal_handler_disconnect (binding->settings, binding->handler_id);
3026   g_object_unref (binding->settings);
3027   g_slice_free (GSettingsWritableBinding, binding);
3028 }
3029 
3030 static void
g_settings_binding_writable_changed(GSettings * settings,const gchar * key,gpointer user_data)3031 g_settings_binding_writable_changed (GSettings   *settings,
3032                                      const gchar *key,
3033                                      gpointer     user_data)
3034 {
3035   GSettingsWritableBinding *binding = user_data;
3036   gboolean writable;
3037 
3038   g_assert (settings == binding->settings);
3039   g_assert (key == binding->key);
3040 
3041   writable = g_settings_is_writable (settings, key);
3042 
3043   if (binding->inverted)
3044     writable = !writable;
3045 
3046   g_object_set (binding->object, binding->property, writable, NULL);
3047 }
3048 
3049 /**
3050  * g_settings_bind_writable:
3051  * @settings: a #GSettings object
3052  * @key: the key to bind
3053  * @object: (type GObject.Object):a #GObject
3054  * @property: the name of a boolean property to bind
3055  * @inverted: whether to 'invert' the value
3056  *
3057  * Create a binding between the writability of @key in the
3058  * @settings object and the property @property of @object.
3059  * The property must be boolean; "sensitive" or "visible"
3060  * properties of widgets are the most likely candidates.
3061  *
3062  * Writable bindings are always uni-directional; changes of the
3063  * writability of the setting will be propagated to the object
3064  * property, not the other way.
3065  *
3066  * When the @inverted argument is %TRUE, the binding inverts the
3067  * value as it passes from the setting to the object, i.e. @property
3068  * will be set to %TRUE if the key is not writable.
3069  *
3070  * Note that the lifecycle of the binding is tied to @object,
3071  * and that you can have only one binding per object property.
3072  * If you bind the same property twice on the same object, the second
3073  * binding overrides the first one.
3074  *
3075  * Since: 2.26
3076  */
3077 void
g_settings_bind_writable(GSettings * settings,const gchar * key,gpointer object,const gchar * property,gboolean inverted)3078 g_settings_bind_writable (GSettings   *settings,
3079                           const gchar *key,
3080                           gpointer     object,
3081                           const gchar *property,
3082                           gboolean     inverted)
3083 {
3084   GSettingsWritableBinding *binding;
3085   gchar *detailed_signal;
3086   GParamSpec *pspec;
3087 
3088   g_return_if_fail (G_IS_SETTINGS (settings));
3089 
3090   pspec = g_object_class_find_property (G_OBJECT_GET_CLASS (object), property);
3091   if (pspec == NULL)
3092     {
3093       g_critical ("g_settings_bind_writable: no property '%s' on class '%s'",
3094                   property, G_OBJECT_TYPE_NAME (object));
3095       return;
3096     }
3097   if ((pspec->flags & G_PARAM_WRITABLE) == 0)
3098     {
3099       g_critical ("g_settings_bind_writable: property '%s' on class '%s' is not writable",
3100                   property, G_OBJECT_TYPE_NAME (object));
3101       return;
3102     }
3103 
3104   binding = g_slice_new (GSettingsWritableBinding);
3105   binding->settings = g_object_ref (settings);
3106   binding->object = object;
3107   binding->key = g_intern_string (key);
3108   binding->property = g_intern_string (property);
3109   binding->inverted = inverted;
3110 
3111   detailed_signal = g_strdup_printf ("writable-changed::%s", key);
3112   binding->handler_id =
3113     g_signal_connect (settings, detailed_signal,
3114                       G_CALLBACK (g_settings_binding_writable_changed),
3115                       binding);
3116   g_free (detailed_signal);
3117 
3118   g_object_set_qdata_full (object, g_settings_binding_quark (property),
3119                            binding, g_settings_writable_binding_free);
3120 
3121   g_settings_binding_writable_changed (settings, binding->key, binding);
3122 }
3123 
3124 /**
3125  * g_settings_unbind:
3126  * @object: (type GObject.Object): the object
3127  * @property: the property whose binding is removed
3128  *
3129  * Removes an existing binding for @property on @object.
3130  *
3131  * Note that bindings are automatically removed when the
3132  * object is finalized, so it is rarely necessary to call this
3133  * function.
3134  *
3135  * Since: 2.26
3136  */
3137 void
g_settings_unbind(gpointer object,const gchar * property)3138 g_settings_unbind (gpointer     object,
3139                    const gchar *property)
3140 {
3141   GQuark binding_quark;
3142 
3143   binding_quark = g_settings_binding_quark (property);
3144   g_object_set_qdata (object, binding_quark, NULL);
3145 }
3146 
3147 /* GAction {{{1 */
3148 
3149 typedef struct
3150 {
3151   GObject parent_instance;
3152 
3153   GSettingsSchemaKey key;
3154   GSettings *settings;
3155 } GSettingsAction;
3156 
3157 typedef GObjectClass GSettingsActionClass;
3158 
3159 static GType g_settings_action_get_type (void);
3160 static void g_settings_action_iface_init (GActionInterface *iface);
3161 G_DEFINE_TYPE_WITH_CODE (GSettingsAction, g_settings_action, G_TYPE_OBJECT,
3162                          G_IMPLEMENT_INTERFACE (G_TYPE_ACTION, g_settings_action_iface_init))
3163 
3164 enum
3165 {
3166   ACTION_PROP_0,
3167   ACTION_PROP_NAME,
3168   ACTION_PROP_PARAMETER_TYPE,
3169   ACTION_PROP_ENABLED,
3170   ACTION_PROP_STATE_TYPE,
3171   ACTION_PROP_STATE
3172 };
3173 
3174 static const gchar *
g_settings_action_get_name(GAction * action)3175 g_settings_action_get_name (GAction *action)
3176 {
3177   GSettingsAction *gsa = (GSettingsAction *) action;
3178 
3179   return gsa->key.name;
3180 }
3181 
3182 static const GVariantType *
g_settings_action_get_parameter_type(GAction * action)3183 g_settings_action_get_parameter_type (GAction *action)
3184 {
3185   GSettingsAction *gsa = (GSettingsAction *) action;
3186   const GVariantType *type;
3187 
3188   type = g_variant_get_type (gsa->key.default_value);
3189   if (g_variant_type_equal (type, G_VARIANT_TYPE_BOOLEAN))
3190     type = NULL;
3191 
3192   return type;
3193 }
3194 
3195 static gboolean
g_settings_action_get_enabled(GAction * action)3196 g_settings_action_get_enabled (GAction *action)
3197 {
3198   GSettingsAction *gsa = (GSettingsAction *) action;
3199 
3200   return g_settings_is_writable (gsa->settings, gsa->key.name);
3201 }
3202 
3203 static const GVariantType *
g_settings_action_get_state_type(GAction * action)3204 g_settings_action_get_state_type (GAction *action)
3205 {
3206   GSettingsAction *gsa = (GSettingsAction *) action;
3207 
3208   return g_variant_get_type (gsa->key.default_value);
3209 }
3210 
3211 static GVariant *
g_settings_action_get_state(GAction * action)3212 g_settings_action_get_state (GAction *action)
3213 {
3214   GSettingsAction *gsa = (GSettingsAction *) action;
3215   GVariant *value;
3216 
3217   value = g_settings_read_from_backend (gsa->settings, &gsa->key, FALSE, FALSE);
3218 
3219   if (value == NULL)
3220     value = g_settings_schema_key_get_translated_default (&gsa->key);
3221 
3222   if (value == NULL)
3223     value = g_variant_ref (gsa->key.default_value);
3224 
3225   return value;
3226 }
3227 
3228 static GVariant *
g_settings_action_get_state_hint(GAction * action)3229 g_settings_action_get_state_hint (GAction *action)
3230 {
3231   GSettingsAction *gsa = (GSettingsAction *) action;
3232 
3233   /* no point in reimplementing this... */
3234   return g_settings_schema_key_get_range (&gsa->key);
3235 }
3236 
3237 static void
g_settings_action_change_state(GAction * action,GVariant * value)3238 g_settings_action_change_state (GAction  *action,
3239                                 GVariant *value)
3240 {
3241   GSettingsAction *gsa = (GSettingsAction *) action;
3242 
3243   if (g_settings_schema_key_type_check (&gsa->key, value) && g_settings_schema_key_range_check (&gsa->key, value))
3244     g_settings_write_to_backend (gsa->settings, &gsa->key, value);
3245 }
3246 
3247 static void
g_settings_action_activate(GAction * action,GVariant * parameter)3248 g_settings_action_activate (GAction  *action,
3249                             GVariant *parameter)
3250 {
3251   GSettingsAction *gsa = (GSettingsAction *) action;
3252 
3253   if (g_variant_is_of_type (gsa->key.default_value, G_VARIANT_TYPE_BOOLEAN))
3254     {
3255       GVariant *old;
3256 
3257       if (parameter != NULL)
3258         return;
3259 
3260       old = g_settings_action_get_state (action);
3261       parameter = g_variant_new_boolean (!g_variant_get_boolean (old));
3262       g_variant_unref (old);
3263     }
3264 
3265   g_action_change_state (action, parameter);
3266 }
3267 
3268 static void
g_settings_action_get_property(GObject * object,guint prop_id,GValue * value,GParamSpec * pspec)3269 g_settings_action_get_property (GObject *object, guint prop_id,
3270                                 GValue *value, GParamSpec *pspec)
3271 {
3272   GAction *action = G_ACTION (object);
3273 
3274   switch (prop_id)
3275     {
3276     case ACTION_PROP_NAME:
3277       g_value_set_string (value, g_settings_action_get_name (action));
3278       break;
3279 
3280     case ACTION_PROP_PARAMETER_TYPE:
3281       g_value_set_boxed (value, g_settings_action_get_parameter_type (action));
3282       break;
3283 
3284     case ACTION_PROP_ENABLED:
3285       g_value_set_boolean (value, g_settings_action_get_enabled (action));
3286       break;
3287 
3288     case ACTION_PROP_STATE_TYPE:
3289       g_value_set_boxed (value, g_settings_action_get_state_type (action));
3290       break;
3291 
3292     case ACTION_PROP_STATE:
3293       g_value_set_variant (value, g_settings_action_get_state (action));
3294       break;
3295 
3296     default:
3297       g_assert_not_reached ();
3298     }
3299 }
3300 
3301 static void
g_settings_action_finalize(GObject * object)3302 g_settings_action_finalize (GObject *object)
3303 {
3304   GSettingsAction *gsa = (GSettingsAction *) object;
3305 
3306   g_signal_handlers_disconnect_by_data (gsa->settings, gsa);
3307   g_object_unref (gsa->settings);
3308   g_settings_schema_key_clear (&gsa->key);
3309 
3310   G_OBJECT_CLASS (g_settings_action_parent_class)
3311     ->finalize (object);
3312 }
3313 
3314 static void
g_settings_action_init(GSettingsAction * gsa)3315 g_settings_action_init (GSettingsAction *gsa)
3316 {
3317 }
3318 
3319 static void
g_settings_action_iface_init(GActionInterface * iface)3320 g_settings_action_iface_init (GActionInterface *iface)
3321 {
3322   iface->get_name = g_settings_action_get_name;
3323   iface->get_parameter_type = g_settings_action_get_parameter_type;
3324   iface->get_enabled = g_settings_action_get_enabled;
3325   iface->get_state_type = g_settings_action_get_state_type;
3326   iface->get_state = g_settings_action_get_state;
3327   iface->get_state_hint = g_settings_action_get_state_hint;
3328   iface->change_state = g_settings_action_change_state;
3329   iface->activate = g_settings_action_activate;
3330 }
3331 
3332 static void
g_settings_action_class_init(GSettingsActionClass * class)3333 g_settings_action_class_init (GSettingsActionClass *class)
3334 {
3335   class->get_property = g_settings_action_get_property;
3336   class->finalize = g_settings_action_finalize;
3337 
3338   g_object_class_override_property (class, ACTION_PROP_NAME, "name");
3339   g_object_class_override_property (class, ACTION_PROP_PARAMETER_TYPE, "parameter-type");
3340   g_object_class_override_property (class, ACTION_PROP_ENABLED, "enabled");
3341   g_object_class_override_property (class, ACTION_PROP_STATE_TYPE, "state-type");
3342   g_object_class_override_property (class, ACTION_PROP_STATE, "state");
3343 }
3344 
3345 static void
g_settings_action_changed(GSettings * settings,const gchar * key,gpointer user_data)3346 g_settings_action_changed (GSettings   *settings,
3347                            const gchar *key,
3348                            gpointer     user_data)
3349 {
3350   g_object_notify (user_data, "state");
3351 }
3352 
3353 static void
g_settings_action_enabled_changed(GSettings * settings,const gchar * key,gpointer user_data)3354 g_settings_action_enabled_changed (GSettings   *settings,
3355                                    const gchar *key,
3356                                    gpointer     user_data)
3357 {
3358   g_object_notify (user_data, "enabled");
3359 }
3360 
3361 /**
3362  * g_settings_create_action:
3363  * @settings: a #GSettings
3364  * @key: the name of a key in @settings
3365  *
3366  * Creates a #GAction corresponding to a given #GSettings key.
3367  *
3368  * The action has the same name as the key.
3369  *
3370  * The value of the key becomes the state of the action and the action
3371  * is enabled when the key is writable.  Changing the state of the
3372  * action results in the key being written to.  Changes to the value or
3373  * writability of the key cause appropriate change notifications to be
3374  * emitted for the action.
3375  *
3376  * For boolean-valued keys, action activations take no parameter and
3377  * result in the toggling of the value.  For all other types,
3378  * activations take the new value for the key (which must have the
3379  * correct type).
3380  *
3381  * Returns: (transfer full): a new #GAction
3382  *
3383  * Since: 2.32
3384  **/
3385 GAction *
g_settings_create_action(GSettings * settings,const gchar * key)3386 g_settings_create_action (GSettings   *settings,
3387                           const gchar *key)
3388 {
3389   GSettingsAction *gsa;
3390   gchar *detailed_signal;
3391 
3392   g_return_val_if_fail (G_IS_SETTINGS (settings), NULL);
3393   g_return_val_if_fail (key != NULL, NULL);
3394 
3395   gsa = g_object_new (g_settings_action_get_type (), NULL);
3396   gsa->settings = g_object_ref (settings);
3397   g_settings_schema_key_init (&gsa->key, settings->priv->schema, key);
3398 
3399   detailed_signal = g_strdup_printf ("changed::%s", key);
3400   g_signal_connect (settings, detailed_signal, G_CALLBACK (g_settings_action_changed), gsa);
3401   g_free (detailed_signal);
3402   detailed_signal = g_strdup_printf ("writable-changed::%s", key);
3403   g_signal_connect (settings, detailed_signal, G_CALLBACK (g_settings_action_enabled_changed), gsa);
3404   g_free (detailed_signal);
3405 
3406   return G_ACTION (gsa);
3407 }
3408 
3409 /* Epilogue {{{1 */
3410 
3411 /* vim:set foldmethod=marker: */
3412