diff options
Diffstat (limited to 'src/gs-prefs.c')
-rw-r--r-- | src/gs-prefs.c | 995 |
1 files changed, 995 insertions, 0 deletions
diff --git a/src/gs-prefs.c b/src/gs-prefs.c new file mode 100644 index 0000000..0f9d14e --- /dev/null +++ b/src/gs-prefs.c @@ -0,0 +1,995 @@ +/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 8 -*- + * + * Copyright (C) 2004-2006 William Jon McCann <[email protected]> + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + * + * Authors: William Jon McCann <[email protected]> + * + */ + +#include "config.h" + +#include <string.h> + +#include <glib.h> +#include <glib-object.h> +#include <mateconf/mateconf-client.h> + +#include "gs-prefs.h" + +static void gs_prefs_class_init (GSPrefsClass *klass); +static void gs_prefs_init (GSPrefs *prefs); +static void gs_prefs_finalize (GObject *object); + +#define MATE_LOCKDOWN_DIR "/desktop/mate/lockdown" +#define KEY_LOCK_DISABLE MATE_LOCKDOWN_DIR "/disable_lock_screen" +#define KEY_USER_SWITCH_DISABLE MATE_LOCKDOWN_DIR "/disable_user_switching" + +#define KEY_DIR "/apps/mate-screensaver" +#define MATE_SESSION_DIR "/desktop/mate/session" +#define KEY_IDLE_ACTIVATION_ENABLED KEY_DIR "/idle_activation_enabled" +#define KEY_LOCK_ENABLED KEY_DIR "/lock_enabled" +#define KEY_MODE KEY_DIR "/mode" +#define KEY_ACTIVATE_DELAY MATE_SESSION_DIR "/idle_delay" +#define KEY_POWER_DELAY KEY_DIR "/power_management_delay" +#define KEY_LOCK_DELAY KEY_DIR "/lock_delay" +#define KEY_CYCLE_DELAY KEY_DIR "/cycle_delay" +#define KEY_THEMES KEY_DIR "/themes" +#define KEY_USER_SWITCH_ENABLED KEY_DIR "/user_switch_enabled" +#define KEY_LOGOUT_ENABLED KEY_DIR "/logout_enabled" +#define KEY_LOGOUT_DELAY KEY_DIR "/logout_delay" +#define KEY_LOGOUT_COMMAND KEY_DIR "/logout_command" +#define KEY_KEYBOARD_ENABLED KEY_DIR "/embedded_keyboard_enabled" +#define KEY_KEYBOARD_COMMAND KEY_DIR "/embedded_keyboard_command" +#define KEY_STATUS_MESSAGE_ENABLED KEY_DIR "/status_message_enabled" + +#define GS_PREFS_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), GS_TYPE_PREFS, GSPrefsPrivate)) + +struct GSPrefsPrivate +{ + MateConfClient *mateconf_client; +}; + +enum +{ + CHANGED, + LAST_SIGNAL +}; + +enum +{ + PROP_0 +}; + +static MateConfEnumStringPair mode_enum_map [] = +{ + { GS_MODE_BLANK_ONLY, "blank-only" }, + { GS_MODE_RANDOM, "random" }, + { GS_MODE_SINGLE, "single" }, + { 0, NULL } +}; + +static guint signals [LAST_SIGNAL] = { 0, }; + +G_DEFINE_TYPE (GSPrefs, gs_prefs, G_TYPE_OBJECT) + +static void +gs_prefs_set_property (GObject *object, + guint prop_id, + const GValue *value, + GParamSpec *pspec) +{ + switch (prop_id) + { + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); + break; + } +} + +static void +gs_prefs_get_property (GObject *object, + guint prop_id, + GValue *value, + GParamSpec *pspec) +{ + switch (prop_id) + { + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); + break; + } +} + +static void +gs_prefs_class_init (GSPrefsClass *klass) +{ + GObjectClass *object_class = G_OBJECT_CLASS (klass); + + object_class->finalize = gs_prefs_finalize; + object_class->get_property = gs_prefs_get_property; + object_class->set_property = gs_prefs_set_property; + + + signals [CHANGED] = + g_signal_new ("changed", + G_TYPE_FROM_CLASS (object_class), + G_SIGNAL_RUN_LAST, + G_STRUCT_OFFSET (GSPrefsClass, changed), + NULL, + NULL, + g_cclosure_marshal_VOID__VOID, + G_TYPE_NONE, + 0); + + g_type_class_add_private (klass, sizeof (GSPrefsPrivate)); + +} + +static void +_gs_prefs_set_timeout (GSPrefs *prefs, + int value) +{ + if (value < 1) + value = 10; + + /* pick a reasonable large number for the + upper bound */ + if (value > 480) + value = 480; + + prefs->timeout = value * 60000; +} + +static void +_gs_prefs_set_power_timeout (GSPrefs *prefs, + int value) +{ + if (value < 1) + value = 60; + + /* pick a reasonable large number for the + upper bound */ + if (value > 480) + value = 480; + + /* this value is in seconds - others are in minutes */ + prefs->power_timeout = value * 1000; +} + +static void +_gs_prefs_set_lock_timeout (GSPrefs *prefs, + int value) +{ + if (value < 0) + value = 0; + + /* pick a reasonable large number for the + upper bound */ + if (value > 480) + value = 480; + + prefs->lock_timeout = value * 60000; +} + +static void +_gs_prefs_set_cycle_timeout (GSPrefs *prefs, + int value) +{ + if (value < 1) + value = 1; + + /* pick a reasonable large number for the + upper bound */ + if (value > 480) + value = 480; + + prefs->cycle = value * 60000; +} + +static void +_gs_prefs_set_mode (GSPrefs *prefs, + const char *value) +{ + int mode; + + if (value && mateconf_string_to_enum (mode_enum_map, value, &mode)) + prefs->mode = mode; + else + prefs->mode = GS_MODE_BLANK_ONLY; +} + +static void +_gs_prefs_set_themes (GSPrefs *prefs, + GSList *list) +{ + if (prefs->themes) + { + g_slist_foreach (prefs->themes, (GFunc)g_free, NULL); + g_slist_free (prefs->themes); + } + + /* take ownership of the list */ + prefs->themes = list; +} + +static void +_gs_prefs_set_idle_activation_enabled (GSPrefs *prefs, + gboolean value) +{ + prefs->idle_activation_enabled = value; +} + +static void +_gs_prefs_set_lock_enabled (GSPrefs *prefs, + gboolean value) +{ + prefs->lock_enabled = value; +} + +static void +_gs_prefs_set_lock_disabled (GSPrefs *prefs, + gboolean value) +{ + prefs->lock_disabled = value; +} + +static void +_gs_prefs_set_user_switch_disabled (GSPrefs *prefs, + gboolean value) +{ + prefs->user_switch_disabled = value; +} + +static void +_gs_prefs_set_keyboard_enabled (GSPrefs *prefs, + gboolean value) +{ + prefs->keyboard_enabled = value; +} + +static void +_gs_prefs_set_keyboard_command (GSPrefs *prefs, + const char *value) +{ + g_free (prefs->keyboard_command); + prefs->keyboard_command = NULL; + + if (value) + { + /* FIXME: check command */ + + prefs->keyboard_command = g_strdup (value); + } +} + +static void +_gs_prefs_set_status_message_enabled (GSPrefs *prefs, + gboolean enabled) +{ + prefs->status_message_enabled = enabled; +} + +static void +_gs_prefs_set_logout_enabled (GSPrefs *prefs, + gboolean value) +{ + prefs->logout_enabled = value; +} + +static void +_gs_prefs_set_logout_command (GSPrefs *prefs, + const char *value) +{ + g_free (prefs->logout_command); + prefs->logout_command = NULL; + + if (value) + { + /* FIXME: check command */ + + prefs->logout_command = g_strdup (value); + } +} + +static void +_gs_prefs_set_logout_timeout (GSPrefs *prefs, + int value) +{ + if (value < 0) + value = 0; + + /* pick a reasonable large number for the + upper bound */ + if (value > 480) + value = 480; + + prefs->logout_timeout = value * 60000; +} + +static void +_gs_prefs_set_user_switch_enabled (GSPrefs *prefs, + gboolean value) +{ + prefs->user_switch_enabled = value; +} + +static void +key_error_and_free (const char *key, + GError *error) +{ + g_warning ("Error retrieving configuration key '%s': %s", key, error->message); + g_error_free (error); + error = NULL; +} + +static void +gs_prefs_load_from_mateconf (GSPrefs *prefs) +{ + glong value; + gboolean bvalue; + char *string; + GSList *list; + GError *error; + + error = NULL; + bvalue = mateconf_client_get_bool (prefs->priv->mateconf_client, KEY_IDLE_ACTIVATION_ENABLED, &error); + if (! error) + { + _gs_prefs_set_idle_activation_enabled (prefs, bvalue); + } + else + { + key_error_and_free (KEY_IDLE_ACTIVATION_ENABLED, error); + } + + error = NULL; + bvalue = mateconf_client_get_bool (prefs->priv->mateconf_client, KEY_LOCK_ENABLED, &error); + if (! error) + { + _gs_prefs_set_lock_enabled (prefs, bvalue); + } + else + { + key_error_and_free (KEY_LOCK_ENABLED, error); + } + + error = NULL; + bvalue = mateconf_client_get_bool (prefs->priv->mateconf_client, KEY_LOCK_DISABLE, &error); + if (! error) + { + _gs_prefs_set_lock_disabled (prefs, bvalue); + } + else + { + key_error_and_free (KEY_LOCK_DISABLE, error); + } + + error = NULL; + bvalue = mateconf_client_get_bool (prefs->priv->mateconf_client, KEY_USER_SWITCH_DISABLE, &error); + if (! error) + { + _gs_prefs_set_user_switch_disabled (prefs, bvalue); + } + else + { + key_error_and_free (KEY_USER_SWITCH_DISABLE, error); + } + + error = NULL; + value = mateconf_client_get_int (prefs->priv->mateconf_client, KEY_ACTIVATE_DELAY, &error); + if (! error) + { + _gs_prefs_set_timeout (prefs, value); + } + else + { + key_error_and_free (KEY_ACTIVATE_DELAY, error); + } + + error = NULL; + value = mateconf_client_get_int (prefs->priv->mateconf_client, KEY_POWER_DELAY, &error); + if (! error) + { + _gs_prefs_set_power_timeout (prefs, value); + } + else + { + key_error_and_free (KEY_POWER_DELAY, error); + } + + error = NULL; + value = mateconf_client_get_int (prefs->priv->mateconf_client, KEY_LOCK_DELAY, &error); + if (! error) + { + _gs_prefs_set_lock_timeout (prefs, value); + } + else + { + key_error_and_free (KEY_LOCK_DELAY, error); + } + + error = NULL; + value = mateconf_client_get_int (prefs->priv->mateconf_client, KEY_CYCLE_DELAY, &error); + if (! error) + { + _gs_prefs_set_cycle_timeout (prefs, value); + } + else + { + key_error_and_free (KEY_CYCLE_DELAY, error); + } + + error = NULL; + string = mateconf_client_get_string (prefs->priv->mateconf_client, KEY_MODE, &error); + if (! error) + { + _gs_prefs_set_mode (prefs, string); + } + else + { + key_error_and_free (KEY_MODE, error); + } + g_free (string); + + error = NULL; + list = mateconf_client_get_list (prefs->priv->mateconf_client, + KEY_THEMES, + MATECONF_VALUE_STRING, + &error); + if (! error) + { + _gs_prefs_set_themes (prefs, list); + } + else + { + key_error_and_free (KEY_THEMES, error); + } + + /* Embedded keyboard options */ + + error = NULL; + bvalue = mateconf_client_get_bool (prefs->priv->mateconf_client, KEY_KEYBOARD_ENABLED, &error); + if (! error) + { + _gs_prefs_set_keyboard_enabled (prefs, bvalue); + } + else + { + key_error_and_free (KEY_KEYBOARD_ENABLED, error); + } + + error = NULL; + string = mateconf_client_get_string (prefs->priv->mateconf_client, KEY_KEYBOARD_COMMAND, &error); + if (! error) + { + _gs_prefs_set_keyboard_command (prefs, string); + } + else + { + key_error_and_free (KEY_KEYBOARD_COMMAND, error); + } + g_free (string); + + error = NULL; + bvalue = mateconf_client_get_bool (prefs->priv->mateconf_client, KEY_STATUS_MESSAGE_ENABLED, &error); + if (! error) + { + _gs_prefs_set_status_message_enabled (prefs, bvalue); + } + else + { + key_error_and_free (KEY_STATUS_MESSAGE_ENABLED, error); + } + + /* Logout options */ + + error = NULL; + bvalue = mateconf_client_get_bool (prefs->priv->mateconf_client, KEY_LOGOUT_ENABLED, &error); + if (! error) + { + _gs_prefs_set_logout_enabled (prefs, bvalue); + } + else + { + key_error_and_free (KEY_LOGOUT_ENABLED, error); + } + + error = NULL; + string = mateconf_client_get_string (prefs->priv->mateconf_client, KEY_LOGOUT_COMMAND, &error); + if (! error) + { + _gs_prefs_set_logout_command (prefs, string); + } + else + { + key_error_and_free (KEY_LOGOUT_COMMAND, error); + } + g_free (string); + + error = NULL; + value = mateconf_client_get_int (prefs->priv->mateconf_client, KEY_LOGOUT_DELAY, &error); + if (! error) + { + _gs_prefs_set_logout_timeout (prefs, value); + } + else + { + key_error_and_free (KEY_LOGOUT_DELAY, error); + } + + /* User switching options */ + + error = NULL; + bvalue = mateconf_client_get_bool (prefs->priv->mateconf_client, KEY_USER_SWITCH_ENABLED, &error); + if (! error) + { + _gs_prefs_set_user_switch_enabled (prefs, bvalue); + } + else + { + key_error_and_free (KEY_USER_SWITCH_ENABLED, error); + } +} + +static void +invalid_type_warning (const char *type) +{ + g_warning ("Error retrieving configuration key '%s': Invalid type", + type); +} + +static void +key_changed_cb (MateConfClient *client, + guint cnxn_id, + MateConfEntry *entry, + GSPrefs *prefs) +{ + gboolean changed = FALSE; + const char *key; + MateConfValue *value; + + key = mateconf_entry_get_key (entry); + + if (! g_str_has_prefix (key, KEY_DIR) && ! g_str_has_prefix (key, MATE_LOCKDOWN_DIR)) + return; + + value = mateconf_entry_get_value (entry); + + if (strcmp (key, KEY_MODE) == 0) + { + + if (value->type == MATECONF_VALUE_STRING) + { + const char *str; + + str = mateconf_value_get_string (value); + _gs_prefs_set_mode (prefs, str); + + changed = TRUE; + } + else + { + invalid_type_warning (key); + } + + } + else if (strcmp (key, KEY_THEMES) == 0) + { + GSList *list = NULL; + + if (value == NULL + || value->type != MATECONF_VALUE_LIST) + { + return; + } + + list = mateconf_value_get_list (value); + + if (list + && mateconf_value_get_list_type (value) == MATECONF_VALUE_STRING) + { + GSList *l; + GSList *new_list; + + changed = TRUE; + + new_list = NULL; + for (l = list; l; l = l->next) + { + char *s; + + s = mateconf_value_to_string (l->data); + + new_list = g_slist_prepend (new_list, g_strdup (s)); + + g_free (s); + } + + new_list = g_slist_reverse (new_list); + + _gs_prefs_set_themes (prefs, new_list); + + } + + } + else if (strcmp (key, KEY_ACTIVATE_DELAY) == 0) + { + + if (value->type == MATECONF_VALUE_INT) + { + int delay; + + delay = mateconf_value_get_int (value); + _gs_prefs_set_timeout (prefs, delay); + + changed = TRUE; + } + else + { + invalid_type_warning (key); + } + + } + else if (strcmp (key, KEY_POWER_DELAY) == 0) + { + + if (value->type == MATECONF_VALUE_INT) + { + int delay; + + delay = mateconf_value_get_int (value); + _gs_prefs_set_power_timeout (prefs, delay); + + changed = TRUE; + } + else + { + invalid_type_warning (key); + } + + } + else if (strcmp (key, KEY_LOCK_DELAY) == 0) + { + + if (value->type == MATECONF_VALUE_INT) + { + int delay; + + delay = mateconf_value_get_int (value); + _gs_prefs_set_lock_timeout (prefs, delay); + + changed = TRUE; + } + else + { + invalid_type_warning (key); + } + + } + else if (strcmp (key, KEY_IDLE_ACTIVATION_ENABLED) == 0) + { + + if (value->type == MATECONF_VALUE_BOOL) + { + gboolean enabled; + + enabled = mateconf_value_get_bool (value); + _gs_prefs_set_idle_activation_enabled (prefs, enabled); + + changed = TRUE; + } + else + { + invalid_type_warning (key); + } + + } + else if (strcmp (key, KEY_LOCK_ENABLED) == 0) + { + + if (value->type == MATECONF_VALUE_BOOL) + { + gboolean enabled; + + enabled = mateconf_value_get_bool (value); + _gs_prefs_set_lock_enabled (prefs, enabled); + + changed = TRUE; + } + else + { + invalid_type_warning (key); + } + + } + else if (strcmp (key, KEY_LOCK_DISABLE) == 0) + { + + if (value->type == MATECONF_VALUE_BOOL) + { + gboolean disabled; + + disabled = mateconf_value_get_bool (value); + _gs_prefs_set_lock_disabled (prefs, disabled); + + changed = TRUE; + } + else + { + invalid_type_warning (key); + } + + } + else if (strcmp (key, KEY_USER_SWITCH_DISABLE) == 0) + { + + if (value->type == MATECONF_VALUE_BOOL) + { + gboolean disabled; + + disabled = mateconf_value_get_bool (value); + _gs_prefs_set_user_switch_disabled (prefs, disabled); + + changed = TRUE; + } + else + { + invalid_type_warning (key); + } + + } + else if (strcmp (key, KEY_CYCLE_DELAY) == 0) + { + + if (value->type == MATECONF_VALUE_INT) + { + int delay; + + delay = mateconf_value_get_int (value); + _gs_prefs_set_cycle_timeout (prefs, delay); + + changed = TRUE; + } + else + { + invalid_type_warning (key); + } + + } + else if (strcmp (key, KEY_KEYBOARD_ENABLED) == 0) + { + + if (value->type == MATECONF_VALUE_BOOL) + { + gboolean enabled; + + enabled = mateconf_value_get_bool (value); + _gs_prefs_set_keyboard_enabled (prefs, enabled); + + changed = TRUE; + } + else + { + invalid_type_warning (key); + } + + } + else if (strcmp (key, KEY_KEYBOARD_COMMAND) == 0) + { + + if (value->type == MATECONF_VALUE_STRING) + { + const char *command; + + command = mateconf_value_get_string (value); + _gs_prefs_set_keyboard_command (prefs, command); + + changed = TRUE; + } + else + { + invalid_type_warning (key); + } + + } + else if (strcmp (key, KEY_STATUS_MESSAGE_ENABLED) == 0) + { + + if (value->type == MATECONF_VALUE_BOOL) + { + gboolean enabled; + + enabled = mateconf_value_get_bool (value); + _gs_prefs_set_status_message_enabled (prefs, enabled); + + changed = TRUE; + } + else + { + invalid_type_warning (key); + } + + } + else if (strcmp (key, KEY_LOGOUT_ENABLED) == 0) + { + + if (value->type == MATECONF_VALUE_BOOL) + { + gboolean enabled; + + enabled = mateconf_value_get_bool (value); + _gs_prefs_set_logout_enabled (prefs, enabled); + + changed = TRUE; + } + else + { + invalid_type_warning (key); + } + + } + else if (strcmp (key, KEY_LOGOUT_DELAY) == 0) + { + + if (value->type == MATECONF_VALUE_INT) + { + int delay; + + delay = mateconf_value_get_int (value); + _gs_prefs_set_logout_timeout (prefs, delay); + + changed = TRUE; + } + else + { + invalid_type_warning (key); + } + + } + else if (strcmp (key, KEY_LOGOUT_COMMAND) == 0) + { + + if (value->type == MATECONF_VALUE_STRING) + { + const char *command; + + command = mateconf_value_get_string (value); + _gs_prefs_set_logout_command (prefs, command); + + changed = TRUE; + } + else + { + invalid_type_warning (key); + } + + } + else if (strcmp (key, KEY_USER_SWITCH_ENABLED) == 0) + { + + if (value->type == MATECONF_VALUE_BOOL) + { + gboolean enabled; + + enabled = mateconf_value_get_bool (value); + _gs_prefs_set_user_switch_enabled (prefs, enabled); + + changed = TRUE; + } + else + { + invalid_type_warning (key); + } + + } + else + { + g_warning ("Config key not handled: %s", key); + } + + if (changed && prefs) + { + g_signal_emit (prefs, signals [CHANGED], 0); + } +} + +static void +gs_prefs_init (GSPrefs *prefs) +{ + prefs->priv = GS_PREFS_GET_PRIVATE (prefs); + + prefs->priv->mateconf_client = mateconf_client_get_default (); + + prefs->idle_activation_enabled = TRUE; + prefs->lock_enabled = TRUE; + prefs->lock_disabled = FALSE; + prefs->logout_enabled = FALSE; + prefs->user_switch_enabled = FALSE; + + prefs->timeout = 600000; + prefs->power_timeout = 60000; + prefs->lock_timeout = 0; + prefs->logout_timeout = 14400000; + prefs->cycle = 600000; + + prefs->mode = GS_MODE_SINGLE; + + /* MateConf setup */ + mateconf_client_add_dir (prefs->priv->mateconf_client, + KEY_DIR, + MATECONF_CLIENT_PRELOAD_NONE, NULL); + mateconf_client_add_dir (prefs->priv->mateconf_client, + MATE_LOCKDOWN_DIR, + MATECONF_CLIENT_PRELOAD_NONE, NULL); + mateconf_client_add_dir (prefs->priv->mateconf_client, + MATE_SESSION_DIR, + MATECONF_CLIENT_PRELOAD_NONE, NULL); + + + mateconf_client_notify_add (prefs->priv->mateconf_client, + KEY_DIR, + (MateConfClientNotifyFunc)key_changed_cb, + prefs, + NULL, NULL); + mateconf_client_notify_add (prefs->priv->mateconf_client, + MATE_LOCKDOWN_DIR, + (MateConfClientNotifyFunc)key_changed_cb, + prefs, + NULL, NULL); + + gs_prefs_load_from_mateconf (prefs); +} + +static void +gs_prefs_finalize (GObject *object) +{ + GSPrefs *prefs; + + g_return_if_fail (object != NULL); + g_return_if_fail (GS_IS_PREFS (object)); + + prefs = GS_PREFS (object); + + g_return_if_fail (prefs->priv != NULL); + + if (prefs->priv->mateconf_client) + { + g_object_unref (prefs->priv->mateconf_client); + prefs->priv->mateconf_client = NULL; + } + + if (prefs->themes) + { + g_slist_foreach (prefs->themes, (GFunc)g_free, NULL); + g_slist_free (prefs->themes); + } + + g_free (prefs->logout_command); + g_free (prefs->keyboard_command); + + G_OBJECT_CLASS (gs_prefs_parent_class)->finalize (object); +} + +GSPrefs * +gs_prefs_new (void) +{ + GObject *prefs; + + prefs = g_object_new (GS_TYPE_PREFS, NULL); + + return GS_PREFS (prefs); +} |