/*
 * Copyright © 2009, 2010 Codethink Limited
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2 of the licence, or (at your option) any later version.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this library; if not, see <http://www.gnu.org/licenses/>.
 *
 * Author: Ryan Lortie <desrt@desrt.ca>
 */

/* Prelude {{{1 */
#include "config.h"

#include <glib.h>
#include <glibintl.h>

#include "gsettings.h"

#include "gdelayedsettingsbackend.h"
#include "gsettingsbackendinternal.h"
#include "gsettings-mapping.h"
#include "gsettingsschema-internal.h"
#include "gaction.h"

#include "strinfo.c"

/**
 * SECTION:gsettings
 * @short_description: High-level API for application settings
 * @include: gio/gio.h
 *
 * The #GSettings class provides a convenient API for storing and retrieving
 * application settings.
 *
 * Reads and writes can be considered to be non-blocking.  Reading
 * settings with #GSettings is typically extremely fast: on
 * approximately the same order of magnitude (but slower than) a
 * #GHashTable lookup.  Writing settings is also extremely fast in terms
 * of time to return to your application, but can be extremely expensive
 * for other threads and other processes.  Many settings backends
 * (including dconf) have lazy initialisation which means in the common
 * case of the user using their computer without modifying any settings
 * a lot of work can be avoided.  For dconf, the D-Bus service doesn't
 * even need to be started in this case.  For this reason, you should
 * only ever modify #GSettings keys in response to explicit user action.
 * Particular care should be paid to ensure that modifications are not
 * made during startup -- for example, when setting the initial value
 * of preferences widgets.  The built-in g_settings_bind() functionality
 * is careful not to write settings in response to notify signals as a
 * result of modifications that it makes to widgets.
 *
 * When creating a GSettings instance, you have to specify a schema
 * that describes the keys in your settings and their types and default
 * values, as well as some other information.
 *
 * Normally, a schema has as fixed path that determines where the settings
 * are stored in the conceptual global tree of settings. However, schemas
 * can also be '[relocatable][gsettings-relocatable]', i.e. not equipped with
 * a fixed path. This is
 * useful e.g. when the schema describes an 'account', and you want to be
 * able to store a arbitrary number of accounts.
 *
 * Paths must start with and end with a forward slash character ('/')
 * and must not contain two sequential slash characters.  Paths should
 * be chosen based on a domain name associated with the program or
 * library to which the settings belong.  Examples of paths are
 * "/org/gtk/settings/file-chooser/" and "/ca/desrt/dconf-editor/".
 * Paths should not start with "/apps/", "/desktop/" or "/system/" as
 * they often did in GConf.
 *
 * Unlike other configuration systems (like GConf), GSettings does not
 * restrict keys to basic types like strings and numbers. GSettings stores
 * values as #GVariant, and allows any #GVariantType for keys. Key names
 * are restricted to lowercase characters, numbers and '-'. Furthermore,
 * the names must begin with a lowercase character, must not end
 * with a '-', and must not contain consecutive dashes.
 *
 * Similar to GConf, the default values in GSettings schemas can be
 * localized, but the localized values are stored in gettext catalogs
 * and looked up with the domain that is specified in the
 * `gettext-domain` attribute of the <schemalist> or <schema>
 * elements and the category that is specified in the `l10n` attribute of
 * the <default> element. The string which is translated includes all text in
 * the <default> element, including any surrounding quotation marks.
 *
 * The `l10n` attribute must be set to `messages` or `time`, and sets the
 * [locale category for
 * translation](https://www.gnu.org/software/gettext/manual/html_node/Aspects.html#index-locale-categories-1).
 * The `messages` category should be used by default; use `time` for
 * translatable date or time formats. A translation comment can be added as an
 * XML comment immediately above the <default> element — it is recommended to
 * add these comments to aid translators understand the meaning and
 * implications of the default value. An optional translation `context`
 * attribute can be set on the <default> element to disambiguate multiple
 * defaults which use the same string.
 *
 * For example:
 * |[
 *  <!-- Translators: A list of words which are not allowed to be typed, in
 *       GVariant serialization syntax.
 *       See: https://developer.gnome.org/glib/stable/gvariant-text.html -->
 *  <default l10n='messages' context='Banned words'>['bad', 'words']</default>
 * ]|
 *
 * Translations of default values must remain syntactically valid serialized
 * #GVariants (e.g. retaining any surrounding quotation marks) or runtime
 * errors will occur.
 *
 * GSettings uses schemas in a compact binary form that is created
 * by the [glib-compile-schemas][glib-compile-schemas]
 * utility. The input is a schema description in an XML format.
 *
 * A DTD for the gschema XML format can be found here:
 * [gschema.dtd](https://git.gnome.org/browse/glib/tree/gio/gschema.dtd)
 *
 * The [glib-compile-schemas][glib-compile-schemas] tool expects schema
 * files to have the extension `.gschema.xml`.
 *
 * At runtime, schemas are identified by their id (as specified in the
 * id attribute of the <schema> element). The convention for schema
 * ids is to use a dotted name, similar in style to a D-Bus bus name,
 * e.g. "org.gnome.SessionManager". In particular, if the settings are
 * for a specific service that owns a D-Bus bus name, the D-Bus bus name
 * and schema id should match. For schemas which deal with settings not
 * associated with one named application, the id should not use
 * StudlyCaps, e.g. "org.gnome.font-rendering".
 *
 * In addition to #GVariant types, keys can have types that have
 * enumerated types. These can be described by a <choice>,
 * <enum> or <flags> element, as seen in the
 * [example][schema-enumerated]. The underlying type of such a key
 * is string, but you can use g_settings_get_enum(), g_settings_set_enum(),
 * g_settings_get_flags(), g_settings_set_flags() access the numeric values
 * corresponding to the string value of enum and flags keys.
 *
 * An example for default value:
 * |[
 * <schemalist>
 *   <schema id="org.gtk.Test" path="/org/gtk/Test/" gettext-domain="test">
 *
 *     <key name="greeting" type="s">
 *       <default l10n="messages">"Hello, earthlings"</default>
 *       <summary>A greeting</summary>
 *       <description>
 *         Greeting of the invading martians
 *       </description>
 *     </key>
 *
 *     <key name="box" type="(ii)">
 *       <default>(20,30)</default>
 *     </key>
 *
 *   </schema>
 * </schemalist>
 * ]|
 *
 * An example for ranges, choices and enumerated types:
 * |[
 * <schemalist>
 *
 *   <enum id="org.gtk.Test.myenum">
 *     <value nick="first" value="1"/>
 *     <value nick="second" value="2"/>
 *   </enum>
 *
 *   <flags id="org.gtk.Test.myflags">
 *     <value nick="flag1" value="1"/>
 *     <value nick="flag2" value="2"/>
 *     <value nick="flag3" value="4"/>
 *   </flags>
 *
 *   <schema id="org.gtk.Test">
 *
 *     <key name="key-with-range" type="i">
 *       <range min="1" max="100"/>
 *       <default>10</default>
 *     </key>
 *
 *     <key name="key-with-choices" type="s">
 *       <choices>
 *         <choice value='Elisabeth'/>
 *         <choice value='Annabeth'/>
 *         <choice value='Joe'/>
 *       </choices>
 *       <aliases>
 *         <alias value='Anna' target='Annabeth'/>
 *         <alias value='Beth' target='Elisabeth'/>
 *       </aliases>
 *       <default>'Joe'</default>
 *     </key>
 *
 *     <key name='enumerated-key' enum='org.gtk.Test.myenum'>
 *       <default>'first'</default>
 *     </key>
 *
 *     <key name='flags-key' flags='org.gtk.Test.myflags'>
 *       <default>["flag1","flag2"]</default>
 *     </key>
 *   </schema>
 * </schemalist>
 * ]|
 *
 * ## Vendor overrides
 *
 * Default values are defined in the schemas that get installed by
 * an application. Sometimes, it is necessary for a vendor or distributor
 * to adjust these defaults. Since patching the XML source for the schema
 * is inconvenient and error-prone,
 * [glib-compile-schemas][glib-compile-schemas] reads so-called vendor
 * override' files. These are keyfiles in the same directory as the XML
 * schema sources which can override default values. The schema id serves
 * as the group name in the key file, and the values are expected in
 * serialized GVariant form, as in the following example:
 * |[
 *     [org.gtk.Example]
 *     key1='string'
 *     key2=1.5
 * ]|
 *
 * glib-compile-schemas expects schema files to have the extension
 * `.gschema.override`.
 *
 * ## Binding
 *
 * A very convenient feature of GSettings lets you bind #GObject properties
 * directly to settings, using g_settings_bind(). Once a GObject property
 * has been bound to a setting, changes on either side are automatically
 * propagated to the other side. GSettings handles details like mapping
 * between GObject and GVariant types, and preventing infinite cycles.
 *
 * This makes it very easy to hook up a preferences dialog to the
 * underlying settings. To make this even more convenient, GSettings
 * looks for a boolean property with the name "sensitivity" and
 * automatically binds it to the writability of the bound setting.
 * If this 'magic' gets in the way, it can be suppressed with the
 * #G_SETTINGS_BIND_NO_SENSITIVITY flag.
 *
 * ## Relocatable schemas # {#gsettings-relocatable}
 *
 * A relocatable schema is one with no `path` attribute specified on its
 * <schema> element. By using g_settings_new_with_path(), a #GSettings object
 * can be instantiated for a relocatable schema, assigning a path to the
 * instance. Paths passed to g_settings_new_with_path() will typically be
 * constructed dynamically from a constant prefix plus some form of instance
 * identifier; but they must still be valid GSettings paths. Paths could also
 * be constant and used with a globally installed schema originating from a
 * dependency library.
 *
 * For example, a relocatable schema could be used to store geometry information
 * for different windows in an application. If the schema ID was
 * `org.foo.MyApp.Window`, it could be instantiated for paths
 * `/org/foo/MyApp/main/`, `/org/foo/MyApp/document-1/`,
 * `/org/foo/MyApp/document-2/`, etc. If any of the paths are well-known
 * they can be specified as <child> elements in the parent schema, e.g.:
 * |[
 * <schema id="org.foo.MyApp" path="/org/foo/MyApp/">
 *   <child name="main" schema="org.foo.MyApp.Window"/>
 * </schema>
 * ]|
 *
 * ## Build system integration # {#gsettings-build-system}
 *
 * GSettings comes with autotools integration to simplify compiling and
 * installing schemas. To add GSettings support to an application, add the
 * following to your `configure.ac`:
 * |[
 * GLIB_GSETTINGS
 * ]|
 *
 * In the appropriate `Makefile.am`, use the following snippet to compile and
 * install the named schema:
 * |[
 * gsettings_SCHEMAS = org.foo.MyApp.gschema.xml
 * EXTRA_DIST = $(gsettings_SCHEMAS)
 *
 * @GSETTINGS_RULES@
 * ]|
 *
 * No changes are needed to the build system to mark a schema XML file for
 * translation. Assuming it sets the `gettext-domain` attribute, a schema may
 * be marked for translation by adding it to `POTFILES.in`, assuming gettext
 * 0.19 is in use (the preferred method for translation):
 * |[
 * data/org.foo.MyApp.gschema.xml
 * ]|
 *
 * Alternatively, if intltool 0.50.1 is in use:
 * |[
 * [type: gettext/gsettings]data/org.foo.MyApp.gschema.xml
 * ]|
 *
 * GSettings will use gettext to look up translations for the <summary> and
 * <description> elements, and also any <default> elements which have a `l10n`
 * attribute set. Translations must not be included in the `.gschema.xml` file
 * by the build system, for example by using intltool XML rules with a
 * `.gschema.xml.in` template.
 *
 * If an enumerated type defined in a C header file is to be used in a GSettings
 * schema, it can either be defined manually using an <enum> element in the
 * schema XML, or it can be extracted automatically from the C header. This
 * approach is preferred, as it ensures the two representations are always
 * synchronised. To do so, add the following to the relevant `Makefile.am`:
 * |[
 * gsettings_ENUM_NAMESPACE = org.foo.MyApp
 * gsettings_ENUM_FILES = my-app-enums.h my-app-misc.h
 * ]|
 *
 * `gsettings_ENUM_NAMESPACE` specifies the schema namespace for the enum files,
 * which are specified in `gsettings_ENUM_FILES`. This will generate a
 * `org.foo.MyApp.enums.xml` file containing the extracted enums, which will be
 * automatically included in the schema compilation, install and uninstall
 * rules. It should not be committed to version control or included in
 * `EXTRA_DIST`.
 */

/**
 * GSettings:
 *
 * #GSettings is an opaque data structure and can only be accessed
 * using the following functions.
 **/

struct _GSettingsPrivate
{
  /* where the signals go... */
  GMainContext *main_context;

