Blame conf/dconf/config.c

Packit Service 1d8f1c
/* -*- mode: C; c-basic-offset: 4; indent-tabs-mode: nil; -*- */
Packit Service 1d8f1c
/* vim:set et sts=4: */
Packit Service 1d8f1c
/* ibus - The Input Bus
Packit Service 1d8f1c
 * Copyright (C) 2008-2010 Peng Huang <shawn.p.huang@gmail.com>
Packit Service 1d8f1c
 * Copyright (C) 2011 Daiki Ueno <ueno@unixuser.org>
Packit Service 1d8f1c
 * Copyright (C) 2008-2011 Red Hat, Inc.
Packit Service 1d8f1c
 *
Packit Service 1d8f1c
 * This library is free software; you can redistribute it and/or
Packit Service 1d8f1c
 * modify it under the terms of the GNU Lesser General Public
Packit Service 1d8f1c
 * License as published by the Free Software Foundation; either
Packit Service 1d8f1c
 * version 2.1 of the License, or (at your option) any later version.
Packit Service 1d8f1c
 *
Packit Service 1d8f1c
 * This library is distributed in the hope that it will be useful,
Packit Service 1d8f1c
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
Packit Service 1d8f1c
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
Packit Service 1d8f1c
 * Lesser General Public License for more details.
Packit Service 1d8f1c
 *
Packit Service 1d8f1c
 * You should have received a copy of the GNU Lesser General Public
Packit Service 1d8f1c
 * License along with this library; if not, write to the Free Software
Packit Service 1d8f1c
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301
Packit Service 1d8f1c
 * USA
Packit Service 1d8f1c
 */
Packit Service 1d8f1c
Packit Service 1d8f1c
#include <string.h>
Packit Service 1d8f1c
#include <ibus.h>
Packit Service 1d8f1c
#include "config-private.h"
Packit Service 1d8f1c
Packit Service 1d8f1c
#define DCONF_PREFIX "/desktop/ibus"
Packit Service 1d8f1c
#define DCONF_PRESERVE_NAME_PREFIXES_KEY \
Packit Service 1d8f1c
    DCONF_PREFIX"/general/dconf-preserve-name-prefixes"
Packit Service 1d8f1c
Packit Service 1d8f1c
struct _IBusConfigDConf {
Packit Service 1d8f1c
    IBusConfigService parent;
Packit Service 1d8f1c
    DConfClient *client;
Packit Service 1d8f1c
Packit Service 1d8f1c
    /* if a dconf path matches one of preserve_name_prefixes, don't convert
Packit Service 1d8f1c
       key names from/to GSettings key names (see _to_gsettings_name
Packit Service 1d8f1c
       and _from_gsettings_name) */
Packit Service 1d8f1c
    GSList *preserve_name_prefixes;
Packit Service 1d8f1c
};
Packit Service 1d8f1c
Packit Service 1d8f1c
struct _IBusConfigDConfClass {
Packit Service 1d8f1c
    IBusConfigServiceClass parent;
Packit Service 1d8f1c
};
Packit Service 1d8f1c
Packit Service 1d8f1c
/* functions prototype */
Packit Service 1d8f1c
static void      ibus_config_dconf_class_init  (IBusConfigDConfClass *class);
Packit Service 1d8f1c
static void      ibus_config_dconf_init        (IBusConfigDConf      *config);
Packit Service 1d8f1c
static void      ibus_config_dconf_destroy     (IBusConfigDConf      *config);
Packit Service 1d8f1c
static gboolean  ibus_config_dconf_set_value   (IBusConfigService    *config,
Packit Service 1d8f1c
                                                const gchar          *section,
Packit Service 1d8f1c
                                                const gchar          *name,
Packit Service 1d8f1c
                                                GVariant             *value,
Packit Service 1d8f1c
                                                GError              **error);
Packit Service 1d8f1c
static GVariant *ibus_config_dconf_get_value   (IBusConfigService    *config,
Packit Service 1d8f1c
                                                const gchar          *section,
Packit Service 1d8f1c
                                                const gchar          *name,
Packit Service 1d8f1c
                                                GError              **error);
Packit Service 1d8f1c
static GVariant *ibus_config_dconf_get_values  (IBusConfigService    *config,
Packit Service 1d8f1c
                                                const gchar          *section,
Packit Service 1d8f1c
                                                GError              **error);
