1 /*
2 * Copyright © 2014 Red Hat, Inc. All rights reserved.
3 * Copyright © 2014 Ding-Yi Chen <dchen@redhat.com>
4 *
5 * This file is part of the ibus-chewing Project.
6 *
7 * This program is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU General Public License
9 * as published by the Free Software Foundation; either version 2
10 * of the License, or (at your option) any later version.
11 *
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
16 *
17 * You should have received a copy of the GNU General Public License
18 * along with this program; if not, write to the Free Software
19 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
20 */
21
22 #include <ibus.h>
23 #include <glib.h>
24 #include <gconf/gconf.h>
25 #include <gconf/gconf-client.h>
26 #include "MakerDialogUtil.h"
27 #include "GConf2Backend.h"
28
29 static GHashTable *camalCasedKeyTable = NULL;
30
31 gchar *gconf2_backend_get_key(MkdgBackend * backend,
32 const gchar * section, const gchar * key,
33 gpointer userData);
34
gconf_value_to_g_value(GConfValue * confValue,GValue * value)35 static GValue *gconf_value_to_g_value(GConfValue * confValue,
36 GValue * value)
37 {
38 GType gType = G_VALUE_TYPE(value);
39 switch (confValue->type) {
40 case GCONF_VALUE_BOOL:
41 if (gType != G_TYPE_BOOLEAN) {
42 return NULL;
43 }
44 g_value_set_boolean(value, gconf_value_get_bool(confValue));
45 break;
46 case GCONF_VALUE_INT:
47 if (gType != G_TYPE_INT && gType != G_TYPE_UINT) {
48 return NULL;
49 } else if (gType == G_TYPE_INT) {
50 g_value_set_int(value, gconf_value_get_int(confValue));
51 } else {
52 g_value_set_uint(value, gconf_value_get_int(confValue));
53 }
54 break;
55 case GCONF_VALUE_STRING:
56 if (gType != G_TYPE_STRING) {
57 return NULL;
58 }
59 g_value_set_string(value, gconf_value_get_string(confValue));
60 break;
61 default:
62 return NULL;
63 }
64 return value;
65 }
66
gconf_value_new_g_value(GValue * value)67 static GConfValue *gconf_value_new_g_value(GValue * value)
68 {
69 GConfValue *confValue;
70 GType gType = G_VALUE_TYPE(value);
71 switch (gType) {
72 case G_TYPE_BOOLEAN:
73 confValue = gconf_value_new(GCONF_VALUE_BOOL);
74 gconf_value_set_bool(confValue, g_value_get_boolean(value));
75 break;
76 case G_TYPE_INT:
77 confValue = gconf_value_new(GCONF_VALUE_INT);
78 gconf_value_set_int(confValue, g_value_get_int(value));
79 break;
80 case G_TYPE_UINT:
81 confValue = gconf_value_new(GCONF_VALUE_INT);
82 gconf_value_set_int(confValue, g_value_get_uint(value));
83 break;
84 case G_TYPE_STRING:
85 confValue = gconf_value_new(GCONF_VALUE_STRING);
86 gconf_value_set_string(confValue, g_value_get_string(value));
87 break;
88 default:
89 return NULL;
90 }
91 return confValue;
92 }
93
94 #define KEY_BUFFER_SIZE 100
to_real_key(gchar * confKey,MkdgBackend * backend,const gchar * section,const gchar * key)95 static gchar *to_real_key(gchar * confKey, MkdgBackend * backend,
96 const gchar * section, const gchar * key)
97 {
98 gchar *camalCasedKey =
99 gconf2_backend_get_key(backend, section, key, NULL);
100
101 if (!STRING_IS_EMPTY(backend->basePath)) {
102 g_strlcpy(confKey, backend->basePath, KEY_BUFFER_SIZE);
103 g_strlcat(confKey, "/", KEY_BUFFER_SIZE);
104 } else {
105 g_strlcpy(confKey, "/", KEY_BUFFER_SIZE);
106 }
107
108 if (!STRING_IS_EMPTY(section)) {
109 g_strlcat(confKey, section, KEY_BUFFER_SIZE);
110 g_strlcat(confKey, "/", KEY_BUFFER_SIZE);
111 }
112 g_strlcat(confKey, camalCasedKey, KEY_BUFFER_SIZE);
113 return confKey;
114 }
115
116 /*============================================
117 * Interface routines
118 */
gconf2_backend_get_key(MkdgBackend * backend,const gchar * section,const gchar * key,gpointer userData)119 gchar *gconf2_backend_get_key(MkdgBackend * backend,
120 const gchar * section, const gchar * key,
121 gpointer userData)
122 {
123 gchar *camalCasedKey =
124 (gchar *) g_hash_table_lookup(camalCasedKeyTable, key);
125 if (camalCasedKey == NULL) {
126 camalCasedKey = mkdg_str_dash_to_camel(key);
127 g_hash_table_insert(camalCasedKeyTable, (gpointer) key,
128 camalCasedKey);
129 }
130 return camalCasedKey;
131 }
132
gconf2_backend_read_value(MkdgBackend * backend,GValue * value,const gchar * section,const gchar * key,gpointer userData)133 GValue *gconf2_backend_read_value(MkdgBackend * backend,
134 GValue * value,
135 const gchar * section,
136 const gchar * key, gpointer userData)
137 {
138 mkdg_log(DEBUG, "gconf2_backend_read_value(-,-,%s,%s,-):", section,
139 key);
140 GConfClient *config = (GConfClient *) backend->config;
141 GError *err = NULL;
142 gchar confKey[KEY_BUFFER_SIZE];
143 to_real_key(confKey, backend, section, key);
144 GConfValue *confValue = gconf_client_get(config, confKey, &err);
145
146 if (confValue == NULL) {
147 mkdg_log(ERROR,
148 "gconf2_backend_read_value(-,-,%s,%s,-): Failed to retrieve confValue",
149 section, key);
150 return NULL;
151 }
152 if (err != NULL) {
153 mkdg_log(ERROR, "gconf2_backend_read_value(-,-,%s,%s,-): %s",
154 section, key, err->message);
155 return NULL;
156 }
157 return gconf_value_to_g_value(confValue, value);
158 }
159
gconf2_backend_write_value(MkdgBackend * backend,GValue * value,const gchar * section,const gchar * key,gpointer userData)160 gboolean gconf2_backend_write_value(MkdgBackend * backend,
161 GValue * value,
162 const gchar * section,
163 const gchar * key, gpointer userData)
164 {
165 GConfClient *config = (GConfClient *) backend->config;
166 GError *err = NULL;
167 gchar confKey[KEY_BUFFER_SIZE];
168 to_real_key(confKey, backend, section, key);
169 GConfValue *confValue = gconf_value_new_g_value(value);
170 gconf_client_set(config, confKey, confValue, &err);
171 gconf_value_free(confValue);
172 if (err != NULL) {
173 mkdg_log(ERROR, "gconf2_backend_write_value(-,-,%s,%s,-): %s",
174 section, key, err->message);
175 return FALSE;
176 }
177 return TRUE;
178 }
179
gconf2_backend_new(const gchar * basePath,gpointer auxData)180 MkdgBackend *gconf2_backend_new(const gchar * basePath, gpointer auxData)
181 {
182 GConfClient *client = gconf_client_get_default();
183 MkdgBackend *result = mkdg_backend_new(GCONF2_BACKEND_ID,
184 (gpointer) client, basePath,
185 auxData);
186 camalCasedKeyTable = g_hash_table_new(g_str_hash, g_str_equal);
187 result->getKeyFunc = gconf2_backend_get_key;
188 result->readFunc = gconf2_backend_read_value;
189 result->writeFunc = gconf2_backend_write_value;
190 return result;
191 }
192