  GSettingsBackend *backend;
  GSettingsSchema *schema;
  gchar *path;

  GDelayedSettingsBackend *delayed;
};

enum
{
  PROP_0,
  PROP_SCHEMA,
  PROP_SCHEMA_ID,
  PROP_BACKEND,
  PROP_PATH,
  PROP_HAS_UNAPPLIED,
  PROP_DELAY_APPLY
};

enum
{
  SIGNAL_WRITABLE_CHANGE_EVENT,
  SIGNAL_WRITABLE_CHANGED,
  SIGNAL_CHANGE_EVENT,
  SIGNAL_CHANGED,
  N_SIGNALS
};

static guint g_settings_signals[N_SIGNALS];

G_DEFINE_TYPE_WITH_PRIVATE (GSettings, g_settings, G_TYPE_OBJECT)

/* Signals {{{1 */
static gboolean
g_settings_real_change_event (GSettings    *settings,
                              const GQuark *keys,
                              gint          n_keys)
{
  gint i;

  if (keys == NULL)
    keys = g_settings_schema_list (settings->priv->schema, &n_keys);

  for (i = 0; i < n_keys; i++)
    {
      const gchar *key = g_quark_to_string (keys[i]);

      if (g_str_has_suffix (key, "/"))
        continue;

      g_signal_emit (settings, g_settings_signals[SIGNAL_CHANGED], keys[i], key);
    }

  return FALSE;
}

static gboolean
g_settings_real_writable_change_event (GSettings *settings,
                                       GQuark     key)
{
  const GQuark *keys = &key;
  gint n_keys = 1;
  gint i;

  if (key == 0)
    keys = g_settings_schema_list (settings->priv->schema, &n_keys);

  for (i = 0; i < n_keys; i++)
    {
      const gchar *key = g_quark_to_string (keys[i]);

      if (g_str_has_suffix (key, "/"))
        continue;

      g_signal_emit (settings, g_settings_signals[SIGNAL_WRITABLE_CHANGED], keys[i], key);
    }

  return FALSE;
}

static void
settings_backend_changed (GObject             *target,
                          GSettingsBackend    *backend,
                          const gchar         *key,
                          gpointer             origin_tag)
{
  GSettings *settings = G_SETTINGS (target);
  gboolean ignore_this;
  gint i;

  /* We used to assert here:
   *
   *   settings->priv->backend == backend
   *
   * but it could be the case that a notification is queued for delivery
   * while someone calls g_settings_delay() (which changes the backend).
   *
   * Since the delay backend would just pass that straight through
   * anyway, it doesn't make sense to try to detect this case.
   * Therefore, we just accept it.
   */

  for (i = 0; key[i] == settings->priv->path[i]; i++);

  if (settings->priv->path[i] == '\0' &&
      g_settings_schema_has_key (settings->priv->schema, key + i))
    {
      GQuark quark;

      quark = g_quark_from_string (key + i);
      g_signal_emit (settings, g_settings_signals[SIGNAL_CHANGE_EVENT],
                     0, &quark, 1, &ignore_this);
    }
}

static void
settings_backend_path_changed (GObject          *target,
                               GSettingsBackend *backend,
                               const gchar      *path,
                               gpointer          origin_tag)
{
  GSettings *settings = G_SETTINGS (target);
  gboolean ignore_this;

  if (g_str_has_prefix (settings->priv->path, path))
    g_signal_emit (settings, g_settings_signals[SIGNAL_CHANGE_EVENT],
                   0, NULL, 0, &ignore_this);
}

static void
settings_backend_keys_changed (GObject             *target,
                               GSettingsBackend    *backend,
                               const gchar         *path,
                               gpointer             origin_tag,
                               const gchar * const *items)
{
  GSettings *settings = G_SETTINGS (target);
  gboolean ignore_this;
  gint i;

  for (i = 0; settings->priv->path[i] &&
              settings->priv->path[i] == path[i]; i++);

  if (path[i] == '\0')
    {
      GQuark quarks[256];
      gint j, l = 0;

      for (j = 0; items[j]; j++)
         {
           const gchar *item = items[j];
           gint k;

           for (k = 0; item[k] == settings->priv->path[i + k]; k++);

           if (settings->priv->path[i + k] == '\0' &&
               g_settings_schema_has_key (settings->priv->schema, item + k))
             quarks[l++] = g_quark_from_string (item + k);

           /* "256 quarks ought to be enough for anybody!"
            * If this bites you, I'm sorry.  Please file a bug.
            */
           g_assert (l < 256);
         }

      if (l > 0)
        g_signal_emit (settings, g_settings_signals[SIGNAL_CHANGE_EVENT],
                       0, quarks, l, &ignore_this);
    }
}

static void
settings_backend_writable_changed (GObject          *target,
                                   GSettingsBackend *backend,
                                   const gchar      *key)
{
  GSettings *settings = G_SETTINGS (target);
  gboolean ignore_this;
  gint i;

  for (i = 0; key[i] == settings->priv->path[i]; i++);

  if (settings->priv->path[i] == '\0' &&
      g_settings_schema_has_key (settings->priv->schema, key + i))
    g_signal_emit (settings, g_settings_signals[SIGNAL_WRITABLE_CHANGE_EVENT],
                   0, g_quark_from_string (key + i), &ignore_this);
}

static void
settings_backend_path_writable_changed (GObject          *target,
                                        GSettingsBackend *backend,
                                        const gchar      *path)
{
  GSettings *settings = G_SETTINGS (target);
  gboolean ignore_this;

  if (g_str_has_prefix (settings->priv->path, path))
    g_signal_emit (settings, g_settings_signals[SIGNAL_WRITABLE_CHANGE_EVENT],
                   0, (GQuark) 0, &ignore_this);
}

/* Properties, Construction, Destruction {{{1 */
static void
g_settings_set_property (GObject      *object,
                         guint         prop_id,
                         const GValue *value,
                         GParamSpec   *pspec)
{
  GSettings *settings = G_SETTINGS (object);

  switch (prop_id)
    {
    case PROP_SCHEMA:
      {
        GSettingsSchema *schema;

        schema = g_value_dup_boxed (value);

        /* we receive a set_property() call for "settings-schema" even
         * if it was not specified (ie: with NULL value).  ->schema
         * could already be set at this point (ie: via "schema-id").
         * check for NULL to avoid clobbering the existing value.
         */
        if (schema != NULL)
          {
            g_assert (settings->priv->schema == NULL);
            settings->priv->schema = schema;
          }
      }
      break;

    case PROP_SCHEMA_ID:
      {
        const gchar *schema_id;

        schema_id = g_value_get_string (value);

        /* we receive a set_property() call for both "schema" and
         * "schema-id", even if they are not set.  Hopefully only one of
         * them is non-NULL.
         */
        if (schema_id != NULL)
          {
            GSettingsSchemaSource *default_source;

            g_assert (settings->priv->schema == NULL);
            default_source = g_settings_schema_source_get_default ();

            if (default_source == NULL)
              g_error ("No GSettings schemas are installed on the system");

            settings->priv->schema = g_settings_schema_source_lookup (default_source, schema_id, TRUE);

            if (settings->priv->schema == NULL)
              g_error ("Settings schema '%s' is not installed\n", schema_id);
          }
      }
      break;

    case PROP_PATH:
      settings->priv->path = g_value_dup_string (value);
      break;

    case PROP_BACKEND:
      settings->priv->backend = g_value_dup_object (value);
      break;

    default:
      g_assert_not_reached ();
    }
}

static void
g_settings_get_property (GObject    *object,
                         guint       prop_id,
                         GValue     *value,
                         GParamSpec *pspec)
{
  GSettings *settings = G_SETTINGS (object);

  switch (prop_id)
    {
    case PROP_SCHEMA:
      g_value_set_boxed (value, settings->priv->schema);
      break;

     case PROP_SCHEMA_ID:
      g_value_set_string (value, g_settings_schema_get_id (settings->priv->schema));
      break;

     case PROP_BACKEND:
      g_value_set_object (value, settings->priv->backend);
      break;

     case PROP_PATH:
      g_value_set_string (value, settings->priv->path);
      break;

     case PROP_HAS_UNAPPLIED:
      g_value_set_boolean (value, g_settings_get_has_unapplied (settings));
      break;

     case PROP_DELAY_APPLY:
      g_value_set_boolean (value, settings->priv->delayed != NULL);
      break;

     default:
      g_assert_not_reached ();
    }
}

static const GSettingsListenerVTable listener_vtable = {
  settings_backend_changed,
  settings_backend_path_changed,
  settings_backend_keys_changed,
  settings_backend_writable_changed,
  settings_backend_path_writable_changed
};

static void
g_settings_constructed (GObject *object)
{
  GSettings *settings = G_SETTINGS (object);
  const gchar *schema_path;

  schema_path = g_settings_schema_get_path (settings->priv->schema);

  if (settings->priv->path && schema_path && strcmp (settings->priv->path, schema_path) != 0)
    g_error ("settings object created with schema '%s' and path '%s', but path '%s' is specified by schema",
             g_settings_schema_get_id (settings->priv->schema), settings->priv->path, schema_path);

  if (settings->priv->path == NULL)
    {
      if (schema_path == NULL)
        g_error ("attempting to create schema '%s' without a path",
                 g_settings_schema_get_id (settings->priv->schema));

      settings->priv->path = g_strdup (schema_path);
    }

  if (settings->priv->backend == NULL)
    settings->priv->backend = g_settings_backend_get_default ();

  g_settings_backend_watch (settings->priv->backend,
                            &listener_vtable, G_OBJECT (settings),
                            settings->priv->main_context);
  g_settings_backend_subscribe (settings->priv->backend,
                                settings->priv->path);
}

static void
g_settings_finalize (GObject *object)
{
  GSettings *settings = G_SETTINGS (object);

  g_settings_backend_unsubscribe (settings->priv->backend,
                                  settings->priv->path);
  g_main_context_unref (settings->priv->main_context);
  g_object_unref (settings->priv->backend);
  g_settings_schema_unref (settings->priv->schema);
  g_free (settings->priv->path);

  G_OBJECT_CLASS (g_settings_parent_class)->finalize (object);
}

static void
g_settings_init (GSettings *settings)
{
  settings->priv = g_settings_get_instance_private (settings);
  settings->priv->main_context = g_main_context_ref_thread_default ();
}

