gvdb test: avoid infinite recursion
[dconf.git] / dbus-1 / dconf-dbus-1.c
blob67de4a0624fab2303ce49c7f465144f51543d706
1 /**
2 * Copyright © 2010 Canonical Limited
4 * This program is free software: you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License as published by
6 * the Free Software Foundation, either version 3 of the licence, or (at
7 * your option) any later version.
9 * This program is distributed in the hope that it will be useful, but
10 * WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 * General Public License for more details.
14 * You should have received a copy of the GNU General Public License
15 * along with this program. If not, see <http://www.gnu.org/licenses/>.
17 * Author: Ryan Lortie <desrt@desrt.ca>
18 **/
20 #include "config.h"
22 #include "dconf-dbus-1.h"
24 #include "../engine/dconf-engine.h"
25 #include "dconf-libdbus-1.h"
27 #include <string.h>
29 struct _DConfDBusClient
31 DConfEngine *engine;
32 GSList *watches;
33 gint ref_count;
36 typedef struct
38 gchar *path;
39 DConfDBusNotify notify;
40 gpointer user_data;
41 } Watch;
43 void
44 dconf_engine_change_notify (DConfEngine *engine,
45 const gchar *prefix,
46 const gchar * const *changes,
47 const gchar *tag,
48 gboolean is_writability,
49 gpointer origin_tag,
50 gpointer user_data)
52 DConfDBusClient *dcdbc = user_data;
53 gchar **my_changes;
54 gint n_changes;
55 GSList *iter;
56 gint i;
58 n_changes = g_strv_length ((gchar **) changes);
59 my_changes = g_new (gchar *, n_changes + 1);
61 for (i = 0; i < n_changes; i++)
62 my_changes[i] = g_strconcat (prefix, changes[i], NULL);
63 my_changes[i] = NULL;
65 for (iter = dcdbc->watches; iter; iter = iter->next)
67 Watch *watch = iter->data;
69 for (i = 0; i < n_changes; i++)
70 if (g_str_has_prefix (my_changes[i], watch->path))
71 watch->notify (dcdbc, my_changes[i], watch->user_data);
74 g_strfreev (my_changes);
77 GVariant *
78 dconf_dbus_client_read (DConfDBusClient *dcdbc,
79 const gchar *key)
81 return dconf_engine_read (dcdbc->engine, NULL, key);
84 gboolean
85 dconf_dbus_client_write (DConfDBusClient *dcdbc,
86 const gchar *key,
87 GVariant *value)
89 DConfChangeset *changeset;
90 gboolean success;
92 changeset = dconf_changeset_new_write (key, value);
93 success = dconf_engine_change_fast (dcdbc->engine, changeset, NULL, NULL);
94 dconf_changeset_unref (changeset);
96 return success;
99 void
100 dconf_dbus_client_subscribe (DConfDBusClient *dcdbc,
101 const gchar *path,
102 DConfDBusNotify notify,
103 gpointer user_data)
105 Watch *watch;
107 watch = g_slice_new (Watch);
108 watch->path = g_strdup (path);
109 watch->notify = notify;
110 watch->user_data = user_data;
112 dcdbc->watches = g_slist_prepend (dcdbc->watches, watch);
114 dconf_engine_watch_fast (dcdbc->engine, path);
117 void
118 dconf_dbus_client_unsubscribe (DConfDBusClient *dcdbc,
119 DConfDBusNotify notify,
120 gpointer user_data)
122 GSList **ptr;
124 for (ptr = &dcdbc->watches; *ptr; ptr = &(*ptr)->next)
126 Watch *watch = (*ptr)->data;
128 if (watch->notify == notify && watch->user_data == user_data)
130 *ptr = g_slist_remove_link (*ptr, *ptr);
131 dconf_engine_unwatch_fast (dcdbc->engine, watch->path);
132 g_free (watch->path);
133 g_slice_free (Watch, watch);
134 return;
138 g_warning ("No matching watch found to unsubscribe");
141 gboolean
142 dconf_dbus_client_has_pending (DConfDBusClient *dcdbc)
144 return dconf_engine_has_outstanding (dcdbc->engine);
147 DConfDBusClient *
148 dconf_dbus_client_new (const gchar *profile,
149 DBusConnection *session,
150 DBusConnection *system)
152 DConfDBusClient *dcdbc;
154 if (session == NULL)
155 session = dbus_bus_get (DBUS_BUS_SESSION, NULL);
157 if (system == NULL)
158 system = dbus_bus_get (DBUS_BUS_SYSTEM, NULL);
160 dconf_libdbus_1_provide_bus (G_BUS_TYPE_SESSION, session);
161 dconf_libdbus_1_provide_bus (G_BUS_TYPE_SYSTEM, system);
163 dcdbc = g_slice_new (DConfDBusClient);
164 dcdbc->engine = dconf_engine_new (NULL, dcdbc, NULL);
165 dcdbc->watches = NULL;
166 dcdbc->ref_count = 1;
168 return dcdbc;
171 void
172 dconf_dbus_client_unref (DConfDBusClient *dcdbc)
174 if (--dcdbc->ref_count == 0)
176 g_return_if_fail (dcdbc->watches == NULL);
178 g_slice_free (DConfDBusClient, dcdbc);
182 DConfDBusClient *
183 dconf_dbus_client_ref (DConfDBusClient *dcdbc)
185 dcdbc->ref_count++;
187 return dcdbc;