|
Packit |
3ff832 |
/* -*- mode: C; c-basic-offset: 4; indent-tabs-mode: nil; -*- */
|
|
Packit |
3ff832 |
/* vim:set et sts=4: */
|
|
Packit |
3ff832 |
|
|
Packit |
3ff832 |
#include <string.h>
|
|
Packit |
3ff832 |
#include <ibus.h>
|
|
Packit |
3ff832 |
#include "config.h"
|
|
Packit |
3ff832 |
|
|
Packit |
3ff832 |
#define GCONF_PREFIX "/desktop/ibus"
|
|
Packit |
3ff832 |
|
|
Packit |
3ff832 |
struct _IBusConfigGConf {
|
|
Packit |
3ff832 |
IBusConfigService parent;
|
|
Packit |
3ff832 |
GConfClient *client;
|
|
Packit |
3ff832 |
};
|
|
Packit |
3ff832 |
|
|
Packit |
3ff832 |
struct _IBusConfigGConfClass {
|
|
Packit |
3ff832 |
IBusConfigServiceClass parent;
|
|
Packit |
3ff832 |
|
|
Packit |
3ff832 |
};
|
|
Packit |
3ff832 |
|
|
Packit |
3ff832 |
/* functions prototype */
|
|
Packit |
3ff832 |
static void ibus_config_gconf_class_init (IBusConfigGConfClass *class);
|
|
Packit |
3ff832 |
static void ibus_config_gconf_init (IBusConfigGConf *config);
|
|
Packit |
3ff832 |
static void ibus_config_gconf_destroy (IBusConfigGConf *config);
|
|
Packit |
3ff832 |
static gboolean ibus_config_gconf_set_value (IBusConfigService *config,
|
|
Packit |
3ff832 |
const gchar *section,
|
|
Packit |
3ff832 |
const gchar *name,
|
|
Packit |
3ff832 |
GVariant *value,
|
|
Packit |
3ff832 |
GError **error);
|
|
Packit |
3ff832 |
static GVariant *ibus_config_gconf_get_value (IBusConfigService *config,
|
|
Packit |
3ff832 |
const gchar *section,
|
|
Packit |
3ff832 |
const gchar *name,
|
|
Packit |
3ff832 |
GError **error);
|
|
Packit |
3ff832 |
static GVariant *ibus_config_gconf_get_values (IBusConfigService *config,
|
|
Packit |
3ff832 |
const gchar *section,
|
|
Packit |
3ff832 |
GError **error);
|
|
Packit |
3ff832 |
static gboolean ibus_config_gconf_unset_value (IBusConfigService *config,
|
|
Packit |
3ff832 |
const gchar *section,
|
|
Packit |
3ff832 |
const gchar *name,
|
|
Packit |
3ff832 |
GError **error);
|
|
Packit |
3ff832 |
static GConfValue *_to_gconf_value (GVariant *value);
|
|
Packit |
3ff832 |
static GVariant *_from_gconf_value (const GConfValue *gvalue);
|
|
Packit |
3ff832 |
|
|
Packit |
3ff832 |
G_DEFINE_TYPE (IBusConfigGConf, ibus_config_gconf, IBUS_TYPE_CONFIG_SERVICE)
|
|
Packit |
3ff832 |
|
|
Packit |
3ff832 |
static void
|
|
Packit |
3ff832 |
ibus_config_gconf_class_init (IBusConfigGConfClass *class)
|
|
Packit |
3ff832 |
{
|
|
Packit |
3ff832 |
GObjectClass *object_class = G_OBJECT_CLASS (class);
|
|
Packit |
3ff832 |
|
|
Packit |
3ff832 |
IBUS_OBJECT_CLASS (object_class)->destroy = (IBusObjectDestroyFunc) ibus_config_gconf_destroy;
|
|
Packit |
3ff832 |
IBUS_CONFIG_SERVICE_CLASS (object_class)->set_value = ibus_config_gconf_set_value;
|
|
Packit |
3ff832 |
IBUS_CONFIG_SERVICE_CLASS (object_class)->get_value = ibus_config_gconf_get_value;
|
|
Packit |
3ff832 |
IBUS_CONFIG_SERVICE_CLASS (object_class)->get_values = ibus_config_gconf_get_values;
|
|
Packit |
3ff832 |
IBUS_CONFIG_SERVICE_CLASS (object_class)->unset_value = ibus_config_gconf_unset_value;
|
|
Packit |
3ff832 |
}
|
|
Packit |
3ff832 |
|
|
Packit |
3ff832 |
static void
|
|
Packit |
3ff832 |
_value_changed_cb (GConfClient *client,
|
|
Packit |
3ff832 |
const gchar *key,
|
|
Packit |
3ff832 |
GConfValue *value,
|
|
Packit |
3ff832 |
IBusConfigGConf *config)
|
|
Packit |
3ff832 |
{
|
|
Packit |
3ff832 |
gchar *p, *section, *name;
|
|
Packit |
3ff832 |
|
|
Packit |
3ff832 |
g_return_if_fail (key != NULL);
|
|
Packit |
3ff832 |
|
|
Packit |
3ff832 |
p = g_strdup (key);
|
|
Packit |
3ff832 |
section = p + sizeof (GCONF_PREFIX);
|
|
Packit |
3ff832 |
name = rindex (p, '/') + 1;
|
|
Packit |
3ff832 |
*(name - 1) = '\0';
|
|
Packit |
3ff832 |
|
|
Packit |
3ff832 |
GVariant *variant;
|
|
Packit |
3ff832 |
if (value) {
|
|
Packit |
3ff832 |
variant = _from_gconf_value (value);
|
|
Packit |
3ff832 |
}
|
|
Packit |
3ff832 |
else {
|
|
Packit |
3ff832 |
/* Use a empty typle for a unset value */
|
|
Packit |
3ff832 |
variant = g_variant_new_tuple (NULL, 0);
|
|
Packit |
3ff832 |
}
|
|
Packit |
3ff832 |
g_return_if_fail (variant != NULL);
|
|
Packit |
3ff832 |
ibus_config_service_value_changed ((IBusConfigService *) config,
|
|
Packit |
3ff832 |
section,
|
|
Packit |
3ff832 |
name,
|
|
Packit |
3ff832 |
variant);
|
|
Packit |
3ff832 |
g_variant_unref (variant);
|
|
Packit |
3ff832 |
g_free (p);
|
|
Packit |
3ff832 |
}
|
|
Packit |
3ff832 |
|
|
Packit |
3ff832 |
static void
|
|
Packit |
3ff832 |
ibus_config_gconf_init (IBusConfigGConf *config)
|
|
Packit |
3ff832 |
{
|
|
Packit |
3ff832 |
config->client = gconf_client_get_default ();
|
|
Packit |
3ff832 |
gconf_client_add_dir (config->client,
|
|
Packit |
3ff832 |
GCONF_PREFIX,
|
|
Packit |
3ff832 |
GCONF_CLIENT_PRELOAD_RECURSIVE,
|
|
Packit |
3ff832 |
NULL);
|
|
Packit |
3ff832 |
g_signal_connect (config->client, "value-changed", G_CALLBACK (_value_changed_cb), config);
|
|
Packit |
3ff832 |
}
|
|
Packit |
3ff832 |
|
|
Packit |
3ff832 |
static void
|
|
Packit |
3ff832 |
ibus_config_gconf_destroy (IBusConfigGConf *config)
|
|
Packit |
3ff832 |
{
|
|
Packit |
3ff832 |
if (config->client) {
|
|
Packit |
3ff832 |
g_signal_handlers_disconnect_by_func (config->client, G_CALLBACK (_value_changed_cb), config);
|
|
Packit |
3ff832 |
g_object_unref (config->client);
|
|
Packit |
3ff832 |
config->client = NULL;
|
|
Packit |
3ff832 |
}
|
|
Packit |
3ff832 |
|
|
Packit |
3ff832 |
IBUS_OBJECT_CLASS (ibus_config_gconf_parent_class)->destroy ((IBusObject *)config);
|
|
Packit |
3ff832 |
}
|
|
Packit |
3ff832 |
|
|
Packit |
3ff832 |
static GConfValue *
|
|
Packit |
3ff832 |
_to_gconf_value (GVariant *value)
|
|
Packit |
3ff832 |
{
|
|
Packit |
3ff832 |
GConfValue *gv = NULL;
|
|
Packit |
3ff832 |
|
|
Packit |
3ff832 |
switch (g_variant_classify (value)) {
|
|
Packit |
3ff832 |
case G_VARIANT_CLASS_STRING:
|
|
Packit |
3ff832 |
{
|
|
Packit |
3ff832 |
gv = gconf_value_new (GCONF_VALUE_STRING);
|
|
Packit |
3ff832 |
gconf_value_set_string (gv, g_variant_get_string (value, NULL));
|
|
Packit |
3ff832 |
}
|
|
Packit |
3ff832 |
break;
|
|
Packit |
3ff832 |
case G_VARIANT_CLASS_INT32:
|
|
Packit |
3ff832 |
{
|
|
Packit |
3ff832 |
gv = gconf_value_new (GCONF_VALUE_INT);
|
|
Packit |
3ff832 |
gconf_value_set_int (gv, g_variant_get_int32 (value));
|
|
Packit |
3ff832 |
}
|
|
Packit |
3ff832 |
break;
|
|
Packit |
3ff832 |
case G_VARIANT_CLASS_BOOLEAN:
|
|
Packit |
3ff832 |
{
|
|
Packit |
3ff832 |
gv = gconf_value_new (GCONF_VALUE_BOOL);
|
|
Packit |
3ff832 |
gconf_value_set_bool (gv, g_variant_get_boolean (value));
|
|
Packit |
3ff832 |
}
|
|
Packit |
3ff832 |
break;
|
|
Packit |
3ff832 |
case G_VARIANT_CLASS_DOUBLE:
|
|
Packit |
3ff832 |
{
|
|
Packit |
3ff832 |
gv = gconf_value_new (GCONF_VALUE_FLOAT);
|
|
Packit |
3ff832 |
gconf_value_set_float (gv, g_variant_get_double (value));
|
|
Packit |
3ff832 |
}
|
|
Packit |
3ff832 |
break;
|
|
Packit |
3ff832 |
case G_VARIANT_CLASS_ARRAY:
|
|
Packit |
3ff832 |
{
|
|
Packit |
3ff832 |
const GVariantType *element_type = g_variant_type_element (g_variant_get_type (value));
|
|
Packit |
3ff832 |
|
|
Packit |
3ff832 |
GConfValueType type = GCONF_VALUE_INVALID;
|
|
Packit |
3ff832 |
if (g_variant_type_equal (element_type, G_VARIANT_TYPE_STRING))
|
|
Packit |
3ff832 |
type = GCONF_VALUE_STRING;
|
|
Packit |
3ff832 |
else if (g_variant_type_equal (element_type, G_VARIANT_TYPE_INT32))
|
|
Packit |
3ff832 |
type = GCONF_VALUE_INT;
|
|
Packit |
3ff832 |
else if (g_variant_type_equal (element_type, G_VARIANT_TYPE_BOOLEAN))
|
|
Packit |
3ff832 |
type = GCONF_VALUE_BOOL;
|
|
Packit |
3ff832 |
else if (g_variant_type_equal (element_type, G_VARIANT_TYPE_DOUBLE))
|
|
Packit |
3ff832 |
type = GCONF_VALUE_FLOAT;
|
|
Packit |
3ff832 |
else
|
|
Packit |
3ff832 |
g_return_val_if_reached (NULL);
|
|
Packit |
3ff832 |
|
|
Packit |
3ff832 |
gv = gconf_value_new (GCONF_VALUE_LIST);
|
|
Packit |
3ff832 |
gconf_value_set_list_type (gv, type);
|
|
Packit |
3ff832 |
|
|
Packit |
3ff832 |
GSList *elements = NULL;
|
|
Packit |
3ff832 |
GVariantIter iter;
|
|
Packit |
3ff832 |
GVariant *child;
|
|
Packit |
3ff832 |
g_variant_iter_init (&iter, value);
|
|
Packit |
3ff832 |
while ((child = g_variant_iter_next_value (&iter)) != NULL) {
|
|
Packit |
3ff832 |
elements = g_slist_append (elements, _to_gconf_value (child));
|
|
Packit |
3ff832 |
g_variant_unref (child);
|
|
Packit |
3ff832 |
}
|
|
Packit |
3ff832 |
gconf_value_set_list_nocopy (gv, elements);
|
|
Packit |
3ff832 |
}
|
|
Packit |
3ff832 |
break;
|
|
Packit |
3ff832 |
default:
|
|
Packit |
3ff832 |
g_return_val_if_reached (NULL);
|
|
Packit |
3ff832 |
}
|
|
Packit |
3ff832 |
|
|
Packit |
3ff832 |
return gv;
|
|
Packit |
3ff832 |
}
|
|
Packit |
3ff832 |
|
|
Packit |
3ff832 |
static GVariant *
|
|
Packit |
3ff832 |
_from_gconf_value (const GConfValue *gv)
|
|
Packit |
3ff832 |
{
|
|
Packit |
3ff832 |
g_assert (gv != NULL);
|
|
Packit |
3ff832 |
|
|
Packit |
3ff832 |
switch (gv->type) {
|
|
Packit |
3ff832 |
case GCONF_VALUE_STRING:
|
|
Packit |
3ff832 |
return g_variant_new_string (gconf_value_get_string (gv));
|
|
Packit |
3ff832 |
case GCONF_VALUE_INT:
|
|
Packit |
3ff832 |
return g_variant_new_int32 (gconf_value_get_int (gv));
|
|
Packit |
3ff832 |
case GCONF_VALUE_FLOAT:
|
|
Packit |
3ff832 |
return g_variant_new_double (gconf_value_get_float (gv));
|
|
Packit |
3ff832 |
case GCONF_VALUE_BOOL:
|
|
Packit |
3ff832 |
return g_variant_new_boolean (gconf_value_get_bool (gv));
|
|
Packit |
3ff832 |
case GCONF_VALUE_LIST:
|
|
Packit |
3ff832 |
{
|
|
Packit |
3ff832 |
GVariantBuilder builder;
|
|
Packit |
3ff832 |
switch (gconf_value_get_list_type (gv)) {
|
|
Packit |
3ff832 |
case GCONF_VALUE_STRING:
|
|
Packit |
3ff832 |
g_variant_builder_init (&builder, G_VARIANT_TYPE("as")); break;
|
|
Packit |
3ff832 |
case GCONF_VALUE_INT:
|
|
Packit |
3ff832 |
g_variant_builder_init (&builder, G_VARIANT_TYPE("ai")); break;
|
|
Packit |
3ff832 |
case GCONF_VALUE_FLOAT:
|
|
Packit |
3ff832 |
g_variant_builder_init (&builder, G_VARIANT_TYPE("ad")); break;
|
|
Packit |
3ff832 |
case GCONF_VALUE_BOOL:
|
|
Packit |
3ff832 |
g_variant_builder_init (&builder, G_VARIANT_TYPE("ab")); break;
|
|
Packit |
3ff832 |
break;
|
|
Packit |
3ff832 |
default:
|
|
Packit |
3ff832 |
g_assert_not_reached ();
|
|
Packit |
3ff832 |
}
|
|
Packit |
3ff832 |
|
|
Packit |
3ff832 |
GSList *list = gconf_value_get_list (gv);
|
|
Packit |
3ff832 |
GSList *p = list;
|
|
Packit |
3ff832 |
while (p != NULL) {
|
|
Packit |
3ff832 |
switch (gconf_value_get_list_type (gv)) {
|
|
Packit |
3ff832 |
case GCONF_VALUE_STRING:
|
|
Packit |
3ff832 |
g_variant_builder_add (&builder, "s", gconf_value_get_string ((GConfValue *)p->data));
|
|
Packit |
3ff832 |
break;
|
|
Packit |
3ff832 |
case GCONF_VALUE_INT:
|
|
Packit |
3ff832 |
g_variant_builder_add (&builder, "i", gconf_value_get_int ((GConfValue *)p->data));
|
|
Packit |
3ff832 |
break;
|
|
Packit |
3ff832 |
case GCONF_VALUE_FLOAT:
|
|
Packit |
3ff832 |
g_variant_builder_add (&builder, "d", gconf_value_get_float ((GConfValue *)p->data));
|
|
Packit |
3ff832 |
break;
|
|
Packit |
3ff832 |
case GCONF_VALUE_BOOL:
|
|
Packit |
3ff832 |
g_variant_builder_add (&builder, "b", gconf_value_get_bool ((GConfValue *)p->data));
|
|
Packit |
3ff832 |
break;
|
|
Packit |
3ff832 |
default:
|
|
Packit |
3ff832 |
g_assert_not_reached ();
|
|
Packit |
3ff832 |
}
|
|
Packit |
3ff832 |
p = p->next;
|
|
Packit |
3ff832 |
}
|
|
Packit |
3ff832 |
return g_variant_builder_end (&builder);
|
|
Packit |
3ff832 |
}
|
|
Packit |
3ff832 |
default:
|
|
Packit |
3ff832 |
g_assert_not_reached ();
|
|
Packit |
3ff832 |
}
|
|
Packit |
3ff832 |
}
|
|
Packit |
3ff832 |
|
|
Packit |
3ff832 |
|
|
Packit |
3ff832 |
static gboolean
|
|
Packit |
3ff832 |
ibus_config_gconf_set_value (IBusConfigService *config,
|
|
Packit |
3ff832 |
const gchar *section,
|
|
Packit |
3ff832 |
const gchar *name,
|
|
Packit |
3ff832 |
GVariant *value,
|
|
Packit |
3ff832 |
GError **error)
|
|
Packit |
3ff832 |
{
|
|
Packit |
3ff832 |
gchar *key;
|
|
Packit |
3ff832 |
GConfValue *gv;
|
|
Packit |
3ff832 |
|
|
Packit |
3ff832 |
gv = _to_gconf_value (value);
|
|
Packit |
3ff832 |
if (gv == NULL) {
|
|
Packit |
3ff832 |
gchar *str = g_variant_print (value, TRUE);
|
|
Packit |
3ff832 |
g_set_error (error,
|
|
Packit |
3ff832 |
G_DBUS_ERROR, G_DBUS_ERROR_FAILED,
|
|
Packit |
3ff832 |
"Can not set config value [%s:%s] to %s.",
|
|
Packit |
3ff832 |
section, name, str);
|
|
Packit |
3ff832 |
g_free (str);
|
|
Packit |
3ff832 |
return FALSE;
|
|
Packit |
3ff832 |
}
|
|
Packit |
3ff832 |
key = g_strdup_printf (GCONF_PREFIX"/%s/%s", section, name);
|
|
Packit |
3ff832 |
gconf_client_set (((IBusConfigGConf *)config)->client, key, gv, error);
|
|
Packit |
3ff832 |
|
|
Packit |
3ff832 |
g_free (key);
|
|
Packit |
3ff832 |
gconf_value_free (gv);
|
|
Packit |
3ff832 |
|
|
Packit |
3ff832 |
if (*error != NULL) {
|
|
Packit |
3ff832 |
return FALSE;
|
|
Packit |
3ff832 |
}
|
|
Packit |
3ff832 |
return TRUE;
|
|
Packit |
3ff832 |
}
|
|
Packit |
3ff832 |
|
|
Packit |
3ff832 |
static GVariant *
|
|
Packit |
3ff832 |
ibus_config_gconf_get_value (IBusConfigService *config,
|
|
Packit |
3ff832 |
const gchar *section,
|
|
Packit |
3ff832 |
const gchar *name,
|
|
Packit |
3ff832 |
GError **error)
|
|
Packit |
3ff832 |
{
|
|
Packit |
3ff832 |
gchar *key = g_strdup_printf (GCONF_PREFIX"/%s/%s", section, name);
|
|
Packit |
3ff832 |
|
|
Packit |
3ff832 |
GConfValue *gv = gconf_client_get (((IBusConfigGConf *) config)->client, key, NULL);
|
|
Packit |
3ff832 |
|
|
Packit |
3ff832 |
g_free (key);
|
|
Packit |
3ff832 |
|
|
Packit |
3ff832 |
if (gv == NULL) {
|
|
Packit |
3ff832 |
g_set_error (error,
|
|
Packit |
3ff832 |
G_DBUS_ERROR, G_DBUS_ERROR_FAILED,
|
|
Packit |
3ff832 |
"Config value [%s:%s] does not exist.", section, name);
|
|
Packit |
3ff832 |
return NULL;
|
|
Packit |
3ff832 |
}
|
|
Packit |
3ff832 |
|
|
Packit |
3ff832 |
GVariant *variant = _from_gconf_value (gv);
|
|
Packit |
3ff832 |
gconf_value_free (gv);
|
|
Packit |
3ff832 |
|
|
Packit |
3ff832 |
return g_variant_ref_sink (variant);
|
|
Packit |
3ff832 |
}
|
|
Packit |
3ff832 |
|
|
Packit |
3ff832 |
static GVariant *
|
|
Packit |
3ff832 |
ibus_config_gconf_get_values (IBusConfigService *config,
|
|
Packit |
3ff832 |
const gchar *section,
|
|
Packit |
3ff832 |
GError **error)
|
|
Packit |
3ff832 |
{
|
|
Packit |
3ff832 |
gchar *dir = g_strdup_printf (GCONF_PREFIX"/%s", section);
|
|
Packit |
3ff832 |
gint len = strlen(dir) + 1;
|
|
Packit |
3ff832 |
GSList *entries = gconf_client_all_entries (((IBusConfigGConf *) config)->client, dir, NULL);
|
|
Packit |
3ff832 |
g_free (dir);
|
|
Packit |
3ff832 |
|
|
Packit |
3ff832 |
GSList *p;
|
|
Packit |
3ff832 |
GVariantBuilder builder;
|
|
Packit |
3ff832 |
|
|
Packit |
3ff832 |
g_variant_builder_init (&builder, G_VARIANT_TYPE ("a{sv}"));
|
|
Packit |
3ff832 |
for (p = entries; p != NULL; p = p->next) {
|
|
Packit |
3ff832 |
GConfEntry *entry = (GConfEntry *)p->data;
|
|
Packit |
3ff832 |
if (entry->key != NULL && entry->value != NULL) {
|
|
Packit |
3ff832 |
const gchar *name = entry->key + len;
|
|
Packit |
3ff832 |
GVariant *value = _from_gconf_value (entry->value);
|
|
Packit |
3ff832 |
g_variant_builder_add (&builder, "{sv}", name, value);
|
|
Packit |
3ff832 |
}
|
|
Packit |
3ff832 |
gconf_entry_free (entry);
|
|
Packit |
3ff832 |
}
|
|
Packit |
3ff832 |
g_slist_free (entries);
|
|
Packit |
3ff832 |
|
|
Packit |
3ff832 |
return g_variant_builder_end (&builder);
|
|
Packit |
3ff832 |
}
|
|
Packit |
3ff832 |
|
|
Packit |
3ff832 |
static gboolean
|
|
Packit |
3ff832 |
ibus_config_gconf_unset_value (IBusConfigService *config,
|
|
Packit |
3ff832 |
const gchar *section,
|
|
Packit |
3ff832 |
const gchar *name,
|
|
Packit |
3ff832 |
GError **error)
|
|
Packit |
3ff832 |
{
|
|
Packit |
3ff832 |
gchar *key = g_strdup_printf (GCONF_PREFIX"/%s/%s", section, name);
|
|
Packit |
3ff832 |
|
|
Packit |
3ff832 |
gboolean retval = gconf_client_unset (((IBusConfigGConf *)config)->client, key, error);
|
|
Packit |
3ff832 |
g_free (key);
|
|
Packit |
3ff832 |
|
|
Packit |
3ff832 |
return retval;
|
|
Packit |
3ff832 |
}
|
|
Packit |
3ff832 |
|
|
Packit |
3ff832 |
IBusConfigGConf *
|
|
Packit |
3ff832 |
ibus_config_gconf_new (GDBusConnection *connection)
|
|
Packit |
3ff832 |
{
|
|
Packit |
3ff832 |
IBusConfigGConf *config;
|
|
Packit |
3ff832 |
config = (IBusConfigGConf *) g_object_new (IBUS_TYPE_CONFIG_GCONF,
|
|
Packit |
3ff832 |
"object-path", IBUS_PATH_CONFIG,
|
|
Packit |
3ff832 |
"connection", connection,
|
|
Packit |
3ff832 |
NULL);
|
|
Packit |
3ff832 |
return config;
|
|
Packit |
3ff832 |
}
|