diff options
author | Havoc Pennington <hp@pobox.com> | 2001-12-09 22:41:12 +0000 |
---|---|---|
committer | Havoc Pennington <hp@src.gnome.org> | 2001-12-09 22:41:12 +0000 |
commit | 6981a8198bdce947fa2f43a28babe427e740282b (patch) | |
tree | e247cdeeb2810c60ea00e7620e903fd82eca7668 /src/prefs.c | |
parent | b3778e4470e08dab6017d0134c81607920110e74 (diff) | |
download | metacity-6981a8198bdce947fa2f43a28babe427e740282b.tar.gz |
move SM init a bit later in the process, and init prefs
2001-12-09 Havoc Pennington <hp@pobox.com>
* src/main.c (main): move SM init a bit later in the process, and
init prefs
* src/session.c: fix no SM case (though I hardly know why I'm
bothering)
* src/main.c (main): call bindtextdomain
* src/util.h (_): actually call gettext
* configure.in: put in AM_GLIB_GNU_GETTEXT and gconf stuff
* src/prefs.c: Preferences - this marks the beginning of our doom.
None of them are actually implemented yet, but we monitor
some stuff from gconf.
Diffstat (limited to 'src/prefs.c')
-rw-r--r-- | src/prefs.c | 441 |
1 files changed, 441 insertions, 0 deletions
diff --git a/src/prefs.c b/src/prefs.c new file mode 100644 index 00000000..a82d69a4 --- /dev/null +++ b/src/prefs.c @@ -0,0 +1,441 @@ +/* Metacity preferences */ + +/* + * Copyright (C) 2001 Havoc Pennington + * + * 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. + */ + +#include <config.h> +#include "prefs.h" +#include "util.h" +#include <gconf/gconf-client.h> +#include <string.h> + +/* If you add a key, it needs updating in init() and in the gconf + * notify listener and of course in the .schemas file + */ +#define KEY_FOCUS_MODE "/apps/metacity/general/focus_mode" +#define KEY_USE_DESKTOP_FONT "/apps/metacity/general/titlebar_uses_desktop_font" +#define KEY_TITLEBAR_FONT "/apps/metacity/general/titlebar_font" +#define KEY_TITLEBAR_FONT_SIZE "/apps/metacity/general/titlebar_font_size" + +static GConfClient *client = NULL; +static GList *listeners = NULL; +static GList *changes = NULL; +static guint changed_idle; +static gboolean use_desktop_font = TRUE; +static PangoFontDescription *titlebar_font = NULL; +static int titlebar_font_size = 0; +static MetaFocusMode focus_mode = META_FOCUS_MODE_CLICK; + +static gboolean update_use_desktop_font (gboolean value); +static gboolean update_titlebar_font (const char *value); +static gboolean update_titlebar_font_size (int value); +static gboolean update_focus_mode (const char *value); + +static void queue_changed (MetaPreference pref); +static void change_notify (GConfClient *client, + guint cnxn_id, + GConfEntry *entry, + gpointer user_data); + + + + +typedef struct +{ + MetaPrefsChangedFunc func; + gpointer data; +} MetaPrefsListener; + +void +meta_prefs_add_listener (MetaPrefsChangedFunc func, + gpointer data) +{ + MetaPrefsListener *l; + + l = g_new (MetaPrefsListener, 1); + l->func = func; + l->data = data; + + listeners = g_list_prepend (listeners, l); +} + +void +meta_prefs_remove_listener (MetaPrefsChangedFunc func, + gpointer data) +{ + GList *tmp; + + tmp = listeners; + while (tmp != NULL) + { + MetaPrefsListener *l = tmp->data; + + if (l->func == func && + l->data == data) + { + g_free (l); + listeners = g_list_delete_link (listeners, tmp); + + return; + } + + tmp = tmp->next; + } + + meta_bug ("Did not find listener to remove\n"); +} + +static void +emit_changed (MetaPreference pref) +{ + GList *tmp; + GList *copy; + + meta_verbose ("Notifying listeners that pref %s changed\n", + meta_preference_to_string (pref)); + + copy = g_list_copy (listeners); + + tmp = copy; + while (tmp != NULL) + { + MetaPrefsListener *l = tmp->data; + + (* l->func) (pref, l->data); + + tmp = tmp->next; + } + + g_list_free (copy); +} + +static gboolean +changed_idle_handler (gpointer data) +{ + GList *tmp; + GList *copy; + + changed_idle = 0; + + copy = g_list_copy (changes); /* reentrancy paranoia */ + + g_list_free (changes); + changes = NULL; + + tmp = copy; + while (tmp != NULL) + { + MetaPreference pref = GPOINTER_TO_INT (tmp->data); + + emit_changed (pref); + + tmp = tmp->next; + } + + g_list_free (copy); + + return FALSE; +} + +static void +queue_changed (MetaPreference pref) +{ + meta_verbose ("Queueing change of pref %s\n", + meta_preference_to_string (pref)); + + if (g_list_find (changes, GINT_TO_POINTER (pref)) == NULL) + changes = g_list_prepend (changes, GINT_TO_POINTER (pref)); + else + meta_verbose ("Change of pref %s was already pending\n", + meta_preference_to_string (pref)); + + if (changed_idle == 0) + changed_idle = g_idle_add (changed_idle_handler, NULL); +} + +static void +cleanup_error (GError **error) +{ + if (*error) + { + meta_warning ("%s", (*error)->message); + + g_error_free (*error); + *error = NULL; + } +} + +void +meta_prefs_init (void) +{ + GError *err = NULL; + char *str_val; + int int_val; + gboolean bool_val; + + if (client != NULL) + return; + + /* returns a reference which we hold forever */ + client = gconf_client_get_default (); + + gconf_client_add_dir (client, "/apps/metacity", + GCONF_CLIENT_PRELOAD_RECURSIVE, + &err); + cleanup_error (&err); + + str_val = gconf_client_get_string (client, KEY_FOCUS_MODE, + &err); + cleanup_error (&err); + update_focus_mode (str_val); + g_free (str_val); + + bool_val = gconf_client_get_bool (client, KEY_USE_DESKTOP_FONT, + &err); + cleanup_error (&err); + update_use_desktop_font (bool_val); + + int_val = gconf_client_get_int (client, KEY_TITLEBAR_FONT_SIZE, + &err); + cleanup_error (&err); + update_titlebar_font_size (int_val); + + str_val = gconf_client_get_string (client, KEY_TITLEBAR_FONT, + &err); + cleanup_error (&err); + update_titlebar_font (str_val); + g_free (str_val); + + gconf_client_notify_add (client, "/apps/metacity", + change_notify, + NULL, + NULL, + &err); + cleanup_error (&err); +} + +static void +change_notify (GConfClient *client, + guint cnxn_id, + GConfEntry *entry, + gpointer user_data) +{ + const char *key; + GConfValue *value; + + key = gconf_entry_get_key (entry); + value = gconf_entry_get_value (entry); + + if (strcmp (key, KEY_FOCUS_MODE) == 0) + { + const char *str; + + if (value && value->type != GCONF_VALUE_STRING) + { + meta_warning (_("GConf key \"%s\" is set to an invalid type\n"), + KEY_FOCUS_MODE); + goto out; + } + + str = value ? gconf_value_get_string (value) : NULL; + + if (update_focus_mode (str)) + queue_changed (META_PREF_FOCUS_MODE); + } + else if (strcmp (key, KEY_TITLEBAR_FONT) == 0) + { + const char *str; + + if (value && value->type != GCONF_VALUE_STRING) + { + meta_warning (_("GConf key \"%s\" is set to an invalid type\n"), + KEY_TITLEBAR_FONT); + goto out; + } + + str = value ? gconf_value_get_string (value) : NULL; + + if (update_titlebar_font (str)) + queue_changed (META_PREF_TITLEBAR_FONT); + } + else if (strcmp (key, KEY_TITLEBAR_FONT_SIZE) == 0) + { + int d; + + if (value && value->type != GCONF_VALUE_INT) + { + meta_warning (_("GConf key \"%s\" is set to an invalid type\n"), + KEY_TITLEBAR_FONT_SIZE); + goto out; + } + + d = value ? gconf_value_get_int (value) : 0; + + if (update_titlebar_font_size (d)) + queue_changed (META_PREF_TITLEBAR_FONT_SIZE); + } + else if (strcmp (key, KEY_USE_DESKTOP_FONT) == 0) + { + gboolean b; + + if (value && value->type != GCONF_VALUE_BOOL) + { + meta_warning (_("GConf key \"%s\" is set to an invalid type\n"), + KEY_USE_DESKTOP_FONT); + goto out; + } + + b = value ? gconf_value_get_bool (value) : TRUE; + + /* There's no external pref for this, it just affects whether + * get_titlebar_font returns NULL, so that's what we queue + * the change on + */ + if (update_use_desktop_font (b)) + queue_changed (META_PREF_TITLEBAR_FONT); + } + else + meta_verbose ("Key %s doesn't mean anything to Metacity\n", + key); + + out: + /* nothing */ +} + +static gboolean +update_focus_mode (const char *value) +{ + MetaFocusMode old_mode = focus_mode; + + if (value != NULL) + { + if (g_ascii_strcasecmp (value, "click") == 0) + focus_mode = META_FOCUS_MODE_CLICK; + else if (g_ascii_strcasecmp (value, "sloppy") == 0) + focus_mode = META_FOCUS_MODE_SLOPPY; + else if (g_ascii_strcasecmp (value, "mouse") == 0) + focus_mode = META_FOCUS_MODE_MOUSE; + else + meta_warning (_("GConf key '%s' is set to an invalid value"), + KEY_FOCUS_MODE); + } + + return (old_mode != focus_mode); +} + +MetaFocusMode +meta_prefs_get_focus_mode (void) +{ + return focus_mode; +} + +static gboolean +update_use_desktop_font (gboolean value) +{ + gboolean old = use_desktop_font; + + use_desktop_font = value; + + return old != value; +} + +static gboolean +update_titlebar_font (const char *value) +{ + PangoFontDescription *new_desc; + + new_desc = NULL; + + if (value) + { + new_desc = pango_font_description_from_string (value); + if (new_desc == NULL) + meta_warning (_("Could not parse font description \"%s\" from GConf key %s\n"), + value, KEY_TITLEBAR_FONT); + } + + if (new_desc && titlebar_font && + pango_font_description_equal (new_desc, titlebar_font)) + { + pango_font_description_free (new_desc); + return FALSE; + } + else + { + if (titlebar_font) + pango_font_description_free (titlebar_font); + + titlebar_font = new_desc; + + return TRUE; + } +} + +const PangoFontDescription* +meta_prefs_get_titlebar_font (void) +{ + if (use_desktop_font) + return NULL; + else + return titlebar_font; +} + +static gboolean +update_titlebar_font_size (int value) +{ + int old = titlebar_font_size; + + if (value < 0) + { + meta_warning (_("%d stored in GConf key %s is not a valid font size\n"), + value, KEY_TITLEBAR_FONT_SIZE); + value = 0; + } + + titlebar_font_size = value; + + return old != titlebar_font_size; +} + +int +meta_prefs_get_titlebar_font_size (void) +{ + return titlebar_font_size; +} + +const char* +meta_preference_to_string (MetaPreference pref) +{ + switch (pref) + { + case META_PREF_FOCUS_MODE: + return "FOCUS_MODE"; + break; + + case META_PREF_TITLEBAR_FONT: + return "TITLEBAR_FONT"; + break; + + case META_PREF_TITLEBAR_FONT_SIZE: + return "TITLEBAR_FONT_SIZE"; + break; + } + + return "(unknown)"; +} |