static void
g_settings_class_init (GSettingsClass *class)
{
  GObjectClass *object_class = G_OBJECT_CLASS (class);

  class->writable_change_event = g_settings_real_writable_change_event;
  class->change_event = g_settings_real_change_event;

  object_class->set_property = g_settings_set_property;
  object_class->get_property = g_settings_get_property;
  object_class->constructed = g_settings_constructed;
  object_class->finalize = g_settings_finalize;

  /**
   * GSettings::changed:
   * @settings: the object on which the signal was emitted
   * @key: the name of the key that changed
   *
   * The "changed" signal is emitted when a key has potentially changed.
   * You should call one of the g_settings_get() calls to check the new
   * value.
   *
   * This signal supports detailed connections.  You can connect to the
   * detailed signal "changed::x" in order to only receive callbacks
   * when key "x" changes.
   *
   * Note that @settings only emits this signal if you have read @key at
   * least once while a signal handler was already connected for @key.
   */
  g_settings_signals[SIGNAL_CHANGED] =
    g_signal_new (I_("changed"), G_TYPE_SETTINGS,
                  G_SIGNAL_RUN_LAST | G_SIGNAL_DETAILED,
                  G_STRUCT_OFFSET (GSettingsClass, changed),
                  NULL, NULL, g_cclosure_marshal_VOID__STRING, G_TYPE_NONE,
                  1, G_TYPE_STRING | G_SIGNAL_TYPE_STATIC_SCOPE);

  /**
   * GSettings::change-event:
   * @settings: the object on which the signal was emitted
   * @keys: (array length=n_keys) (element-type GQuark) (allow-none):
   *        an array of #GQuarks for the changed keys, or %NULL
   * @n_keys: the length of the @keys array, or 0
   *
   * The "change-event" signal is emitted once per change event that
   * affects this settings object.  You should connect to this signal
   * only if you are interested in viewing groups of changes before they
   * are split out into multiple emissions of the "changed" signal.
   * For most use cases it is more appropriate to use the "changed" signal.
   *
   * In the event that the change event applies to one or more specified
   * keys, @keys will be an array of #GQuark of length @n_keys.  In the
   * event that the change event applies to the #GSettings object as a
   * whole (ie: potentially every key has been changed) then @keys will
   * be %NULL and @n_keys will be 0.
   *
   * The default handler for this signal invokes the "changed" signal
   * for each affected key.  If any other connected handler returns
   * %TRUE then this default functionality will be suppressed.
   *
   * Returns: %TRUE to stop other handlers from being invoked for the
   *          event. FALSE to propagate the event further.
   */
  g_settings_signals[SIGNAL_CHANGE_EVENT] =
    g_signal_new (I_("change-event"), G_TYPE_SETTINGS,
                  G_SIGNAL_RUN_LAST,
                  G_STRUCT_OFFSET (GSettingsClass, change_event),
                  g_signal_accumulator_true_handled, NULL,
                  NULL,
                  G_TYPE_BOOLEAN, 2, G_TYPE_POINTER, G_TYPE_INT);

  /**
   * GSettings::writable-changed:
   * @settings: the object on which the signal was emitted
   * @key: the key
   *
   * The "writable-changed" signal is emitted when the writability of a
   * key has potentially changed.  You should call
   * g_settings_is_writable() in order to determine the new status.
   *
   * This signal supports detailed connections.  You can connect to the
   * detailed signal "writable-changed::x" in order to only receive
   * callbacks when the writability of "x" changes.
   */
  g_settings_signals[SIGNAL_WRITABLE_CHANGED] =
    g_signal_new (I_("writable-changed"), G_TYPE_SETTINGS,
                  G_SIGNAL_RUN_LAST | G_SIGNAL_DETAILED,
                  G_STRUCT_OFFSET (GSettingsClass, writable_changed),
                  NULL, NULL, g_cclosure_marshal_VOID__STRING, G_TYPE_NONE,
                  1, G_TYPE_STRING | G_SIGNAL_TYPE_STATIC_SCOPE);

  /**
   * GSettings::writable-change-event:
   * @settings: the object on which the signal was emitted
   * @key: the quark of the key, or 0
   *
   * The "writable-change-event" signal is emitted once per writability
   * change event that affects this settings object.  You should connect
   * to this signal if you are interested in viewing groups of changes
   * before they are split out into multiple emissions of the
   * "writable-changed" signal.  For most use cases it is more
   * appropriate to use the "writable-changed" signal.
   *
   * In the event that the writability change applies only to a single
   * key, @key will be set to the #GQuark for that key.  In the event
   * that the writability change affects the entire settings object,
   * @key will be 0.
   *
   * The default handler for this signal invokes the "writable-changed"
   * and "changed" signals for each affected key.  This is done because
   * changes in writability might also imply changes in value (if for
   * example, a new mandatory setting is introduced).  If any other
   * connected handler returns %TRUE then this default functionality
   * will be suppressed.
   *
   * Returns: %TRUE to stop other handlers from being invoked for the
   *          event. FALSE to propagate the event further.
   */
  g_settings_signals[SIGNAL_WRITABLE_CHANGE_EVENT] =
    g_signal_new (I_("writable-change-event"), G_TYPE_SETTINGS,
                  G_SIGNAL_RUN_LAST,
                  G_STRUCT_OFFSET (GSettingsClass, writable_change_event),
                  g_signal_accumulator_true_handled, NULL,
                  NULL, G_TYPE_BOOLEAN, 1, G_TYPE_UINT);

  /**
   * GSettings:context:
   *
   * The name of the context that the settings are stored in.
   */
  g_object_class_install_property (object_class, PROP_BACKEND,
    g_param_spec_object ("backend",
                         P_("GSettingsBackend"),
                         P_("The GSettingsBackend for this settings object"),
                         G_TYPE_SETTINGS_BACKEND, G_PARAM_CONSTRUCT_ONLY |
                         G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));

  /**
   * GSettings:settings-schema:
   *
   * The #GSettingsSchema describing the types of keys for this
   * #GSettings object.
   *
   * Ideally, this property would be called 'schema'.  #GSettingsSchema
   * has only existed since version 2.32, however, and before then the
   * 'schema' property was used to refer to the ID of the schema rather
   * than the schema itself.  Take care.
   */
  g_object_class_install_property (object_class, PROP_SCHEMA,
    g_param_spec_boxed ("settings-schema",
                        P_("schema"),
                        P_("The GSettingsSchema for this settings object"),
                        G_TYPE_SETTINGS_SCHEMA,
                        G_PARAM_CONSTRUCT_ONLY |
                        G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));

  /**
   * GSettings:schema:
   *
   * The name of the schema that describes the types of keys
   * for this #GSettings object.
   *
   * The type of this property is *not* #GSettingsSchema.
   * #GSettingsSchema has only existed since version 2.32 and
   * unfortunately this name was used in previous versions to refer to
   * the schema ID rather than the schema itself.  Take care to use the
   * 'settings-schema' property if you wish to pass in a
   * #GSettingsSchema.
   *
   * Deprecated:2.32:Use the 'schema-id' property instead.  In a future
   * version, this property may instead refer to a #GSettingsSchema.
   */
  g_object_class_install_property (object_class, PROP_SCHEMA_ID,
    g_param_spec_string ("schema",
                         P_("Schema name"),
                         P_("The name of the schema for this settings object"),
                         NULL,
                         G_PARAM_CONSTRUCT_ONLY |
                         G_PARAM_DEPRECATED | G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));

  /**
   * GSettings:schema-id:
   *
   * The name of the schema that describes the types of keys
   * for this #GSettings object.
   */
  g_object_class_install_property (object_class, PROP_SCHEMA_ID,
    g_param_spec_string ("schema-id",
                         P_("Schema name"),
                         P_("The name of the schema for this settings object"),
                         NULL,
                         G_PARAM_CONSTRUCT_ONLY |
                         G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));

   /**
    * GSettings:path:
    *
    * The path within the backend where the settings are stored.
    */
   g_object_class_install_property (object_class, PROP_PATH,
     g_param_spec_string ("path",
                          P_("Base path"),
                          P_("The path within the backend where the settings are"),
                          NULL,
                          G_PARAM_CONSTRUCT_ONLY |
                          G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));

   /**
    * GSettings:has-unapplied:
    *
    * If this property is %TRUE, the #GSettings object has outstanding
    * changes that will be applied when g_settings_apply() is called.
    */
   g_object_class_install_property (object_class, PROP_HAS_UNAPPLIED,
     g_param_spec_boolean ("has-unapplied",
                           P_("Has unapplied changes"),
                           P_("TRUE if there are outstanding changes to apply()"),
                           FALSE,
                           G_PARAM_READABLE | G_PARAM_STATIC_STRINGS));

   /**
    * GSettings:delay-apply:
    *
    * Whether the #GSettings object is in 'delay-apply' mode. See
    * g_settings_delay() for details.
    *
    * Since: 2.28
    */
   g_object_class_install_property (object_class, PROP_DELAY_APPLY,
     g_param_spec_boolean ("delay-apply",
                           P_("Delay-apply mode"),
                           P_("Whether this settings object is in 'delay-apply' mode"),
                           FALSE,
                           G_PARAM_READABLE | G_PARAM_STATIC_STRINGS));
}

/* Construction (new, new_with_path, etc.) {{{1 */
/**
 * g_settings_new:
 * @schema_id: the id of the schema
 *
 * Creates a new #GSettings object with the schema specified by
 * @schema_id.
 *
 * Signals on the newly created #GSettings object will be dispatched
 * via the thread-default #GMainContext in effect at the time of the
 * call to g_settings_new().  The new #GSettings will hold a reference
 * on the context.  See g_main_context_push_thread_default().
 *
 * Returns: a new #GSettings object
 *
 * Since: 2.26
 */
GSettings *
g_settings_new (const gchar *schema_id)
{
  g_return_val_if_fail (schema_id != NULL, NULL);

  return g_object_new (G_TYPE_SETTINGS,
                       "schema-id", schema_id,
                       NULL);
}

static gboolean
path_is_valid (const gchar *path)
{
  if (!path)
    return FALSE;

  if (path[0] != '/')
    return FALSE;

  if (!g_str_has_suffix (path, "/"))
    return FALSE;

  return strstr (path, "//") == NULL;
}

/**
 * g_settings_new_with_path:
 * @schema_id: the id of the schema
 * @path: the path to use
 *
 * Creates a new #GSettings object with the relocatable schema specified
 * by @schema_id and a given path.
 *
 * You only need to do this if you want to directly create a settings
 * object with a schema that doesn't have a specified path of its own.
 * That's quite rare.
 *
 * It is a programmer error to call this function for a schema that
 * has an explicitly specified path.
 *
 * It is a programmer error if @path is not a valid path.  A valid path
 * begins and ends with '/' and does not contain two consecutive '/'
 * characters.
 *
 * Returns: a new #GSettings object
 *
 * Since: 2.26
 */
GSettings *
g_settings_new_with_path (const gchar *schema_id,
                          const gchar *path)
{
  g_return_val_if_fail (schema_id != NULL, NULL);
  g_return_val_if_fail (path_is_valid (path), NULL);

  return g_object_new (G_TYPE_SETTINGS,
                       "schema-id", schema_id,
                       "path", path,
                       NULL);
}

/**
 * g_settings_new_with_backend:
 * @schema_id: the id of the schema
 * @backend: the #GSettingsBackend to use
 *
 * Creates a new #GSettings object with the schema specified by
 * @schema_id and a given #GSettingsBackend.
 *
 * Creating a #GSettings object with a different backend allows accessing
 * settings from a database other than the usual one. For example, it may make
 * sense to pass a backend corresponding to the "defaults" settings database on
 * the system to get a settings object that modifies the system default
 * settings instead of the settings for this user.
 *
 * Returns: a new #GSettings object
 *
 * Since: 2.26
 */
GSettings *
g_settings_new_with_backend (const gchar      *schema_id,
                             GSettingsBackend *backend)
{
  g_return_val_if_fail (schema_id != NULL, NULL);
  g_return_val_if_fail (G_IS_SETTINGS_BACKEND (backend), NULL);

  return g_object_new (G_TYPE_SETTINGS,
                       "schema-id", schema_id,
                       "backend", backend,
                       NULL);
}

/**
 * g_settings_new_with_backend_and_path:
 * @schema_id: the id of the schema
 * @backend: the #GSettingsBackend to use
 * @path: the path to use
 *
 * Creates a new #GSettings object with the schema specified by
 * @schema_id and a given #GSettingsBackend and path.
 *
 * This is a mix of g_settings_new_with_backend() and
 * g_settings_new_with_path().
 *
 * Returns: a new #GSettings object
 *
 * Since: 2.26
 */
GSettings *
g_settings_new_with_backend_and_path (const gchar      *schema_id,
                                      GSettingsBackend *backend,
                                      const gchar      *path)
{
  g_return_val_if_fail (schema_id != NULL, NULL);
  g_return_val_if_fail (G_IS_SETTINGS_BACKEND (backend), NULL);
  g_return_val_if_fail (path_is_valid (path), NULL);

  return g_object_new (G_TYPE_SETTINGS,
                       "schema-id", schema_id,
                       "backend", backend,
                       "path", path,
                       NULL);
}

/**
 * g_settings_new_full:
 * @schema: a #GSettingsSchema
 * @backend: (allow-none): a #GSettingsBackend
 * @path: (allow-none): the path to use
 *
 * Creates a new #GSettings object with a given schema, backend and
 * path.
 *
 * It should be extremely rare that you ever want to use this function.
 * It is made available for advanced use-cases (such as plugin systems
 * that want to provide access to schemas loaded from custom locations,
 * etc).
 *
 * At the most basic level, a #GSettings object is a pure composition of
 * 4 things: a #GSettingsSchema, a #GSettingsBackend, a path within that
 * backend, and a #GMainContext to which signals are dispatched.
 *
 * This constructor therefore gives you full control over constructing
 * #GSettings instances.  The first 3 parameters are given directly as
 * @schema, @backend and @path, and the main context is taken from the
 * thread-default (as per g_settings_new()).
 *
 * If @backend is %NULL then the default backend is used.
 *
 * If @path is %NULL then the path from the schema is used.  It is an
 * error if @path is %NULL and the schema has no path of its own or if
 * @path is non-%NULL and not equal to the path that the schema does
 * have.
 *
 * Returns: a new #GSettings object
 *
 * Since: 2.32
 */
GSettings *
g_settings_new_full (GSettingsSchema  *schema,
                     GSettingsBackend *backend,
                     const gchar      *path)
{
  g_return_val_if_fail (schema != NULL, NULL);
  g_return_val_if_fail (backend == NULL || G_IS_SETTINGS_BACKEND (backend), NULL);
  g_return_val_if_fail (path == NULL || path_is_valid (path), NULL);

  return g_object_new (G_TYPE_SETTINGS,
                       "settings-schema", schema,
                       "backend", backend,
                       "path", path,
                       NULL);
}

/* Internal read/write utilities {{{1 */
static gboolean
g_settings_write_to_backend (GSettings          *settings,
                             GSettingsSchemaKey *key,
                             GVariant           *value)
{
  gboolean success;
  gchar *path;

  path = g_strconcat (settings->priv->path, key->name, NULL);
  success = g_settings_backend_write (settings->priv->backend, path, value, NULL);
  g_free (path);

  return success;
}

