summaryrefslogtreecommitdiffstats
path: root/gconf/config.c
diff options
context:
space:
mode:
Diffstat (limited to 'gconf/config.c')
-rw-r--r--gconf/config.c312
1 files changed, 312 insertions, 0 deletions
diff --git a/gconf/config.c b/gconf/config.c
new file mode 100644
index 0000000..a7fa394
--- /dev/null
+++ b/gconf/config.c
@@ -0,0 +1,312 @@
+/* vim:set et sts=4: */
+
+#include <string.h>
+#include <ibus.h>
+#include "config.h"
+
+#define GCONF_PREFIX "/desktop/ibus"
+
+/* functions prototype */
+static void ibus_config_gconf_class_init (IBusConfigGConfClass *klass);
+static void ibus_config_gconf_init (IBusConfigGConf *config);
+static void ibus_config_gconf_destroy (IBusConfigGConf *config);
+static gboolean ibus_config_gconf_set_value (IBusConfigService *config,
+ const gchar *section,
+ const gchar *name,
+ const GValue *value,
+ IBusError **error);
+static gboolean ibus_config_gconf_get_value (IBusConfigService *config,
+ const gchar *section,
+ const gchar *name,
+ GValue *value,
+ IBusError **error);
+
+static GConfValue *_to_gconf_value (const GValue *value);
+static void _from_gconf_value (GValue *value,
+ const GConfValue *gvalue);
+
+static IBusConfigServiceClass *parent_class = NULL;
+
+GType
+ibus_config_gconf_get_type (void)
+{
+ static GType type = 0;
+
+ static const GTypeInfo type_info = {
+ sizeof (IBusConfigGConfClass),
+ (GBaseInitFunc) NULL,
+ (GBaseFinalizeFunc) NULL,
+ (GClassInitFunc) ibus_config_gconf_class_init,
+ NULL,
+ NULL,
+ sizeof (IBusConfigGConf),
+ 0,
+ (GInstanceInitFunc) ibus_config_gconf_init,
+ };
+
+ if (type == 0) {
+ type = g_type_register_static (IBUS_TYPE_CONFIG_SERVICE,
+ "IBusConfigGConf",
+ &type_info,
+ (GTypeFlags) 0);
+ }
+
+ return type;
+}
+
+static void
+ibus_config_gconf_class_init (IBusConfigGConfClass *klass)
+{
+ GObjectClass *object_class = G_OBJECT_CLASS (klass);
+
+ parent_class = (IBusConfigServiceClass *) g_type_class_peek_parent (klass);
+
+ IBUS_OBJECT_CLASS (object_class)->destroy = (IBusObjectDestroyFunc) ibus_config_gconf_destroy;
+ IBUS_CONFIG_SERVICE_CLASS (object_class)->set_value = ibus_config_gconf_set_value;
+ IBUS_CONFIG_SERVICE_CLASS (object_class)->get_value = ibus_config_gconf_get_value;
+}
+
+static void
+_value_changed_cb (GConfClient *client,
+ const gchar *key,
+ GConfValue *value,
+ IBusConfigGConf *config)
+{
+ gchar *p, *section, *name;
+ GValue v = { 0 };
+
+ p = g_strdup (key);
+ section = p + sizeof (GCONF_PREFIX);
+ name = rindex (p, '/') + 1;
+ *(name - 1) = '\0';
+
+
+ _from_gconf_value (&v, value);
+ ibus_config_service_value_changed ((IBusConfigService *) config,
+ section,
+ name,
+ &v);
+ g_free (p);
+ g_value_unset (&v);
+}
+
+static void
+ibus_config_gconf_init (IBusConfigGConf *config)
+{
+ config->client = gconf_client_get_default ();
+ gconf_client_add_dir (config->client, GCONF_PREFIX, GCONF_CLIENT_PRELOAD_NONE, NULL);
+ g_signal_connect (config->client, "value-changed", G_CALLBACK (_value_changed_cb), config);
+}
+
+static void
+ibus_config_gconf_destroy (IBusConfigGConf *config)
+{
+ if (config->client) {
+ g_object_unref (config->client);
+ config->client = NULL;
+ }
+
+ IBUS_OBJECT_CLASS (parent_class)->destroy ((IBusObject *)config);
+}
+
+static GConfValue *
+_to_gconf_value (const GValue *value)
+{
+ GConfValue *gv;
+ GType type = G_VALUE_TYPE (value);
+
+ switch (type) {
+ case G_TYPE_STRING:
+ {
+ gv = gconf_value_new (GCONF_VALUE_STRING);
+ gconf_value_set_string (gv, g_value_get_string (value));
+ }
+ break;
+ case G_TYPE_INT:
+ {
+ gv = gconf_value_new (GCONF_VALUE_INT);
+ gconf_value_set_int (gv, g_value_get_int (value));
+ }
+ break;
+ case G_TYPE_UINT:
+ {
+ gv = gconf_value_new (GCONF_VALUE_INT);
+ gconf_value_set_int (gv, g_value_get_uint (value));
+ }
+ break;
+ case G_TYPE_BOOLEAN:
+ {
+ gv = gconf_value_new (GCONF_VALUE_BOOL);
+ gconf_value_set_bool (gv, g_value_get_boolean (value));
+ }
+ break;
+ case G_TYPE_DOUBLE:
+ {
+ gv = gconf_value_new (GCONF_VALUE_FLOAT);
+ gconf_value_set_float (gv, g_value_get_double (value));
+ }
+ break;
+ case G_TYPE_FLOAT:
+ {
+ gv = gconf_value_new (GCONF_VALUE_FLOAT);
+ gconf_value_set_float (gv, g_value_get_float (value));
+ }
+ break;
+ default:
+ if (type == G_TYPE_VALUE_ARRAY) {
+
+ GSList *l = NULL;
+ GType list_type = G_TYPE_STRING;
+ GValueArray *array = g_value_get_boxed (value);
+ gint i;
+
+ if (array && array->n_values > 0) {
+ list_type = G_VALUE_TYPE (&(array->values[0]));
+ }
+
+ gv = gconf_value_new (GCONF_VALUE_LIST);
+
+ switch (list_type) {
+ case G_TYPE_STRING:
+ gconf_value_set_list_type (gv, GCONF_VALUE_STRING); break;
+ case G_TYPE_INT:
+ case G_TYPE_UINT:
+ gconf_value_set_list_type (gv, GCONF_VALUE_INT); break;
+ case G_TYPE_BOOLEAN:
+ gconf_value_set_list_type (gv, GCONF_VALUE_BOOL); break;
+ case G_TYPE_FLOAT:
+ case G_TYPE_DOUBLE:
+ gconf_value_set_list_type (gv, GCONF_VALUE_FLOAT); break;
+ default:
+ g_assert_not_reached ();
+ }
+
+ for (i = 0; array && i < array->n_values; i++) {
+ GConfValue *tmp;
+ g_assert (G_VALUE_TYPE (&(array->values[i])) == list_type);
+ tmp = _to_gconf_value (&(array->values[i]));
+ l = g_slist_append (l, tmp);
+ }
+ gconf_value_set_list_nocopy (gv, l);
+ }
+ else
+ g_assert_not_reached ();
+ }
+ return gv;
+}
+
+static void
+_from_gconf_value (GValue *value,
+ const GConfValue *gv)
+{
+ g_assert (value);
+ g_assert (gv);
+
+ switch (gv->type) {
+ case GCONF_VALUE_STRING:
+ g_value_init (value, G_TYPE_STRING);
+ g_value_set_string (value, gconf_value_get_string (gv));
+ return;
+ case GCONF_VALUE_INT:
+ g_value_init (value, G_TYPE_INT);
+ g_value_set_int (value, gconf_value_get_int (gv));
+ return;
+ case GCONF_VALUE_FLOAT:
+ g_value_init (value, G_TYPE_DOUBLE);
+ g_value_set_double (value, gconf_value_get_float (gv));
+ return;
+ case GCONF_VALUE_BOOL:
+ g_value_init (value, G_TYPE_BOOLEAN);
+ g_value_set_boolean (value, gconf_value_get_bool (gv));
+ return;
+ case GCONF_VALUE_LIST:
+ {
+ g_value_init (value, G_TYPE_VALUE_ARRAY);
+
+ GSList *list, *p;
+ GValueArray *va;
+
+ list = gconf_value_get_list (gv);
+ va = g_value_array_new (g_slist_length (list));
+ for (p = list; p != NULL; p = p->next) {
+ GValue tmp = {0};
+ _from_gconf_value (&tmp, (GConfValue *) p->data);
+ g_value_array_append (va, &tmp);
+ }
+
+ g_value_take_boxed (value, va);
+ }
+ return;
+ default:
+ g_assert_not_reached ();
+ break;
+ }
+}
+
+
+static gboolean
+ibus_config_gconf_set_value (IBusConfigService *config,
+ const gchar *section,
+ const gchar *name,
+ const GValue *value,
+ IBusError **error)
+{
+ gchar *key;
+ GConfValue *gv;
+ GError *gerror = NULL;
+
+ gv = _to_gconf_value (value);
+
+ key = g_strdup_printf (GCONF_PREFIX"/%s/%s", section, name);
+
+ gconf_client_set (((IBusConfigGConf *)config)->client, key, gv, &gerror);
+ g_free (key);
+ gconf_value_free (gv);
+
+ if (gerror != NULL) {
+ if (error) {
+ *error = ibus_error_new_from_text (DBUS_ERROR_FAILED, gerror->message);
+ g_error_free (gerror);
+ }
+ return FALSE;
+ }
+
+ return TRUE;
+}
+static gboolean
+ibus_config_gconf_get_value (IBusConfigService *config,
+ const gchar *section,
+ const gchar *name,
+ GValue *value,
+ IBusError **error)
+{
+ gchar *key;
+ GConfValue *gv;
+
+ key = g_strdup_printf (GCONF_PREFIX"/%s/%s", section, name);
+
+ gv = gconf_client_get (((IBusConfigGConf *) config)->client, key, NULL);
+ g_free (key);
+
+ if (gv == NULL) {
+ *error = ibus_error_new_from_printf (DBUS_ERROR_FAILED,
+ "Can not get value [%s->%s]", section, name);
+ return FALSE;
+ }
+
+ _from_gconf_value (value, gv);
+ gconf_value_free (gv);
+ return TRUE;
+}
+
+IBusConfigGConf *
+ibus_config_gconf_new (IBusConnection *connection)
+{
+ IBusConfigGConf *config;
+
+ config = (IBusConfigGConf *) g_object_new (IBUS_TYPE_CONFIG_GCONF,
+ "path", IBUS_PATH_CONFIG,
+ "connection", connection,
+ NULL);
+ return config;
+}