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