static GVariant *
g_settings_read_from_backend (GSettings          *settings,
                              GSettingsSchemaKey *key,
                              gboolean            user_value_only,
                              gboolean            default_value)
{
  GVariant *value;
  GVariant *fixup;
  gchar *path;

  path = g_strconcat (settings->priv->path, key->name, NULL);
  if (user_value_only)
    value = g_settings_backend_read_user_value (settings->priv->backend, path, key->type);
  else
    value = g_settings_backend_read (settings->priv->backend, path, key->type, default_value);
  g_free (path);

  if (value != NULL)
    {
      fixup = g_settings_schema_key_range_fixup (key, value);
      g_variant_unref (value);
    }
  else
    fixup = NULL;

  return fixup;
}

/* Public Get/Set API {{{1 (get, get_value, set, set_value, get_mapped) */
/**
 * g_settings_get_value:
 * @settings: a #GSettings object
 * @key: the key to get the value for
 *
 * Gets the value that is stored in @settings for @key.
 *
 * It is a programmer error to give a @key that isn't contained in the
 * schema for @settings.
 *
 * Returns: a new #GVariant
 *
 * Since: 2.26
 */
GVariant *
g_settings_get_value (GSettings   *settings,
                      const gchar *key)
{
  GSettingsSchemaKey skey;
  GVariant *value;

  g_return_val_if_fail (G_IS_SETTINGS (settings), NULL);
  g_return_val_if_fail (key != NULL, NULL);

  g_settings_schema_key_init (&skey, settings->priv->schema, key);
  value = g_settings_read_from_backend (settings, &skey, FALSE, FALSE);

  if (value == NULL)
    value = g_settings_schema_key_get_translated_default (&skey);

  if (value == NULL)
    value = g_variant_ref (skey.default_value);

  g_settings_schema_key_clear (&skey);

  return value;
}

/**
 * g_settings_get_user_value:
 * @settings: a #GSettings object
 * @key: the key to get the user value for
 *
 * Checks the "user value" of a key, if there is one.
 *
 * The user value of a key is the last value that was set by the user.
 *
 * After calling g_settings_reset() this function should always return
 * %NULL (assuming something is not wrong with the system
 * configuration).
 *
 * It is possible that g_settings_get_value() will return a different
 * value than this function.  This can happen in the case that the user
 * set a value for a key that was subsequently locked down by the system
 * administrator -- this function will return the user's old value.
 *
 * This function may be useful for adding a "reset" option to a UI or
 * for providing indication that a particular value has been changed.
 *
 * It is a programmer error to give a @key that isn't contained in the
 * schema for @settings.
 *
 * Returns: (allow-none) (transfer full): the user's value, if set
 *
 * Since: 2.40
 **/
GVariant *
g_settings_get_user_value (GSettings   *settings,
                           const gchar *key)
{
  GSettingsSchemaKey skey;
  GVariant *value;

  g_return_val_if_fail (G_IS_SETTINGS (settings), NULL);
  g_return_val_if_fail (key != NULL, NULL);

  g_settings_schema_key_init (&skey, settings->priv->schema, key);
  value = g_settings_read_from_backend (settings, &skey, TRUE, FALSE);
  g_settings_schema_key_clear (&skey);

  return value;
}

/**
 * g_settings_get_default_value:
 * @settings: a #GSettings object
 * @key: the key to get the default value for
 *
 * Gets the "default value" of a key.
 *
 * This is the value that would be read if g_settings_reset() were to be
 * called on the key.
 *
 * Note that this may be a different value than returned by
 * g_settings_schema_key_get_default_value() if the system administrator
 * has provided a default value.
 *
 * Comparing the return values of g_settings_get_default_value() and
 * g_settings_get_value() is not sufficient for determining if a value
 * has been set because the user may have explicitly set the value to
 * something that happens to be equal to the default.  The difference
 * here is that if the default changes in the future, the user's key
 * will still be set.
 *
 * This function may be useful for adding an indication to a UI of what
 * the default value was before the user set it.
 *
 * It is a programmer error to give a @key that isn't contained in the
 * schema for @settings.
 *
 * Returns: (allow-none) (transfer full): the default value
 *
 * Since: 2.40
 **/
GVariant *
g_settings_get_default_value (GSettings   *settings,
                              const gchar *key)
{
  GSettingsSchemaKey skey;
  GVariant *value;

  g_return_val_if_fail (G_IS_SETTINGS (settings), NULL);
  g_return_val_if_fail (key != NULL, NULL);

  g_settings_schema_key_init (&skey, settings->priv->schema, key);
  value = g_settings_read_from_backend (settings, &skey, FALSE, TRUE);

  if (value == NULL)
    value = g_settings_schema_key_get_translated_default (&skey);

  if (value == NULL)
    value = g_variant_ref (skey.default_value);

  g_settings_schema_key_clear (&skey);

  return value;
}

/**
 * g_settings_get_enum:
 * @settings: a #GSettings object
 * @key: the key to get the value for
 *
 * Gets the value that is stored in @settings for @key and converts it
 * to the enum value that it represents.
 *
 * In order to use this function the type of the value must be a string
 * and it must be marked in the schema file as an enumerated type.
 *
 * It is a programmer error to give a @key that isn't contained in the
 * schema for @settings or is not marked as an enumerated type.
 *
 * If the value stored in the configuration database is not a valid
 * value for the enumerated type then this function will return the
 * default value.
 *
 * Returns: the enum value
 *
 * Since: 2.26
 **/
gint
g_settings_get_enum (GSettings   *settings,
                     const gchar *key)
{
  GSettingsSchemaKey skey;
  GVariant *value;
  gint result;

  g_return_val_if_fail (G_IS_SETTINGS (settings), -1);
  g_return_val_if_fail (key != NULL, -1);

  g_settings_schema_key_init (&skey, settings->priv->schema, key);

  if (!skey.is_enum)
    {
      g_critical ("g_settings_get_enum() called on key '%s' which is not "
                  "associated with an enumerated type", skey.name);
      g_settings_schema_key_clear (&skey);
      return -1;
    }

  value = g_settings_read_from_backend (settings, &skey, FALSE, FALSE);

  if (value == NULL)
    value = g_settings_schema_key_get_translated_default (&skey);

  if (value == NULL)
    value = g_variant_ref (skey.default_value);

  result = g_settings_schema_key_to_enum (&skey, value);
  g_settings_schema_key_clear (&skey);
  g_variant_unref (value);

  return result;
}

/**
 * g_settings_set_enum:
 * @settings: a #GSettings object
 * @key: a key, within @settings
 * @value: an enumerated value
 *
 * Looks up the enumerated type nick for @value and writes it to @key,
 * within @settings.
 *
 * It is a programmer error to give a @key that isn't contained in the
 * schema for @settings or is not marked as an enumerated type, or for
 * @value not to be a valid value for the named type.
 *
 * After performing the write, accessing @key directly with
 * g_settings_get_string() will return the 'nick' associated with
 * @value.
 *
 * Returns: %TRUE, if the set succeeds
 **/
gboolean
g_settings_set_enum (GSettings   *settings,
                     const gchar *key,
                     gint         value)
{
  GSettingsSchemaKey skey;
  GVariant *variant;
  gboolean success;

  g_return_val_if_fail (G_IS_SETTINGS (settings), FALSE);
  g_return_val_if_fail (key != NULL, FALSE);

  g_settings_schema_key_init (&skey, settings->priv->schema, key);

  if (!skey.is_enum)
    {
      g_critical ("g_settings_set_enum() called on key '%s' which is not "
                  "associated with an enumerated type", skey.name);
      return FALSE;
    }

  if (!(variant = g_settings_schema_key_from_enum (&skey, value)))
    {
      g_critical ("g_settings_set_enum(): invalid enum value %d for key '%s' "
                  "in schema '%s'.  Doing nothing.", value, skey.name,
                  g_settings_schema_get_id (skey.schema));
      g_settings_schema_key_clear (&skey);
      return FALSE;
    }

  success = g_settings_write_to_backend (settings, &skey, variant);
  g_settings_schema_key_clear (&skey);

  return success;
}

/**
 * g_settings_get_flags:
 * @settings: a #GSettings object
 * @key: the key to get the value for
 *
 * Gets the value that is stored in @settings for @key and converts it
 * to the flags value that it represents.
 *
 * In order to use this function the type of the value must be an array
 * of strings and it must be marked in the schema file as an flags type.
 *
 * It is a programmer error to give a @key that isn't contained in the
 * schema for @settings or is not marked as a flags type.
 *
 * If the value stored in the configuration database is not a valid
 * value for the flags type then this function will return the default
 * value.
 *
 * Returns: the flags value
 *
 * Since: 2.26
 **/
guint
g_settings_get_flags (GSettings   *settings,
                      const gchar *key)
{
  GSettingsSchemaKey skey;
  GVariant *value;
  guint result;

  g_return_val_if_fail (G_IS_SETTINGS (settings), -1);
  g_return_val_if_fail (key != NULL, -1);

  g_settings_schema_key_init (&skey, settings->priv->schema, key);

  if (!skey.is_flags)
    {
      g_critical ("g_settings_get_flags() called on key '%s' which is not "
                  "associated with a flags type", skey.name);
      g_settings_schema_key_clear (&skey);
      return -1;
    }

  value = g_settings_read_from_backend (settings, &skey, FALSE, FALSE);

  if (value == NULL)
    value = g_settings_schema_key_get_translated_default (&skey);

  if (value == NULL)
    value = g_variant_ref (skey.default_value);

  result = g_settings_schema_key_to_flags (&skey, value);
  g_settings_schema_key_clear (&skey);
  g_variant_unref (value);

  return result;
}

/**
 * g_settings_set_flags:
 * @settings: a #GSettings object
 * @key: a key, within @settings
 * @value: a flags value
 *
 * Looks up the flags type nicks for the bits specified by @value, puts
 * them in an array of strings and writes the array to @key, within
 * @settings.
 *
 * It is a programmer error to give a @key that isn't contained in the
 * schema for @settings or is not marked as a flags type, or for @value
 * to contain any bits that are not value for the named type.
 *
 * After performing the write, accessing @key directly with
 * g_settings_get_strv() will return an array of 'nicks'; one for each
 * bit in @value.
 *
 * Returns: %TRUE, if the set succeeds
 **/
gboolean
g_settings_set_flags (GSettings   *settings,
                      const gchar *key,
                      guint        value)
{
  GSettingsSchemaKey skey;
  GVariant *variant;
  gboolean success;

  g_return_val_if_fail (G_IS_SETTINGS (settings), FALSE);
  g_return_val_if_fail (key != NULL, FALSE);

  g_settings_schema_key_init (&skey, settings->priv->schema, key);

  if (!skey.is_flags)
    {
      g_critical ("g_settings_set_flags() called on key '%s' which is not "
                  "associated with a flags type", skey.name);
      return FALSE;
    }

  if (!(variant = g_settings_schema_key_from_flags (&skey, value)))
    {
      g_critical ("g_settings_set_flags(): invalid flags value 0x%08x "
                  "for key '%s' in schema '%s'.  Doing nothing.",
                  value, skey.name, g_settings_schema_get_id (skey.schema));
      g_settings_schema_key_clear (&skey);
      return FALSE;
    }

  success = g_settings_write_to_backend (settings, &skey, variant);
  g_settings_schema_key_clear (&skey);

  return success;
}

/**
 * g_settings_set_value:
 * @settings: a #GSettings object
 * @key: the name of the key to set
 * @value: a #GVariant of the correct type
 *
 * Sets @key in @settings to @value.
 *
 * It is a programmer error to give a @key that isn't contained in the
 * schema for @settings or for @value to have the incorrect type, per
 * the schema.
 *
 * If @value is floating then this function consumes the reference.
 *
 * Returns: %TRUE if setting the key succeeded,
 *     %FALSE if the key was not writable
 *
 * Since: 2.26
 **/
gboolean
g_settings_set_value (GSettings   *settings,
                      const gchar *key,
                      GVariant    *value)
{
  GSettingsSchemaKey skey;
  gboolean success;

  g_return_val_if_fail (G_IS_SETTINGS (settings), FALSE);
  g_return_val_if_fail (key != NULL, FALSE);

  g_settings_schema_key_init (&skey, settings->priv->schema, key);

  if (!g_settings_schema_key_type_check (&skey, value))
    {
      g_critical ("g_settings_set_value: key '%s' in '%s' expects type '%s', but a GVariant of type '%s' was given",
                  key,
                  g_settings_schema_get_id (settings->priv->schema),
                  g_variant_type_peek_string (skey.type),
                  g_variant_get_type_string (value));

        return FALSE;
      }

  if (!g_settings_schema_key_range_check (&skey, value))
    {
      g_warning ("g_settings_set_value: value for key '%s' in schema '%s' "
                 "is outside of valid range",
                 key,
                 g_settings_schema_get_id (settings->priv->schema));

        return FALSE;
    }

  success = g_settings_write_to_backend (settings, &skey, value);
  g_settings_schema_key_clear (&skey);

  return success;
}

