1 /* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 8 -*-
3 * Copyright (C) 2008 Vincent Untz <vuntz@gnome.org>
5 * Based on set-timezone.c from gnome-panel which was GPLv2+ with this
7 * Copyright (C) 2007 David Zeuthen <david@fubar.dk>
9 * This program is free software; you can redistribute it and/or modify
10 * it under the terms of the GNU General Public License as published by
11 * the Free Software Foundation; either version 2 of the License, or
12 * (at your option) any later version.
14 * This program is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 * GNU General Public License for more details.
19 * You should have received a copy of the GNU General Public License
20 * along with this program; if not, write to the Free Software
21 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
36 #include <dbus/dbus-glib.h>
37 #include <dbus/dbus-glib-lowlevel.h>
39 #include "gconf-policykit.h"
41 #define CACHE_VALIDITY_SEC 10
43 static DBusGConnection *
47 static DBusGConnection *bus = NULL;
51 bus = dbus_g_bus_get (DBUS_BUS_SYSTEM, &error);
53 g_warning ("Couldn't connect to system bus: %s",
63 can_set (const gchar *key, gboolean mandatory)
66 DBusGProxy *proxy = NULL;
72 bus = get_system_bus ();
76 proxy = dbus_g_proxy_new_for_name (bus,
77 "org.gnome.GConf.Defaults",
79 "org.gnome.GConf.Defaults");
85 func = mandatory ? "CanSetMandatory" : "CanSetSystem";
87 if (!dbus_g_proxy_call (proxy, func,
93 g_warning ("error calling %s: %s\n", func, error->message);
99 g_object_unref (proxy);
106 time_t last_refreshed;
110 static GHashTable *defaults_cache = NULL;
111 static GHashTable *mandatory_cache = NULL;
114 gconf_pk_can_set (const gchar *key, gboolean mandatory)
121 cache = mandatory ? &mandatory_cache : &defaults_cache;
123 *cache = g_hash_table_new (g_str_hash, g_str_equal);
124 entry = (CacheEntry *) g_hash_table_lookup (*cache, key);
126 entry = g_new0 (CacheEntry, 1);
127 g_hash_table_insert (*cache, (char *) key, entry);
129 if (ABS (now - entry->last_refreshed) > CACHE_VALIDITY_SEC) {
130 entry->can_set = can_set (key, mandatory);
131 entry->last_refreshed = now;
134 return entry->can_set;
138 gconf_pk_can_set_default (const gchar *key)
140 return gconf_pk_can_set (key, FALSE);
144 gconf_pk_can_set_mandatory (const gchar *key)
146 return gconf_pk_can_set (key, TRUE);
150 gconf_pk_update_can_set_cache (const gchar *key,
158 cache = mandatory ? &mandatory_cache : &defaults_cache;
160 *cache = g_hash_table_new (g_str_hash, g_str_equal);
161 entry = (CacheEntry *) g_hash_table_lookup (*cache, key);
163 entry = g_new0 (CacheEntry, 1);
164 g_hash_table_insert (*cache, (char *) key, entry);
167 entry->last_refreshed = now;
176 GDestroyNotify notify;
177 } GConfPKCallbackData;
180 _gconf_pk_data_ref (gpointer d)
182 GConfPKCallbackData *data = d;
190 _gconf_pk_data_unref (gpointer d)
192 GConfPKCallbackData *data = d;
195 if (data->ref_count == 0) {
197 data->notify (data->data);
199 g_slice_free (GConfPKCallbackData, data);
203 static void set_key_async (GConfPKCallbackData *data);
206 gconf_pk_update_can_set_cache (const gchar *key,
210 set_key_notify (DBusGProxy *proxy,
211 DBusGProxyCall *call,
214 GConfPKCallbackData *data = user_data;
215 GError *error = NULL;
217 if (dbus_g_proxy_end_call (proxy, call, &error, G_TYPE_INVALID)) {
218 gconf_pk_update_can_set_cache (data->key, data->mandatory);
220 data->callback (data->data, NULL);
223 if (error->domain == DBUS_GERROR &&
224 error->code == DBUS_GERROR_NO_REPLY) {
225 /* these errors happen because dbus doesn't
226 * use monotonic clocks
228 g_warning ("ignoring no-reply error when setting key");
229 g_error_free (error);
231 data->callback (data->data, NULL);
235 data->callback (data->data, error);
237 g_error_free (error);
243 set_key_async (GConfPKCallbackData *data)
245 DBusGConnection *bus;
248 gchar *keys[2] = { data->key, NULL };
250 bus = get_system_bus ();
254 proxy = dbus_g_proxy_new_for_name (bus,
255 "org.gnome.GConf.Defaults",
257 "org.gnome.GConf.Defaults");
259 call = data->mandatory ? "SetMandatory" : "SetSystem";
260 dbus_g_proxy_begin_call_with_timeout (proxy,
263 _gconf_pk_data_ref (data),
264 _gconf_pk_data_unref,
275 gconf_pk_set_default_async (const gchar *key,
278 GDestroyNotify notify)
280 GConfPKCallbackData *data;
285 data = g_slice_new0 (GConfPKCallbackData);
287 data->mandatory = FALSE;
288 data->key = g_strdup (key);
289 data->callback = callback;
291 data->notify = notify;
293 set_key_async (data);
294 _gconf_pk_data_unref (data);
298 gconf_pk_set_mandatory_async (const gchar *key,
301 GDestroyNotify notify)
303 GConfPKCallbackData *data;
308 data = g_slice_new0 (GConfPKCallbackData);
310 data->mandatory = TRUE;
311 data->key = g_strdup (key);
312 data->callback = callback;
314 data->notify = notify;
316 set_key_async (data);
317 _gconf_pk_data_unref (data);