Packit Service 1d8f1c
static gboolean  ibus_config_dconf_unset_value (IBusConfigService    *config,
Packit Service 1d8f1c
                                                const gchar          *section,
Packit Service 1d8f1c
                                                const gchar          *name,
Packit Service 1d8f1c
                                                GError              **error);
Packit Service 1d8f1c
Packit Service 1d8f1c
G_DEFINE_TYPE (IBusConfigDConf, ibus_config_dconf, IBUS_TYPE_CONFIG_SERVICE)
Packit Service 1d8f1c
Packit Service 1d8f1c
static void
Packit Service 1d8f1c
ibus_config_dconf_class_init (IBusConfigDConfClass *class)
Packit Service 1d8f1c
{
Packit Service 1d8f1c
    IBusObjectClass *object_class = IBUS_OBJECT_CLASS (class);
Packit Service 1d8f1c
    IBusConfigServiceClass *config_class = IBUS_CONFIG_SERVICE_CLASS (class);
Packit Service 1d8f1c
Packit Service 1d8f1c
    object_class->destroy = (IBusObjectDestroyFunc) ibus_config_dconf_destroy;
Packit Service 1d8f1c
    config_class->set_value = ibus_config_dconf_set_value;
Packit Service 1d8f1c
    config_class->get_value = ibus_config_dconf_get_value;
Packit Service 1d8f1c
    config_class->get_values = ibus_config_dconf_get_values;
Packit Service 1d8f1c
    config_class->unset_value = ibus_config_dconf_unset_value;
Packit Service 1d8f1c
}
Packit Service 1d8f1c
Packit Service 1d8f1c
static gboolean
Packit Service 1d8f1c
_has_prefixes (const gchar *path, GSList *prefixes)
Packit Service 1d8f1c
{
Packit Service 1d8f1c
    GSList *head = prefixes;
Packit Service 1d8f1c
    for (; head; head = head->next) {
Packit Service 1d8f1c
        if (g_str_has_prefix (path, head->data)) {
Packit Service 1d8f1c
            return TRUE;
Packit Service 1d8f1c
        }
Packit Service 1d8f1c
    }
Packit Service 1d8f1c
    return FALSE;
Packit Service 1d8f1c
}
Packit Service 1d8f1c
Packit Service 1d8f1c
/* Convert key names from/to GSettings names.  While GSettings only
Packit Service 1d8f1c
 * accepts lowercase letters / numbers / and dash ('-'), IBus uses
Packit Service 1d8f1c
 * underscore ('_') and some engines even use uppercase letters.
Packit Service 1d8f1c
 *
Packit Service 1d8f1c
 * To minimize the gap, we do the following conversion:
Packit Service 1d8f1c
 *
Packit Service 1d8f1c
 * - when converting from IBus names to GSettings names, first convert
Packit Service 1d8f1c
 *   all letters to lowercase and then replace underscores with dashes.
Packit Service 1d8f1c
 * - when converting from GSettings names to IBus names, simply
Packit Service 1d8f1c
 *   replace dashes with underscores.
Packit Service 1d8f1c
 *
Packit Service 1d8f1c
 * Note that though the conversion does not always roundtrip, it does
Packit Service 1d8f1c
 * in most cases.
Packit Service 1d8f1c
 */