/**
 * g_settings_get:
 * @settings: a #GSettings object
 * @key: the key to get the value for
 * @format: a #GVariant format string
 * @...: arguments as per @format
 *
 * Gets the value that is stored at @key in @settings.
 *
 * A convenience function that combines g_settings_get_value() with
 * g_variant_get().
 *
 * It is a programmer error to give a @key that isn't contained in the
 * schema for @settings or for the #GVariantType of @format to mismatch
 * the type given in the schema.
 *
 * Since: 2.26
 */
void
g_settings_get (GSettings   *settings,
                const gchar *key,
                const gchar *format,
                ...)
{
  GVariant *value;
  va_list ap;

  value = g_settings_get_value (settings, key);

  if (strchr (format, '&'))
    {
      g_critical ("%s: the format string may not contain '&' (key '%s' from schema '%s'). "
                  "This call will probably stop working with a future version of glib.",
                  G_STRFUNC, key, g_settings_schema_get_id (settings->priv->schema));
    }

  va_start (ap, format);
  g_variant_get_va (value, format, NULL, &ap);
  va_end (ap);

  g_variant_unref (value);
}

/**
 * g_settings_set:
 * @settings: a #GSettings object
 * @key: the name of the key to set
 * @format: a #GVariant format string
 * @...: arguments as per @format
 *
 * Sets @key in @settings to @value.
 *
 * A convenience function that combines g_settings_set_value() with
 * g_variant_new().
 *
 * It is a programmer error to give a @key that isn't contained in the
 * schema for @settings or for the #GVariantType of @format to mismatch
 * the type given in the schema.
 *
 * Returns: %TRUE if setting the key succeeded,
 *     %FALSE if the key was not writable
 *
 * Since: 2.26
 */
gboolean
g_settings_set (GSettings   *settings,
                const gchar *key,
                const gchar *format,
                ...)
{
  GVariant *value;
  va_list ap;

  va_start (ap, format);
  value = g_variant_new_va (format, NULL, &ap);
  va_end (ap);

  return g_settings_set_value (settings, key, value);
}

/**
 * g_settings_get_mapped:
 * @settings: a #GSettings object
 * @key: the key to get the value for
 * @mapping: (scope call): the function to map the value in the
 *           settings database to the value used by the application
 * @user_data: user data for @mapping
 *
 * Gets the value that is stored at @key in @settings, subject to
 * application-level validation/mapping.
 *
 * You should use this function when the application needs to perform
 * some processing on the value of the key (for example, parsing).  The
 * @mapping function performs that processing.  If the function
 * indicates that the processing was unsuccessful (due to a parse error,
 * for example) then the mapping is tried again with another value.
 *
 * This allows a robust 'fall back to defaults' behaviour to be
 * implemented somewhat automatically.
 *
 * The first value that is tried is the user's setting for the key.  If
 * the mapping function fails to map this value, other values may be
 * tried in an unspecified order (system or site defaults, translated
 * schema default values, untranslated schema default values, etc).
 *
 * If the mapping function fails for all possible values, one additional
 * attempt is made: the mapping function is called with a %NULL value.
 * If the mapping function still indicates failure at this point then
 * the application will be aborted.
 *
 * The result parameter for the @mapping function is pointed to a
 * #gpointer which is initially set to %NULL.  The same pointer is given
 * to each invocation of @mapping.  The final value of that #gpointer is
 * what is returned by this function.  %NULL is valid; it is returned
 * just as any other value would be.
 *
 * Returns: (transfer full): the result, which may be %NULL
 **/
gpointer
g_settings_get_mapped (GSettings           *settings,
                       const gchar         *key,
                       GSettingsGetMapping  mapping,
                       gpointer             user_data)
{
  gpointer result = NULL;
  GSettingsSchemaKey skey;
  GVariant *value;
  gboolean okay;

  g_return_val_if_fail (G_IS_SETTINGS (settings), NULL);
  g_return_val_if_fail (key != NULL, NULL);
  g_return_val_if_fail (mapping != NULL, NULL);

  g_settings_schema_key_init (&skey, settings->priv->schema, key);

  if ((value = g_settings_read_from_backend (settings, &skey, FALSE, FALSE)))
    {
      okay = mapping (value, &result, user_data);
      g_variant_unref (value);
      if (okay) goto okay;
    }

  if ((value = g_settings_schema_key_get_translated_default (&skey)))
    {
      okay = mapping (value, &result, user_data);
      g_variant_unref (value);
      if (okay) goto okay;
    }

  if (mapping (skey.default_value, &result, user_data))
    goto okay;

  if (!mapping (NULL, &result, user_data))
    g_error ("The mapping function given to g_settings_get_mapped() for key "
             "'%s' in schema '%s' returned FALSE when given a NULL value.",
             key, g_settings_schema_get_id (settings->priv->schema));

 okay:
  g_settings_schema_key_clear (&skey);

  return result;
}

/* Convenience API (get, set_string, int, double, boolean, strv) {{{1 */
/**
 * g_settings_get_string:
 * @settings: a #GSettings object
 * @key: the key to get the value for
 *
 * Gets the value that is stored at @key in @settings.
 *
 * A convenience variant of g_settings_get() for strings.
 *
 * It is a programmer error to give a @key that isn't specified as
 * having a string type in the schema for @settings.
 *
 * Returns: a newly-allocated string
 *
 * Since: 2.26
 */
gchar *
g_settings_get_string (GSettings   *settings,
                       const gchar *key)
{
  GVariant *value;
  gchar *result;

  value = g_settings_get_value (settings, key);
  result = g_variant_dup_string (value, NULL);
  g_variant_unref (value);

  return result;
}

/**
 * g_settings_set_string:
 * @settings: a #GSettings object
 * @key: the name of the key to set
 * @value: the value to set it to
 *
 * Sets @key in @settings to @value.
 *
 * A convenience variant of g_settings_set() for strings.
 *
 * It is a programmer error to give a @key that isn't specified as
 * having a string type in the schema for @settings.
 *
 * Returns: %TRUE if setting the key succeeded,
 *     %FALSE if the key was not writable
 *
 * Since: 2.26
 */
gboolean
g_settings_set_string (GSettings   *settings,
                       const gchar *key,
                       const gchar *value)
{
  return g_settings_set_value (settings, key, g_variant_new_string (value));
}

/**
 * g_settings_get_int:
 * @settings: a #GSettings object
 * @key: the key to get the value for
 *
 * Gets the value that is stored at @key in @settings.
 *
 * A convenience variant of g_settings_get() for 32-bit integers.
 *
 * It is a programmer error to give a @key that isn't specified as
 * having a int32 type in the schema for @settings.
 *
 * Returns: an integer
 *
 * Since: 2.26
 */
gint
g_settings_get_int (GSettings   *settings,
                    const gchar *key)
{
  GVariant *value;
  gint result;

  value = g_settings_get_value (settings, key);
  result = g_variant_get_int32 (value);
  g_variant_unref (value);

  return result;
}

/**
 * g_settings_set_int:
 * @settings: a #GSettings object
 * @key: the name of the key to set
 * @value: the value to set it to
 *
 * Sets @key in @settings to @value.
 *
 * A convenience variant of g_settings_set() for 32-bit integers.
 *
 * It is a programmer error to give a @key that isn't specified as
 * having a int32 type in the schema for @settings.
 *
 * Returns: %TRUE if setting the key succeeded,
 *     %FALSE if the key was not writable
 *
 * Since: 2.26
 */
gboolean
g_settings_set_int (GSettings   *settings,
                    const gchar *key,
                    gint         value)
{
  return g_settings_set_value (settings, key, g_variant_new_int32 (value));
}

/**
 * g_settings_get_int64:
 * @settings: a #GSettings object
 * @key: the key to get the value for
 *
 * Gets the value that is stored at @key in @settings.
 *
 * A convenience variant of g_settings_get() for 64-bit integers.
 *
 * It is a programmer error to give a @key that isn't specified as
 * having a int64 type in the schema for @settings.
 *
 * Returns: a 64-bit integer
 *
 * Since: 2.50
 */
gint64
g_settings_get_int64 (GSettings   *settings,
                      const gchar *key)
{
  GVariant *value;
  gint64 result;

  value = g_settings_get_value (settings, key);
  result = g_variant_get_int64 (value);
  g_variant_unref (value);

  return result;
}

/**
 * g_settings_set_int64:
 * @settings: a #GSettings object
 * @key: the name of the key to set
 * @value: the value to set it to
 *
 * Sets @key in @settings to @value.
 *
 * A convenience variant of g_settings_set() for 64-bit integers.
 *
 * It is a programmer error to give a @key that isn't specified as
 * having a int64 type in the schema for @settings.
 *
 * Returns: %TRUE if setting the key succeeded,
 *     %FALSE if the key was not writable
 *
 * Since: 2.50
 */
gboolean
g_settings_set_int64 (GSettings   *settings,
                      const gchar *key,
                      gint64       value)
{
  return g_settings_set_value (settings, key, g_variant_new_int64 (value));
}

/**
 * g_settings_get_uint:
 * @settings: a #GSettings object
 * @key: the key to get the value for
 *
 * Gets the value that is stored at @key in @settings.
 *
 * A convenience variant of g_settings_get() for 32-bit unsigned
 * integers.
 *
 * It is a programmer error to give a @key that isn't specified as
 * having a uint32 type in the schema for @settings.
 *
 * Returns: an unsigned integer
 *
 * Since: 2.30
 */
guint
g_settings_get_uint (GSettings   *settings,
                     const gchar *key)
{
  GVariant *value;
  guint result;

  value = g_settings_get_value (settings, key);
  result = g_variant_get_uint32 (value);
  g_variant_unref (value);

  return result;
}

/**
 * g_settings_set_uint:
 * @settings: a #GSettings object
 * @key: the name of the key to set
 * @value: the value to set it to
 *
 * Sets @key in @settings to @value.
 *
 * A convenience variant of g_settings_set() for 32-bit unsigned
 * integers.
 *
 * It is a programmer error to give a @key that isn't specified as
 * having a uint32 type in the schema for @settings.
 *
 * Returns: %TRUE if setting the key succeeded,
 *     %FALSE if the key was not writable
 *
 * Since: 2.30
 */
gboolean
g_settings_set_uint (GSettings   *settings,
                     const gchar *key,
                     guint        value)
{
  return g_settings_set_value (settings, key, g_variant_new_uint32 (value));
}

/**
 * g_settings_get_uint64:
 * @settings: a #GSettings object
 * @key: the key to get the value for
 *
 * Gets the value that is stored at @key in @settings.
 *
 * A convenience variant of g_settings_get() for 64-bit unsigned
 * integers.
 *
 * It is a programmer error to give a @key that isn't specified as
 * having a uint64 type in the schema for @settings.
 *
 * Returns: a 64-bit unsigned integer
 *
 * Since: 2.50
 */
guint64
g_settings_get_uint64 (GSettings   *settings,
                       const gchar *key)
{
  GVariant *value;
  guint64 result;

  value = g_settings_get_value (settings, key);
  result = g_variant_get_uint64 (value);
  g_variant_unref (value);

  return result;
}

/**
 * g_settings_set_uint64:
 * @settings: a #GSettings object
 * @key: the name of the key to set
 * @value: the value to set it to
 *
 * Sets @key in @settings to @value.
 *
 * A convenience variant of g_settings_set() for 64-bit unsigned
 * integers.
 *
 * It is a programmer error to give a @key that isn't specified as
 * having a uint64 type in the schema for @settings.
 *
 * Returns: %TRUE if setting the key succeeded,
 *     %FALSE if the key was not writable
 *
 * Since: 2.50
 */
gboolean
g_settings_set_uint64 (GSettings   *settings,
                       const gchar *key,
                       guint64      value)
{
  return g_settings_set_value (settings, key, g_variant_new_uint64 (value));
}

/**
 * g_settings_get_double:
 * @settings: a #GSettings object
 * @key: the key to get the value for
 *
 * Gets the value that is stored at @key in @settings.
 *
 * A convenience variant of g_settings_get() for doubles.
 *
 * It is a programmer error to give a @key that isn't specified as
 * having a 'double' type in the schema for @settings.
 *
 * Returns: a double
 *
 * Since: 2.26
 */
gdouble
g_settings_get_double (GSettings   *settings,
                       const gchar *key)
{
  GVariant *value;
  gdouble result;

  value = g_settings_get_value (settings, key);
  result = g_variant_get_double (value);
  g_variant_unref (value);

  return result;
}

