1 /* -*- mode: C; c-basic-offset: 4; indent-tabs-mode: nil; -*- */
2 /* vim:set et sts=4: */
8 #define GCONF_PREFIX "/desktop/ibus"
10 struct _IBusConfigGConf {
11 IBusConfigService parent;
15 struct _IBusConfigGConfClass {
16 IBusConfigServiceClass parent;
20 /* functions prototype */
21 static void ibus_config_gconf_class_init (IBusConfigGConfClass *class);
22 static void ibus_config_gconf_init (IBusConfigGConf *config);
23 static void ibus_config_gconf_destroy (IBusConfigGConf *config);
24 static gboolean ibus_config_gconf_set_value (IBusConfigService *config,
29 static GVariant *ibus_config_gconf_get_value (IBusConfigService *config,
33 static GVariant *ibus_config_gconf_get_values (IBusConfigService *config,
36 static gboolean ibus_config_gconf_unset_value (IBusConfigService *config,
40 static GConfValue *_to_gconf_value (GVariant *value);
41 static GVariant *_from_gconf_value (const GConfValue *gvalue);
43 G_DEFINE_TYPE (IBusConfigGConf, ibus_config_gconf, IBUS_TYPE_CONFIG_SERVICE)
46 ibus_config_gconf_class_init (IBusConfigGConfClass *class)
48 GObjectClass *object_class = G_OBJECT_CLASS (class);
50 IBUS_OBJECT_CLASS (object_class)->destroy = (IBusObjectDestroyFunc) ibus_config_gconf_destroy;
51 IBUS_CONFIG_SERVICE_CLASS (object_class)->set_value = ibus_config_gconf_set_value;
52 IBUS_CONFIG_SERVICE_CLASS (object_class)->get_value = ibus_config_gconf_get_value;
53 IBUS_CONFIG_SERVICE_CLASS (object_class)->get_values = ibus_config_gconf_get_values;
54 IBUS_CONFIG_SERVICE_CLASS (object_class)->unset_value = ibus_config_gconf_unset_value;
58 _value_changed_cb (GConfClient *client,
61 IBusConfigGConf *config)
63 gchar *p, *section, *name;
65 g_return_if_fail (key != NULL);
68 section = p + sizeof (GCONF_PREFIX);
69 name = rindex (p, '/') + 1;
74 variant = _from_gconf_value (value);
77 /* Use a empty typle for a unset value */
78 variant = g_variant_new_tuple (NULL, 0);
80 g_return_if_fail (variant != NULL);
81 ibus_config_service_value_changed ((IBusConfigService *) config,
85 g_variant_unref (variant);
90 ibus_config_gconf_init (IBusConfigGConf *config)
92 config->client = gconf_client_get_default ();
93 gconf_client_add_dir (config->client,
95 GCONF_CLIENT_PRELOAD_RECURSIVE,
97 g_signal_connect (config->client, "value-changed", G_CALLBACK (_value_changed_cb), config);
101 ibus_config_gconf_destroy (IBusConfigGConf *config)
103 if (config->client) {
104 g_signal_handlers_disconnect_by_func (config->client, G_CALLBACK (_value_changed_cb), config);
105 g_object_unref (config->client);
106 config->client = NULL;
109 IBUS_OBJECT_CLASS (ibus_config_gconf_parent_class)->destroy ((IBusObject *)config);
113 _to_gconf_value (GVariant *value)
115 GConfValue *gv = NULL;
117 switch (g_variant_classify (value)) {
118 case G_VARIANT_CLASS_STRING:
120 gv = gconf_value_new (GCONF_VALUE_STRING);
121 gconf_value_set_string (gv, g_variant_get_string (value, NULL));
124 case G_VARIANT_CLASS_INT32:
126 gv = gconf_value_new (GCONF_VALUE_INT);
127 gconf_value_set_int (gv, g_variant_get_int32 (value));
130 case G_VARIANT_CLASS_BOOLEAN:
132 gv = gconf_value_new (GCONF_VALUE_BOOL);
133 gconf_value_set_bool (gv, g_variant_get_boolean (value));
136 case G_VARIANT_CLASS_DOUBLE:
138 gv = gconf_value_new (GCONF_VALUE_FLOAT);
139 gconf_value_set_float (gv, g_variant_get_double (value));
142 case G_VARIANT_CLASS_ARRAY:
144 const GVariantType *element_type = g_variant_type_element (g_variant_get_type (value));
146 GConfValueType type = GCONF_VALUE_INVALID;
147 if (g_variant_type_equal (element_type, G_VARIANT_TYPE_STRING))
148 type = GCONF_VALUE_STRING;
149 else if (g_variant_type_equal (element_type, G_VARIANT_TYPE_INT32))
150 type = GCONF_VALUE_INT;
151 else if (g_variant_type_equal (element_type, G_VARIANT_TYPE_BOOLEAN))
152 type = GCONF_VALUE_BOOL;
153 else if (g_variant_type_equal (element_type, G_VARIANT_TYPE_DOUBLE))
154 type = GCONF_VALUE_FLOAT;
156 g_return_val_if_reached (NULL);
158 gv = gconf_value_new (GCONF_VALUE_LIST);
159 gconf_value_set_list_type (gv, type);
161 GSList *elements = NULL;
164 g_variant_iter_init (&iter, value);
165 while ((child = g_variant_iter_next_value (&iter)) != NULL) {
166 elements = g_slist_append (elements, _to_gconf_value (child));
167 g_variant_unref (child);
169 gconf_value_set_list_nocopy (gv, elements);
173 g_return_val_if_reached (NULL);
180 _from_gconf_value (const GConfValue *gv)
182 g_assert (gv != NULL);
185 case GCONF_VALUE_STRING:
186 return g_variant_new_string (gconf_value_get_string (gv));
187 case GCONF_VALUE_INT:
188 return g_variant_new_int32 (gconf_value_get_int (gv));
189 case GCONF_VALUE_FLOAT:
190 return g_variant_new_double (gconf_value_get_float (gv));
191 case GCONF_VALUE_BOOL:
192 return g_variant_new_boolean (gconf_value_get_bool (gv));
193 case GCONF_VALUE_LIST:
195 GVariantBuilder builder;
196 switch (gconf_value_get_list_type (gv)) {
197 case GCONF_VALUE_STRING:
198 g_variant_builder_init (&builder, G_VARIANT_TYPE("as")); break;
199 case GCONF_VALUE_INT:
200 g_variant_builder_init (&builder, G_VARIANT_TYPE("ai")); break;
201 case GCONF_VALUE_FLOAT:
202 g_variant_builder_init (&builder, G_VARIANT_TYPE("ad")); break;
203 case GCONF_VALUE_BOOL:
204 g_variant_builder_init (&builder, G_VARIANT_TYPE("ab")); break;
207 g_assert_not_reached ();
210 GSList *list = gconf_value_get_list (gv);
213 switch (gconf_value_get_list_type (gv)) {
214 case GCONF_VALUE_STRING:
215 g_variant_builder_add (&builder, "s", gconf_value_get_string ((GConfValue *)p->data));
217 case GCONF_VALUE_INT:
218 g_variant_builder_add (&builder, "i", gconf_value_get_int ((GConfValue *)p->data));
220 case GCONF_VALUE_FLOAT:
221 g_variant_builder_add (&builder, "d", gconf_value_get_float ((GConfValue *)p->data));
223 case GCONF_VALUE_BOOL:
224 g_variant_builder_add (&builder, "b", gconf_value_get_bool ((GConfValue *)p->data));
227 g_assert_not_reached ();
231 return g_variant_builder_end (&builder);
234 g_assert_not_reached ();
240 ibus_config_gconf_set_value (IBusConfigService *config,
241 const gchar *section,
249 gv = _to_gconf_value (value);
251 gchar *str = g_variant_print (value, TRUE);
252 *error = g_error_new (G_DBUS_ERROR, G_DBUS_ERROR_FAILED,
253 "Can not set config value [%s:%s] to %s.",
258 key = g_strdup_printf (GCONF_PREFIX"/%s/%s", section, name);
259 gconf_client_set (((IBusConfigGConf *)config)->client, key, gv, error);
262 gconf_value_free (gv);
264 if (*error != NULL) {
271 ibus_config_gconf_get_value (IBusConfigService *config,
272 const gchar *section,
276 gchar *key = g_strdup_printf (GCONF_PREFIX"/%s/%s", section, name);
278 GConfValue *gv = gconf_client_get (((IBusConfigGConf *) config)->client, key, NULL);
283 *error = g_error_new (G_DBUS_ERROR, G_DBUS_ERROR_FAILED,
284 "Config value [%s:%s] does not exist.", section, name);
288 GVariant *variant = _from_gconf_value (gv);
289 gconf_value_free (gv);
295 ibus_config_gconf_get_values (IBusConfigService *config,
296 const gchar *section,
299 gchar *dir = g_strdup_printf (GCONF_PREFIX"/%s", section);
300 gint len = strlen(dir) + 1;
301 GSList *entries = gconf_client_all_entries (((IBusConfigGConf *) config)->client, dir, NULL);
305 GVariantBuilder *builder = g_variant_builder_new (G_VARIANT_TYPE ("a{sv}"));
306 for (p = entries; p != NULL; p = p->next) {
307 GConfEntry *entry = (GConfEntry *)p->data;
308 if (entry->key != NULL && entry->value != NULL) {
309 const gchar *name = entry->key + len;
310 GVariant *value = _from_gconf_value (entry->value);
311 g_variant_builder_add (builder, "{sv}", name, value);
313 gconf_entry_free (entry);
315 g_slist_free (entries);
317 return g_variant_builder_end (builder);
321 ibus_config_gconf_unset_value (IBusConfigService *config,
322 const gchar *section,
326 gchar *key = g_strdup_printf (GCONF_PREFIX"/%s/%s", section, name);
328 gconf_client_unset (((IBusConfigGConf *)config)->client, key, error);
331 if (*error != NULL) {
338 ibus_config_gconf_new (GDBusConnection *connection)
340 IBusConfigGConf *config;
341 config = (IBusConfigGConf *) g_object_new (IBUS_TYPE_CONFIG_GCONF,
342 "object-path", IBUS_PATH_CONFIG,
343 "connection", connection,