source: proiecte/PPPP/gdm/common/gdm-settings-client.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: 14.2 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#define DBUS_API_SUBJECT_TO_CHANGE
33#include <dbus/dbus-glib.h>
34#include <dbus/dbus-glib-lowlevel.h>
35
36#include <glib.h>
37#include <glib/gi18n.h>
38#include <glib/gstdio.h>
39#include <glib-object.h>
40
41#include "gdm-settings-client.h"
42#include "gdm-settings-utils.h"
43
44#define SETTINGS_DBUS_NAME      "org.gnome.DisplayManager"
45#define SETTINGS_DBUS_PATH      "/org/gnome/DisplayManager/Settings"
46#define SETTINGS_DBUS_INTERFACE "org.gnome.DisplayManager.Settings"
47
48static GHashTable      *notifiers      = NULL;
49static GHashTable      *schemas        = NULL;
50static DBusGProxy      *settings_proxy = NULL;
51static DBusGConnection *connection     = NULL;
52static guint32          id_serial      = 0;
53
54typedef struct {
55        guint                       id;
56        char                       *root;
57        GdmSettingsClientNotifyFunc func;
58        gpointer                    user_data;
59        GFreeFunc                   destroy_notify;
60} GdmSettingsClientNotify;
61
62static void
63gdm_settings_client_notify_free (GdmSettingsClientNotify *notify)
64{
65        g_free (notify->root);
66
67        if (notify->destroy_notify != NULL) {
68                notify->destroy_notify (notify->user_data);
69        }
70
71        g_free (notify);
72}
73
74static GdmSettingsEntry *
75get_entry_for_key (const char *key)
76{
77        GdmSettingsEntry *entry;
78
79        entry = g_hash_table_lookup (schemas, key);
80
81        if (entry == NULL) {
82                g_warning ("GdmSettingsClient: unable to find schema for key: %s", key);
83        }
84
85        return entry;
86}
87
88static gboolean
89set_value (const char *key,
90           const char *value)
91{
92        GError  *error;
93        gboolean res;
94
95        /* FIXME: check cache */
96
97        g_debug ("Setting %s=%s", key, value);
98        error = NULL;
99        res = dbus_g_proxy_call (settings_proxy,
100                                 "SetValue",
101                                 &error,
102                                 G_TYPE_STRING, key,
103                                 G_TYPE_STRING, value,
104                                 G_TYPE_INVALID,
105                                 G_TYPE_INVALID);
106        if (! res) {
107                if (error != NULL) {
108                        /*g_debug ("Failed to get value for %s: %s", key, error->message);*/
109                        g_error_free (error);
110                } else {
111                        /*g_debug ("Failed to get value for %s", key);*/
112                }
113
114                return FALSE;
115        }
116
117        return TRUE;
118}
119
120static gboolean
121get_value (const char *key,
122           char      **value)
123{
124        GError  *error;
125        char    *str;
126        gboolean res;
127
128        /* FIXME: check cache */
129
130        error = NULL;
131        res = dbus_g_proxy_call (settings_proxy,
132                                 "GetValue",
133                                 &error,
134                                 G_TYPE_STRING, key,
135                                 G_TYPE_INVALID,
136                                 G_TYPE_STRING, &str,
137                                 G_TYPE_INVALID);
138        if (! res) {
139                if (error != NULL) {
140                        /*g_debug ("Failed to get value for %s: %s", key, error->message);*/
141                        g_error_free (error);
142                } else {
143                        /*g_debug ("Failed to get value for %s", key);*/
144                }
145
146                return FALSE;
147        }
148
149        if (value != NULL) {
150                *value = g_strdup (str);
151        }
152
153        g_free (str);
154
155        return TRUE;
156}
157
158static void
159assert_signature (GdmSettingsEntry *entry,
160                  const char       *signature)
161{
162        const char *sig;
163
164        sig = gdm_settings_entry_get_signature (entry);
165
166        g_assert (sig != NULL);
167        g_assert (signature != NULL);
168        g_assert (strcmp (signature, sig) == 0);
169}
170
171static guint32
172get_next_serial (void)
173{
174        guint32 serial;
175
176        serial = id_serial++;
177
178        if ((gint32)id_serial < 0) {
179                id_serial = 1;
180        }
181
182        return serial;
183}
184
185guint
186gdm_settings_client_notify_add (const char                 *root,
187                                GdmSettingsClientNotifyFunc func,
188                                gpointer                    user_data,
189                                GFreeFunc                   destroy_notify)
190{
191        guint32                  id;
192        GdmSettingsClientNotify *notify;
193
194        id = get_next_serial ();
195
196        notify = g_new0 (GdmSettingsClientNotify, 1);
197        notify->id = id;
198        notify->root = g_strdup (root);
199        notify->func = func;
200        notify->user_data = user_data;
201        notify->destroy_notify = destroy_notify;
202
203        g_hash_table_insert (notifiers, GINT_TO_POINTER (id), notify);
204
205        return id;
206}
207
208void
209gdm_settings_client_notify_remove (guint id)
210{
211        g_hash_table_remove (notifiers, GINT_TO_POINTER (id));
212}
213
214gboolean
215gdm_settings_client_get_string (const char  *key,
216                                char       **value)
217{
218        GdmSettingsEntry *entry;
219        gboolean          ret;
220        gboolean          res;
221        char             *str;
222
223        g_return_val_if_fail (key != NULL, FALSE);
224
225        entry = get_entry_for_key (key);
226        g_assert (entry != NULL);
227
228        assert_signature (entry, "s");
229
230        ret = FALSE;
231
232        res = get_value (key, &str);
233
234        if (! res) {
235                /* use the default */
236                str = g_strdup (gdm_settings_entry_get_default_value (entry));
237        }
238
239        if (value != NULL) {
240                *value = g_strdup (str);
241        }
242
243        ret = TRUE;
244
245        g_free (str);
246
247        return ret;
248}
249
250gboolean
251gdm_settings_client_get_locale_string (const char  *key,
252                                       const char  *locale,
253                                       char       **value)
254{
255        char    *candidate_key;
256        char    *translated_value;
257        char   **languages;
258        gboolean free_languages = FALSE;
259        int      i;
260        gboolean ret;
261
262        g_return_val_if_fail (key != NULL, FALSE);
263
264        candidate_key = NULL;
265        translated_value = NULL;
266
267        if (locale != NULL) {
268                languages = g_new (char *, 2);
269                languages[0] = (char *)locale;
270                languages[1] = NULL;
271
272                free_languages = TRUE;
273        } else {
274                languages = (char **) g_get_language_names ();
275                free_languages = FALSE;
276        }
277
278        for (i = 0; languages[i]; i++) {
279                gboolean res;
280
281                candidate_key = g_strdup_printf ("%s[%s]", key, languages[i]);
282
283                res = get_value (candidate_key, &translated_value);
284                g_free (candidate_key);
285
286                if (res) {
287                        break;
288                }
289
290                g_free (translated_value);
291                translated_value = NULL;
292        }
293
294        /* Fallback to untranslated key
295         */
296        if (translated_value == NULL) {
297                get_value (key, &translated_value);
298        }
299
300        if (free_languages) {
301                g_strfreev (languages);
302        }
303
304        if (translated_value != NULL) {
305                ret = TRUE;
306                if (value != NULL) {
307                        *value = g_strdup (translated_value);
308                }
309        } else {
310                ret = FALSE;
311        }
312
313        g_free (translated_value);
314
315        return ret;
316}
317
318gboolean
319gdm_settings_client_get_boolean (const char *key,
320                                 gboolean   *value)
321{
322        GdmSettingsEntry *entry;
323        gboolean          ret;
324        gboolean          res;
325        char             *str;
326
327        g_return_val_if_fail (key != NULL, FALSE);
328
329        entry = get_entry_for_key (key);
330        g_assert (entry != NULL);
331
332        assert_signature (entry, "b");
333
334        ret = FALSE;
335
336        res = get_value (key, &str);
337
338        if (! res) {
339                /* use the default */
340                str = g_strdup (gdm_settings_entry_get_default_value (entry));
341        }
342
343        ret = gdm_settings_parse_value_as_boolean  (str, value);
344
345        g_free (str);
346
347        return ret;
348}
349
350gboolean
351gdm_settings_client_get_int (const char *key,
352                             int        *value)
353{
354        GdmSettingsEntry *entry;
355        gboolean          ret;
356        gboolean          res;
357        char             *str;
358
359        g_return_val_if_fail (key != NULL, FALSE);
360
361        entry = get_entry_for_key (key);
362        g_assert (entry != NULL);
363
364        assert_signature (entry, "i");
365
366        ret = FALSE;
367
368        res = get_value (key, &str);
369
370        if (! res) {
371                /* use the default */
372                str = g_strdup (gdm_settings_entry_get_default_value (entry));
373        }
374
375        ret = gdm_settings_parse_value_as_integer (str, value);
376
377        g_free (str);
378
379        return ret;
380}
381
382gboolean
383gdm_settings_client_set_int (const char *key,
384                             int         value)
385{
386        GdmSettingsEntry *entry;
387        gboolean          res;
388        char             *str;
389
390        g_return_val_if_fail (key != NULL, FALSE);
391
392        entry = get_entry_for_key (key);
393        g_assert (entry != NULL);
394
395        assert_signature (entry, "i");
396
397        str = gdm_settings_parse_integer_as_value (value);
398
399        res = set_value (key, str);
400
401        g_free (str);
402
403        return res;
404}
405
406gboolean
407gdm_settings_client_set_string (const char *key,
408                                const char *value)
409{
410        GdmSettingsEntry *entry;
411        gboolean          res;
412
413        g_return_val_if_fail (key != NULL, FALSE);
414
415        entry = get_entry_for_key (key);
416        g_assert (entry != NULL);
417
418        assert_signature (entry, "s");
419
420        res = set_value (key, value);
421
422        return res;
423}
424
425gboolean
426gdm_settings_client_set_boolean (const char *key,
427                                 gboolean    value)
428{
429        GdmSettingsEntry *entry;
430        gboolean          res;
431        char             *str;
432
433        g_return_val_if_fail (key != NULL, FALSE);
434
435        entry = get_entry_for_key (key);
436        g_assert (entry != NULL);
437
438        assert_signature (entry, "b");
439
440        str = gdm_settings_parse_boolean_as_value (value);
441
442        res = set_value (key, str);
443
444        g_free (str);
445
446        return res;
447}
448
449static void
450hashify_list (GdmSettingsEntry *entry,
451              gpointer          data)
452{
453        g_hash_table_insert (schemas, g_strdup (gdm_settings_entry_get_key (entry)), entry);
454}
455
456static void
457send_notification (gpointer                 key,
458                   GdmSettingsClientNotify *notify,
459                   GdmSettingsEntry        *entry)
460{
461        /* get out if the key is not in the region of interest */
462        if (! g_str_has_prefix (gdm_settings_entry_get_key (entry), notify->root)) {
463                return;
464        }
465
466        notify->func (notify->id, entry, notify->user_data);
467}
468
469static void
470on_value_changed (DBusGProxy *proxy,
471                  const char *key,
472                  const char *old_value,
473                  const char *new_value,
474                  gpointer    data)
475{
476        GdmSettingsEntry *entry;
477
478        g_debug ("Value Changed key=%s old=%s new=%s", key, old_value, new_value);
479
480        /* lookup entry */
481        entry = get_entry_for_key (key);
482
483        if (entry == NULL) {
484                return;
485        }
486
487        gdm_settings_entry_set_value (entry, new_value);
488
489        g_hash_table_foreach (notifiers, (GHFunc)send_notification, entry);
490}
491
492gboolean
493gdm_settings_client_init (const char *file,
494                          const char *root)
495{
496        GError  *error;
497        GSList  *list;
498
499        g_return_val_if_fail (file != NULL, FALSE);
500        g_return_val_if_fail (root != NULL, FALSE);
501
502        g_assert (schemas == NULL);
503
504        error = NULL;
505        connection = dbus_g_bus_get (DBUS_BUS_SYSTEM, &error);
506        if (connection == NULL) {
507                if (error != NULL) {
508                        g_warning ("error getting system bus: %s", error->message);
509                        g_error_free (error);
510                }
511                return FALSE;
512        }
513
514        settings_proxy = dbus_g_proxy_new_for_name (connection,
515                                                    SETTINGS_DBUS_NAME,
516                                                    SETTINGS_DBUS_PATH,
517                                                    SETTINGS_DBUS_INTERFACE);
518        if (settings_proxy == NULL) {
519                g_warning ("Unable to connect to settings server");
520                return FALSE;
521        }
522
523        list = NULL;
524        if (! gdm_settings_parse_schemas (file, root, &list)) {
525                g_warning ("Unable to parse schemas");
526                return FALSE;
527        }
528
529        notifiers = g_hash_table_new_full (g_direct_hash, g_direct_equal, NULL, (GDestroyNotify)gdm_settings_client_notify_free);
530
531        schemas = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, (GDestroyNotify)gdm_settings_entry_free);
532        g_slist_foreach (list, (GFunc)hashify_list, NULL);
533
534        dbus_g_proxy_add_signal (settings_proxy, "ValueChanged", G_TYPE_STRING, G_TYPE_STRING, G_TYPE_STRING, G_TYPE_INVALID);
535        dbus_g_proxy_connect_signal (settings_proxy,
536                                     "ValueChanged",
537                                     G_CALLBACK (on_value_changed),
538                                     NULL,
539                                     NULL);
540
541
542        return TRUE;
543}
544
545void
546gdm_settings_client_shutdown (void)
547{
548
549}
Note: See TracBrowser for help on using the repository browser.