/**
 * g_settings_set_double:
 * @settings: a #GSettings object
 * @key: the name of the key to set
 * @value: the value to set it to
 *
 * Sets @key in @settings to @value.
 *
 * A convenience variant of g_settings_set() for doubles.
 *
 * It is a programmer error to give a @key that isn't specified as
 * having a 'double' type in the schema for @settings.
 *
 * Returns: %TRUE if setting the key succeeded,
 *     %FALSE if the key was not writable
 *
 * Since: 2.26
 */
gboolean
g_settings_set_double (GSettings   *settings,
                       const gchar *key,
                       gdouble      value)
{
  return g_settings_set_value (settings, key, g_variant_new_double (value));
}

/**
 * g_settings_get_boolean:
 * @settings: a #GSettings object
 * @key: the key to get the value for
 *
 * Gets the value that is stored at @key in @settings.
 *
 * A convenience variant of g_settings_get() for booleans.
 *
 * It is a programmer error to give a @key that isn't specified as
 * having a boolean type in the schema for @settings.
 *
 * Returns: a boolean
 *
 * Since: 2.26
 */
gboolean
g_settings_get_boolean (GSettings  *settings,
                       const gchar *key)
{
  GVariant *value;
  gboolean result;

  value = g_settings_get_value (settings, key);
  result = g_variant_get_boolean (value);
  g_variant_unref (value);

  return result;
}

/**
 * g_settings_set_boolean:
 * @settings: a #GSettings object
 * @key: the name of the key to set
 * @value: the value to set it to
 *
 * Sets @key in @settings to @value.
 *
 * A convenience variant of g_settings_set() for booleans.
 *
 * It is a programmer error to give a @key that isn't specified as
 * having a boolean type in the schema for @settings.
 *
 * Returns: %TRUE if setting the key succeeded,
 *     %FALSE if the key was not writable
 *
 * Since: 2.26
 */
gboolean
g_settings_set_boolean (GSettings  *settings,
                       const gchar *key,
                       gboolean     value)
{
  return g_settings_set_value (settings, key, g_variant_new_boolean (value));
}

/**
 * g_settings_get_strv:
 * @settings: a #GSettings object
 * @key: the key to get the value for
 *
 * A convenience variant of g_settings_get() for string arrays.
 *
 * It is a programmer error to give a @key that isn't specified as
 * having an array of strings type in the schema for @settings.
 *
 * Returns: (array zero-terminated=1) (transfer full): a
 * newly-allocated, %NULL-terminated array of strings, the value that
 * is stored at @key in @settings.
 *
 * Since: 2.26
 */
gchar **
g_settings_get_strv (GSettings   *settings,
                     const gchar *key)
{
  GVariant *value;
  gchar **result;

  value = g_settings_get_value (settings, key);
  result = g_variant_dup_strv (value, NULL);
  g_variant_unref (value);

  return result;
}

/**
 * g_settings_set_strv:
 * @settings: a #GSettings object
 * @key: the name of the key to set
 * @value: (allow-none) (array zero-terminated=1): the value to set it to, or %NULL
 *
 * Sets @key in @settings to @value.
 *
 * A convenience variant of g_settings_set() for string arrays.  If
 * @value is %NULL, then @key is set to be the empty array.
 *
 * It is a programmer error to give a @key that isn't specified as
 * having an array of strings type in the schema for @settings.
 *
 * Returns: %TRUE if setting the key succeeded,
 *     %FALSE if the key was not writable
 *
 * Since: 2.26
 */
gboolean
g_settings_set_strv (GSettings           *settings,
                     const gchar         *key,
                     const gchar * const *value)
{
  GVariant *array;

  if (value != NULL)
    array = g_variant_new_strv (value, -1);
  else
    array = g_variant_new_strv (NULL, 0);

  return g_settings_set_value (settings, key, array);
}

/* Delayed apply (delay, apply, revert, get_has_unapplied) {{{1 */
/**
 * g_settings_delay:
 * @settings: a #GSettings object
 *
 * Changes the #GSettings object into 'delay-apply' mode. In this
 * mode, changes to @settings are not immediately propagated to the
 * backend, but kept locally until g_settings_apply() is called.
 *
 * Since: 2.26
 */
void
g_settings_delay (GSettings *settings)
{
  g_return_if_fail (G_IS_SETTINGS (settings));

  if (settings->priv->delayed)
    return;

  settings->priv->delayed =
    g_delayed_settings_backend_new (settings->priv->backend,
                                    settings,
                                    settings->priv->main_context);
  g_settings_backend_unwatch (settings->priv->backend, G_OBJECT (settings));
  g_object_unref (settings->priv->backend);

  settings->priv->backend = G_SETTINGS_BACKEND (settings->priv->delayed);
  g_settings_backend_watch (settings->priv->backend,
                            &listener_vtable, G_OBJECT (settings),
                            settings->priv->main_context);

  g_object_notify (G_OBJECT (settings), "delay-apply");
}

/**
 * g_settings_apply:
 * @settings: a #GSettings instance
 *
 * Applies any changes that have been made to the settings.  This
 * function does nothing unless @settings is in 'delay-apply' mode;
 * see g_settings_delay().  In the normal case settings are always
 * applied immediately.
 **/
void
g_settings_apply (GSettings *settings)
{
  if (settings->priv->delayed)
    {
      GDelayedSettingsBackend *delayed;

      delayed = G_DELAYED_SETTINGS_BACKEND (settings->priv->backend);
      g_delayed_settings_backend_apply (delayed);
    }
}

/**
 * g_settings_revert:
 * @settings: a #GSettings instance
 *
 * Reverts all non-applied changes to the settings.  This function
 * does nothing unless @settings is in 'delay-apply' mode; see
 * g_settings_delay().  In the normal case settings are always applied
 * immediately.
 *
 * Change notifications will be emitted for affected keys.
 **/
void
g_settings_revert (GSettings *settings)
{
  if (settings->priv->delayed)
    {
      GDelayedSettingsBackend *delayed;

      delayed = G_DELAYED_SETTINGS_BACKEND (settings->priv->backend);
      g_delayed_settings_backend_revert (delayed);
    }
}

/**
 * g_settings_get_has_unapplied:
 * @settings: a #GSettings object
 *
 * Returns whether the #GSettings object has any unapplied
 * changes.  This can only be the case if it is in 'delayed-apply' mode.
 *
 * Returns: %TRUE if @settings has unapplied changes
 *
 * Since: 2.26
 */
gboolean
g_settings_get_has_unapplied (GSettings *settings)
{
  g_return_val_if_fail (G_IS_SETTINGS (settings), FALSE);

  return settings->priv->delayed &&
         g_delayed_settings_backend_get_has_unapplied (
           G_DELAYED_SETTINGS_BACKEND (settings->priv->backend));
}

/* Extra API (reset, sync, get_child, is_writable, list_*, ranges) {{{1 */
/**
 * g_settings_reset:
 * @settings: a #GSettings object
 * @key: the name of a key
 *
 * Resets @key to its default value.
 *
 * This call resets the key, as much as possible, to its default value.
 * That might the value specified in the schema or the one set by the
 * administrator.
 **/
void
g_settings_reset (GSettings *settings,
                  const gchar *key)
{
  gchar *path;

  g_return_if_fail (G_IS_SETTINGS (settings));
  g_return_if_fail (key != NULL);

  path = g_strconcat (settings->priv->path, key, NULL);
  g_settings_backend_reset (settings->priv->backend, path, NULL);
  g_free (path);
}

/**
 * g_settings_sync:
 *
 * Ensures that all pending operations for the given are complete for
 * the default backend.
 *
 * Writes made to a #GSettings are handled asynchronously.  For this
 * reason, it is very unlikely that the changes have it to disk by the
 * time g_settings_set() returns.
 *
 * This call will block until all of the writes have made it to the
 * backend.  Since the mainloop is not running, no change notifications
 * will be dispatched during this call (but some may be queued by the
 * time the call is done).
 **/
void
g_settings_sync (void)
{
  g_settings_backend_sync_default ();
}

/**
 * g_settings_is_writable:
 * @settings: a #GSettings object
 * @name: the name of a key
 *
 * Finds out if a key can be written or not
 *
 * Returns: %TRUE if the key @name is writable
 *
 * Since: 2.26
 */
gboolean
g_settings_is_writable (GSettings   *settings,
                        const gchar *name)
{
  gboolean writable;
  gchar *path;

  g_return_val_if_fail (G_IS_SETTINGS (settings), FALSE);

  path = g_strconcat (settings->priv->path, name, NULL);
  writable = g_settings_backend_get_writable (settings->priv->backend, path);
  g_free (path);

  return writable;
}

/**
 * g_settings_get_child:
 * @settings: a #GSettings object
 * @name: the name of the child schema
 *
 * Creates a child settings object which has a base path of
 * `base-path/@name`, where `base-path` is the base path of
 * @settings.
 *
 * The schema for the child settings object must have been declared
 * in the schema of @settings using a <child> element.
 *
 * Returns: (transfer full): a 'child' settings object
 *
 * Since: 2.26
 */
GSettings *
g_settings_get_child (GSettings   *settings,
                      const gchar *name)
{
  const gchar *child_schema;
  gchar *child_path;
  gchar *child_name;
  GSettings *child;

  g_return_val_if_fail (G_IS_SETTINGS (settings), NULL);

  child_name = g_strconcat (name, "/", NULL);
  child_schema = g_settings_schema_get_string (settings->priv->schema,
                                               child_name);
  if (child_schema == NULL)
    g_error ("Schema '%s' has no child '%s'",
             g_settings_schema_get_id (settings->priv->schema), name);

  child_path = g_strconcat (settings->priv->path, child_name, NULL);
  child = g_object_new (G_TYPE_SETTINGS,
                        "backend", settings->priv->backend,
                        "schema-id", child_schema,
                        "path", child_path,
                        NULL);
  g_free (child_path);
  g_free (child_name);

  return child;
}

/**
 * g_settings_list_keys:
 * @settings: a #GSettings object
 *
 * Introspects the list of keys on @settings.
 *
 * You should probably not be calling this function from "normal" code
 * (since you should already know what keys are in your schema).  This
 * function is intended for introspection reasons.
 *
 * You should free the return value with g_strfreev() when you are done
 * with it.
 *
 * Returns: (transfer full) (element-type utf8): a list of the keys on @settings
 */
gchar **
g_settings_list_keys (GSettings *settings)
{
  return g_settings_schema_list_keys (settings->priv->schema);
}

/**
 * g_settings_list_children:
 * @settings: a #GSettings object
 *
 * Gets the list of children on @settings.
 *
 * The list is exactly the list of strings for which it is not an error
 * to call g_settings_get_child().
 *
 * For GSettings objects that are lists, this value can change at any
 * time and you should connect to the "children-changed" signal to watch
 * for those changes.  Note that there is a race condition here: you may
 * request a child after listing it only for it to have been destroyed
 * in the meantime.  For this reason, g_settings_get_child() may return
 * %NULL even for a child that was listed by this function.
 *
 * For GSettings objects that are not lists, you should probably not be
 * calling this function from "normal" code (since you should already
 * know what children are in your schema).  This function may still be
 * useful there for introspection reasons, however.
 *
 * You should free the return value with g_strfreev() when you are done
 * with it.
 *
 * Returns: (transfer full) (element-type utf8): a list of the children on @settings
 */
gchar **
g_settings_list_children (GSettings *settings)
{
  return g_settings_schema_list_children (settings->priv->schema);
}

/**
 * g_settings_get_range:
 * @settings: a #GSettings
 * @key: the key to query the range of
 *
 * Queries the range of a key.
 *
 * Since: 2.28
 *
 * Deprecated:2.40:Use g_settings_schema_key_get_range() instead.
 **/
GVariant *
g_settings_get_range (GSettings   *settings,
                      const gchar *key)
{
  GSettingsSchemaKey skey;
  GVariant *range;

  g_settings_schema_key_init (&skey, settings->priv->schema, key);
  range = g_settings_schema_key_get_range (&skey);
  g_settings_schema_key_clear (&skey);

  return range;
}

/**
 * g_settings_range_check:
 * @settings: a #GSettings
 * @key: the key to check
 * @value: the value to check
 *
 * Checks if the given @value is of the correct type and within the
 * permitted range for @key.
 *
 * Returns: %TRUE if @value is valid for @key
 *
 * Since: 2.28
 *
 * Deprecated:2.40:Use g_settings_schema_key_range_check() instead.
 **/
gboolean
g_settings_range_check (GSettings   *settings,
                        const gchar *key,
                        GVariant    *value)
{
  GSettingsSchemaKey skey;
  gboolean good;

  g_settings_schema_key_init (&skey, settings->priv->schema, key);
  good = g_settings_schema_key_range_check (&skey, value);
  g_settings_schema_key_clear (&skey);

  return good;
}