Packit Service 1d8f1c
static gchar *
Packit Service 1d8f1c
_to_gsettings_name (const gchar *name)
Packit Service 1d8f1c
{
Packit Service 1d8f1c
    return g_strcanon (g_ascii_strdown (name, -1),
Packit Service 1d8f1c
                       "abcdefghijklmnopqrstuvwxyz0123456789-",
Packit Service 1d8f1c
                       '-');
Packit Service 1d8f1c
}
Packit Service 1d8f1c
Packit Service 1d8f1c
static gchar *
Packit Service 1d8f1c
_from_gsettings_name (const gchar *name)
Packit Service 1d8f1c
{
Packit Service 1d8f1c
    gchar *retval = g_strdup (name), *p;
Packit Service 1d8f1c
    for (p = retval; *p != '\0'; p++)
Packit Service 1d8f1c
        if (*p == '-')
Packit Service 1d8f1c
            *p = '_';
Packit Service 1d8f1c
    return retval;
Packit Service 1d8f1c
}
Packit Service 1d8f1c
Packit Service 1d8f1c
typedef gchar *(* NameConvFunc) (const gchar *);
Packit Service 1d8f1c
Packit Service 1d8f1c
static gchar *
Packit Service 1d8f1c
_conv_path (const gchar *path, NameConvFunc conv_func)
Packit Service 1d8f1c
{
Packit Service 1d8f1c
    gchar **strv = g_strsplit (path, "/", -1), **p;
Packit Service 1d8f1c
    gchar *retval;
Packit Service 1d8f1c
Packit Service 1d8f1c
    for (p = strv; *p; p++) {
Packit Service 1d8f1c
        gchar *canon;
Packit Service 1d8f1c
        canon = (*conv_func) (*p);
Packit Service 1d8f1c
        g_free (*p);
Packit Service 1d8f1c
        *p = canon;
Packit Service 1d8f1c
    }
Packit Service 1d8f1c
Packit Service 1d8f1c
    retval = g_strjoinv ("/", strv);
Packit Service 1d8f1c
    g_strfreev (strv);
Packit Service 1d8f1c
    return retval;
Packit Service 1d8f1c
}
Packit Service 1d8f1c
Packit Service 1d8f1c
static gchar *
Packit Service 1d8f1c
_to_gsettings_path (const gchar *path)
Packit Service 1d8f1c
{
Packit Service 1d8f1c
    return _conv_path (path, _to_gsettings_name);
Packit Service 1d8f1c
}
Packit Service 1d8f1c
Packit Service 1d8f1c
static gchar *
Packit Service 1d8f1c
_from_gsettings_path (const gchar *gpath)
Packit Service 1d8f1c
{
Packit Service 1d8f1c
    return _conv_path (gpath, _from_gsettings_name);
Packit Service 1d8f1c
}
Packit Service 1d8f1c
Packit Service 1d8f1c
static void
Packit Service 1d8f1c
_watch_func (DConfClient         *client,
Packit Service 1d8f1c
             const gchar         *gpath,
Packit Service 1d8f1c
             const gchar * const *items,
Packit Service 1d8f1c
#ifndef DCONF_0_13_4
Packit Service 1d8f1c
             gint                 n_items,
Packit Service 1d8f1c
#endif
Packit Service 1d8f1c
             const gchar         *tag,
Packit Service 1d8f1c
             IBusConfigDConf     *config)
