2 * Copyright © 2012 Canonical Limited
4 * This library is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU Lesser General Public
6 * License as published by the Free Software Foundation; either
7 * version 2 of the licence, or (at your option) any later version.
9 * This library is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 * Lesser General Public License for more details.
14 * You should have received a copy of the GNU Lesser General Public
15 * License along with this library; if not, write to the
16 * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
17 * Boston, MA 02111-1307, USA.
19 * Author: Ryan Lortie <desrt@desrt.ca>
22 #include "dconf-service.h"
24 #include "dconf-generated.h"
25 #include "dconf-writer.h"
26 #include "dconf-blame.h"
31 typedef GApplicationClass DConfServiceClass
;
34 GApplication parent_instance
;
41 G_DEFINE_TYPE (DConfService
, dconf_service
, G_TYPE_APPLICATION
)
44 dconf_service_signalled (gpointer user_data
)
46 DConfService
*service
= user_data
;
48 g_application_release (G_APPLICATION (service
));
50 return G_SOURCE_REMOVE
;
54 string_set_free (GHashTable
*set
)
62 n_items
= g_hash_table_size (set
);
63 result
= g_new (gchar
*, n_items
+ 1);
65 g_hash_table_iter_init (&iter
, set
);
66 while (g_hash_table_iter_next (&iter
, &key
, NULL
))
69 g_hash_table_iter_steal (&iter
);
73 g_assert_cmpint (n_items
, ==, i
);
74 g_hash_table_unref (set
);
82 return g_hash_table_new_full (g_str_hash
, g_str_equal
, g_free
, NULL
);
86 string_set_add (GHashTable
*set
,
89 g_hash_table_add (set
, g_strdup (string
));
93 dconf_service_subtree_enumerate (GDBusConnection
*connection
,
95 const gchar
*object_path
,
98 DConfService
*service
= user_data
;
103 set
= string_set_new ();
104 g_hash_table_iter_init (&iter
, service
->writers
);
105 while (g_hash_table_iter_next (&iter
, &key
, NULL
))
106 string_set_add (set
, key
);
108 return string_set_free (set
);
111 GDBusInterfaceInfo
**
112 dconf_service_subtree_introspect (GDBusConnection
*connection
,
114 const gchar
*object_path
,
118 GDBusInterfaceInfo
**result
;
123 result
= g_new (GDBusInterfaceInfo
*, 2);
124 result
[0] = dconf_dbus_writer_interface_info ();
131 dconf_service_get_writer (DConfService
*service
,
132 GDBusConnection
*connection
,
133 const gchar
*base_path
,
136 GDBusInterfaceSkeleton
*writer
;
138 writer
= g_hash_table_lookup (service
->writers
, name
);
142 GError
*error
= NULL
;
145 writer
= dconf_writer_new (DCONF_TYPE_WRITER
, name
);
146 g_hash_table_insert (service
->writers
, g_strdup (name
), writer
);
147 object_path
= g_strjoin ("/", base_path
, name
, NULL
);
148 g_dbus_interface_skeleton_export (writer
, connection
, object_path
, &error
);
149 g_assert_no_error (error
);
150 g_free (object_path
);
156 const GDBusInterfaceVTable
*
157 dconf_service_subtree_dispatch (GDBusConnection
*connection
,
159 const gchar
*object_path
,
160 const gchar
*interface_name
,
162 gpointer
*out_user_data
,
165 DConfService
*service
= user_data
;
167 g_assert_cmpstr (interface_name
, ==, "ca.desrt.dconf.Writer");
168 g_assert (node
!= NULL
);
170 *out_user_data
= dconf_service_get_writer (service
, connection
, object_path
, node
);
172 return g_dbus_interface_skeleton_get_vtable (*out_user_data
);
176 dconf_service_dbus_register (GApplication
*application
,
177 GDBusConnection
*connection
,
178 const gchar
*object_path
,
181 const GDBusSubtreeVTable subtree_vtable
= {
182 dconf_service_subtree_enumerate
,
183 dconf_service_subtree_introspect
,
184 dconf_service_subtree_dispatch
186 DConfService
*service
= DCONF_SERVICE (application
);
187 GError
*local_error
= NULL
;
189 service
->blame
= dconf_blame_get ();
192 g_dbus_interface_skeleton_export (G_DBUS_INTERFACE_SKELETON (service
->blame
),
193 connection
, object_path
, &local_error
);
194 g_assert_no_error (local_error
);
197 service
->subtree_id
= g_dbus_connection_register_subtree (connection
, "/ca/desrt/dconf/Writer", &subtree_vtable
,
198 G_DBUS_SUBTREE_FLAGS_DISPATCH_TO_UNENUMERATED_NODES
,
199 g_object_ref (service
), g_object_unref
, &local_error
);
200 g_assert_no_error (local_error
);
206 dconf_service_dbus_unregister (GApplication
*application
,
207 GDBusConnection
*connection
,
208 const gchar
*object_path
)
210 DConfService
*service
= DCONF_SERVICE (application
);
214 g_dbus_interface_skeleton_unexport (G_DBUS_INTERFACE_SKELETON (service
->blame
));
215 g_object_unref (service
->blame
);
216 service
->blame
= NULL
;
219 g_dbus_connection_unregister_subtree (connection
, service
->subtree_id
);
220 service
->subtree_id
= 0;
224 dconf_service_startup (GApplication
*application
)
226 DConfService
*service
= DCONF_SERVICE (application
);
228 G_APPLICATION_CLASS (dconf_service_parent_class
)
229 ->startup (application
);
231 g_unix_signal_add (SIGTERM
, dconf_service_signalled
, service
);
232 g_unix_signal_add (SIGINT
, dconf_service_signalled
, service
);
233 g_unix_signal_add (SIGHUP
, dconf_service_signalled
, service
);
235 g_application_hold (application
);
239 dconf_service_shutdown (GApplication
*application
)
241 G_APPLICATION_CLASS (dconf_service_parent_class
)
242 ->shutdown (application
);
246 dconf_service_init (DConfService
*service
)
248 service
->writers
= g_hash_table_new_full (g_str_hash
, g_str_equal
, g_free
, g_object_unref
);
252 dconf_service_class_init (GApplicationClass
*class)
254 class->dbus_register
= dconf_service_dbus_register
;
255 class->dbus_unregister
= dconf_service_dbus_unregister
;
256 class->startup
= dconf_service_startup
;
257 class->shutdown
= dconf_service_shutdown
;
261 dconf_service_new (void)
263 return g_object_new (DCONF_TYPE_SERVICE
,
264 "application-id", "ca.desrt.dconf",
265 "flags", G_APPLICATION_IS_SERVICE
,