/* Binding {{{1 */
typedef struct
{
  GSettingsSchemaKey key;
  GSettings *settings;
  GObject *object;

  GSettingsBindGetMapping get_mapping;
  GSettingsBindSetMapping set_mapping;
  gpointer user_data;
  GDestroyNotify destroy;

  guint writable_handler_id;
  guint property_handler_id;
  const GParamSpec *property;
  guint key_handler_id;

  /* prevent recursion */
  gboolean running;
} GSettingsBinding;

static void
g_settings_binding_free (gpointer data)
{
  GSettingsBinding *binding = data;

  g_assert (!binding->running);

  if (binding->writable_handler_id)
    g_signal_handler_disconnect (binding->settings,
                                 binding->writable_handler_id);

  if (binding->key_handler_id)
    g_signal_handler_disconnect (binding->settings,
                                 binding->key_handler_id);

  if (g_signal_handler_is_connected (binding->object,
                                     binding->property_handler_id))
  g_signal_handler_disconnect (binding->object,
                               binding->property_handler_id);

  g_settings_schema_key_clear (&binding->key);

  if (binding->destroy)
    binding->destroy (binding->user_data);

  g_object_unref (binding->settings);

  g_slice_free (GSettingsBinding, binding);
}

static GQuark
g_settings_binding_quark (const char *property)
{
  GQuark quark;
  gchar *tmp;

  tmp = g_strdup_printf ("gsettingsbinding-%s", property);
  quark = g_quark_from_string (tmp);
  g_free (tmp);

  return quark;
}

static void
g_settings_binding_key_changed (GSettings   *settings,
                                const gchar *key,
                                gpointer     user_data)
{
  GSettingsBinding *binding = user_data;
  GValue value = G_VALUE_INIT;
  GVariant *variant;

  g_assert (settings == binding->settings);
  g_assert (key == binding->key.name);

  if (binding->running)
    return;

  binding->running = TRUE;

  g_value_init (&value, binding->property->value_type);

  variant = g_settings_read_from_backend (binding->settings, &binding->key, FALSE, FALSE);
  if (variant && !binding->get_mapping (&value, variant, binding->user_data))
    {
      /* silently ignore errors in the user's config database */
      g_variant_unref (variant);
      variant = NULL;
    }

  if (variant == NULL)
    {
      variant = g_settings_schema_key_get_translated_default (&binding->key);
      if (variant &&
          !binding->get_mapping (&value, variant, binding->user_data))
        {
          /* flag translation errors with a warning */
          g_warning ("Translated default '%s' for key '%s' in schema '%s' "
                     "was rejected by the binding mapping function",
                     binding->key.unparsed, binding->key.name,
                     g_settings_schema_get_id (binding->key.schema));
          g_variant_unref (variant);
          variant = NULL;
        }
    }

  if (variant == NULL)
    {
      variant = g_variant_ref (binding->key.default_value);
      if (!binding->get_mapping (&value, variant, binding->user_data))
        g_error ("The schema default value for key '%s' in schema '%s' "
                 "was rejected by the binding mapping function.",
                 binding->key.name, g_settings_schema_get_id (binding->key.schema));
    }

  g_object_set_property (binding->object, binding->property->name, &value);
  g_variant_unref (variant);
  g_value_unset (&value);

  binding->running = FALSE;
}

static void
g_settings_binding_property_changed (GObject          *object,
                                     const GParamSpec *pspec,
                                     gpointer          user_data)
{
  GSettingsBinding *binding = user_data;
  GValue value = G_VALUE_INIT;
  GVariant *variant;

  g_assert (object == binding->object);
  g_assert (pspec == binding->property);

  if (binding->running)
    return;

  binding->running = TRUE;

  g_value_init (&value, pspec->value_type);
  g_object_get_property (object, pspec->name, &value);
  if ((variant = binding->set_mapping (&value, binding->key.type,
                                       binding->user_data)))
    {
      g_variant_take_ref (variant);

      if (!g_settings_schema_key_type_check (&binding->key, variant))
        {
          g_critical ("binding mapping function for key '%s' returned "
                      "GVariant of type '%s' when type '%s' was requested",
                      binding->key.name, g_variant_get_type_string (variant),
                      g_variant_type_dup_string (binding->key.type));
          return;
        }

      if (!g_settings_schema_key_range_check (&binding->key, variant))
        {
          g_critical ("GObject property '%s' on a '%s' object is out of "
                      "schema-specified range for key '%s' of '%s': %s",
                      binding->property->name, g_type_name (binding->property->owner_type),
                      binding->key.name, g_settings_schema_get_id (binding->key.schema),
                      g_variant_print (variant, TRUE));
          return;
        }

      g_settings_write_to_backend (binding->settings, &binding->key, variant);
      g_variant_unref (variant);
    }
  g_value_unset (&value);

  binding->running = FALSE;
}

static gboolean
g_settings_bind_invert_boolean_get_mapping (GValue   *value,
                                            GVariant *variant,
                                            gpointer  user_data)
{
  g_value_set_boolean (value, !g_variant_get_boolean (variant));
  return TRUE;
}

static GVariant *
g_settings_bind_invert_boolean_set_mapping (const GValue       *value,
                                            const GVariantType *expected_type,
                                            gpointer            user_data)
{
  return g_variant_new_boolean (!g_value_get_boolean (value));
}

/**
 * g_settings_bind:
 * @settings: a #GSettings object
 * @key: the key to bind
 * @object: (type GObject.Object): a #GObject
 * @property: the name of the property to bind
 * @flags: flags for the binding
 *
 * Create a binding between the @key in the @settings object
 * and the property @property of @object.
 *
 * The binding uses the default GIO mapping functions to map
 * between the settings and property values. These functions
 * handle booleans, numeric types and string types in a
 * straightforward way. Use g_settings_bind_with_mapping() if
 * you need a custom mapping, or map between types that are not
 * supported by the default mapping functions.
 *
 * Unless the @flags include %G_SETTINGS_BIND_NO_SENSITIVITY, this
 * function also establishes a binding between the writability of
 * @key and the "sensitive" property of @object (if @object has
 * a boolean property by that name). See g_settings_bind_writable()
 * for more details about writable bindings.
 *
 * Note that the lifecycle of the binding is tied to the object,
 * and that you can have only one binding per object property.
 * If you bind the same property twice on the same object, the second
 * binding overrides the first one.
 *
 * Since: 2.26
 */
void
g_settings_bind (GSettings          *settings,
                 const gchar        *key,
                 gpointer            object,
                 const gchar        *property,
                 GSettingsBindFlags  flags)
{
  GSettingsBindGetMapping get_mapping = NULL;
  GSettingsBindSetMapping set_mapping = NULL;

  if (flags & G_SETTINGS_BIND_INVERT_BOOLEAN)
    {
      get_mapping = g_settings_bind_invert_boolean_get_mapping;
      set_mapping = g_settings_bind_invert_boolean_set_mapping;

      /* can't pass this flag to g_settings_bind_with_mapping() */
      flags &= ~G_SETTINGS_BIND_INVERT_BOOLEAN;
    }

  g_settings_bind_with_mapping (settings, key, object, property, flags,
                                get_mapping, set_mapping, NULL, NULL);
}

/**
 * g_settings_bind_with_mapping: (skip)
 * @settings: a #GSettings object
 * @key: the key to bind
 * @object: (type GObject.Object): a #GObject
 * @property: the name of the property to bind
 * @flags: flags for the binding
 * @get_mapping: a function that gets called to convert values
 *     from @settings to @object, or %NULL to use the default GIO mapping
 * @set_mapping: a function that gets called to convert values
 *     from @object to @settings, or %NULL to use the default GIO mapping
 * @user_data: data that gets passed to @get_mapping and @set_mapping
 * @destroy: #GDestroyNotify function for @user_data
 *
 * Create a binding between the @key in the @settings object
 * and the property @property of @object.
 *
 * The binding uses the provided mapping functions to map between
 * settings and property values.
 *
 * Note that the lifecycle of the binding is tied to the object,
 * and that you can have only one binding per object property.
 * If you bind the same property twice on the same object, the second
 * binding overrides the first one.
 *
 * Since: 2.26
 */
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)
{
  GSettingsBinding *binding;
  GObjectClass *objectclass;
  gchar *detailed_signal;
  GQuark binding_quark;

  g_return_if_fail (G_IS_SETTINGS (settings));
  g_return_if_fail (key != NULL);
  g_return_if_fail (G_IS_OBJECT (object));
  g_return_if_fail (property != NULL);
  g_return_if_fail (~flags & G_SETTINGS_BIND_INVERT_BOOLEAN);

  objectclass = G_OBJECT_GET_CLASS (object);

  binding = g_slice_new0 (GSettingsBinding);
  g_settings_schema_key_init (&binding->key, settings->priv->schema, key);
  binding->settings = g_object_ref (settings);
  binding->object = object;
  binding->property = g_object_class_find_property (objectclass, property);
  binding->user_data = user_data;
  binding->destroy = destroy;
  binding->get_mapping = get_mapping ? get_mapping : g_settings_get_mapping;
  binding->set_mapping = set_mapping ? set_mapping : g_settings_set_mapping;

  if (!(flags & (G_SETTINGS_BIND_GET | G_SETTINGS_BIND_SET)))
    flags |= G_SETTINGS_BIND_GET | G_SETTINGS_BIND_SET;

  if (binding->property == NULL)
    {
      g_critical ("g_settings_bind: no property '%s' on class '%s'",
                  property, G_OBJECT_TYPE_NAME (object));
      return;
    }

  if ((flags & G_SETTINGS_BIND_GET) &&
      (binding->property->flags & G_PARAM_WRITABLE) == 0)
    {
      g_critical ("g_settings_bind: property '%s' on class '%s' is not "
                  "writable", binding->property->name, G_OBJECT_TYPE_NAME (object));
      return;
    }
  if ((flags & G_SETTINGS_BIND_SET) &&
      (binding->property->flags & G_PARAM_READABLE) == 0)
    {
      g_critical ("g_settings_bind: property '%s' on class '%s' is not "
                  "readable", binding->property->name, G_OBJECT_TYPE_NAME (object));
      return;
    }

  if (get_mapping == g_settings_bind_invert_boolean_get_mapping)
    {
      /* g_settings_bind_invert_boolean_get_mapping() is a private
       * function, so if we are here it means that g_settings_bind() was
       * called with G_SETTINGS_BIND_INVERT_BOOLEAN.
       *
       * Ensure that both sides are boolean.
       */

      if (binding->property->value_type != G_TYPE_BOOLEAN)
        {
          g_critical ("g_settings_bind: G_SETTINGS_BIND_INVERT_BOOLEAN "
                      "was specified, but property '%s' on type '%s' has "
                      "type '%s'", binding->property->name, G_OBJECT_TYPE_NAME (object),
                      g_type_name ((binding->property->value_type)));
          return;
        }

      if (!g_variant_type_equal (binding->key.type, G_VARIANT_TYPE_BOOLEAN))
        {
          g_critical ("g_settings_bind: G_SETTINGS_BIND_INVERT_BOOLEAN "
                      "was specified, but key '%s' on schema '%s' has "
                      "type '%s'", key, g_settings_schema_get_id (settings->priv->schema),
                      g_variant_type_dup_string (binding->key.type));
          return;
        }

    }

  else if (((get_mapping == NULL && (flags & G_SETTINGS_BIND_GET)) ||
            (set_mapping == NULL && (flags & G_SETTINGS_BIND_SET))) &&
           !g_settings_mapping_is_compatible (binding->property->value_type,
                                              binding->key.type))
    {
      g_critical ("g_settings_bind: property '%s' on class '%s' has type "
                  "'%s' which is not compatible with type '%s' of key '%s' "
                  "on schema '%s'", binding->property->name, G_OBJECT_TYPE_NAME (object),
                  g_type_name (binding->property->value_type),
                  g_variant_type_dup_string (binding->key.type), key,
                  g_settings_schema_get_id (settings->priv->schema));
      return;
    }

  if ((flags & G_SETTINGS_BIND_SET) &&
      (~flags & G_SETTINGS_BIND_NO_SENSITIVITY))
    {
      GParamSpec *sensitive;

      sensitive = g_object_class_find_property (objectclass, "sensitive");

      if (sensitive && sensitive->value_type == G_TYPE_BOOLEAN &&
          (sensitive->flags & G_PARAM_WRITABLE))
        g_settings_bind_writable (settings, binding->key.name, object, "sensitive", FALSE);
    }

  if (flags & G_SETTINGS_BIND_SET)
    {
      detailed_signal = g_strdup_printf ("notify::%s", binding->property->name);
      binding->property_handler_id =
        g_signal_connect (object, detailed_signal,
                          G_CALLBACK (g_settings_binding_property_changed),
                          binding);
      g_free (detailed_signal);

      if (~flags & G_SETTINGS_BIND_GET)
        g_settings_binding_property_changed (object,
                                             binding->property,
                                             binding);
    }

  if (flags & G_SETTINGS_BIND_GET)
    {
      if (~flags & G_SETTINGS_BIND_GET_NO_CHANGES)
        {
          detailed_signal = g_strdup_printf ("changed::%s", key);
          binding->key_handler_id =
            g_signal_connect (settings, detailed_signal,
                              G_CALLBACK (g_settings_binding_key_changed),
                              binding);
          g_free (detailed_signal);
        }

      g_settings_binding_key_changed (settings, binding->key.name, binding);
    }

  binding_quark = g_settings_binding_quark (binding->property->name);
  g_object_set_qdata_full (object, binding_quark,
                           binding, g_settings_binding_free);
}