Packit Service 1d8f1c
{
Packit Service 1d8f1c
    gchar **gkeys = NULL;
Packit Service 1d8f1c
    gint i;
Packit Service 1d8f1c
#ifdef DCONF_0_13_4
Packit Service 1d8f1c
    gint n_items;
Packit Service 1d8f1c
Packit Service 1d8f1c
    n_items = g_strv_length ((gchar **)items);
Packit Service 1d8f1c
#endif
Packit Service 1d8f1c
Packit Service 1d8f1c
    g_return_if_fail (gpath != NULL);
Packit Service 1d8f1c
    g_return_if_fail (n_items >= 0);
Packit Service 1d8f1c
Packit Service 1d8f1c
    if (dconf_is_key (gpath, NULL)) {
Packit Service 1d8f1c
        /* If path is a key, the notification should be taken to mean
Packit Service 1d8f1c
           that one key may have changed. */
Packit Service 1d8f1c
        n_items = 1;
Packit Service 1d8f1c
        gkeys = g_malloc0_n (n_items + 1, sizeof (gchar *));
Packit Service 1d8f1c
        gkeys[0] = g_strdup (gpath);
Packit Service 1d8f1c
    } else {
Packit Service 1d8f1c
        if (n_items == 0) {
Packit Service 1d8f1c
            /* If path is a dir and items is empty then it is an
Packit Service 1d8f1c
               indication that any key under path may have
Packit Service 1d8f1c
               changed. */
Packit Service 1d8f1c
            gkeys = dconf_client_list (config->client, gpath, &n_items);
Packit Service 1d8f1c
        } else {
Packit Service 1d8f1c
            gkeys = g_boxed_copy (G_TYPE_STRV, items);
Packit Service 1d8f1c
        }
Packit Service 1d8f1c
        for (i = 0; i < n_items; i++) {
Packit Service 1d8f1c
            gchar *gname = gkeys[i];
Packit Service 1d8f1c
            gkeys[i] = g_strdup_printf ("%s/%s", gpath, gname);
Packit Service 1d8f1c
            g_free (gname);
Packit Service 1d8f1c
        }
Packit Service 1d8f1c
    }
Packit Service 1d8f1c
Packit Service 1d8f1c
    for (i = 0; i < n_items; i++) {
Packit Service 1d8f1c
        gchar *gname, *path, *name;
Packit Service 1d8f1c
        GVariant *variant = dconf_client_read (config->client, gkeys[i]);
Packit Service 1d8f1c
Packit Service 1d8f1c
        if (variant == NULL) {
Packit Service 1d8f1c
            /* Use a empty tuple for a unset value */
Packit Service 1d8f1c
            variant = g_variant_new_tuple (NULL, 0);
Packit Service 1d8f1c
            g_variant_ref_sink (variant);
Packit Service 1d8f1c
        }
Packit Service 1d8f1c
Packit Service 1d8f1c
        gname = strrchr (gkeys[i], '/');
Packit Service 1d8f1c
        g_assert (gname);
Packit Service 1d8f1c
        *gname++ = '\0';
Packit Service 1d8f1c
Packit Service 1d8f1c
        if (_has_prefixes (gkeys[i], config->preserve_name_prefixes)) {
Packit Service 1d8f1c
            path = gkeys[i];
Packit Service 1d8f1c
            name = gname;
Packit Service 1d8f1c
        } else {
Packit Service 1d8f1c
            path = _from_gsettings_path (gkeys[i]);
Packit Service 1d8f1c
            name = _from_gsettings_name (gname);
Packit Service 1d8f1c
        }
Packit Service 1d8f1c
Packit Service 1d8f1c
        ibus_config_service_value_changed ((IBusConfigService *) config,
Packit Service 1d8f1c
                                           path + sizeof (DCONF_PREFIX),
Packit Service 1d8f1c
                                           name,
Packit Service 1d8f1c
                                           variant);
Packit Service 1d8f1c
        if (path != gkeys[i]) {
Packit Service 1d8f1c
            g_free (path);
Packit Service 1d8f1c
        }
Packit Service 1d8f1c
        if (name != gname) {
Packit Service 1d8f1c
            g_free (name);
Packit Service 1d8f1c
        }
Packit Service 1d8f1c
        g_variant_unref (variant);
Packit Service 1d8f1c
    }
Packit Service 1d8f1c
    g_strfreev (gkeys);
Packit Service 1d8f1c
}
Packit Service 1d8f1c
Packit Service 1d8f1c
static void
Packit Service 1d8f1c
ibus_config_dconf_init (IBusConfigDConf *config)
Packit Service 1d8f1c
{
Packit Service 1d8f1c
    GVariant *variant;
Packit Service 1d8f1c
#ifdef DCONF_0_13_4
Packit Service 1d8f1c
    config->client = dconf_client_new ();
Packit Service 1d8f1c
Packit Service 1d8f1c
    g_signal_connect (config->client, "changed",
Packit Service 1d8f1c
                      G_CALLBACK (_watch_func), config);
Packit Service 1d8f1c
Packit Service 1d8f1c
    dconf_client_watch_fast (config->client, DCONF_PREFIX"/");
Packit Service 1d8f1c
#else
Packit Service 1d8f1c
    GError *error;
Packit Service 1d8f1c
Packit Service 1d8f1c
    config->client = dconf_client_new ("ibus",
Packit Service 1d8f1c
                                       (DConfWatchFunc)_watch_func,
Packit Service 1d8f1c
                                       config,
Packit Service 1d8f1c
                                       NULL);
Packit Service 1d8f1c
Packit Service 1d8f1c
    error = NULL;
Packit Service 1d8f1c
    if (!dconf_client_watch (config->client, DCONF_PREFIX"/", NULL, &error)) {
Packit Service 1d8f1c
        g_warning ("Can not watch dconf path %s: %s",
Packit Service 1d8f1c
                   DCONF_PREFIX"/", error->message);
Packit Service 1d8f1c
        g_error_free (error);
Packit Service 1d8f1c
    }
Packit Service 1d8f1c
#endif
Packit Service 1d8f1c
Packit Service 1d8f1c
    config->preserve_name_prefixes = NULL;
Packit Service 1d8f1c
    variant = dconf_client_read (config->client,
Packit Service 1d8f1c
                                 DCONF_PRESERVE_NAME_PREFIXES_KEY);
Packit Service 1d8f1c
    if (variant != NULL) {
Packit Service 1d8f1c
        GVariantIter iter;
Packit Service 1d8f1c
        GVariant *child;
Packit Service 1d8f1c
Packit Service 1d8f1c
        g_variant_iter_init (&iter, variant);
Packit Service 1d8f1c
        while ((child = g_variant_iter_next_value (&iter))) {
Packit Service 1d8f1c
            char *prefix = g_variant_dup_string (child, NULL);
Packit Service 1d8f1c
            config->preserve_name_prefixes =
Packit Service 1d8f1c
                g_slist_prepend (config->preserve_name_prefixes,
Packit Service 1d8f1c
                                 prefix);
Packit Service 1d8f1c
            g_variant_unref (child);
Packit Service 1d8f1c
        }
Packit Service 1d8f1c
        g_variant_unref (variant);
Packit Service 1d8f1c
    }
Packit Service 1d8f1c
}
Packit Service 1d8f1c
Packit Service 1d8f1c
static void
Packit Service 1d8f1c
ibus_config_dconf_destroy (IBusConfigDConf *config)
Packit Service 1d8f1c
{
Packit Service 1d8f1c
    if (config->client) {
Packit Service 1d8f1c
#ifdef DCONF_0_13_4
Packit Service 1d8f1c
        dconf_client_unwatch_fast (config->client, DCONF_PREFIX"/");
Packit Service 1d8f1c
#else
Packit Service 1d8f1c
        GError *error = NULL;
Packit Service 1d8f1c
        if (!dconf_client_unwatch (config->client, DCONF_PREFIX"/", NULL, &error)) {
Packit Service 1d8f1c
            g_warning ("Can not unwatch dconf path %s: %s",
Packit Service 1d8f1c
                       DCONF_PREFIX"/", error->message);
Packit Service 1d8f1c
            g_error_free (error);
Packit Service 1d8f1c
        }
Packit Service 1d8f1c
#endif
Packit Service 1d8f1c
Packit Service 1d8f1c
        g_object_unref (config->client);
Packit Service 1d8f1c
        config->client = NULL;
Packit Service 1d8f1c
    }
Packit Service 1d8f1c
Packit Service 1d8f1c
    g_slist_free_full (config->preserve_name_prefixes, (GDestroyNotify) g_free);
Packit Service 1d8f1c
    config->preserve_name_prefixes = NULL;
Packit Service 1d8f1c
Packit Service 1d8f1c
    IBUS_OBJECT_CLASS (ibus_config_dconf_parent_class)->
Packit Service 1d8f1c
        destroy ((IBusObject *)config);
Packit Service 1d8f1c
}
Packit Service 1d8f1c
Packit Service 1d8f1c
static gboolean
Packit Service 1d8f1c
ibus_config_dconf_set_value (IBusConfigService *config,
Packit Service 1d8f1c
                             const gchar       *section,
Packit Service 1d8f1c
                             const gchar       *name,
Packit Service 1d8f1c
                             GVariant          *value,
Packit Service 1d8f1c
                             GError           **error)
