summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRay Strode <rstrode@redhat.com>2005-11-08 11:42:58 +0000
committerRodrigo Moya <rodrigo@src.gnome.org>2005-11-08 11:42:58 +0000
commit88f932c5fcdd0cf984a9316f89ba76b8edc5053e (patch)
treec1f405441914de7e8725152f0d30d66e100e76b1
parent399843cd8c5ffa21473ebc97f86ed6af09446808 (diff)
downloadgnome-control-center-88f932c5fcdd0cf984a9316f89ba76b8edc5053e.tar.gz
Remap buttons on auxillary mice for left-handed mode (bug 314409).
2005-10-21 Ray Strode <rstrode@redhat.com> Remap buttons on auxillary mice for left-handed mode (bug 314409). * gnome-settings-mouse.c (supports_xinput_devices): new function to detect XInput Extension (configure_button_layout): new function to set up logical mouse button layout for left or right handed mode (xinput_device_has_buttons): new function to detect if an xinput device has buttons to reconfigure (set_xinput_devices_left_handed): new function to set auxillary mice into left-handed mode (set_left_handed): call set_xinput_devices_left_handed if available 2005-10-18 Rodrigo Moya <rodrigo@novell.com><> * gnome-settings-font.c (load_xcursor_theme): * gnome-settings-xsettings.c (gnome_xft_settings_set_xsettings): run xrdb with -nocpp, since it's not needed here. 2005-10-16 Rodrigo Moya <rodrigo@novell.com> * factory.c: declare a global GConfClient. (main): unref the global GConfClient. * gnome-settings-daemon.[ch] (gnome_settings_daemon_get_conf_client): new function to use the same GConfClient everywhere. (gnome_settings_daemon_new): use the global GConfClient. * gnome-settings-accessibility-keyboard.c (set_server_from_gconf, ax_response_callback, set_gconf_from_server): * gnome-settings-gtk1theme.c (apply_settings): * gnome-settings-keybindings.c (bindings_get_entry): * gnome-settings-keyboard.c (numlock_get_gconf_state, numlock_set_gconf_state, apply_settings): * gnome-settings-keyboard-xkb.c (apply_xkb_settings, gnome_settings_keyboard_xkb_sysconfig_changed_response, gnome_settings_keyboard_xkb_analyze_sysconfig, gnome_settings_chk_file_list): * gnome-settings-screensaver.c (key_toggled_cb, really_start_screensaver): * gnome-settings-sound.c (apply_settings): * gnome-settings-xmodmap.c (check_button_callback, gnome_settings_load_modmap_files, remove_button_clicked_callback, load_button_clicked_callback, gnome_settings_modmap_dialog_call): * gnome-settings-xsettings.c (xft_callback): use the global GConfClient. * gnome-settings-keyboard-xkb.c (gnome_settings_keyboard_xkb_load): don't get another GConfClient when we're getting one passed! 2005-10-14 Rodrigo Moya <rodrigo@novell.com> * gnome-settings-daemon.c (child_watch_cb): added this function to watch for children... (gnome_settings_daemon_spawn_with_input): ...started here, instead of just blocking. * gnome-settings-screensaver.c (gnome_settings_screensaver_load): do lazy loading of the screensaver. (really_start_screensaver): start on a 25 seconds timeout. * gnome-settings-typing-break.c (gnome_settings_typing_break_load): do lazy loading og the typing break applet. (really_setup_typing_break): start on a 30 seconds timeout. 2005-10-14 Erwann Chenede <erwann.chenede@sun.com> Fixes #314774 * gnome-settings-xrdb.c (gnome_settings_xrdb_load): connect to "notify:gtk-theme-name" signal, to run xrdb only when the whole theme has been changed. (theme_changed): callback for "notify:gtk-theme-name". 2005-10-10 Jürg Billeter <j@bitron.ch> reviewed by: Sergey V. Udaltsov <svu@gnome.org> * gnome-settings-keyboard.c: (gsd_keyboard_get_hostname_key), (numlock_NumLock_modifier_mask), (numlock_set_xkb_state), (numlock_gconf_state_key), (numlock_get_gconf_state), (numlock_set_gconf_state), (numlock_xkb_callback), (numlock_install_xkb_callback), (apply_settings), (gnome_settings_keyboard_init): Remember NumLock state between sessions. Fixes bug #74215. Patch by Sebastian Kapfer <sebastian_kapfer@web.de>
-rw-r--r--gnome-settings-daemon/ChangeLog90
-rw-r--r--gnome-settings-daemon/factory.c7
-rw-r--r--gnome-settings-daemon/gnome-settings-accessibility-keyboard.c9
-rw-r--r--gnome-settings-daemon/gnome-settings-daemon.c40
-rw-r--r--gnome-settings-daemon/gnome-settings-daemon.h2
-rw-r--r--gnome-settings-daemon/gnome-settings-font.c2
-rw-r--r--gnome-settings-daemon/gnome-settings-gtk1theme.c5
-rw-r--r--gnome-settings-daemon/gnome-settings-keybindings.c3
-rw-r--r--gnome-settings-daemon/gnome-settings-keyboard-xkb.c23
-rw-r--r--gnome-settings-daemon/gnome-settings-keyboard.c179
-rw-r--r--gnome-settings-daemon/gnome-settings-mouse.c166
-rw-r--r--gnome-settings-daemon/gnome-settings-screensaver.c38
-rw-r--r--gnome-settings-daemon/gnome-settings-sound.c4
-rw-r--r--gnome-settings-daemon/gnome-settings-typing-break.c8
-rw-r--r--gnome-settings-daemon/gnome-settings-xmodmap.c23
-rw-r--r--gnome-settings-daemon/gnome-settings-xrdb.c25
-rw-r--r--gnome-settings-daemon/gnome-settings-xsettings.c5
17 files changed, 523 insertions, 106 deletions
diff --git a/gnome-settings-daemon/ChangeLog b/gnome-settings-daemon/ChangeLog
index a82e3ce1d..357d63a88 100644
--- a/gnome-settings-daemon/ChangeLog
+++ b/gnome-settings-daemon/ChangeLog
@@ -1,3 +1,93 @@
+2005-10-21 Ray Strode <rstrode@redhat.com>
+
+ Remap buttons on auxillary mice for left-handed
+ mode (bug 314409).
+
+ * gnome-settings-mouse.c (supports_xinput_devices): new
+ function to detect XInput Extension
+ (configure_button_layout): new function to set up
+ logical mouse button layout for left or right handed
+ mode
+ (xinput_device_has_buttons): new function to detect if
+ an xinput device has buttons to reconfigure
+ (set_xinput_devices_left_handed): new function to set
+ auxillary mice into left-handed mode
+ (set_left_handed): call set_xinput_devices_left_handed
+ if available
+
+2005-10-18 Rodrigo Moya <rodrigo@novell.com><>
+
+ * gnome-settings-font.c (load_xcursor_theme):
+ * gnome-settings-xsettings.c (gnome_xft_settings_set_xsettings):
+ run xrdb with -nocpp, since it's not needed here.
+
+2005-10-16 Rodrigo Moya <rodrigo@novell.com>
+
+ * factory.c: declare a global GConfClient.
+ (main): unref the global GConfClient.
+
+ * gnome-settings-daemon.[ch] (gnome_settings_daemon_get_conf_client):
+ new function to use the same GConfClient everywhere.
+ (gnome_settings_daemon_new): use the global GConfClient.
+
+ * gnome-settings-accessibility-keyboard.c (set_server_from_gconf,
+ ax_response_callback, set_gconf_from_server):
+ * gnome-settings-gtk1theme.c (apply_settings):
+ * gnome-settings-keybindings.c (bindings_get_entry):
+ * gnome-settings-keyboard.c (numlock_get_gconf_state,
+ numlock_set_gconf_state, apply_settings):
+ * gnome-settings-keyboard-xkb.c (apply_xkb_settings,
+ gnome_settings_keyboard_xkb_sysconfig_changed_response,
+ gnome_settings_keyboard_xkb_analyze_sysconfig,
+ gnome_settings_chk_file_list):
+ * gnome-settings-screensaver.c (key_toggled_cb,
+ really_start_screensaver):
+ * gnome-settings-sound.c (apply_settings):
+ * gnome-settings-xmodmap.c (check_button_callback,
+ gnome_settings_load_modmap_files, remove_button_clicked_callback,
+ load_button_clicked_callback, gnome_settings_modmap_dialog_call):
+ * gnome-settings-xsettings.c (xft_callback):
+ use the global GConfClient.
+
+ * gnome-settings-keyboard-xkb.c (gnome_settings_keyboard_xkb_load):
+ don't get another GConfClient when we're getting one passed!
+
+2005-10-14 Rodrigo Moya <rodrigo@novell.com>
+
+ * gnome-settings-daemon.c (child_watch_cb): added this function to
+ watch for children...
+ (gnome_settings_daemon_spawn_with_input): ...started here, instead
+ of just blocking.
+
+ * gnome-settings-screensaver.c (gnome_settings_screensaver_load): do
+ lazy loading of the screensaver.
+ (really_start_screensaver): start on a 25 seconds timeout.
+
+ * gnome-settings-typing-break.c (gnome_settings_typing_break_load): do
+ lazy loading og the typing break applet.
+ (really_setup_typing_break): start on a 30 seconds timeout.
+
+2005-10-14 Erwann Chenede <erwann.chenede@sun.com>
+
+ Fixes #314774
+
+ * gnome-settings-xrdb.c (gnome_settings_xrdb_load): connect to
+ "notify:gtk-theme-name" signal, to run xrdb only when the whole theme
+ has been changed.
+ (theme_changed): callback for "notify:gtk-theme-name".
+
+2005-10-10 Jürg Billeter <j@bitron.ch>
+
+ reviewed by: Sergey V. Udaltsov <svu@gnome.org>
+
+ * gnome-settings-keyboard.c: (gsd_keyboard_get_hostname_key),
+ (numlock_NumLock_modifier_mask), (numlock_set_xkb_state),
+ (numlock_gconf_state_key), (numlock_get_gconf_state),
+ (numlock_set_gconf_state), (numlock_xkb_callback),
+ (numlock_install_xkb_callback), (apply_settings),
+ (gnome_settings_keyboard_init): Remember NumLock state between sessions.
+ Fixes bug #74215. Patch by Sebastian Kapfer <sebastian_kapfer@web.de>
+
2005-09-16 Kjartan Maraas <kmaraas@gnome.org>
* gnome-settings-font.c: (load_xcursor_theme): Don't leak
diff --git a/gnome-settings-daemon/factory.c b/gnome-settings-daemon/factory.c
index 20948e626..4e2a30c7e 100644
--- a/gnome-settings-daemon/factory.c
+++ b/gnome-settings-daemon/factory.c
@@ -13,6 +13,7 @@
#include <libgnomeui/gnome-client.h>
static BonoboObject *services_server = NULL;
+GConfClient *conf_client = NULL;
int main (int argc, char *argv [])
{
@@ -57,5 +58,9 @@ int main (int argc, char *argv [])
gtk_main();
+ /* cleanup */
+ if (conf_client)
+ g_object_unref (conf_client);
+
return -1;
-}
+}
diff --git a/gnome-settings-daemon/gnome-settings-accessibility-keyboard.c b/gnome-settings-daemon/gnome-settings-accessibility-keyboard.c
index d3e681dcc..b25a4d431 100644
--- a/gnome-settings-daemon/gnome-settings-accessibility-keyboard.c
+++ b/gnome-settings-daemon/gnome-settings-accessibility-keyboard.c
@@ -158,9 +158,9 @@ set_ctrl_from_gconf (XkbDescRec *desc, GConfClient *client,
static void
set_server_from_gconf (GConfEntry *ignored)
{
- GConfClient *client = gconf_client_get_default ();
XkbDescRec *desc;
gboolean enable_accessX;
+ GConfClient *client = gnome_settings_daemon_get_conf_client ();
desc = get_xkb_desc_rec ();
if (!desc) {
@@ -283,8 +283,6 @@ set_server_from_gconf (GConfEntry *ignored)
XSync (GDK_DISPLAY (), FALSE);
gdk_error_trap_pop ();
-
- g_object_unref (client);
}
static gboolean
@@ -299,7 +297,7 @@ ax_response_callback (gint response_id, guint revert_controls_mask, gboolean ena
case GTK_RESPONSE_REJECT:
case GTK_RESPONSE_CANCEL:
{
- GConfClient *client = gconf_client_get_default ();
+ GConfClient *client = gnome_settings_daemon_get_conf_client ();
/* we're reverting, so we invert sense of 'enabled' flag */
d ("cancelling AccessX request");
@@ -420,7 +418,7 @@ static void
set_gconf_from_server (GConfEntry *ignored)
{
gboolean in_gconf;
- GConfClient *client = gconf_client_get_default ();
+ GConfClient *client = gnome_settings_daemon_get_conf_client ();
GConfChangeSet *cs = gconf_change_set_new ();
XkbDescRec *desc = get_xkb_desc_rec ();
gboolean changed = FALSE, slowkeys_changed, stickykeys_changed;
@@ -520,7 +518,6 @@ set_gconf_from_server (GConfEntry *ignored)
gconf_client_suggest_sync (client, NULL);
}
gconf_change_set_unref (cs);
- g_object_unref (client);
}
static GdkFilterReturn
diff --git a/gnome-settings-daemon/gnome-settings-daemon.c b/gnome-settings-daemon/gnome-settings-daemon.c
index e1cc0e09a..6d53769df 100644
--- a/gnome-settings-daemon/gnome-settings-daemon.c
+++ b/gnome-settings-daemon/gnome-settings-daemon.c
@@ -334,7 +334,7 @@ gnome_settings_daemon_new (void)
/* We use GConfClient not GConfClient because a cache isn't useful
* for us
*/
- client = gconf_client_get_default ();
+ client = gnome_settings_daemon_get_conf_client ();
/* gnome_settings_disk_init (client);*/
gnome_settings_font_init (client);
@@ -410,8 +410,6 @@ gnome_settings_daemon_new (void)
gnome_settings_xrdb_load (client);
gnome_settings_typing_break_load (client);
- g_object_unref (client);
-
return G_OBJECT (daemon);
}
@@ -446,6 +444,19 @@ wait_for_child (int pid,
return TRUE;
}
+static void
+child_watch_cb (GPid pid, gint status, gpointer user_data)
+{
+ gchar *command = user_data;
+
+ if (!WIFEXITED (status) || WEXITSTATUS (status))
+ {
+ g_warning ("Command %s failed", command);
+ }
+
+ g_free (command);
+
+}
/*
* Helper function for spawn_with_input() - write an entire
@@ -493,6 +504,7 @@ gnome_settings_daemon_spawn_with_input (char **argv,
int child_pid;
int inpipe;
GError *err = NULL;
+ gchar *command;
if (!g_spawn_async_with_pipes (NULL /* working directory */, argv, NULL /* envp */,
G_SPAWN_SEARCH_PATH | G_SPAWN_DO_NOT_REAP_CHILD,
@@ -509,25 +521,27 @@ gnome_settings_daemon_spawn_with_input (char **argv,
return;
}
+ command = g_strjoinv (" ", argv);
if (input)
{
if (!write_all (inpipe, input, strlen (input)))
{
- gchar *command = g_strjoinv (" ", argv);
g_warning ("Could not write input to %s", command);
- g_free (command);
}
close (inpipe);
}
-
- wait_for_child (child_pid, &exit_status);
+
+ g_child_watch_add (child_pid, (GChildWatchFunc) child_watch_cb, command);
+}
- if (!WIFEXITED (exit_status) || WEXITSTATUS (exit_status))
- {
- gchar *command = g_strjoinv (" ", argv);
- g_warning ("Command %s failed", command);
- g_free (command);
- }
+extern GConfClient *conf_client;
+
+GConfClient *
+gnome_settings_daemon_get_conf_client (void)
+{
+ if (!conf_client)
+ conf_client = gconf_client_get_default ();
+ return conf_client;
}
diff --git a/gnome-settings-daemon/gnome-settings-daemon.h b/gnome-settings-daemon/gnome-settings-daemon.h
index 9621640d0..18e9209f1 100644
--- a/gnome-settings-daemon/gnome-settings-daemon.h
+++ b/gnome-settings-daemon/gnome-settings-daemon.h
@@ -69,6 +69,8 @@ GObject *gnome_settings_daemon_new (void);
void gnome_settings_daemon_spawn_with_input (char **argv,
const char *input);
+GConfClient *gnome_settings_daemon_get_conf_client (void);
+
G_END_DECLS
#endif /* __GNOME_SETTINGS_DAEMON_H */
diff --git a/gnome-settings-daemon/gnome-settings-font.c b/gnome-settings-daemon/gnome-settings-font.c
index b4c4797b4..f000f8003 100644
--- a/gnome-settings-daemon/gnome-settings-font.c
+++ b/gnome-settings-daemon/gnome-settings-font.c
@@ -20,7 +20,7 @@ load_xcursor_theme (GConfClient *client)
{
gchar *cursor_theme;
gint size;
- char *add[] = { "xrdb", "-merge", NULL };
+ char *add[] = { "xrdb", "-nocpp", "-merge", NULL };
GString *add_string = g_string_new (NULL);
cursor_theme = gconf_client_get_string (client,
diff --git a/gnome-settings-daemon/gnome-settings-gtk1theme.c b/gnome-settings-daemon/gnome-settings-gtk1theme.c
index 9bc1f65ad..b02e64a2a 100644
--- a/gnome-settings-daemon/gnome-settings-gtk1theme.c
+++ b/gnome-settings-daemon/gnome-settings-gtk1theme.c
@@ -146,7 +146,7 @@ check_filename (char *base_dir,
static void
apply_settings (void)
{
- GConfClient *client = gconf_client_get_default ();
+ GConfClient *client = gnome_settings_daemon_get_conf_client ();
gchar *current_theme;
gchar *theme_filename;
gchar *rc_filename;
@@ -202,8 +202,7 @@ apply_settings (void)
if (write_contents (rc_filename, new_contents))
send_change_message ();
}
-
- g_object_unref (client);
+
g_free (new_contents);
g_free (current_contents);
g_free (rc_filename);
diff --git a/gnome-settings-daemon/gnome-settings-keybindings.c b/gnome-settings-daemon/gnome-settings-keybindings.c
index a6c9ce8e4..8c5ed7e47 100644
--- a/gnome-settings-daemon/gnome-settings-keybindings.c
+++ b/gnome-settings-daemon/gnome-settings-keybindings.c
@@ -178,7 +178,7 @@ bindings_get_entry (char *subdir)
char *gconf_key;
char *action = NULL;
char *key = NULL;
- GConfClient *client = gconf_client_get_default();
+ GConfClient *client = gnome_settings_daemon_get_conf_client ();
g_return_val_if_fail (subdir != NULL, FALSE);
@@ -190,7 +190,6 @@ bindings_get_entry (char *subdir)
/* Get entries for this binding */
list = gconf_client_all_entries (client, subdir, NULL);
- g_object_unref (client);
for (li = list; li != NULL; li = li->next)
{
diff --git a/gnome-settings-daemon/gnome-settings-keyboard-xkb.c b/gnome-settings-daemon/gnome-settings-keyboard-xkb.c
index 7e2a73cc0..b772cef29 100644
--- a/gnome-settings-daemon/gnome-settings-keyboard-xkb.c
+++ b/gnome-settings-daemon/gnome-settings-keyboard-xkb.c
@@ -146,9 +146,8 @@ apply_xkb_settings (void)
if (!initedOk)
return;
- confClient = gconf_client_get_default ();
+ confClient = gnome_settings_daemon_get_conf_client ();
GSwitchItKbdConfigInit (&currentSysKbdConfig, confClient);
- g_object_unref (confClient);
GSwitchItKbdConfigLoadFromGConf (&currentKbdConfig, &initialSysKbdConfig);
@@ -180,7 +179,7 @@ gnome_settings_keyboard_xkb_sysconfig_changed_response (GtkDialog * dialog,
gboolean dontShowAgain = gtk_toggle_button_get_active (
GTK_TOGGLE_BUTTON (g_object_get_data (G_OBJECT (dialog), "chkDontShowAgain")));
- confClient = gconf_client_get_default ();
+ confClient = gnome_settings_daemon_get_conf_client ();
switch (what2do) {
case RESPONSE_USE_X:
@@ -196,8 +195,6 @@ gnome_settings_keyboard_xkb_sysconfig_changed_response (GtkDialog * dialog,
gconf_client_set_bool (confClient, DISABLE_SYSCONF_CHANGED_WARNING_KEY, TRUE, NULL);
gtk_widget_destroy (GTK_WIDGET (dialog));
-
- g_object_unref (confClient);
}
static void
@@ -209,11 +206,10 @@ gnome_settings_keyboard_xkb_analyze_sysconfig (void)
if (!initedOk)
return;
- confClient = gconf_client_get_default ();
+ confClient = gnome_settings_daemon_get_conf_client ();
GSwitchItKbdConfigInit (&backupGConfKbdConfig, confClient);
GSwitchItKbdConfigInit (&initialSysKbdConfig, confClient);
dontShow = gconf_client_get_bool (confClient, DISABLE_SYSCONF_CHANGED_WARNING_KEY, NULL);
- g_object_unref (confClient);
GSwitchItKbdConfigLoadFromGConfBackup (&backupGConfKbdConfig);
GSwitchItKbdConfigLoadFromXInitial (&initialSysKbdConfig);
@@ -275,7 +271,7 @@ gnome_settings_chk_file_list (void)
GSList *tmp = NULL;
GSList *tmp_l = NULL;
gboolean new_file_exist = FALSE;
- GConfClient *confClient = gconf_client_get_default ();
+ GConfClient *confClient = gnome_settings_daemon_get_conf_client ();
homeDir = g_dir_open (g_get_home_dir (), 0, NULL);
while ((fname = g_dir_read_name (homeDir)) != NULL) {
@@ -316,8 +312,6 @@ gnome_settings_chk_file_list (void)
g_slist_foreach (last_login_file_list, (GFunc) g_free, NULL);
g_slist_free (last_login_file_list);
- g_object_unref (G_OBJECT (confClient));
-
return new_file_exist;
}
@@ -385,14 +379,9 @@ gnome_settings_keyboard_xkb_init (GConfClient * client)
void
gnome_settings_keyboard_xkb_load (GConfClient * client)
{
- GConfClient *confClient;
- confClient = gconf_client_get_default ();
-
- GSwitchItConfigInit (&currentConfig, confClient);
+ GSwitchItConfigInit (&currentConfig, client);
apply_settings ();
- GSwitchItKbdConfigInit (&currentKbdConfig, confClient);
+ GSwitchItKbdConfigInit (&currentKbdConfig, client);
apply_xkb_settings ();
-
- g_object_unref (confClient);
}
diff --git a/gnome-settings-daemon/gnome-settings-keyboard.c b/gnome-settings-daemon/gnome-settings-keyboard.c
index bdad73b79..bf417a425 100644
--- a/gnome-settings-daemon/gnome-settings-keyboard.c
+++ b/gnome-settings-daemon/gnome-settings-keyboard.c
@@ -38,9 +38,11 @@
#endif
#ifdef HAVE_X11_EXTENSIONS_XKB_H
#include <X11/XKBlib.h>
+#include <X11/keysym.h>
#endif
#include <string.h>
+#include <unistd.h>
#ifdef HAVE_X11_EXTENSIONS_XF86MISC_H
static gboolean
@@ -78,6 +80,162 @@ xkb_set_keyboard_autorepeat_rate (int delay, int rate)
}
#endif
+#define GSD_KEYBOARD_KEY "/desktop/gnome/peripherals/keyboard"
+
+static char *
+gsd_keyboard_get_hostname_key (const char *subkey)
+{
+#ifdef HOST_NAME_MAX
+ char hostname[HOST_NAME_MAX + 1];
+#else
+ char hostname[256];
+#endif
+
+ if (gethostname (hostname, sizeof (hostname)) == 0 &&
+ strcmp (hostname, "localhost") != 0 &&
+ strcmp (hostname, "localhost.localdomain") != 0)
+ {
+ char *key = g_strconcat (GSD_KEYBOARD_KEY
+ "/host-",
+ hostname,
+ "/0/",
+ subkey,
+ (char *)NULL);
+ return key;
+ }
+ else
+ return NULL;
+}
+
+#ifdef HAVE_X11_EXTENSIONS_XKB_H
+
+enum {
+ NUMLOCK_STATE_OFF = 0,
+ NUMLOCK_STATE_ON = 1,
+ NUMLOCK_STATE_UNKNOWN = 2
+};
+
+/* something fatal has happened so that it makes no
+ * sense to try to remember anything.
+ * that means: no calls to the set_state functions!
+ */
+static gboolean
+numlock_setup_error = FALSE;
+
+/* we didn't apply GConf settings yet
+ * don't overwrite them with the initial state from
+ * the newly started session!
+ */
+static gboolean
+numlock_starting_up = TRUE;
+
+
+static unsigned
+numlock_NumLock_modifier_mask ()
+{
+ Display *dpy = GDK_DISPLAY_XDISPLAY (gdk_display_get_default ());
+ return XkbKeysymToModifiers (dpy, XK_Num_Lock);
+}
+
+static void
+numlock_set_xkb_state (gboolean new_state)
+{
+ Display *dpy = GDK_DISPLAY_XDISPLAY (gdk_display_get_default ());
+ if (new_state != NUMLOCK_STATE_ON && new_state != NUMLOCK_STATE_OFF)
+ return;
+ unsigned num_mask = numlock_NumLock_modifier_mask ();
+ XkbLockModifiers (dpy, XkbUseCoreKbd, num_mask, new_state ? num_mask : 0);
+}
+
+static char *
+numlock_gconf_state_key ()
+{
+ char *key = gsd_keyboard_get_hostname_key ("numlock_on");
+ if (!key)
+ {
+ numlock_setup_error = TRUE;
+ g_warning ("numlock: Numlock remembering disabled because your hostname is set to \"localhost\".");
+ }
+ return key;
+}
+
+static int
+numlock_get_gconf_state ()
+{
+ GConfClient *gcc;
+ GError *err = NULL;
+ char *key = numlock_gconf_state_key ();
+ if (!key) return NUMLOCK_STATE_UNKNOWN;
+ gcc = gnome_settings_daemon_get_conf_client ();
+ int curr_state = gconf_client_get_bool (gcc, key, &err);
+ if (err) curr_state = NUMLOCK_STATE_UNKNOWN;
+ g_clear_error (&err);
+ g_free (key);
+ return curr_state;
+}
+
+static void
+numlock_set_gconf_state (gboolean new_state)
+{
+ char *key;
+ GConfClient *gcc;
+ if (new_state != NUMLOCK_STATE_ON && new_state != NUMLOCK_STATE_OFF)
+ return;
+ key = numlock_gconf_state_key ();
+ if (!key) return;
+ gcc = gnome_settings_daemon_get_conf_client ();
+ gconf_client_set_bool (gcc, key, new_state, NULL);
+ g_free (key);
+}
+
+static GdkFilterReturn
+numlock_xkb_callback (GdkXEvent *xev_, GdkEvent *gdkev_, gpointer xkb_event_code)
+{
+ XEvent *xev = (XEvent *)xev_;
+ if (xev->type == GPOINTER_TO_INT (xkb_event_code)) {
+ XkbEvent *xkbev = (XkbEvent *)xev;
+ if (xkbev->any.xkb_type == XkbStateNotify)
+ if (xkbev->state.changed & XkbModifierLockMask) {
+ unsigned num_mask = numlock_NumLock_modifier_mask ();
+ unsigned locked_mods = xkbev->state.locked_mods;
+ int numlock_state = !! (num_mask & locked_mods);
+
+ if (!numlock_starting_up && !numlock_setup_error)
+ numlock_set_gconf_state (numlock_state);
+ }
+ }
+ return GDK_FILTER_CONTINUE;
+}
+
+static void
+numlock_install_xkb_callback ()
+{
+ Display *dpy = GDK_DISPLAY_XDISPLAY (gdk_display_get_default ());
+ int op_code = 0, xkb_event_code = 0;
+ int error_code = 0, major = XkbMajorVersion, minor = XkbMinorVersion;
+ int have_xkb = XkbQueryExtension (dpy,
+ &op_code, &xkb_event_code,
+ &error_code, &major, &minor);
+ if (have_xkb != True)
+ {
+ numlock_setup_error = TRUE;
+ g_warning ("numlock: XkbQueryExtension returned an error");
+ return;
+ }
+
+ XkbSelectEventDetails (dpy,
+ XkbUseCoreKbd,
+ XkbStateNotifyMask,
+ XkbModifierLockMask,
+ XkbModifierLockMask);
+
+ gdk_window_add_filter (NULL,
+ numlock_xkb_callback,
+ GINT_TO_POINTER (xkb_event_code));
+}
+
+#endif /* HAVE_X11_EXTENSIONS_XKB_H */
+
static void
apply_settings (void)
{
@@ -87,10 +245,13 @@ apply_settings (void)
int rate, delay;
int click_volume, bell_volume, bell_pitch, bell_duration;
char *volume_string;
+#ifdef HAVE_X11_EXTENSIONS_XKB_H
+ gboolean rnumlock;
+#endif /* HAVE_X11_EXTENSIONS_XKB_H */
XKeyboardControl kbdcontrol;
- client = gconf_client_get_default ();
+ client = gnome_settings_daemon_get_conf_client ();
repeat = gconf_client_get_bool (client, "/desktop/gnome/peripherals/keyboard/repeat", NULL);
click = gconf_client_get_bool (client, "/desktop/gnome/peripherals/keyboard/click", NULL);
@@ -106,7 +267,9 @@ apply_settings (void)
volume_string = gconf_client_get_string (client, "/desktop/gnome/peripherals/keyboard/bell_mode", NULL);
bell_volume = (volume_string && !strcmp (volume_string, "on")) ? 50 : 0;
g_free (volume_string);
- g_object_unref (client);
+#ifdef HAVE_X11_EXTENSIONS_XKB_H
+ rnumlock = gconf_client_get_bool (client, GSD_KEYBOARD_KEY "/remember_numlock_state", NULL);
+#endif /* HAVE_X11_EXTENSIONS_XKB_H */
gdk_error_trap_push ();
if (repeat) {
@@ -140,6 +303,13 @@ apply_settings (void)
KBKeyClickPercent | KBBellPercent | KBBellPitch | KBBellDuration,
&kbdcontrol);
+
+#ifdef HAVE_X11_EXTENSIONS_XKB_H
+ if (!numlock_setup_error && rnumlock)
+ numlock_set_xkb_state (numlock_get_gconf_state ());
+ numlock_starting_up = FALSE;
+#endif /* HAVE_X11_EXTENSIONS_XKB_H */
+
XSync (GDK_DISPLAY (), FALSE);
gdk_error_trap_pop ();
}
@@ -148,7 +318,10 @@ apply_settings (void)
void
gnome_settings_keyboard_init (GConfClient *client)
{
- gnome_settings_daemon_register_callback ("/desktop/gnome/peripherals/keyboard", (KeyCallbackFunc) apply_settings);
+ gnome_settings_daemon_register_callback (GSD_KEYBOARD_KEY, (KeyCallbackFunc) apply_settings);
+#ifdef HAVE_X11_EXTENSIONS_XKB_H
+ numlock_install_xkb_callback ();
+#endif /* HAVE_X11_EXTENSIONS_XKB_H */
}
void
diff --git a/gnome-settings-daemon/gnome-settings-mouse.c b/gnome-settings-daemon/gnome-settings-mouse.c
index 825674571..66aef21f3 100644
--- a/gnome-settings-daemon/gnome-settings-mouse.c
+++ b/gnome-settings-daemon/gnome-settings-mouse.c
@@ -1,3 +1,5 @@
+#include <config.h>
+
#include <string.h>
#include <math.h>
@@ -6,43 +8,167 @@
#include <gdk/gdkkeysyms.h>
#include <X11/keysym.h>
+#ifdef HAVE_XINPUT
+#include <X11/extensions/XInput.h>
+#endif
+
#include <gconf/gconf.h>
#include "gnome-settings-locate-pointer.h"
#include "gnome-settings-daemon.h"
-#define DEFAULT_PTR_MAP_SIZE 128
+#ifdef HAVE_XINPUT
+static gboolean
+supports_xinput_devices (void)
+{
+ gint op_code, event, error;
+
+ return XQueryExtension (GDK_DISPLAY (), "XInputExtension",
+ &op_code, &event, &error);
+}
+#endif
static void
-set_left_handed (gboolean left_handed)
+configure_button_layout (guchar *buttons,
+ gint n_buttons,
+ gboolean left_handed)
{
- unsigned char *buttons;
- gint n_buttons, i;
- gint idx_1 = 0, idx_3 = 1;
-
- buttons = g_alloca (DEFAULT_PTR_MAP_SIZE);
- n_buttons = XGetPointerMapping (GDK_DISPLAY (), buttons, DEFAULT_PTR_MAP_SIZE);
- if (n_buttons > DEFAULT_PTR_MAP_SIZE) {
- buttons = g_alloca (n_buttons);
- n_buttons = XGetPointerMapping (GDK_DISPLAY (), buttons, n_buttons);
+ const gint left_button = 0;
+ gint right_button;
+
+ /* if the button is higher than 2 (3rd button) then it's
+ * probably one direction of a scroll wheel or something else
+ * uninteresting
+ */
+ right_button = MIN (n_buttons - 1, 2);
+
+ if (left_handed)
+ {
+ buttons[left_button] = right_button + 1;
+ buttons[right_button] = left_button + 1;
+ }
+ else
+ {
+ buttons[left_button] = left_button + 1;
+ buttons[right_button] = right_button + 1;
}
+}
+
+#ifdef HAVE_XINPUT
+static gboolean
+xinput_device_has_buttons (XDeviceInfo *device_info)
+{
+ int i;
+ XAnyClassInfo *class_info;
+
+ class_info = device_info->inputclassinfo;
+ for (i = 0; i < device_info->num_classes; i++)
+ {
+ if (class_info->class == ButtonClass)
+ {
+ XButtonInfo *button_info;
+
+ button_info = (XButtonInfo *) class_info;
+ if (button_info->num_buttons > 0)
+ return TRUE;
+ }
+
+ class_info = (XAnyClassInfo *) (((guchar *) class_info) +
+ class_info->length);
+ }
+ return FALSE;
+}
+
+static void
+set_xinput_devices_left_handed (gboolean left_handed)
+{
+ XDeviceInfo *device_info;
+ gint n_devices;
+ guchar *buttons;
+ gsize buttons_capacity = 16;
+ gint n_buttons;
+ gint i;
+
+ device_info = XListInputDevices (GDK_DISPLAY (), &n_devices);
- for (i = 0; i < n_buttons; i++)
+ if (n_devices > 0)
+ buttons = g_new (guchar, buttons_capacity);
+ else
+ buttons = NULL;
+
+ for (i = 0; i < n_devices; i++)
{
- if (buttons[i] == 1)
- idx_1 = i;
- else if (buttons[i] == ((n_buttons < 3) ? 2 : 3))
- idx_3 = i;
+ XDevice *device = NULL;
+
+ if ((device_info[i].use != IsXExtensionDevice) ||
+ (!xinput_device_has_buttons (&device_info[i])))
+ continue;
+
+ gdk_error_trap_push ();
+
+ device = XOpenDevice (GDK_DISPLAY (), device_info[i].id);
+
+ if ((gdk_error_trap_pop () != 0) ||
+ (device == NULL))
+ continue;
+
+ n_buttons = XGetDeviceButtonMapping (GDK_DISPLAY (), device,
+ buttons,
+ buttons_capacity);
+
+ while (n_buttons > buttons_capacity)
+ {
+ buttons_capacity = n_buttons;
+ buttons = (guchar *) g_realloc (buttons,
+ buttons_capacity * sizeof (guchar));
+
+ n_buttons = XGetDeviceButtonMapping (GDK_DISPLAY (), device,
+ buttons,
+ buttons_capacity);
+ }
+
+ configure_button_layout (buttons, n_buttons, left_handed);
+
+ XSetDeviceButtonMapping (GDK_DISPLAY (), device, buttons, n_buttons);
+ XCloseDevice (GDK_DISPLAY (), device);
}
+ g_free (buttons);
+
+ if (device_info != NULL)
+ XFreeDeviceList (device_info);
+}
+#endif
- if ((left_handed && idx_1 < idx_3) ||
- (!left_handed && idx_1 > idx_3))
+static void
+set_left_handed (gboolean left_handed)
+{
+ guchar *buttons ;
+ gsize buttons_capacity = 16;
+ gint n_buttons;
+
+#ifdef HAVE_XINPUT
+ if (supports_xinput_devices ())
+ set_xinput_devices_left_handed (left_handed);
+#endif
+
+ buttons = g_new (guchar, buttons_capacity);
+ n_buttons = XGetPointerMapping (GDK_DISPLAY (), buttons,
+ (gint) buttons_capacity);
+ while (n_buttons > buttons_capacity)
{
- buttons[idx_1] = ((n_buttons < 3) ? 2 : 3);
- buttons[idx_3] = 1;
+ buttons_capacity = n_buttons;
+ buttons = (guchar *) g_realloc (buttons,
+ buttons_capacity * sizeof (guchar));
+
+ n_buttons = XGetPointerMapping (GDK_DISPLAY (), buttons,
+ (gint) buttons_capacity);
}
+ configure_button_layout (buttons, n_buttons, left_handed);
+
XSetPointerMapping (GDK_DISPLAY (), buttons, n_buttons);
+
+ g_free (buttons);
}
static void
diff --git a/gnome-settings-daemon/gnome-settings-screensaver.c b/gnome-settings-daemon/gnome-settings-screensaver.c
index 8da197cfa..e7686ae2e 100644
--- a/gnome-settings-daemon/gnome-settings-screensaver.c
+++ b/gnome-settings-daemon/gnome-settings-screensaver.c
@@ -24,6 +24,7 @@
#include <config.h>
+#include "gnome-settings-daemon.h"
#include "gnome-settings-screensaver.h"
#include <glib/gi18n.h>
@@ -61,34 +62,29 @@ key_toggled_cb (GtkWidget *toggle, gpointer data)
{
GConfClient *client;
- client = gconf_client_get_default ();
+ client = gnome_settings_daemon_get_conf_client ();
gconf_client_set_bool (client,
SHOW_STARTUP_ERRORS_KEY,
gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (toggle))
? 0 : 1,
NULL);
- g_object_unref (client);
}
-void
-gnome_settings_screensaver_load (GConfClient *client)
+static gboolean
+really_start_screensaver (gpointer user_data)
{
GError *gerr = NULL;
- gboolean start_screensaver, use_gscreensaver = FALSE;
+ gboolean use_gscreensaver = FALSE;
gboolean show_error;
GtkWidget *dialog, *toggle;
gchar *ss_command;
-
- start_screensaver = gconf_client_get_bool (client, START_SCREENSAVER_KEY, NULL);
-
- if (!start_screensaver)
- return;
+ GConfClient *client;
if ((ss_command = g_find_program_in_path ("gnome-screensaver")))
use_gscreensaver = TRUE;
else {
if (!(ss_command = g_find_program_in_path ("xscreensaver")))
- return;
+ return FALSE;
}
g_free (ss_command);
@@ -98,12 +94,13 @@ gnome_settings_screensaver_load (GConfClient *client)
ss_command = XSCREENSAVER_COMMAND;
if (g_spawn_command_line_async (ss_command, &gerr))
- return;
+ return FALSE;
+ client = gnome_settings_daemon_get_conf_client ();
show_error = gconf_client_get_bool (client, SHOW_STARTUP_ERRORS_KEY, NULL);
if (!show_error) {
g_error_free (gerr);
- return;
+ return FALSE;
}
dialog = gtk_message_dialog_new (NULL,
@@ -137,5 +134,20 @@ gnome_settings_screensaver_load (GConfClient *client)
gtk_dialog_set_default_response (GTK_DIALOG (dialog), GTK_RESPONSE_OK);
gtk_widget_show (dialog);
+
+ return FALSE;
+}
+
+void
+gnome_settings_screensaver_load (GConfClient *client)
+{
+ gboolean start_screensaver;
+
+ start_screensaver = gconf_client_get_bool (client, START_SCREENSAVER_KEY, NULL);
+
+ if (!start_screensaver)
+ return;
+
+ g_timeout_add (25000, (GSourceFunc) really_start_screensaver, NULL);
}
diff --git a/gnome-settings-daemon/gnome-settings-sound.c b/gnome-settings-daemon/gnome-settings-sound.c
index 51410263e..882a68fb3 100644
--- a/gnome-settings-daemon/gnome-settings-sound.c
+++ b/gnome-settings-daemon/gnome-settings-sound.c
@@ -144,7 +144,7 @@ apply_settings (void)
gboolean enable_esd;
gboolean event_sounds;
- client = gconf_client_get_default ();
+ client = gnome_settings_daemon_get_conf_client ();
enable_esd = gconf_client_get_bool (client, "/desktop/gnome/sound/enable_esd", NULL);
event_sounds = gconf_client_get_bool (client, "/desktop/gnome/sound/event_sounds", NULL);
@@ -175,8 +175,6 @@ apply_settings (void)
sound_properties_foreach (props, reload_foreach_cb, NULL);
gtk_object_destroy (GTK_OBJECT (props));
}
-
- g_object_unref (client);
}
void
diff --git a/gnome-settings-daemon/gnome-settings-typing-break.c b/gnome-settings-daemon/gnome-settings-typing-break.c
index fbb9ec9c8..bb05b8836 100644
--- a/gnome-settings-daemon/gnome-settings-typing-break.c
+++ b/gnome-settings-daemon/gnome-settings-typing-break.c
@@ -88,10 +88,16 @@ gnome_settings_typing_break_init (GConfClient *client)
gnome_settings_daemon_register_callback ("/desktop/gnome/typing_break", typing_break_callback);
}
+static gboolean
+really_setup_typing_break (gpointer user_data)
+{
+ setup_typing_break (TRUE);
+ return FALSE;
+}
void
gnome_settings_typing_break_load (GConfClient *client)
{
if (gconf_client_get_bool (client, "/desktop/gnome/typing_break/enabled", NULL))
- setup_typing_break (TRUE);
+ g_timeout_add (30000, (GSourceFunc) really_setup_typing_break, NULL);
}
diff --git a/gnome-settings-daemon/gnome-settings-xmodmap.c b/gnome-settings-daemon/gnome-settings-xmodmap.c
index a9098d316..6f1b06c4e 100644
--- a/gnome-settings-daemon/gnome-settings-xmodmap.c
+++ b/gnome-settings-daemon/gnome-settings-xmodmap.c
@@ -1,6 +1,6 @@
/* gnome-settings-xmodmap.c
*
- * Copyright © 2005 Novell Inc.
+ * Copyright © 2005 Novell Inc.
*
* Written by Shakti Sen <shprasad@novell.com>
*
@@ -22,6 +22,7 @@
#include <config.h>
+#include "gnome-settings-daemon.h"
#include "gnome-settings-xmodmap.h"
#include <string.h>
@@ -43,7 +44,8 @@ static void
check_button_callback (GtkWidget *chk_button,
gpointer data)
{
- GConfClient *confClient = gconf_client_get_default ();
+ GConfClient *confClient = gnome_settings_daemon_get_conf_client ();
+
if (gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (chk_button))) {
gconf_client_set_bool (confClient, DISABLE_XMM_WARNING_KEY, TRUE,
NULL);
@@ -52,13 +54,12 @@ check_button_callback (GtkWidget *chk_button,
gconf_client_set_bool (confClient, DISABLE_XMM_WARNING_KEY, FALSE,
NULL);
}
- g_object_unref (confClient);
}
void
gnome_settings_load_modmap_files ()
{
- GConfClient *confClient = gconf_client_get_default ();
+ GConfClient *confClient = gnome_settings_daemon_get_conf_client ();
GSList *tmp = NULL;
GSList *loaded_file_list = gconf_client_get_list (confClient, LOADED_FILES_KEY, GCONF_VALUE_STRING, NULL);
tmp = loaded_file_list;
@@ -69,7 +70,6 @@ gnome_settings_load_modmap_files ()
tmp = tmp->next;
g_free (command);
}
- g_object_unref (confClient);
}
static void
@@ -129,7 +129,7 @@ remove_string_from_list (GSList *list,
static void
remove_button_clicked_callback (GtkWidget *button,
- void *data)
+ void *data)
{
GladeXML *xml;
GtkWidget *dialog;
@@ -155,7 +155,7 @@ remove_button_clicked_callback (GtkWidget *button,
return;
/* Remove the selected file */
- confClient = gconf_client_get_default ();
+ confClient = gnome_settings_daemon_get_conf_client ();
loaded_files = gconf_client_get_list (confClient, LOADED_FILES_KEY, GCONF_VALUE_STRING, NULL);
loaded_files = remove_string_from_list (loaded_files, (char *)filenames->data);
@@ -177,8 +177,6 @@ remove_button_clicked_callback (GtkWidget *button,
g_slist_foreach (loaded_files, (GFunc) g_free, NULL);
g_slist_free (loaded_files);
-
- g_object_unref (G_OBJECT (confClient));
}
static void
@@ -208,7 +206,7 @@ load_button_clicked_callback (GtkWidget *button,
/* Add the files to left-tree-view */
- confClient = gconf_client_get_default ();
+ confClient = gnome_settings_daemon_get_conf_client ();
loaded_files = gconf_client_get_list (confClient, LOADED_FILES_KEY, GCONF_VALUE_STRING, NULL);
tmp = loaded_files;
while (tmp != NULL) {
@@ -238,8 +236,6 @@ load_button_clicked_callback (GtkWidget *button,
}
g_slist_foreach (loaded_files, (GFunc) g_free, NULL);
g_slist_free (loaded_files);
-
- g_object_unref (G_OBJECT (confClient));
}
void
@@ -263,7 +259,7 @@ gnome_settings_modmap_dialog_call (void)
GDir *homeDir;
GSList *loaded_files = NULL;
G_CONST_RETURN gchar *fname;
- GConfClient *confClient = gconf_client_get_default ();
+ GConfClient *confClient = gnome_settings_daemon_get_conf_client ();
homeDir = g_dir_open (g_get_home_dir (), 0, NULL);
if (homeDir == NULL)
return;
@@ -341,7 +337,6 @@ gnome_settings_modmap_dialog_call (void)
gtk_tree_view_column_set_sort_column_id (column, 0);
loaded_files = gconf_client_get_list (confClient, LOADED_FILES_KEY, GCONF_VALUE_STRING, NULL);
- g_object_unref (confClient);
/* Add the data */
tmp = loaded_files;
diff --git a/gnome-settings-daemon/gnome-settings-xrdb.c b/gnome-settings-daemon/gnome-settings-xrdb.c
index 51d22d8c7..37a223180 100644
--- a/gnome-settings-daemon/gnome-settings-xrdb.c
+++ b/gnome-settings-daemon/gnome-settings-xrdb.c
@@ -321,8 +321,9 @@ apply_settings (GtkStyle *style)
return;
}
-static void
-style_set_cb (GtkWidget *widget, GtkStyle *s, gpointer data)
+static void theme_changed (GtkSettings *settings,
+ GParamSpec *pspec,
+ GtkWidget *widget)
{
apply_settings (gtk_widget_get_style (widget));
}
@@ -330,13 +331,25 @@ style_set_cb (GtkWidget *widget, GtkStyle *s, gpointer data)
void
gnome_settings_xrdb_init (GConfClient *client)
{
- widget = gtk_window_new (GTK_WINDOW_TOPLEVEL);
- g_signal_connect (widget, "style-set", (GCallback)style_set_cb, NULL);
- gtk_widget_ensure_style (widget);
}
void
gnome_settings_xrdb_load (GConfClient *client)
{
- style_set_cb (widget, NULL, NULL);
+ static gboolean initialized = FALSE;
+
+ if (!initialized)
+ { /* the initialization is done here otherwise
+ gnome_settings_xsettings_load would generate
+ false hit as gtk-theme-name is set to Default in
+ gnome_settings_xsettings_init */
+ GtkSettings *settings = gtk_settings_get_default ();
+ widget = gtk_window_new (GTK_WINDOW_TOPLEVEL);
+ g_signal_connect (settings,
+ "notify::gtk-theme-name",
+ G_CALLBACK (theme_changed),
+ widget);
+ gtk_widget_ensure_style (widget);
+ initialized = TRUE;
+ }
}
diff --git a/gnome-settings-daemon/gnome-settings-xsettings.c b/gnome-settings-daemon/gnome-settings-xsettings.c
index 1ac5b6b0a..07e7c3ef4 100644
--- a/gnome-settings-daemon/gnome-settings-xsettings.c
+++ b/gnome-settings-daemon/gnome-settings-xsettings.c
@@ -255,10 +255,9 @@ xft_callback (GConfEntry *entry)
GConfClient *client;
int i;
- client = gconf_client_get_default ();
+ client = gnome_settings_daemon_get_conf_client ();
gnome_settings_update_xft (client);
- g_object_unref (client);
for (i = 0; managers [i]; i++)
xsettings_manager_notify (managers [i]);
@@ -383,7 +382,7 @@ gnome_xft_settings_set_xsettings (GnomeXftSettings *settings)
static void
gnome_xft_settings_set_xresources (GnomeXftSettings *settings)
{
- char *add[] = { "xrdb", "-merge", NULL };
+ char *add[] = { "xrdb", "-nocpp", "-merge", NULL };
GString *add_string = g_string_new (NULL);
char *old_locale = g_strdup (setlocale (LC_NUMERIC, NULL));