/* Writability binding {{{1 */
typedef struct
{
  GSettings *settings;
  gpointer object;
  const gchar *key;
  const gchar *property;
  gboolean inverted;
  gulong handler_id;
} GSettingsWritableBinding;

static void
g_settings_writable_binding_free (gpointer data)
{
  GSettingsWritableBinding *binding = data;

  g_signal_handler_disconnect (binding->settings, binding->handler_id);
  g_object_unref (binding->settings);
  g_slice_free (GSettingsWritableBinding, binding);
}

static void
g_settings_binding_writable_changed (GSettings   *settings,
                                     const gchar *key,
                                     gpointer     user_data)
{
  GSettingsWritableBinding *binding = user_data;
  gboolean writable;

  g_assert (settings == binding->settings);
  g_assert (key == binding->key);

  writable = g_settings_is_writable (settings, key);

  if (binding->inverted)
    writable = !writable;

  g_object_set (binding->object, binding->property, writable, NULL);
}

/**
 * g_settings_bind_writable:
 * @settings: a #GSettings object
 * @key: the key to bind
 * @object: (type GObject.Object):a #GObject
 * @property: the name of a boolean property to bind
 * @inverted: whether to 'invert' the value
 *
 * Create a binding between the writability of @key in the
 * @settings object and the property @property of @object.
 * The property must be boolean; "sensitive" or "visible"
 * properties of widgets are the most likely candidates.
 *
 * Writable bindings are always uni-directional; changes of the
 * writability of the setting will be propagated to the object
 * property, not the other way.
 *
 * When the @inverted argument is %TRUE, the binding inverts the
 * value as it passes from the setting to the object, i.e. @property
 * will be set to %TRUE if the key is not writable.
 *
 * Note that the lifecycle of the binding is tied to the object,
 * and that you can have only one binding per object property.
 * If you bind the same property twice on the same object, the second
 * binding overrides the first one.
 *
 * Since: 2.26
 */
void
g_settings_bind_writable (GSettings   *settings,
                          const gchar *key,
                          gpointer     object,
                          const gchar *property,
                          gboolean     inverted)
{
  GSettingsWritableBinding *binding;
  gchar *detailed_signal;
  GParamSpec *pspec;

  g_return_if_fail (G_IS_SETTINGS (settings));

  pspec = g_object_class_find_property (G_OBJECT_GET_CLASS (object), property);
  if (pspec == NULL)
    {
      g_critical ("g_settings_bind_writable: no property '%s' on class '%s'",
                  property, G_OBJECT_TYPE_NAME (object));
      return;
    }
  if ((pspec->flags & G_PARAM_WRITABLE) == 0)
    {
      g_critical ("g_settings_bind_writable: property '%s' on class '%s' is not writable",
                  property, G_OBJECT_TYPE_NAME (object));
      return;
    }

  binding = g_slice_new (GSettingsWritableBinding);
  binding->settings = g_object_ref (settings);
  binding->object = object;
  binding->key = g_intern_string (key);
  binding->property = g_intern_string (property);
  binding->inverted = inverted;

  detailed_signal = g_strdup_printf ("writable-changed::%s", key);
  binding->handler_id =
    g_signal_connect (settings, detailed_signal,
                      G_CALLBACK (g_settings_binding_writable_changed),
                      binding);
  g_free (detailed_signal);

  g_object_set_qdata_full (object, g_settings_binding_quark (property),
                           binding, g_settings_writable_binding_free);

  g_settings_binding_writable_changed (settings, binding->key, binding);
}

/**
 * g_settings_unbind:
 * @object: (type GObject.Object): the object
 * @property: the property whose binding is removed
 *
 * Removes an existing binding for @property on @object.
 *
 * Note that bindings are automatically removed when the
 * object is finalized, so it is rarely necessary to call this
 * function.
 *
 * Since: 2.26
 */
void
g_settings_unbind (gpointer     object,
                   const gchar *property)
{
  GQuark binding_quark;

  binding_quark = g_settings_binding_quark (property);
  g_object_set_qdata (object, binding_quark, NULL);
}

/* GAction {{{1 */

typedef struct
{
  GObject parent_instance;

  GSettingsSchemaKey key;
  GSettings *settings;
} GSettingsAction;

typedef GObjectClass GSettingsActionClass;

static GType g_settings_action_get_type (void);
static void g_settings_action_iface_init (GActionInterface *iface);
G_DEFINE_TYPE_WITH_CODE (GSettingsAction, g_settings_action, G_TYPE_OBJECT,
                         G_IMPLEMENT_INTERFACE (G_TYPE_ACTION, g_settings_action_iface_init))

enum
{
  ACTION_PROP_0,
  ACTION_PROP_NAME,
  ACTION_PROP_PARAMETER_TYPE,
  ACTION_PROP_ENABLED,
  ACTION_PROP_STATE_TYPE,
  ACTION_PROP_STATE
};

static const gchar *
g_settings_action_get_name (GAction *action)
{
  GSettingsAction *gsa = (GSettingsAction *) action;

  return gsa->key.name;
}

static const GVariantType *
g_settings_action_get_parameter_type (GAction *action)
{
  GSettingsAction *gsa = (GSettingsAction *) action;
  const GVariantType *type;

  type = g_variant_get_type (gsa->key.default_value);
  if (g_variant_type_equal (type, G_VARIANT_TYPE_BOOLEAN))
    type = NULL;

  return type;
}

static gboolean
g_settings_action_get_enabled (GAction *action)
{
  GSettingsAction *gsa = (GSettingsAction *) action;

  return g_settings_is_writable (gsa->settings, gsa->key.name);
}

static const GVariantType *
g_settings_action_get_state_type (GAction *action)
{
  GSettingsAction *gsa = (GSettingsAction *) action;

  return g_variant_get_type (gsa->key.default_value);
}

static GVariant *
g_settings_action_get_state (GAction *action)
{
  GSettingsAction *gsa = (GSettingsAction *) action;
  GVariant *value;

  value = g_settings_read_from_backend (gsa->settings, &gsa->key, FALSE, FALSE);

  if (value == NULL)
    value = g_settings_schema_key_get_translated_default (&gsa->key);

  if (value == NULL)
    value = g_variant_ref (gsa->key.default_value);

  return value;
}

static GVariant *
g_settings_action_get_state_hint (GAction *action)
{
  GSettingsAction *gsa = (GSettingsAction *) action;

  /* no point in reimplementing this... */
  return g_settings_schema_key_get_range (&gsa->key);
}

static void
g_settings_action_change_state (GAction  *action,
                                GVariant *value)
{
  GSettingsAction *gsa = (GSettingsAction *) action;

  if (g_settings_schema_key_type_check (&gsa->key, value) && g_settings_schema_key_range_check (&gsa->key, value))
    g_settings_write_to_backend (gsa->settings, &gsa->key, value);
}

static void
g_settings_action_activate (GAction  *action,
                            GVariant *parameter)
{
  GSettingsAction *gsa = (GSettingsAction *) action;

  if (g_variant_is_of_type (gsa->key.default_value, G_VARIANT_TYPE_BOOLEAN))
    {
      GVariant *old;

      if (parameter != NULL)
        return;

      old = g_settings_action_get_state (action);
      parameter = g_variant_new_boolean (!g_variant_get_boolean (old));
      g_variant_unref (old);
    }

  g_action_change_state (action, parameter);
}

static void
g_settings_action_get_property (GObject *object, guint prop_id,
                                GValue *value, GParamSpec *pspec)
{
  GAction *action = G_ACTION (object);

  switch (prop_id)
    {
    case ACTION_PROP_NAME:
      g_value_set_string (value, g_settings_action_get_name (action));
      break;

    case ACTION_PROP_PARAMETER_TYPE:
      g_value_set_boxed (value, g_settings_action_get_parameter_type (action));
      break;

    case ACTION_PROP_ENABLED:
      g_value_set_boolean (value, g_settings_action_get_enabled (action));
      break;

    case ACTION_PROP_STATE_TYPE:
      g_value_set_boxed (value, g_settings_action_get_state_type (action));
      break;

    case ACTION_PROP_STATE:
      g_value_set_variant (value, g_settings_action_get_state (action));
      break;

    default:
      g_assert_not_reached ();
    }
}

static void
g_settings_action_finalize (GObject *object)
{
  GSettingsAction *gsa = (GSettingsAction *) object;

  g_signal_handlers_disconnect_by_data (gsa->settings, gsa);
  g_object_unref (gsa->settings);

  G_OBJECT_CLASS (g_settings_action_parent_class)
    ->finalize (object);
}

static void
g_settings_action_init (GSettingsAction *gsa)
{
}

static void
g_settings_action_iface_init (GActionInterface *iface)
{
  iface->get_name = g_settings_action_get_name;
  iface->get_parameter_type = g_settings_action_get_parameter_type;
  iface->get_enabled = g_settings_action_get_enabled;
  iface->get_state_type = g_settings_action_get_state_type;
  iface->get_state = g_settings_action_get_state;
  iface->get_state_hint = g_settings_action_get_state_hint;
  iface->change_state = g_settings_action_change_state;
  iface->activate = g_settings_action_activate;
}

static void
g_settings_action_class_init (GSettingsActionClass *class)
{
  class->get_property = g_settings_action_get_property;
  class->finalize = g_settings_action_finalize;

  g_object_class_override_property (class, ACTION_PROP_NAME, "name");
  g_object_class_override_property (class, ACTION_PROP_PARAMETER_TYPE, "parameter-type");
  g_object_class_override_property (class, ACTION_PROP_ENABLED, "enabled");
  g_object_class_override_property (class, ACTION_PROP_STATE_TYPE, "state-type");
  g_object_class_override_property (class, ACTION_PROP_STATE, "state");
}

static void
g_settings_action_changed (GSettings   *settings,
                           const gchar *key,
                           gpointer     user_data)
{
  g_object_notify (user_data, "state");
}

static void
g_settings_action_enabled_changed (GSettings   *settings,
                                   const gchar *key,
                                   gpointer     user_data)
{
  g_object_notify (user_data, "enabled");
}

/**
 * g_settings_create_action:
 * @settings: a #GSettings
 * @key: the name of a key in @settings
 *
 * Creates a #GAction corresponding to a given #GSettings key.
 *
 * The action has the same name as the key.
 *
 * The value of the key becomes the state of the action and the action
 * is enabled when the key is writable.  Changing the state of the
 * action results in the key being written to.  Changes to the value or
 * writability of the key cause appropriate change notifications to be
 * emitted for the action.
 *
 * For boolean-valued keys, action activations take no parameter and
 * result in the toggling of the value.  For all other types,
 * activations take the new value for the key (which must have the
 * correct type).
 *
 * Returns: (transfer full): a new #GAction
 *
 * Since: 2.32
 **/
GAction *
g_settings_create_action (GSettings   *settings,
                          const gchar *key)
{
  GSettingsAction *gsa;
  gchar *detailed_signal;

  g_return_val_if_fail (G_IS_SETTINGS (settings), NULL);
  g_return_val_if_fail (key != NULL, NULL);

  gsa = g_object_new (g_settings_action_get_type (), NULL);
  gsa->settings = g_object_ref (settings);
  g_settings_schema_key_init (&gsa->key, settings->priv->schema, key);

  detailed_signal = g_strdup_printf ("changed::%s", key);
  g_signal_connect (settings, detailed_signal, G_CALLBACK (g_settings_action_changed), gsa);
  g_free (detailed_signal);
  detailed_signal = g_strdup_printf ("writable-changed::%s", key);
  g_signal_connect (settings, detailed_signal, G_CALLBACK (g_settings_action_enabled_changed), gsa);
  g_free (detailed_signal);

  return G_ACTION (gsa);
}

/* Epilogue {{{1 */

/* vim:set foldmethod=marker: */
