source: proiecte/PPPP/gdm/common/gdm-settings-desktop-backend.c @ 134

Last change on this file since 134 was 134, checked in by (none), 14 years ago

gdm sources with the modifications for webcam

File size: 11.0 KB
Line 
1/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 8 -*-
2 *
3 * Copyright (C) 2007 William Jon McCann <mccann@jhu.edu>
4 *
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation; either version 2 of the License, or
8 * (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
13 * GNU General Public License for more details.
14 *
15 * You should have received a copy of the GNU General Public License
16 * along with this program; if not, write to the Free Software
17 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
18 *
19 */
20
21#include "config.h"
22
23#include <stdlib.h>
24#include <stdio.h>
25#include <fcntl.h>
26#include <unistd.h>
27#include <string.h>
28#include <signal.h>
29#include <sys/stat.h>
30#include <sys/types.h>
31
32#include <glib.h>
33#include <glib/gi18n.h>
34#include <glib/gstdio.h>
35#include <glib-object.h>
36
37#include "gdm-settings-desktop-backend.h"
38
39#include "gdm-marshal.h"
40
41#define GDM_SETTINGS_DESKTOP_BACKEND_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), GDM_TYPE_SETTINGS_DESKTOP_BACKEND, GdmSettingsDesktopBackendPrivate))
42
43struct GdmSettingsDesktopBackendPrivate
44{
45        char       *filename;
46        GKeyFile   *key_file;
47        gboolean    dirty;
48        guint       save_id;
49};
50
51static void     gdm_settings_desktop_backend_class_init (GdmSettingsDesktopBackendClass *klass);
52static void     gdm_settings_desktop_backend_init       (GdmSettingsDesktopBackend      *settings_desktop_backend);
53static void     gdm_settings_desktop_backend_finalize   (GObject                        *object);
54
55G_DEFINE_TYPE (GdmSettingsDesktopBackend, gdm_settings_desktop_backend, GDM_TYPE_SETTINGS_BACKEND)
56
57static gboolean
58parse_key_string (const char *keystring,
59                  char      **group,
60                  char      **key,
61                  char      **locale,
62                  char      **value)
63{
64        char   **split1;
65        char   **split2;
66        char    *g;
67        char    *k;
68        char    *l;
69        char    *v;
70        char    *tmp1;
71        char    *tmp2;
72        gboolean ret;
73
74        g_return_val_if_fail (keystring != NULL, FALSE);
75
76        ret = FALSE;
77        g = k = v = l = NULL;
78        split1 = split2 = NULL;
79
80        if (group != NULL) {
81                *group = g;
82        }
83        if (key != NULL) {
84                *key = k;
85        }
86        if (locale != NULL) {
87                *locale = l;
88        }
89        if (value != NULL) {
90                *value = v;
91        }
92
93        /*g_debug ("Attempting to parse key string: %s", keystring);*/
94
95        split1 = g_strsplit (keystring, "/", 2);
96        if (split1 == NULL
97            || split1 [0] == NULL
98            || split1 [1] == NULL
99            || split1 [0][0] == '\0'
100            || split1 [1][0] == '\0') {
101                g_warning ("GdmSettingsDesktopBackend: invalid key: %s", keystring);
102                goto out;
103        }
104
105        g = split1 [0];
106
107        split2 = g_strsplit (split1 [1], "=", 2);
108        if (split2 == NULL) {
109                k = split1 [1];
110        } else {
111                k = split2 [0];
112                v = split2 [1];
113        }
114
115        /* trim off the locale */
116        tmp1 = strchr (k, '[');
117        tmp2 = strchr (k, ']');
118        if (tmp1 != NULL && tmp2 != NULL && tmp2 > tmp1) {
119                l = g_strndup (tmp1 + 1, tmp2 - tmp1 - 1);
120                *tmp1 = '\0';
121        }
122
123        ret = TRUE;
124
125        if (group != NULL) {
126                *group = g_strdup (g);
127        }
128        if (key != NULL) {
129                *key = g_strdup (k);
130        }
131        if (locale != NULL) {
132                *locale = g_strdup (l);
133        }
134        if (value != NULL) {
135                *value = g_strdup (v);
136        }
137 out:
138
139        g_strfreev (split1);
140        g_strfreev (split2);
141
142        return ret;
143}
144
145static gboolean
146gdm_settings_desktop_backend_get_value (GdmSettingsBackend *backend,
147                                        const char         *key,
148                                        char              **value,
149                                        GError            **error)
150{
151        GError  *local_error;
152        char    *val;
153        char    *g;
154        char    *k;
155        char    *l;
156        gboolean ret;
157
158        g_return_val_if_fail (GDM_IS_SETTINGS_BACKEND (backend), FALSE);
159        g_return_val_if_fail (key != NULL, FALSE);
160
161        ret = FALSE;
162
163        if (value != NULL) {
164                *value = NULL;
165        }
166
167        val = g = k = l = NULL;
168        /*GDM_SETTINGS_BACKEND_CLASS (gdm_settings_desktop_backend_parent_class)->get_value (display);*/
169        if (! parse_key_string (key, &g, &k, &l, NULL)) {
170                g_set_error (error, GDM_SETTINGS_BACKEND_ERROR, GDM_SETTINGS_BACKEND_ERROR_KEY_NOT_FOUND, "Key not found");
171                goto out;
172        }
173
174        /*g_debug ("Getting key: %s %s %s", g, k, l);*/
175        local_error = NULL;
176        val = g_key_file_get_value (GDM_SETTINGS_DESKTOP_BACKEND (backend)->priv->key_file,
177                                    g,
178                                    k,
179                                    &local_error);
180        if (local_error != NULL) {
181                g_error_free (local_error);
182                g_set_error (error, GDM_SETTINGS_BACKEND_ERROR, GDM_SETTINGS_BACKEND_ERROR_KEY_NOT_FOUND, "Key not found");
183                goto out;
184        }
185
186        if (value != NULL) {
187                *value = g_strdup (val);
188        }
189        ret = TRUE;
190 out:
191        g_free (val);
192        g_free (g);
193        g_free (k);
194        g_free (l);
195
196        return ret;
197}
198
199static void
200save_settings (GdmSettingsDesktopBackend *backend)
201{
202        GError   *local_error;
203        char     *contents;
204        gsize     length;
205
206        if (! backend->priv->dirty) {
207                return;
208        }
209
210        g_debug ("Saving settings to %s", backend->priv->filename);
211
212        local_error = NULL;
213        contents = g_key_file_to_data (backend->priv->key_file, &length, &local_error);
214        if (local_error != NULL) {
215                g_warning ("Unable to save settings: %s", local_error->message);
216                g_error_free (local_error);
217                return;
218        }
219
220        local_error = NULL;
221        g_file_set_contents (backend->priv->filename,
222                             contents,
223                             length,
224                             &local_error);
225        if (local_error != NULL) {
226                g_warning ("Unable to save settings: %s", local_error->message);
227                g_error_free (local_error);
228                g_free (contents);
229                return;
230        }
231
232        g_free (contents);
233
234        backend->priv->dirty = FALSE;
235}
236
237static gboolean
238save_settings_timer (GdmSettingsDesktopBackend *backend)
239{
240        save_settings (backend);
241        backend->priv->save_id = 0;
242        return FALSE;
243}
244
245static void
246queue_save (GdmSettingsDesktopBackend *backend)
247{
248        if (! backend->priv->dirty) {
249                return;
250        }
251
252        if (backend->priv->save_id != 0) {
253                /* already pending */
254                return;
255        }
256
257        backend->priv->save_id = g_timeout_add_seconds (5, (GSourceFunc)save_settings_timer, backend);
258}
259
260static gboolean
261gdm_settings_desktop_backend_set_value (GdmSettingsBackend *backend,
262                                        const char         *key,
263                                        const char         *value,
264                                        GError            **error)
265{
266        GError *local_error;
267        char   *old_val;
268        char   *g;
269        char   *k;
270        char   *l;
271
272        g_return_val_if_fail (GDM_IS_SETTINGS_BACKEND (backend), FALSE);
273        g_return_val_if_fail (key != NULL, FALSE);
274
275        /*GDM_SETTINGS_BACKEND_CLASS (gdm_settings_desktop_backend_parent_class)->get_value (display);*/
276        if (! parse_key_string (key, &g, &k, &l, NULL)) {
277                g_set_error (error, GDM_SETTINGS_BACKEND_ERROR, GDM_SETTINGS_BACKEND_ERROR_KEY_NOT_FOUND, "Key not found");
278                return FALSE;
279        }
280
281        local_error = NULL;
282        old_val = g_key_file_get_value (GDM_SETTINGS_DESKTOP_BACKEND (backend)->priv->key_file,
283                                        g,
284                                        k,
285                                        &local_error);
286        if (local_error != NULL) {
287                g_error_free (local_error);
288        }
289
290        /*g_debug ("Setting key: %s %s %s", g, k, l);*/
291        local_error = NULL;
292        g_key_file_set_value (GDM_SETTINGS_DESKTOP_BACKEND (backend)->priv->key_file,
293                              g,
294                              k,
295                              value);
296
297        GDM_SETTINGS_DESKTOP_BACKEND (backend)->priv->dirty = TRUE;
298        queue_save (GDM_SETTINGS_DESKTOP_BACKEND (backend));
299
300        gdm_settings_backend_value_changed (backend, key, old_val, value);
301
302        g_free (old_val);
303
304        return TRUE;
305}
306
307static void
308gdm_settings_desktop_backend_class_init (GdmSettingsDesktopBackendClass *klass)
309{
310        GObjectClass            *object_class = G_OBJECT_CLASS (klass);
311        GdmSettingsBackendClass *backend_class = GDM_SETTINGS_BACKEND_CLASS (klass);
312
313        object_class->finalize = gdm_settings_desktop_backend_finalize;
314
315        backend_class->get_value = gdm_settings_desktop_backend_get_value;
316        backend_class->set_value = gdm_settings_desktop_backend_set_value;
317
318        g_type_class_add_private (klass, sizeof (GdmSettingsDesktopBackendPrivate));
319}
320
321static void
322gdm_settings_desktop_backend_init (GdmSettingsDesktopBackend *backend)
323{
324        gboolean res;
325        GError  *error;
326
327        backend->priv = GDM_SETTINGS_DESKTOP_BACKEND_GET_PRIVATE (backend);
328
329        backend->priv->key_file = g_key_file_new ();
330        backend->priv->filename = g_strdup (GDMCONFDIR "/custom.conf");
331
332        error = NULL;
333        res = g_key_file_load_from_file (backend->priv->key_file,
334                                         backend->priv->filename,
335                                         G_KEY_FILE_KEEP_COMMENTS | G_KEY_FILE_KEEP_TRANSLATIONS,
336                                         &error);
337        if (! res) {
338                g_warning ("Unable to load file '%s': %s", backend->priv->filename, error->message);
339        }
340}
341
342static void
343gdm_settings_desktop_backend_finalize (GObject *object)
344{
345        GdmSettingsDesktopBackend *backend;
346
347        g_return_if_fail (object != NULL);
348        g_return_if_fail (GDM_IS_SETTINGS_DESKTOP_BACKEND (object));
349
350        backend = GDM_SETTINGS_DESKTOP_BACKEND (object);
351
352        g_return_if_fail (backend->priv != NULL);
353
354        save_settings (backend);
355        g_key_file_free (backend->priv->key_file);
356        g_free (backend->priv->filename);
357
358        G_OBJECT_CLASS (gdm_settings_desktop_backend_parent_class)->finalize (object);
359}
360
361GdmSettingsBackend *
362gdm_settings_desktop_backend_new (void)
363{
364        GObject *object;
365
366        object = g_object_new (GDM_TYPE_SETTINGS_DESKTOP_BACKEND, NULL);
367
368        return GDM_SETTINGS_BACKEND (object);
369}
Note: See TracBrowser for help on using the repository browser.