summaryrefslogtreecommitdiff
path: root/eel/eel-preferences.c
diff options
context:
space:
mode:
Diffstat (limited to 'eel/eel-preferences.c')
-rw-r--r--eel/eel-preferences.c1764
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 */