diff options
Diffstat (limited to 'eel/eel-preferences.c')
-rw-r--r-- | eel/eel-preferences.c | 1764 |
1 files changed, 0 insertions, 1764 deletions
diff --git a/eel/eel-preferences.c b/eel/eel-preferences.c deleted file mode 100644 index a60d0a9e..00000000 --- a/eel/eel-preferences.c +++ /dev/null @@ -1,1764 +0,0 @@ -/* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 8; tab-width: 8 -*- */ - -/* eel-preferences.c - Preference peek/poke/notify implementation. - - Copyright (C) 1999, 2000 Eazel, Inc. - - The Mate Library is free software; you can redistribute it and/or - modify it under the terms of the GNU Library General Public License as - published by the Free Software Foundation; either version 2 of the - License, or (at your option) any later version. - - The Mate Library 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 - Library General Public License for more details. - - You should have received a copy of the GNU Library General Public - License along with the Mate Library; see the file COPYING.LIB. If not, - write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, - Boston, MA 02110-1301, USA. - - Authors: Ramiro Estrugo <[email protected]> -*/ - -#include <config.h> -#include "eel-preferences.h" - -#include "eel-debug.h" -#include "eel-mateconf-extensions.h" -#include "eel-lib-self-check-functions.h" -#include "eel-enumeration.h" -#include "eel-glib-extensions.h" -#include "eel-string.h" -#include <mateconf/mateconf-client.h> -#include <mateconf/mateconf.h> -#include <gtk/gtk.h> - -/* An enumeration used for updating auto-storage variables in a type-specific way. - * FIXME: there is another enumeration like this in eel-global-preferences.c, - * used for different purposes but in a related way. Should we combine them? - */ -typedef enum -{ - PREFERENCE_BOOLEAN = 1, - PREFERENCE_INTEGER, - PREFERENCE_STRING, - PREFERENCE_STRING_ARRAY, - PREFERENCE_STRING_ARRAY_AS_QUARKS -} PreferenceType; - -/* - * PreferencesEntry: - * - * A structure to manage preference hash table nodes. - * Preferences are hash tables. The hash key is the preference name - * (a string). The hash value is a pointer of the following struct: - */ -typedef struct -{ - char *name; - char *description; - PreferenceType type; - gboolean invisible; - GList *callback_list; - GList *auto_storage_list; - int mateconf_connection_id; - char *enumeration_id; - MateConfValue *fallback; -} PreferencesEntry; - -/* - * PreferencesCallbackEntry: - * - * A structure to manage callback lists. A callback list is a GList. - * The callback_data in each list node is a pointer to the following - * struct: - */ -typedef struct -{ - EelPreferencesCallback callback; - gpointer callback_data; -} PreferencesCallbackEntry; - -static GHashTable *global_table = NULL; -static char *storage_path = NULL; -static gboolean initialized = FALSE; - -static void preferences_global_table_free (void); -static char * preferences_key_make (const char *name); -static void preferences_callback_entry_free (PreferencesCallbackEntry *callback_entry); -static void preferences_entry_update_auto_storage (PreferencesEntry *entry); -static PreferencesEntry *preferences_global_table_lookup_or_insert (const char *name); - -static int -preferences_mateconf_value_get_int (const MateConfValue *value) -{ - if (value == NULL) - { - return 0; - } - g_assert (value->type == MATECONF_VALUE_INT); - return mateconf_value_get_int (value); -} - -static gboolean -preferences_mateconf_value_get_bool (const MateConfValue *value) -{ - if (value == NULL) - { - return FALSE; - } - g_assert (value->type == MATECONF_VALUE_BOOL); - return mateconf_value_get_bool (value); -} - -static char * -preferences_mateconf_value_get_string (const MateConfValue *value) -{ - if (value == NULL) - { - return g_strdup (""); - } - g_assert (value->type == MATECONF_VALUE_STRING); - return g_strdup (mateconf_value_get_string (value)); -} - -static char ** -preferences_mateconf_value_get_string_array (const MateConfValue *value) -{ - GSList *slist, *l; - GPtrArray *result; - - if (value == NULL) - { - return NULL; - } - - g_assert (value->type == MATECONF_VALUE_LIST); - g_assert (mateconf_value_get_list_type (value) == MATECONF_VALUE_STRING); - - slist = eel_mateconf_value_get_string_list (value); - - result = g_ptr_array_new (); - for (l = slist; l != NULL; l = l->next) - { - g_ptr_array_add (result, l->data); - } - g_slist_free (slist); - g_ptr_array_add (result, NULL); - - return (char **) g_ptr_array_free (result, FALSE); -} - -static const char * -preferences_peek_storage_path (void) -{ - g_assert (storage_path != NULL); - - return storage_path; -} - -static void -preferences_set_storage_path (const char *new_storage_path) -{ - g_assert (eel_strlen (new_storage_path) > 0); - - /* Make sure the path is indeed different */ - if (eel_str_is_equal (new_storage_path, storage_path)) - { - return; - } - - /* Free the preference hash table */ - preferences_global_table_free (); - - /* Stop monitoring the old path */ - eel_mateconf_monitor_remove (storage_path); - - g_free (storage_path); - storage_path = g_strdup (new_storage_path); - - /* Start monitoring the new path */ - eel_mateconf_monitor_add (storage_path); -} - -static gboolean -preferences_is_initialized (void) -{ - return initialized; -} - -static MateConfValue * -preferences_get_value (const char *name) -{ - MateConfValue *result; - char *key; - PreferencesEntry *entry; - - g_assert (name != NULL); - g_assert (preferences_is_initialized ()); - - key = preferences_key_make (name); - result = eel_mateconf_get_value (key); - g_free (key); - - if (result == NULL) - { - entry = preferences_global_table_lookup_or_insert (name); - - if (entry->fallback) - result = mateconf_value_copy (entry->fallback); - } - - return result; -} - -/* If the preference name begind with a "/", we interpret - * it as a straight mateconf key. */ -static gboolean -preferences_preference_is_mateconf_key (const char *name) -{ - g_assert (name != NULL); - - if (eel_str_has_prefix (name, "/")) - { - return FALSE; - } - - return TRUE; -} - -static char * -preferences_key_make (const char *name) -{ - g_assert (name != NULL); - - if (!preferences_preference_is_mateconf_key (name)) - { - return g_strdup (name); - } - - /* Otherwise, we prefix it with the path */ - return g_strconcat (preferences_peek_storage_path (), "/", - name, NULL); -} - -/* Get default from schema or emergency fallback */ -static MateConfValue * -preferences_get_default_value (const char *name) -{ - MateConfValue *result; - PreferencesEntry *entry; - char *key; - - g_assert (name != NULL); - - key = preferences_key_make (name); - - result = eel_mateconf_get_default_value (key); - - g_free (key); - - if (result == NULL) - { - entry = preferences_global_table_lookup_or_insert (name); - if (entry && entry->fallback) - result = mateconf_value_copy (entry->fallback); - } - - return result; -} - -static int -preferences_callback_entry_compare (gconstpointer a, - gconstpointer b) -{ - const PreferencesCallbackEntry *a_entry = a; - const PreferencesCallbackEntry *b_entry = b; - - if (a_entry->callback < b_entry->callback) - { - return -1; - } - - if (a_entry->callback > b_entry->callback) - { - return +1; - } - - if (a_entry->callback_data < b_entry->callback_data) - { - return -1; - } - - if (a_entry->callback_data > b_entry->callback_data) - { - return +1; - } - - return 0; -} - -/* Public preferences functions */ - -gboolean -eel_preferences_get_is_invisible (const char *name) -{ - g_assert (name != NULL); - g_assert (preferences_is_initialized ()); - - return preferences_global_table_lookup_or_insert (name)->invisible; -} - -void -eel_preferences_set_is_invisible (const char *name, - gboolean is_invisible) -{ - g_return_if_fail (name != NULL); - g_return_if_fail (preferences_is_initialized ()); - - preferences_global_table_lookup_or_insert (name)->invisible = is_invisible; -} - -void -eel_preferences_set_boolean (const char *name, - gboolean boolean_value) -{ - char *key; - - g_return_if_fail (name != NULL); - g_return_if_fail (preferences_is_initialized ()); - - key = preferences_key_make (name); - eel_mateconf_set_boolean (key, boolean_value); - g_free (key); - - eel_mateconf_suggest_sync (); -} - -gboolean -eel_preferences_get_boolean (const char *name) -{ - gboolean result; - MateConfValue *value; - - g_return_val_if_fail (name != NULL, 0); - g_return_val_if_fail (preferences_is_initialized (), 0); - - value = preferences_get_value (name); - result = preferences_mateconf_value_get_bool (value); - eel_mateconf_value_free (value); - - return result; -} - -void -eel_preferences_set_integer (const char *name, - int int_value) -{ - char *key; - int old_value; - - g_return_if_fail (name != NULL); - g_return_if_fail (preferences_is_initialized ()); - - key = preferences_key_make (name); - old_value = eel_preferences_get_integer (name); - - if (int_value != old_value) - { - eel_mateconf_set_integer (key, int_value); - } - g_free (key); -} - -int -eel_preferences_get_integer (const char *name) -{ - int result; - MateConfValue *value; - - g_return_val_if_fail (name != NULL, 0); - g_return_val_if_fail (preferences_is_initialized (), 0); - - value = preferences_get_value (name); - result = preferences_mateconf_value_get_int (value); - eel_mateconf_value_free (value); - - return result; -} - -/* MateConf has no unsigned store, save as signed and cast */ -guint -eel_preferences_get_uint (const char *name) -{ - return (guint)eel_preferences_get_integer (name); -} -void -eel_preferences_set_uint (const char *name, - guint uint_value) -{ - eel_preferences_set_integer (name, (int)uint_value); -} - -guint -eel_preferences_get_enum (const char *name) -{ - guint ret_val; - char *str_value; - MateConfValue *value; - const EelEnumeration *enumeration; - PreferencesEntry *entry; - - g_return_val_if_fail (name != NULL, 0); - g_return_val_if_fail (preferences_is_initialized (), 0); - - entry = preferences_global_table_lookup_or_insert (name); - g_return_val_if_fail (entry != NULL, 0); - - enumeration = eel_enumeration_lookup (entry->enumeration_id); - - if (!enumeration) - { - g_warning ("No enum entry for '%s' (%s)", - name, entry->enumeration_id); - return 0; - } - - value = preferences_get_value (name); - if (value->type == MATECONF_VALUE_INT) /* compatibility path */ - { - ret_val = (guint)preferences_mateconf_value_get_int (value); - eel_mateconf_value_free (value); - return ret_val; - } - - str_value = preferences_mateconf_value_get_string (value); - eel_mateconf_value_free (value); - - if (str_value == NULL) - { - g_warning ("No key for '%s' at %s", str_value, name); - return 0; - } - - ret_val = eel_enumeration_get_value_for_name (enumeration, str_value); - - g_free (str_value); - - return ret_val; -} - -void -eel_preferences_set_enum (const char *name, - guint int_value) -{ - const char *str_value; - const EelEnumeration *enumeration; - PreferencesEntry *entry; - - g_return_if_fail (name != NULL); - g_return_if_fail (preferences_is_initialized ()); - - entry = preferences_global_table_lookup_or_insert (name); - g_return_if_fail (entry != NULL); - - enumeration = eel_enumeration_lookup (entry->enumeration_id); - - if (!enumeration) - { - g_warning ("No enum entry for '%s' (%s)", - name, entry->enumeration_id); - return; - } - - str_value = eel_enumeration_get_name_for_value (enumeration, int_value); - - if (str_value == NULL) - { - g_warning ("No enum match for '%d'", int_value); - return; - } - - eel_preferences_set (name, str_value); -} - -void -eel_preferences_set (const char *name, - const char *string_value) -{ - char *key; - char *old_value; - - g_return_if_fail (name != NULL); - g_return_if_fail (preferences_is_initialized ()); - - key = preferences_key_make (name); - old_value = eel_preferences_get (name); - - if (strcmp (string_value, old_value) != 0) - { - eel_mateconf_set_string (key, string_value); - } - g_free (key); - g_free (old_value); -} - -char * -eel_preferences_get (const char *name) -{ - char *result; - MateConfValue *value; - - g_return_val_if_fail (name != NULL, NULL); - g_return_val_if_fail (preferences_is_initialized (), NULL); - - value = preferences_get_value (name); - result = preferences_mateconf_value_get_string (value); - eel_mateconf_value_free (value); - - return result; -} - -void -eel_preferences_set_string_array (const char *name, - char **strv_value) -{ - GSList *slist; - int i; - char *key; - - g_return_if_fail (name != NULL); - g_return_if_fail (preferences_is_initialized ()); - - slist = NULL; - if (strv_value != NULL) - { - for (i = 0; strv_value[i] != NULL; i++) - { - slist = g_slist_prepend (slist, strv_value[i]); - } - slist = g_slist_reverse (slist); - } - - key = preferences_key_make (name); - eel_mateconf_set_string_list (key, slist); - g_free (key); - - g_slist_free (slist); -} - -static gboolean -string_array_is_valid (char **strv, const char *enumeration_id) -{ - guint i; - gboolean res; - - g_assert (strv != NULL); - g_assert (enumeration_id != NULL); - - res = TRUE; - for (i = 0; strv[i] != NULL; i++) - { - const EelEnumeration *enumeration; - - enumeration = eel_enumeration_lookup (enumeration_id); - if (!enumeration) - { - res = FALSE; - break; - } - - if (!eel_enumeration_contains_name (enumeration, strv[i])) - { - res = FALSE; - break; - } - } - - return res; -} - -char ** -eel_preferences_get_string_array (const char *name) -{ - char **result; - MateConfValue *value; - PreferencesEntry *entry; - MateConfValue *default_value; - - g_return_val_if_fail (name != NULL, NULL); - g_return_val_if_fail (preferences_is_initialized (), NULL); - - value = preferences_get_value (name); - result = preferences_mateconf_value_get_string_array (value); - eel_mateconf_value_free (value); - - entry = preferences_global_table_lookup_or_insert (name); - g_assert (entry != NULL); - - /* No enumeration_id so we're done */ - if (entry->enumeration_id == NULL) - { - return result; - } - - /* Do a sanity check on the validity of the values */ - if (string_array_is_valid (result, entry->enumeration_id)) - { - return result; - } - - /* Forget the bad value and use the default instead */ - g_strfreev (result); - - default_value = preferences_get_default_value (name); - if (default_value) - { - result = preferences_mateconf_value_get_string_array (default_value); - mateconf_value_free (default_value); - } - - return result; -} - -void -eel_preferences_unset (const char *name) -{ - char *key; - - g_return_if_fail (name != NULL); - g_return_if_fail (preferences_is_initialized ()); - - key = preferences_key_make (name); - - eel_mateconf_unset (key); - - g_free (key); -} - -gboolean -eel_preferences_key_is_writable (const char *name) -{ - gboolean result; - char *key; - - g_return_val_if_fail (name != NULL, 0); - g_return_val_if_fail (preferences_is_initialized (), 0); - - key = preferences_key_make (name); - result = eel_mateconf_key_is_writable (key); - g_free (key); - - return result; -} - -/** - * preferences_callback_entry_invoke_function - * - * A function that invokes a callback from the given struct. It is meant to be fed to - * g_list_foreach () - * @data: The list data privately maintained by the GList. - * @callback_data: The callback_data privately maintained by the GList. - **/ -static void -preferences_callback_entry_invoke_function (gpointer data, - gpointer callback_data) -{ - PreferencesCallbackEntry *callback_entry; - - g_assert (data != NULL); - - callback_entry = data; - - (* callback_entry->callback) (callback_entry->callback_data); -} - -static void -preferences_entry_invoke_callbacks (PreferencesEntry *entry) -{ - g_assert (entry != NULL); - - /* Update the auto storage preferences */ - if (entry->auto_storage_list != NULL) - { - preferences_entry_update_auto_storage (entry); - } - - /* Invoke callbacks for this entry if any */ - if (entry->callback_list != NULL) - { - g_list_foreach (entry->callback_list, - preferences_callback_entry_invoke_function, - NULL); - } -} - -static void -update_auto_string (gpointer data, gpointer callback_data) -{ - char **storage; - const char *value; - - g_assert (data != NULL); - g_assert (callback_data != NULL); - - storage = (char **)data; - value = (const char *)callback_data; - - g_free (*storage); - *(char **)storage = g_strdup (value); -} - -static void -update_auto_string_array (gpointer data, gpointer callback_data) -{ - char ***storage; - char **value; - - g_assert (data != NULL); - g_assert (callback_data != NULL); - - storage = (char ***)data; - value = (char **)callback_data; - - g_strfreev (*storage); - *(char ***)storage = value ? g_strdupv (value) : NULL; -} - -static void -update_auto_string_array_as_quarks (gpointer data, gpointer callback_data) -{ - GQuark **storage; - char **value; - int i = 0; - - g_assert (data != NULL); - g_assert (callback_data != NULL); - - storage = (GQuark **)data; - value = (char **)callback_data; - - g_free (*storage); - *storage = g_new (GQuark, g_strv_length (value) + 1); - - if (value != NULL) - { - for (i = 0; value[i] != NULL; ++i) - { - (*storage)[i] = g_quark_from_string (value[i]); - } - } - (*storage)[i] = 0; -} - -static void -update_auto_integer_or_boolean (gpointer data, gpointer callback_data) -{ - g_assert (data != NULL); - - *(int *)data = GPOINTER_TO_INT (callback_data); -} - -static void -preferences_entry_update_auto_storage (PreferencesEntry *entry) -{ - char *new_string_value; - char **new_string_array_value; - int new_int_value; - guint new_uint_value; - gboolean new_boolean_value; - - switch (entry->type) - { - case PREFERENCE_STRING: - if (entry->enumeration_id != NULL) - { - new_uint_value = eel_preferences_get_enum (entry->name); - g_list_foreach (entry->auto_storage_list, - update_auto_integer_or_boolean, - GINT_TO_POINTER (new_uint_value)); - } - else - { - new_string_value = eel_preferences_get (entry->name); - g_list_foreach (entry->auto_storage_list, - update_auto_string, - new_string_value); - g_free (new_string_value); - } - break; - case PREFERENCE_STRING_ARRAY: - new_string_array_value = eel_preferences_get_string_array (entry->name); - g_list_foreach (entry->auto_storage_list, - update_auto_string_array, - new_string_array_value); - g_strfreev (new_string_array_value); - break; - case PREFERENCE_STRING_ARRAY_AS_QUARKS: - new_string_array_value = eel_preferences_get_string_array (entry->name); - g_list_foreach (entry->auto_storage_list, - update_auto_string_array_as_quarks, - new_string_array_value); - g_strfreev (new_string_array_value); - break; - case PREFERENCE_INTEGER: - new_int_value = eel_preferences_get_integer (entry->name); - g_list_foreach (entry->auto_storage_list, - update_auto_integer_or_boolean, - GINT_TO_POINTER (new_int_value)); - break; - case PREFERENCE_BOOLEAN: - new_boolean_value = eel_preferences_get_boolean (entry->name); - g_list_foreach (entry->auto_storage_list, - update_auto_integer_or_boolean, - GINT_TO_POINTER (new_boolean_value)); - break; - default: - g_warning ("unexpected preferences type %d in preferences_entry_update_auto_storage", entry->type); - } -} - -static void -preferences_something_changed_notice (MateConfClient *client, - guint connection_id, - MateConfEntry *entry, - gpointer notice_data) -{ - g_assert (entry != NULL); - g_assert (entry->key != NULL); - g_assert (notice_data != NULL); - - preferences_entry_invoke_callbacks (notice_data); -} - -static void -preferences_entry_ensure_mateconf_connection (PreferencesEntry *entry) -{ - char *key; - - /* - * We install only one mateconf notification for each preference entry. - * Otherwise, we would invoke the installed callbacks more than once - * per registered callback. - */ - if (entry->mateconf_connection_id != EEL_MATECONF_UNDEFINED_CONNECTION) - { - return; - } - - g_assert (entry->name != NULL); - - key = preferences_key_make (entry->name); - - entry->mateconf_connection_id = eel_mateconf_notification_add (key, - preferences_something_changed_notice, - entry); - g_free (key); - - g_assert (entry->mateconf_connection_id != EEL_MATECONF_UNDEFINED_CONNECTION); -} - -/** - * preferences_entry_add_callback - * - * Add a callback to a pref node. Callbacks are fired whenever - * the pref value changes. - * @preferences_entry: The hash node. - * @callback: The user-supplied callback. - * @callback_data: The user-supplied closure. - **/ -static void -preferences_entry_add_callback (PreferencesEntry *entry, - EelPreferencesCallback callback, - gpointer callback_data) -{ - PreferencesCallbackEntry *callback_entry; - GList *l; - - g_assert (entry != NULL); - g_assert (callback != NULL); - - callback_entry = g_new0 (PreferencesCallbackEntry, 1); - callback_entry->callback = callback; - callback_entry->callback_data = callback_data; - - l = g_list_find_custom (entry->callback_list, callback_entry, preferences_callback_entry_compare); - if (l == NULL) - { - entry->callback_list = g_list_append (entry->callback_list, callback_entry); - preferences_entry_ensure_mateconf_connection (entry); - } - else - { - g_warning ("Trying to add a callback for %s that already exists.", entry->name); - } -} - -/** - * preferences_entry_add_auto_storage - * - * Add an auto-storage variable to a pref node. The variable will - * be updated to match the pref value whenever the pref - * the pref value changes. - * @preferences_entry: The hash node. - * @storage: The user-supplied location at which to store the value. - * @type: Which type of variable this is. - **/ -static void -preferences_entry_add_auto_storage (PreferencesEntry *entry, - gpointer storage, - PreferenceType type) -{ - g_assert (entry != NULL); - g_assert (storage != NULL); - g_assert (entry->type == 0 || entry->type == type); - if (g_list_find (entry->auto_storage_list, storage) != NULL) - { - g_warning ("Trying to add an auto storage for %s that already exists.", entry->name); - return; - } - - entry->type = type; - - entry->auto_storage_list = g_list_append (entry->auto_storage_list, storage); - - preferences_entry_ensure_mateconf_connection (entry); -} - -static void -preferences_entry_check_remove_connection (PreferencesEntry *entry) -{ - /* - * If there are no callbacks or auto-storage variables left in the entry, - * remove the mateconf notification. - */ - if (entry->callback_list != NULL || entry->auto_storage_list != NULL) - { - return; - } - - eel_mateconf_notification_remove (entry->mateconf_connection_id); - entry->mateconf_connection_id = EEL_MATECONF_UNDEFINED_CONNECTION; -} - -/** - * preferences_entry_remove_callback - * - * remove a callback from a pref entry. Both the callback and the callback_data must - * match in order for a callback to be removed from the entry. - * @preferences_entry: The hash entry. - * @callback: The user-supplied callback. - * @callback_data: The user-supplied closure. - **/ -static void -preferences_entry_remove_callback (PreferencesEntry *entry, - EelPreferencesCallback callback, - gpointer callback_data) -{ - PreferencesCallbackEntry cb_entry; - GList *l; - - g_assert (entry != NULL); - g_assert (callback != NULL); - - cb_entry.callback = callback; - cb_entry.callback_data = callback_data; - - l = g_list_find_custom (entry->callback_list, &cb_entry, preferences_callback_entry_compare); - if (l != NULL) - { - preferences_callback_entry_free (l->data); - entry->callback_list = g_list_delete_link (entry->callback_list, l); - preferences_entry_check_remove_connection (entry); - } - else - { - g_warning ("Trying to remove a callback for %s without adding it first.", entry->name); - } - - g_assert (g_list_find_custom (entry->callback_list, &cb_entry, preferences_callback_entry_compare) == NULL); -} - -/** - * preferences_entry_remove_auto_storage - * - * remove an auto-storage variable from a pref entry. - * @preferences_entry: The hash entry. - * @storage: The user-supplied location. - **/ -static void -preferences_entry_remove_auto_storage (PreferencesEntry *entry, - gpointer storage) -{ - GList *new_list; - const GList *node; - gpointer storage_in_entry; - - g_assert (entry != NULL); - g_assert (storage != NULL); - g_assert (entry->auto_storage_list != NULL); - - new_list = g_list_copy (entry->auto_storage_list); - - for (node = new_list; node != NULL; node = node->next) - { - storage_in_entry = node->data; - - g_assert (storage_in_entry != NULL); - - if (storage_in_entry == storage) - { - entry->auto_storage_list = g_list_remove (entry->auto_storage_list, - storage); - - switch (entry->type) - { - case PREFERENCE_STRING: - update_auto_string (storage, NULL); - break; - case PREFERENCE_STRING_ARRAY: - update_auto_string_array (storage, NULL); - break; - case PREFERENCE_STRING_ARRAY_AS_QUARKS: - update_auto_string_array_as_quarks (storage, NULL); - break; - case PREFERENCE_BOOLEAN: - case PREFERENCE_INTEGER: - update_auto_integer_or_boolean (storage, NULL); - break; - default: - g_warning ("unexpected preference type %d in preferences_entry_remove_auto_storage", entry->type); - } - } - } - - g_list_free (new_list); - - preferences_entry_check_remove_connection (entry); -} - -/** - * preferences_callback_entry_free - * - * Free a callback info struct. - * @preferences_callback_entry: The struct to free. - **/ -static void -preferences_callback_entry_free (PreferencesCallbackEntry *callback_entry) -{ - g_assert (callback_entry != NULL); - - callback_entry->callback = NULL; - callback_entry->callback_data = NULL; - - g_free (callback_entry); -} - -/** - * preferences_callback_entry_free_func - * - * A function that frees a callback info struct. It is meant to be fed to - * g_list_foreach () - * @data: The list data privately maintained by the GList. - * @callback_data: The callback_data privately maintained by the GList. - **/ -static void -preferences_callback_entry_free_func (gpointer data, - gpointer callback_data) -{ - g_assert (data != NULL); - - preferences_callback_entry_free (data); -} - -/** - * preferences_entry_free - * - * Free a preference hash node's members along with the node itself. - * @preferences_hash_node: The node to free. - **/ -static void -preferences_entry_free (PreferencesEntry *entry) -{ - g_assert (entry != NULL); - - eel_mateconf_notification_remove (entry->mateconf_connection_id); - entry->mateconf_connection_id = EEL_MATECONF_UNDEFINED_CONNECTION; - - g_list_free (entry->auto_storage_list); - eel_g_list_free_deep_custom (entry->callback_list, - preferences_callback_entry_free_func, - NULL); - - entry->auto_storage_list = NULL; - entry->callback_list = NULL; - - g_free (entry->name); - g_free (entry->description); - g_free (entry->enumeration_id); - - eel_mateconf_value_free (entry->fallback); - - g_free (entry); -} - -/** - * preferences_entry_free_func - * - * A function that frees a pref hash node. It is meant to be fed to - * g_hash_table_foreach () - * @key: The hash key privately maintained by the GHashTable. - * @value: The hash value privately maintained by the GHashTable. - * @callback_data: The callback_data privately maintained by the GHashTable. - **/ -static void -preferences_entry_free_func (gpointer key, - gpointer value, - gpointer callback_data) -{ - g_assert (value != NULL); - - preferences_entry_free (value); -} - -static void -preferences_global_table_free (void) -{ - if (global_table == NULL) - { - return; - } - - g_hash_table_foreach (global_table, preferences_entry_free_func, NULL); - g_hash_table_destroy (global_table); - global_table = NULL; - - g_free (storage_path); - storage_path = NULL; -} - -static void -preferences_uninitialize (void) -{ - initialized = FALSE; -} - -static GHashTable * -preferences_global_table_get_global (void) -{ - static gboolean at_exit_handler_added = FALSE; - - if (global_table == NULL) - { - global_table = g_hash_table_new (g_str_hash, g_str_equal); - - if (!at_exit_handler_added) - { - at_exit_handler_added = TRUE; - eel_debug_call_at_shutdown (preferences_global_table_free); - /* ensure that we catch calls to preferences functions after eel shutdown */ - eel_debug_call_at_shutdown (preferences_uninitialize); - } - } - - return global_table; -} - -static PreferencesEntry * -preferences_global_table_lookup (const char *name) -{ - g_assert (name != NULL); - g_assert (preferences_global_table_get_global () != NULL); - - return g_hash_table_lookup (preferences_global_table_get_global (), name); -} - -static PreferencesEntry * -preferences_global_table_insert (const char *name) -{ - PreferencesEntry *entry; - - g_assert (name != NULL); - g_assert (preferences_global_table_get_global () != NULL); - g_assert (preferences_global_table_lookup (name) == NULL); - - entry = g_new0 (PreferencesEntry, 1); - entry->name = g_strdup (name); - - g_hash_table_insert (preferences_global_table_get_global (), entry->name, entry); - - g_assert (entry == preferences_global_table_lookup (name)); - - return entry; -} - -static PreferencesEntry * -preferences_global_table_lookup_or_insert (const char *name) -{ - PreferencesEntry *entry; - - g_assert (name != NULL); - - entry = preferences_global_table_lookup (name); - - if (entry != NULL) - { - return entry; - } - - entry = preferences_global_table_insert (name); - g_assert (entry != NULL); - - return entry; -} - -void -eel_preferences_add_callback (const char *name, - EelPreferencesCallback callback, - gpointer callback_data) -{ - PreferencesEntry *entry; - - g_return_if_fail (name != NULL); - g_return_if_fail (callback != NULL); - g_return_if_fail (preferences_is_initialized ()); - - entry = preferences_global_table_lookup_or_insert (name); - g_assert (entry != NULL); - - preferences_entry_add_callback (entry, callback, callback_data); -} - -void -eel_preferences_add_auto_string (const char *name, - const char **storage) -{ - PreferencesEntry *entry; - char *value; - - g_return_if_fail (name != NULL); - g_return_if_fail (storage != NULL); - g_return_if_fail (preferences_is_initialized ()); - - entry = preferences_global_table_lookup_or_insert (name); - g_assert (entry != NULL); - - preferences_entry_add_auto_storage (entry, storage, PREFERENCE_STRING); - - value = eel_preferences_get (entry->name); - update_auto_string (storage, value); - g_free (value); -} - -void -eel_preferences_add_auto_string_array (const char *name, - char ***storage) -{ - PreferencesEntry *entry; - char **value; - - g_return_if_fail (name != NULL); - g_return_if_fail (storage != NULL); - g_return_if_fail (preferences_is_initialized ()); - - entry = preferences_global_table_lookup_or_insert (name); - g_assert (entry != NULL); - - preferences_entry_add_auto_storage (entry, storage, PREFERENCE_STRING_ARRAY); - - value = eel_preferences_get_string_array (entry->name); - update_auto_string_array (storage, value); - g_strfreev (value); -} - -void -eel_preferences_add_auto_string_array_as_quarks (const char *name, - GQuark **storage) -{ - PreferencesEntry *entry; - char **value; - - g_return_if_fail (name != NULL); - g_return_if_fail (storage != NULL); - g_return_if_fail (preferences_is_initialized ()); - - entry = preferences_global_table_lookup_or_insert (name); - g_assert (entry != NULL); - - preferences_entry_add_auto_storage (entry, storage, PREFERENCE_STRING_ARRAY_AS_QUARKS); - - value = eel_preferences_get_string_array (entry->name); - update_auto_string_array_as_quarks (storage, value); - g_strfreev (value); -} - -void -eel_preferences_add_auto_integer (const char *name, - int *storage) -{ - PreferencesEntry *entry; - int value; - - g_return_if_fail (name != NULL); - g_return_if_fail (storage != NULL); - g_return_if_fail (preferences_is_initialized ()); - - entry = preferences_global_table_lookup_or_insert (name); - g_assert (entry != NULL); - - preferences_entry_add_auto_storage (entry, storage, PREFERENCE_INTEGER); - - value = eel_preferences_get_integer (entry->name); - update_auto_integer_or_boolean (storage, GINT_TO_POINTER (value)); -} - - -void -eel_preferences_add_auto_enum (const char *name, - guint *storage) -{ - PreferencesEntry *entry; - guint value; - - g_return_if_fail (name != NULL); - g_return_if_fail (storage != NULL); - g_return_if_fail (preferences_is_initialized ()); - - entry = preferences_global_table_lookup_or_insert (name); - g_assert (entry != NULL); - g_assert (entry->enumeration_id != NULL); - - preferences_entry_add_auto_storage (entry, storage, PREFERENCE_STRING); - - value = eel_preferences_get_enum (entry->name); - update_auto_integer_or_boolean (storage, GINT_TO_POINTER (value)); -} - -void -eel_preferences_add_auto_boolean (const char *name, - gboolean *storage) -{ - PreferencesEntry *entry; - gboolean value; - - g_return_if_fail (name != NULL); - g_return_if_fail (storage != NULL); - g_return_if_fail (preferences_is_initialized ()); - - entry = preferences_global_table_lookup_or_insert (name); - g_assert (entry != NULL); - - preferences_entry_add_auto_storage (entry, storage, PREFERENCE_BOOLEAN); - - value = eel_preferences_get_boolean (entry->name); - update_auto_integer_or_boolean (storage, GINT_TO_POINTER (value)); -} - -void -eel_preferences_remove_auto_string (const char *name, - const char **storage) -{ - PreferencesEntry *entry; - - g_return_if_fail (name != NULL); - g_return_if_fail (storage != NULL); - g_return_if_fail (preferences_is_initialized ()); - - entry = preferences_global_table_lookup (name); - if (entry == NULL) - { - g_warning ("Trying to remove auto-string for %s without adding it first.", name); - return; - } - - preferences_entry_remove_auto_storage (entry, storage); -} - -void -eel_preferences_remove_auto_string_array (const char *name, - char ***storage) -{ - PreferencesEntry *entry; - - g_return_if_fail (name != NULL); - g_return_if_fail (storage != NULL); - g_return_if_fail (preferences_is_initialized ()); - - entry = preferences_global_table_lookup (name); - if (entry == NULL) - { - g_warning ("Trying to remove auto-string for %s without adding it first.", name); - return; - } - - preferences_entry_remove_auto_storage (entry, storage); -} - -void -eel_preferences_remove_auto_integer (const char *name, - int *storage) -{ - PreferencesEntry *entry; - - g_return_if_fail (name != NULL); - g_return_if_fail (storage != NULL); - g_return_if_fail (preferences_is_initialized ()); - - entry = preferences_global_table_lookup (name); - if (entry == NULL) - { - g_warning ("Trying to remove auto-integer for %s without adding it first.", name); - return; - } - - preferences_entry_remove_auto_storage (entry, storage); -} - -void -eel_preferences_remove_auto_boolean (const char *name, - gboolean *storage) -{ - PreferencesEntry *entry; - - g_return_if_fail (name != NULL); - g_return_if_fail (storage != NULL); - g_return_if_fail (preferences_is_initialized ()); - - entry = preferences_global_table_lookup (name); - if (entry == NULL) - { - g_warning ("Trying to remove auto-boolean for %s without adding it first.", name); - return; - } - - preferences_entry_remove_auto_storage (entry, storage); -} - -typedef struct -{ - char *name; - EelPreferencesCallback callback; - gpointer callback_data; -} WhileAliveData; - -static void -preferences_while_alive_disconnector (gpointer callback_data, GObject *where_object_was) -{ - WhileAliveData *data; - - g_assert (callback_data != NULL); - - data = callback_data; - - /* we might have survived an eel shutdown, which - * already cleared all the callbacks */ - if (preferences_is_initialized ()) - { - eel_preferences_remove_callback (data->name, - data->callback, - data->callback_data); - } - - g_free (data->name); - g_free (data); -} - -void -eel_preferences_add_callback_while_alive (const char *name, - EelPreferencesCallback callback, - gpointer callback_data, - GObject *alive_object) -{ - WhileAliveData *data; - - g_return_if_fail (name != NULL); - g_return_if_fail (callback != NULL); - g_return_if_fail (G_IS_OBJECT (alive_object)); - g_return_if_fail (preferences_is_initialized ()); - - data = g_new (WhileAliveData, 1); - data->name = g_strdup (name); - data->callback = callback; - data->callback_data = callback_data; - - eel_preferences_add_callback (name, callback, callback_data); - - g_object_weak_ref (alive_object, - preferences_while_alive_disconnector, - data); -} - -void -eel_preferences_remove_callback (const char *name, - EelPreferencesCallback callback, - gpointer callback_data) -{ - PreferencesEntry *entry; - - g_return_if_fail (name != NULL); - g_return_if_fail (callback != NULL); - g_return_if_fail (preferences_is_initialized ()); - - entry = preferences_global_table_lookup (name); - - if (entry == NULL) - { - g_warning ("Trying to remove a callback for %s without adding it first.", name); - return; - } - - preferences_entry_remove_callback (entry, callback, callback_data); -} - -void -eel_preferences_set_description (const char *name, - const char *description) -{ - PreferencesEntry *entry; - - g_return_if_fail (name != NULL); - g_return_if_fail (description != NULL); - g_return_if_fail (preferences_is_initialized ()); - - entry = preferences_global_table_lookup_or_insert (name); - g_assert (entry != NULL); - - g_free (entry->description); - entry->description = g_strdup (description); -} - -char * -eel_preferences_get_description (const char *name) -{ - PreferencesEntry *entry; - - g_return_val_if_fail (name != NULL, NULL); - g_return_val_if_fail (preferences_is_initialized (), NULL); - - entry = preferences_global_table_lookup_or_insert (name); - - return g_strdup (entry->description ? entry->description : ""); -} - -void -eel_preferences_set_enumeration_id (const char *name, - const char *enumeration_id) -{ - PreferencesEntry *entry; - - g_return_if_fail (name != NULL); - g_return_if_fail (enumeration_id != NULL); - g_return_if_fail (preferences_is_initialized ()); - - entry = preferences_global_table_lookup_or_insert (name); - g_assert (entry != NULL); - - g_free (entry->enumeration_id); - entry->enumeration_id = g_strdup (enumeration_id); -} - -char * -eel_preferences_get_enumeration_id (const char *name) -{ - PreferencesEntry *entry; - - g_return_val_if_fail (name != NULL, NULL); - g_return_val_if_fail (preferences_is_initialized (), NULL); - - entry = preferences_global_table_lookup_or_insert (name); - - return g_strdup (entry->enumeration_id); -} - -static void -preferences_set_emergency_fallback_stealing_value (const char *name, - MateConfValue *value) -{ - PreferencesEntry *entry; - - g_assert (name != NULL); - g_assert (preferences_is_initialized ()); - - entry = preferences_global_table_lookup_or_insert (name); - g_assert (entry != NULL); - - if (entry->fallback) - mateconf_value_free (entry->fallback); - entry->fallback = value; /* steal ownership of value */ -} - -void -eel_preferences_set_emergency_fallback_string (const char *name, - const char *value) -{ - MateConfValue *mateconf_value; - - g_return_if_fail (name != NULL); - g_return_if_fail (value != NULL); - - mateconf_value = mateconf_value_new (MATECONF_VALUE_STRING); - - mateconf_value_set_string (mateconf_value, value); - - preferences_set_emergency_fallback_stealing_value (name, mateconf_value); -} - -void -eel_preferences_set_emergency_fallback_integer (const char *name, - int value) -{ - MateConfValue *mateconf_value; - - g_return_if_fail (name != NULL); - - mateconf_value = mateconf_value_new (MATECONF_VALUE_INT); - - mateconf_value_set_int (mateconf_value, value); - - preferences_set_emergency_fallback_stealing_value (name, mateconf_value); -} - -void -eel_preferences_set_emergency_fallback_boolean (const char *name, - gboolean value) -{ - MateConfValue *mateconf_value; - - g_return_if_fail (name != NULL); - - mateconf_value = mateconf_value_new (MATECONF_VALUE_BOOL); - - mateconf_value_set_bool (mateconf_value, value); - - preferences_set_emergency_fallback_stealing_value (name, mateconf_value); -} - - -void -eel_preferences_set_emergency_fallback_string_array (const char *name, - char **value) -{ - MateConfValue *mateconf_value; - GSList *list; - int i; - - g_return_if_fail (name != NULL); - g_return_if_fail (value != NULL); - - mateconf_value = mateconf_value_new (MATECONF_VALUE_LIST); - mateconf_value_set_list_type (mateconf_value, MATECONF_VALUE_STRING); - - list = NULL; - for (i = 0; value[i] != NULL; ++i) - { - MateConfValue *v; - - v = mateconf_value_new (MATECONF_VALUE_STRING); - mateconf_value_set_string (v, value[i]); - - list = g_slist_prepend (list, v); - } - - mateconf_value_set_list_nocopy (mateconf_value, g_slist_reverse (list)); - - preferences_set_emergency_fallback_stealing_value (name, mateconf_value); -} - -MateConfValue* -eel_preferences_get_emergency_fallback (const char *name) -{ - PreferencesEntry *entry; - - g_return_val_if_fail (name != NULL, NULL); - g_return_val_if_fail (preferences_is_initialized (), NULL); - - entry = preferences_global_table_lookup_or_insert (name); - - return entry->fallback ? mateconf_value_copy (entry->fallback) : NULL; -} - -gboolean -eel_preferences_monitor_directory (const char *directory) -{ - g_return_val_if_fail (preferences_is_initialized (), FALSE); - - return eel_mateconf_monitor_add (directory); -} - -gboolean -eel_preferences_is_visible (const char *name) -{ - g_return_val_if_fail (name != NULL, FALSE); - g_return_val_if_fail (preferences_is_initialized (), FALSE); - - return !preferences_global_table_lookup_or_insert (name)->invisible; -} - -void -eel_preferences_init (const char *path) -{ - g_return_if_fail (eel_strlen (path) > 0); - - if (initialized) - { - return; - } - - initialized = TRUE; - - preferences_set_storage_path (path); -} - -#if !defined (EEL_OMIT_SELF_CHECK) - -#define CHECK_BOOLEAN(name__, value__) \ -G_STMT_START { \ - eel_preferences_set_boolean ((name__), (value__)); \ - EEL_CHECK_BOOLEAN_RESULT (eel_preferences_get_boolean (name__), (value__)); \ -} G_STMT_END - -#define CHECK_INTEGER(name__, value__) \ -G_STMT_START { \ - eel_preferences_set_integer ((name__), (value__)); \ - EEL_CHECK_INTEGER_RESULT (eel_preferences_get_integer (name__), (value__)); \ -} G_STMT_END - -#define CHECK_STRING(name__, value__) \ -G_STMT_START { \ - eel_preferences_set ((name__), (value__)); \ - EEL_CHECK_STRING_RESULT (eel_preferences_get (name__), (value__)); \ -} G_STMT_END - -void -eel_self_check_preferences (void) -{ - /* Disabled until I can debug why these seemingly harmless tests - * dont work. -re - */ -#if 0 - int original_user_level; - - original_user_level = eel_preferences_get_user_level (); - - EEL_CHECK_INTEGER_RESULT (eel_preferences_get_integer ("self-check/neverset/i"), 0); - EEL_CHECK_STRING_RESULT (eel_preferences_get ("self-check/neverset/s"), ""); - EEL_CHECK_BOOLEAN_RESULT (eel_preferences_get_boolean ("self-check/neverset/b"), FALSE); - - eel_preferences_set_user_level (0); - - /* FIXME: Fails if you add the commented-out lines. */ - /* CHECK_INTEGER ("self-check/i", 0); */ - CHECK_INTEGER ("self-check/i", 666); - /* CHECK_BOOLEAN ("self-check/b", FALSE); */ - CHECK_BOOLEAN ("self-check/b", TRUE); - /* CHECK_STRING ("self-check/s", ""); */ - CHECK_STRING ("self-check/s", "foo"); - - /* Restore the original user level */ - eel_preferences_set_user_level (original_user_level); -#endif -} - -#endif /* !EEL_OMIT_SELF_CHECK */ |