Packit Service 1d8f1c
{
Packit Service 1d8f1c
    IBusConfigDConf *dconf = IBUS_CONFIG_DCONF (config);
Packit Service 1d8f1c
    DConfClient *client = dconf->client;
Packit Service 1d8f1c
    gchar *path, *gpath, *gname, *gkey;
Packit Service 1d8f1c
    gboolean retval;
Packit Service 1d8f1c
Packit Service 1d8f1c
    path = g_strdup_printf (DCONF_PREFIX"/%s", section);
Packit Service 1d8f1c
    gpath = _to_gsettings_path (path);
Packit Service 1d8f1c
    g_free (path);
Packit Service 1d8f1c
Packit Service 1d8f1c
    if (_has_prefixes (gpath, dconf->preserve_name_prefixes)) {
Packit Service 1d8f1c
        gname = (char *) name;
Packit Service 1d8f1c
    } else {
Packit Service 1d8f1c
        gname = _to_gsettings_name (name);
Packit Service 1d8f1c
    }
Packit Service 1d8f1c
    gkey = g_strconcat (gpath, "/", gname, NULL);
Packit Service 1d8f1c
    g_free (gpath);
Packit Service 1d8f1c
    if (gname != name) {
Packit Service 1d8f1c
        g_free (gname);
Packit Service 1d8f1c
    }
Packit Service 1d8f1c
Packit Service 1d8f1c
#ifdef DCONF_0_13_4
rpm-build dbbf76
    /* Use dconf_client_write_sync() instead of dconf_client_write_fast()
rpm-build dbbf76
     * because dconf_client_write_fast() does not sync the data when
rpm-build dbbf76
     * ibus_config_get_values() is called immediately after
rpm-build dbbf76
     * ibus_config_set_value() is called.
rpm-build dbbf76
     * We won't add a new API for the sync only since IBusConfig is
rpm-build dbbf76
     * now deprecated and GSettings is recommended.
rpm-build dbbf76
     */
rpm-build dbbf76
    retval = dconf_client_write_sync (client,
rpm-build dbbf76
                                      gkey,
rpm-build dbbf76
                                      value,
rpm-build dbbf76
                                      NULL,
rpm-build dbbf76
                                      NULL,
rpm-build dbbf76
                                      error);
Packit Service 1d8f1c
#else
Packit Service 1d8f1c
    retval = dconf_client_write (client,
Packit Service 1d8f1c
                                 gkey,
Packit Service 1d8f1c
                                 value,
Packit Service 1d8f1c
                                 NULL,   /* tag */
Packit Service 1d8f1c
                                 NULL,   /* cancellable */
Packit Service 1d8f1c
                                 error);
Packit Service 1d8f1c
#endif
Packit Service 1d8f1c
    g_free (gkey);
Packit Service 1d8f1c
Packit Service 1d8f1c
    return retval;
Packit Service 1d8f1c
}
Packit Service 1d8f1c
Packit Service 1d8f1c
static GVariant *
Packit Service 1d8f1c
ibus_config_dconf_get_value (IBusConfigService *config,
Packit Service 1d8f1c
                             const gchar       *section,
Packit Service 1d8f1c
                             const gchar       *name,
Packit Service 1d8f1c
                             GError           **error)
