1
/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 8 -*-
3
* Copyright (C) 2007 William Jon McCann <mccann@jhu.edu>
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.
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.
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.
29
#include <glib/gi18n.h>
30
#include <glib-object.h>
33
#define GNOME_DESKTOP_USE_UNSTABLE_API
34
#include <libgnome-desktop/gnome-pnp-ids.h>
36
#include "gnome-settings-plugin.h"
37
#include "gnome-settings-plugin-info.h"
38
#include "gnome-settings-manager.h"
39
#include "gnome-settings-profile.h"
41
#define DEFAULT_SETTINGS_PREFIX "org.gnome.settings-daemon"
43
#define PLUGIN_EXT ".gnome-settings-plugin"
45
#define GNOME_SETTINGS_MANAGER_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), GNOME_TYPE_SETTINGS_MANAGER, GnomeSettingsManagerPrivate))
47
static const gchar introspection_xml[] =
48
"<node name='/org/gnome/SettingsDaemon'>"
49
" <interface name='org.gnome.SettingsDaemon'>"
50
" <annotation name='org.freedesktop.DBus.GLib.CSymbol' value='gnome_settings_manager'/>"
51
" <signal name='PluginActivated'>"
52
" <arg name='name' type='s'/>"
54
" <signal name='PluginDeactivated'>"
55
" <arg name='name' type='s'/>"
60
struct GnomeSettingsManagerPrivate
63
GDBusNodeInfo *introspection_data;
64
GDBusConnection *connection;
71
static void gnome_settings_manager_class_init (GnomeSettingsManagerClass *klass);
72
static void gnome_settings_manager_init (GnomeSettingsManager *settings_manager);
73
static void gnome_settings_manager_finalize (GObject *object);
75
G_DEFINE_TYPE (GnomeSettingsManager, gnome_settings_manager, G_TYPE_OBJECT)
77
static gpointer manager_object = NULL;
80
gnome_settings_manager_error_quark (void)
82
static GQuark ret = 0;
84
ret = g_quark_from_static_string ("gnome_settings_manager_error");
91
maybe_activate_plugin (GnomeSettingsPluginInfo *info, gpointer user_data)
93
if (gnome_settings_plugin_info_get_enabled (info)) {
95
res = gnome_settings_plugin_info_activate (info);
97
g_debug ("Plugin %s: active", gnome_settings_plugin_info_get_location (info));
99
g_debug ("Plugin %s: activation failed", gnome_settings_plugin_info_get_location (info));
102
g_debug ("Plugin %s: inactive", gnome_settings_plugin_info_get_location (info));
107
compare_location (GnomeSettingsPluginInfo *a,
108
GnomeSettingsPluginInfo *b)
113
loc_a = gnome_settings_plugin_info_get_location (a);
114
loc_b = gnome_settings_plugin_info_get_location (b);
116
if (loc_a == NULL || loc_b == NULL) {
120
return strcmp (loc_a, loc_b);
124
compare_priority (GnomeSettingsPluginInfo *a,
125
GnomeSettingsPluginInfo *b)
130
prio_a = gnome_settings_plugin_info_get_priority (a);
131
prio_b = gnome_settings_plugin_info_get_priority (b);
133
return prio_a - prio_b;
137
emit_signal (GnomeSettingsManager *manager,
141
GError *error = NULL;
143
/* FIXME: maybe we should queue those up until the D-Bus
144
* connection is available... */
145
if (manager->priv->connection == NULL)
148
if (g_dbus_connection_emit_signal (manager->priv->connection,
153
g_variant_new ("(s)", name),
155
g_debug ("Error emitting signal: %s", error->message);
156
g_error_free (error);
162
on_plugin_activated (GnomeSettingsPluginInfo *info,
163
GnomeSettingsManager *manager)
167
name = gnome_settings_plugin_info_get_location (info);
168
g_debug ("GnomeSettingsManager: emitting plugin-activated %s", name);
169
emit_signal (manager, "PluginActivated", name);
173
on_plugin_deactivated (GnomeSettingsPluginInfo *info,
174
GnomeSettingsManager *manager)
178
name = gnome_settings_plugin_info_get_location (info);
179
g_debug ("GnomeSettingsManager: emitting plugin-deactivated %s", name);
180
emit_signal (manager, "PluginDeactivated", name);
184
contained (const char * const *items,
188
if (g_strcmp0 (*items++, item) == 0) {
197
is_schema (const char *schema)
199
return contained (g_settings_list_schemas (), schema);
203
is_whitelisted (char **whitelist,
204
const char *plugin_name)
206
if (whitelist == NULL ||
207
whitelist[0] == NULL ||
208
g_strcmp0 (whitelist[0], "all") == 0)
211
return contained ((const char * const *) whitelist, plugin_name);
215
_load_file (GnomeSettingsManager *manager,
216
const char *filename)
218
GnomeSettingsPluginInfo *info;
222
g_debug ("Loading plugin: %s", filename);
223
gnome_settings_profile_start ("%s", filename);
225
info = gnome_settings_plugin_info_new_from_file (filename);
230
l = g_slist_find_custom (manager->priv->plugins,
232
(GCompareFunc) compare_location);
237
if (!is_whitelisted (manager->priv->whitelist,
238
gnome_settings_plugin_info_get_location (info))) {
239
g_debug ("Plugin %s ignored as it's not whitelisted",
240
gnome_settings_plugin_info_get_location (info));
244
key_name = g_strdup_printf ("%s.plugins.%s",
245
DEFAULT_SETTINGS_PREFIX,
246
gnome_settings_plugin_info_get_location (info));
248
/* Ignore unknown schemas or else we'll assert */
249
if (is_schema (key_name)) {
250
manager->priv->plugins = g_slist_prepend (manager->priv->plugins,
251
g_object_ref (info));
253
g_signal_connect (info, "activated",
254
G_CALLBACK (on_plugin_activated), manager);
255
g_signal_connect (info, "deactivated",
256
G_CALLBACK (on_plugin_deactivated), manager);
258
gnome_settings_plugin_info_set_settings_prefix (info, key_name);
260
g_warning ("Ignoring unknown module '%s'", key_name);
263
/* Priority is set in the call above */
268
g_object_unref (info);
271
gnome_settings_profile_end ("%s", filename);
275
_load_dir (GnomeSettingsManager *manager,
282
g_debug ("Loading settings plugins from dir: %s", path);
283
gnome_settings_profile_start (NULL);
286
d = g_dir_open (path, 0, &error);
288
g_warning ("%s", error->message);
289
g_error_free (error);
293
while ((name = g_dir_read_name (d))) {
296
if (!g_str_has_suffix (name, PLUGIN_EXT)) {
300
filename = g_build_filename (path, name, NULL);
301
if (g_file_test (filename, G_FILE_TEST_IS_REGULAR)) {
302
_load_file (manager, filename);
309
gnome_settings_profile_end (NULL);
313
_load_all (GnomeSettingsManager *manager)
315
gnome_settings_profile_start (NULL);
317
/* load system plugins */
318
_load_dir (manager, GNOME_SETTINGS_PLUGINDIR G_DIR_SEPARATOR_S);
320
manager->priv->plugins = g_slist_sort (manager->priv->plugins, (GCompareFunc) compare_priority);
321
g_slist_foreach (manager->priv->plugins, (GFunc) maybe_activate_plugin, NULL);
322
gnome_settings_profile_end (NULL);
326
_unload_plugin (GnomeSettingsPluginInfo *info, gpointer user_data)
328
if (gnome_settings_plugin_info_get_enabled (info)) {
329
gnome_settings_plugin_info_deactivate (info);
331
g_object_unref (info);
335
_unload_all (GnomeSettingsManager *manager)
337
g_slist_foreach (manager->priv->plugins, (GFunc) _unload_plugin, NULL);
338
g_slist_free (manager->priv->plugins);
339
manager->priv->plugins = NULL;
343
on_bus_gotten (GObject *source_object,
345
GnomeSettingsManager *manager)
347
GDBusConnection *connection;
348
GError *error = NULL;
350
connection = g_bus_get_finish (res, &error);
351
if (connection == NULL) {
352
g_warning ("Could not get session bus: %s", error->message);
353
g_error_free (error);
356
manager->priv->connection = connection;
358
g_dbus_connection_register_object (connection,
360
manager->priv->introspection_data->interfaces[0],
368
register_manager (GnomeSettingsManager *manager)
370
manager->priv->introspection_data = g_dbus_node_info_new_for_xml (introspection_xml, NULL);
371
g_assert (manager->priv->introspection_data != NULL);
373
g_bus_get (G_BUS_TYPE_SESSION,
375
(GAsyncReadyCallback) on_bus_gotten,
380
gnome_settings_manager_start (GnomeSettingsManager *manager,
385
g_debug ("Starting settings manager");
389
gnome_settings_profile_start (NULL);
391
if (!g_module_supported ()) {
392
g_warning ("gnome-settings-daemon is not able to initialize the plugins.");
394
GNOME_SETTINGS_MANAGER_ERROR,
395
GNOME_SETTINGS_MANAGER_ERROR_GENERAL,
396
"Plugins not supported");
401
g_debug ("loading PNPIDs");
402
manager->priv->pnp_ids = gnome_pnp_ids_new ();
404
gnome_settings_profile_start ("initializing plugins");
405
manager->priv->settings = g_settings_new (DEFAULT_SETTINGS_PREFIX ".plugins");
406
manager->priv->whitelist = g_settings_get_strv (manager->priv->settings, "whitelisted-plugins");
409
gnome_settings_profile_end ("initializing plugins");
413
gnome_settings_profile_end (NULL);
419
gnome_settings_manager_stop (GnomeSettingsManager *manager)
421
g_debug ("Stopping settings manager");
423
_unload_all (manager);
425
if (manager->priv->owner_id > 0) {
426
g_bus_unown_name (manager->priv->owner_id);
427
manager->priv->owner_id = 0;
430
g_clear_pointer (&manager->priv->whitelist, g_strfreev);
431
g_clear_object (&manager->priv->settings);
432
g_clear_object (&manager->priv->pnp_ids);
436
gnome_settings_manager_dispose (GObject *object)
438
GnomeSettingsManager *manager;
440
manager = GNOME_SETTINGS_MANAGER (object);
442
gnome_settings_manager_stop (manager);
444
G_OBJECT_CLASS (gnome_settings_manager_parent_class)->dispose (object);
448
gnome_settings_manager_class_init (GnomeSettingsManagerClass *klass)
450
GObjectClass *object_class = G_OBJECT_CLASS (klass);
452
object_class->dispose = gnome_settings_manager_dispose;
453
object_class->finalize = gnome_settings_manager_finalize;
455
g_type_class_add_private (klass, sizeof (GnomeSettingsManagerPrivate));
459
gnome_settings_manager_init (GnomeSettingsManager *manager)
462
manager->priv = GNOME_SETTINGS_MANAGER_GET_PRIVATE (manager);
466
gnome_settings_manager_finalize (GObject *object)
468
GnomeSettingsManager *manager;
470
g_return_if_fail (object != NULL);
471
g_return_if_fail (GNOME_IS_SETTINGS_MANAGER (object));
473
manager = GNOME_SETTINGS_MANAGER (object);
475
g_return_if_fail (manager->priv != NULL);
477
G_OBJECT_CLASS (gnome_settings_manager_parent_class)->finalize (object);
480
GnomeSettingsManager *
481
gnome_settings_manager_new (void)
483
if (manager_object != NULL) {
484
g_object_ref (manager_object);
486
manager_object = g_object_new (GNOME_TYPE_SETTINGS_MANAGER,
488
g_object_add_weak_pointer (manager_object,
489
(gpointer *) &manager_object);
490
register_manager (manager_object);
493
return GNOME_SETTINGS_MANAGER (manager_object);