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