summaryrefslogtreecommitdiff
path: root/src/prefs.c
diff options
context:
space:
mode:
authorHavoc Pennington <hp@pobox.com>2001-12-09 22:41:12 +0000
committerHavoc Pennington <hp@src.gnome.org>2001-12-09 22:41:12 +0000
commit6981a8198bdce947fa2f43a28babe427e740282b (patch)
treee247cdeeb2810c60ea00e7620e903fd82eca7668 /src/prefs.c
parentb3778e4470e08dab6017d0134c81607920110e74 (diff)
downloadmetacity-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.c441
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)";
+}