Packit Service 1d8f1c
{
Packit Service 1d8f1c
    IBusConfigDConf *dconf = IBUS_CONFIG_DCONF (config);
Packit Service 1d8f1c
    DConfClient *client = dconf->client;
Packit Service 1d8f1c
    gchar *path, *gpath, *gname, *gkey;
Packit Service 1d8f1c
    GVariant *variant;
Packit Service 1d8f1c
Packit Service 1d8f1c
    path = g_strdup_printf (DCONF_PREFIX"/%s", section);
Packit Service 1d8f1c
    gpath = _to_gsettings_path (path);
Packit Service 1d8f1c
    g_free (path);
Packit Service 1d8f1c
Packit Service 1d8f1c
    if (_has_prefixes (gpath, dconf->preserve_name_prefixes)) {
Packit Service 1d8f1c
        gname = (char *) name;
Packit Service 1d8f1c
    } else {
Packit Service 1d8f1c
        gname = _to_gsettings_name (name);
Packit Service 1d8f1c
    }
Packit Service 1d8f1c
    gkey = g_strconcat (gpath, "/", gname, NULL);
Packit Service 1d8f1c
    g_free (gpath);
Packit Service 1d8f1c
    if (gname != name) {
Packit Service 1d8f1c
        g_free (gname);
Packit Service 1d8f1c
    }
Packit Service 1d8f1c
Packit Service 1d8f1c
    variant = dconf_client_read (client, gkey);
Packit Service 1d8f1c
    g_free (gkey);
Packit Service 1d8f1c
Packit Service 1d8f1c
    if (variant == NULL) {
Packit Service 1d8f1c
        g_set_error (error,
Packit Service 1d8f1c
                     G_DBUS_ERROR,
Packit Service 1d8f1c
                     G_DBUS_ERROR_FAILED,
Packit Service 1d8f1c
                     "Config value [%s:%s] does not exist.",
Packit Service 1d8f1c
                     section, name);
Packit Service 1d8f1c
        return NULL;
Packit Service 1d8f1c
    }
Packit Service 1d8f1c
Packit Service 1d8f1c
    return variant;
Packit Service 1d8f1c
}
Packit Service 1d8f1c
Packit Service 1d8f1c
static GVariant *
Packit Service 1d8f1c
ibus_config_dconf_get_values (IBusConfigService *config,
Packit Service 1d8f1c
                              const gchar       *section,
Packit Service 1d8f1c
                              GError           **error)
