1 /* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 8 -*- */
2 /*
3 * Copyright (C) 2008 Imendio AB
4 *
5 * This program is free software; you can redistribute it and/or
6 * modify it under the terms of the GNU General Public License as
7 * published by the Free Software Foundation; either version 2 of the
8 * License, or (at your option) any later version.
9 *
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 * General Public License for more details.
14 *
15 * You should have received a copy of the GNU General Public
16 * License along with this program; if not, write to the
17 * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
18 * Boston, MA 02111-1307, USA.
19 */
20
21 #include "config.h"
22 #include <string.h>
23 #include <gconf/gconf-client.h>
24 #include "ige-conf-private.h"
25
26 typedef struct {
27 GConfClient *gconf_client;
28 GList *defaults;
29 } IgeConfPriv;
30
31 typedef struct {
32 IgeConf *conf;
33 IgeConfNotifyFunc func;
34 gpointer user_data;
35 } IgeConfNotifyData;
36
37 G_DEFINE_TYPE (IgeConf, ige_conf, G_TYPE_OBJECT);
38
39 #define GET_PRIVATE(instance) G_TYPE_INSTANCE_GET_PRIVATE \
40 (instance, IGE_TYPE_CONF, IgeConfPriv);
41
42 static IgeConf *global_conf = NULL;
43
44 static void
conf_finalize(GObject * object)45 conf_finalize (GObject *object)
46 {
47 IgeConfPriv *priv;
48
49 priv = GET_PRIVATE (object);
50
51 /* FIXME: Remove added dirs.
52 gconf_client_remove_dir (priv->gconf_client,
53 CONF_PATH,
54 NULL);
55 */
56
57 g_object_unref (priv->gconf_client);
58
59 _ige_conf_defaults_free_list (priv->defaults);
60
61 G_OBJECT_CLASS (ige_conf_parent_class)->finalize (object);
62 }
63
64 static void
ige_conf_class_init(IgeConfClass * class)65 ige_conf_class_init (IgeConfClass *class)
66 {
67 GObjectClass *object_class;
68
69 object_class = G_OBJECT_CLASS (class);
70
71 object_class->finalize = conf_finalize;
72
73 g_type_class_add_private (object_class, sizeof (IgeConfPriv));
74 }
75
76 static void
ige_conf_init(IgeConf * conf)77 ige_conf_init (IgeConf *conf)
78 {
79 IgeConfPriv *priv;
80
81 priv = GET_PRIVATE (conf);
82
83 priv->gconf_client = gconf_client_get_default ();
84 }
85
86 IgeConf *
ige_conf_get(void)87 ige_conf_get (void)
88 {
89 if (!global_conf) {
90 global_conf = g_object_new (IGE_TYPE_CONF, NULL);
91 }
92
93 return global_conf;
94 }
95
96 void
ige_conf_add_defaults(IgeConf * conf,const gchar * path)97 ige_conf_add_defaults (IgeConf *conf,
98 const gchar *path)
99 {
100 IgeConfPriv *priv = GET_PRIVATE (conf);
101 gchar *root;
102
103 priv->defaults = _ige_conf_defaults_read_file (path, NULL);
104 root = _ige_conf_defaults_get_root (priv->defaults);
105
106 gconf_client_add_dir (priv->gconf_client,
107 root,
108 GCONF_CLIENT_PRELOAD_ONELEVEL,
109 NULL);
110
111 g_free (root);
112 }
113
114 static GConfEntry *
conf_get_entry(IgeConf * conf,const gchar * key)115 conf_get_entry (IgeConf *conf,
116 const gchar *key)
117 {
118 IgeConfPriv *priv;
119
120 priv = GET_PRIVATE (conf);
121
122 return gconf_client_get_entry (priv->gconf_client, key,
123 NULL, TRUE, NULL);
124 }
125
126 gboolean
ige_conf_set_int(IgeConf * conf,const gchar * key,gint value)127 ige_conf_set_int (IgeConf *conf,
128 const gchar *key,
129 gint value)
130 {
131 IgeConfPriv *priv;
132
133 g_return_val_if_fail (IGE_IS_CONF (conf), FALSE);
134
135 priv = GET_PRIVATE (conf);
136
137 return gconf_client_set_int (priv->gconf_client,
138 key,
139 value,
140 NULL);
141 }
142
143 gboolean
ige_conf_get_int(IgeConf * conf,const gchar * key,gint * value)144 ige_conf_get_int (IgeConf *conf,
145 const gchar *key,
146 gint *value)
147 {
148 IgeConfPriv *priv;
149 GConfEntry *entry;
150 gboolean got_value = FALSE;
151
152 *value = 0;
153
154 g_return_val_if_fail (IGE_IS_CONF (conf), FALSE);
155 g_return_val_if_fail (value != NULL, FALSE);
156
157 priv = GET_PRIVATE (conf);
158
159 entry = conf_get_entry (conf, key);
160 if (entry) {
161 GConfValue *v;
162
163 v = gconf_entry_get_value (entry);
164 if (v) {
165 *value = gconf_value_get_int (v);
166 got_value = TRUE;
167 }
168 }
169
170 gconf_entry_free (entry);
171
172 if (!got_value) {
173 *value = _ige_conf_defaults_get_int (priv->defaults, key);
174 }
175
176 return TRUE;
177 }
178
179 gboolean
ige_conf_set_bool(IgeConf * conf,const gchar * key,gboolean value)180 ige_conf_set_bool (IgeConf *conf,
181 const gchar *key,
182 gboolean value)
183 {
184 IgeConfPriv *priv;
185
186 g_return_val_if_fail (IGE_IS_CONF (conf), FALSE);
187
188 priv = GET_PRIVATE (conf);
189
190 return gconf_client_set_bool (priv->gconf_client,
191 key,
192 value,
193 NULL);
194 }
195
196 gboolean
ige_conf_get_bool(IgeConf * conf,const gchar * key,gboolean * value)197 ige_conf_get_bool (IgeConf *conf,
198 const gchar *key,
199 gboolean *value)
200 {
201 IgeConfPriv *priv;
202 GConfEntry *entry;
203 gboolean got_value = FALSE;
204
205 *value = 0;
206
207 g_return_val_if_fail (IGE_IS_CONF (conf), FALSE);
208 g_return_val_if_fail (value != NULL, FALSE);
209
210 priv = GET_PRIVATE (conf);
211
212 entry = conf_get_entry (conf, key);
213 if (entry) {
214 GConfValue *v;
215
216 v = gconf_entry_get_value (entry);
217 if (v) {
218 *value = gconf_value_get_bool (v);
219 got_value = TRUE;
220 }
221 }
222
223 gconf_entry_free (entry);
224
225 if (!got_value) {
226 *value = _ige_conf_defaults_get_bool (priv->defaults, key);
227 }
228
229 return TRUE;
230 }
231
232 gboolean
ige_conf_set_string(IgeConf * conf,const gchar * key,const gchar * value)233 ige_conf_set_string (IgeConf *conf,
234 const gchar *key,
235 const gchar *value)
236 {
237 IgeConfPriv *priv;
238
239 g_return_val_if_fail (IGE_IS_CONF (conf), FALSE);
240
241 priv = GET_PRIVATE (conf);
242
243 return gconf_client_set_string (priv->gconf_client,
244 key,
245 value,
246 NULL);
247 }
248
249 gboolean
ige_conf_get_string(IgeConf * conf,const gchar * key,gchar ** value)250 ige_conf_get_string (IgeConf *conf,
251 const gchar *key,
252 gchar **value)
253 {
254 IgeConfPriv *priv;
255 GError *error = NULL;
256
257 *value = NULL;
258
259 g_return_val_if_fail (IGE_IS_CONF (conf), FALSE);
260
261 priv = GET_PRIVATE (conf);
262
263 *value = gconf_client_get_string (priv->gconf_client,
264 key,
265 &error);
266
267 if (error) {
268 g_error_free (error);
269 return FALSE;
270 }
271
272 if (*value == NULL) {
273 *value = g_strdup (_ige_conf_defaults_get_string (priv->defaults, key));
274 }
275
276 return TRUE;
277 }
278
279 gboolean
ige_conf_set_string_list(IgeConf * conf,const gchar * key,GSList * value)280 ige_conf_set_string_list (IgeConf *conf,
281 const gchar *key,
282 GSList *value)
283 {
284 IgeConfPriv *priv;
285
286 g_return_val_if_fail (IGE_IS_CONF (conf), FALSE);
287
288 priv = GET_PRIVATE (conf);
289
290 return gconf_client_set_list (priv->gconf_client,
291 key,
292 GCONF_VALUE_STRING,
293 value,
294 NULL);
295 }
296
297 gboolean
ige_conf_get_string_list(IgeConf * conf,const gchar * key,GSList ** value)298 ige_conf_get_string_list (IgeConf *conf,
299 const gchar *key,
300 GSList **value)
301 {
302 IgeConfPriv *priv;
303 GError *error = NULL;
304
305 *value = NULL;
306
307 g_return_val_if_fail (IGE_IS_CONF (conf), FALSE);
308
309 priv = GET_PRIVATE (conf);
310
311 *value = gconf_client_get_list (priv->gconf_client,
312 key,
313 GCONF_VALUE_STRING,
314 &error);
315 if (error) {
316 g_error_free (error);
317 return FALSE;
318 }
319
320 return TRUE;
321 }
322
323 static void
conf_notify_data_free(IgeConfNotifyData * data)324 conf_notify_data_free (IgeConfNotifyData *data)
325 {
326 g_object_unref (data->conf);
327 g_slice_free (IgeConfNotifyData, data);
328 }
329
330 static void
conf_notify_func(GConfClient * client,guint id,GConfEntry * entry,gpointer user_data)331 conf_notify_func (GConfClient *client,
332 guint id,
333 GConfEntry *entry,
334 gpointer user_data)
335 {
336 IgeConfNotifyData *data;
337
338 data = user_data;
339
340 data->func (data->conf,
341 gconf_entry_get_key (entry),
342 data->user_data);
343 }
344
345 guint
ige_conf_notify_add(IgeConf * conf,const gchar * key,IgeConfNotifyFunc func,gpointer user_data)346 ige_conf_notify_add (IgeConf *conf,
347 const gchar *key,
348 IgeConfNotifyFunc func,
349 gpointer user_data)
350 {
351 IgeConfPriv *priv;
352 guint id;
353 IgeConfNotifyData *data;
354
355 g_return_val_if_fail (IGE_IS_CONF (conf), 0);
356
357 priv = GET_PRIVATE (conf);
358
359 data = g_slice_new (IgeConfNotifyData);
360 data->func = func;
361 data->user_data = user_data;
362 data->conf = g_object_ref (conf);
363
364 id = gconf_client_notify_add (priv->gconf_client,
365 key,
366 conf_notify_func,
367 data,
368 (GFreeFunc) conf_notify_data_free,
369 NULL);
370
371 return id;
372 }
373
374 gboolean
ige_conf_notify_remove(IgeConf * conf,guint id)375 ige_conf_notify_remove (IgeConf *conf,
376 guint id)
377 {
378 IgeConfPriv *priv;
379
380 g_return_val_if_fail (IGE_IS_CONF (conf), FALSE);
381
382 priv = GET_PRIVATE (conf);
383
384 gconf_client_notify_remove (priv->gconf_client, id);
385
386 return TRUE;
387 }
388