Packit Service 1d8f1c
{
Packit Service 1d8f1c
    IBusConfigDConf *dconf = IBUS_CONFIG_DCONF (config);
Packit Service 1d8f1c
    DConfClient *client = dconf->client;
Packit Service 1d8f1c
    gchar *dir, *gdir;
Packit Service 1d8f1c
    gint len;
Packit Service 1d8f1c
    gchar **entries, **p;
Packit Service 1d8f1c
    GVariantBuilder builder;
Packit Service 1d8f1c
    gboolean preserve_name;
Packit Service 1d8f1c
Packit Service 1d8f1c
    dir = g_strdup_printf (DCONF_PREFIX"/%s/", section);
Packit Service 1d8f1c
    gdir = _to_gsettings_path (dir);
Packit Service 1d8f1c
    g_free (dir);
Packit Service 1d8f1c
Packit Service 1d8f1c
    preserve_name = _has_prefixes (gdir, dconf->preserve_name_prefixes);
Packit Service 1d8f1c
Packit Service 1d8f1c
    entries = dconf_client_list (client, gdir, &len;;
Packit Service 1d8f1c
    g_variant_builder_init (&builder, G_VARIANT_TYPE ("a{sv}"));
Packit Service 1d8f1c
    for (p = entries; *p != NULL; p++) {
Packit Service 1d8f1c
        gchar *gkey = g_strconcat (gdir, *p, NULL);
Packit Service 1d8f1c
        GVariant *value = dconf_client_read (client, gkey);
Packit Service 1d8f1c
        g_free (gkey);
Packit Service 1d8f1c
        if (value) {
Packit Service 1d8f1c
            gchar *name = *p;
Packit Service 1d8f1c
            if (!preserve_name) {
Packit Service 1d8f1c
                name = _from_gsettings_name (*p);
Packit Service 1d8f1c
            }
Packit Service 1d8f1c
            g_variant_builder_add (&builder, "{sv}", name, value);
Packit Service 1d8f1c
            if (name != *p) {
Packit Service 1d8f1c
                g_free (name);
Packit Service 1d8f1c
            }
Packit Service 1d8f1c
            g_variant_unref (value);
Packit Service 1d8f1c
        }
Packit Service 1d8f1c
    }
Packit Service 1d8f1c
    g_strfreev (entries);
Packit Service 1d8f1c
    g_free (gdir);
Packit Service 1d8f1c
Packit Service 1d8f1c
    return g_variant_builder_end (&builder);
Packit Service 1d8f1c
}
Packit Service 1d8f1c
Packit Service 1d8f1c
static gboolean
Packit Service 1d8f1c
ibus_config_dconf_unset_value (IBusConfigService *config,
Packit Service 1d8f1c
                               const gchar       *section,
Packit Service 1d8f1c
                               const gchar       *name,
Packit Service 1d8f1c
                               GError           **error)
Packit Service 1d8f1c
{
Packit Service 1d8f1c
    return ibus_config_dconf_set_value (config, section, name, NULL, error);
Packit Service 1d8f1c
}
Packit Service 1d8f1c
Packit Service 1d8f1c
IBusConfigDConf *
Packit Service 1d8f1c
ibus_config_dconf_new (GDBusConnection *connection)
Packit Service 1d8f1c
{
Packit Service 1d8f1c
    IBusConfigDConf *config;
Packit Service 1d8f1c
    config = (IBusConfigDConf *) g_object_new (IBUS_TYPE_CONFIG_DCONF,
Packit Service 1d8f1c
                                               "object-path", IBUS_PATH_CONFIG,
Packit Service 1d8f1c
                                               "connection", connection,
Packit Service 1d8f1c
                                               NULL);
Packit Service 1d8f1c
    return config;
Packit Service 1d8f1c
}