From e46b4adef5c6c6805b3ca6dbfbe99a4299252514 Mon Sep 17 00:00:00 2001 From: haxar Date: Tue, 21 Feb 2012 20:14:01 -0800 Subject: gsd to msd complete rename patch by NiceandGently; file rename commit --- plugins/keyboard/gsd-keyboard-manager.c | 569 -------------------- plugins/keyboard/gsd-keyboard-manager.h | 62 --- plugins/keyboard/gsd-keyboard-plugin.c | 104 ---- plugins/keyboard/gsd-keyboard-plugin.h | 63 --- plugins/keyboard/gsd-keyboard-xkb.c | 918 -------------------------------- plugins/keyboard/gsd-keyboard-xkb.h | 40 -- plugins/keyboard/gsd-xmodmap.c | 399 -------------- plugins/keyboard/gsd-xmodmap.h | 29 - plugins/keyboard/msd-keyboard-manager.c | 569 ++++++++++++++++++++ plugins/keyboard/msd-keyboard-manager.h | 62 +++ plugins/keyboard/msd-keyboard-plugin.c | 104 ++++ plugins/keyboard/msd-keyboard-plugin.h | 63 +++ plugins/keyboard/msd-keyboard-xkb.c | 918 ++++++++++++++++++++++++++++++++ plugins/keyboard/msd-keyboard-xkb.h | 40 ++ plugins/keyboard/msd-xmodmap.c | 399 ++++++++++++++ plugins/keyboard/msd-xmodmap.h | 29 + 16 files changed, 2184 insertions(+), 2184 deletions(-) delete mode 100644 plugins/keyboard/gsd-keyboard-manager.c delete mode 100644 plugins/keyboard/gsd-keyboard-manager.h delete mode 100644 plugins/keyboard/gsd-keyboard-plugin.c delete mode 100644 plugins/keyboard/gsd-keyboard-plugin.h delete mode 100644 plugins/keyboard/gsd-keyboard-xkb.c delete mode 100644 plugins/keyboard/gsd-keyboard-xkb.h delete mode 100644 plugins/keyboard/gsd-xmodmap.c delete mode 100644 plugins/keyboard/gsd-xmodmap.h create mode 100644 plugins/keyboard/msd-keyboard-manager.c create mode 100644 plugins/keyboard/msd-keyboard-manager.h create mode 100644 plugins/keyboard/msd-keyboard-plugin.c create mode 100644 plugins/keyboard/msd-keyboard-plugin.h create mode 100644 plugins/keyboard/msd-keyboard-xkb.c create mode 100644 plugins/keyboard/msd-keyboard-xkb.h create mode 100644 plugins/keyboard/msd-xmodmap.c create mode 100644 plugins/keyboard/msd-xmodmap.h (limited to 'plugins/keyboard') diff --git a/plugins/keyboard/gsd-keyboard-manager.c b/plugins/keyboard/gsd-keyboard-manager.c deleted file mode 100644 index 0969459..0000000 --- a/plugins/keyboard/gsd-keyboard-manager.c +++ /dev/null @@ -1,569 +0,0 @@ -/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 8 -*- - * - * Copyright © 2001 Ximian, Inc. - * Copyright (C) 2007 William Jon McCann - * - * 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 -#include -#include -#include -#include -#include -#include - -#include - -#include -#include -#include -#include -#include - -#ifdef HAVE_X11_EXTENSIONS_XF86MISC_H - #include -#endif - -#ifdef HAVE_X11_EXTENSIONS_XKB_H - #include - #include -#endif - -#include "mate-settings-profile.h" -#include "msd-keyboard-manager.h" - -#include "msd-keyboard-xkb.h" -#include "msd-xmodmap.h" - -#define MSD_KEYBOARD_MANAGER_GET_PRIVATE(o) \ - (G_TYPE_INSTANCE_GET_PRIVATE((o), MSD_TYPE_KEYBOARD_MANAGER, MsdKeyboardManagerPrivate)) - -#ifndef HOST_NAME_MAX - #define HOST_NAME_MAX 255 -#endif - -#define MSD_KEYBOARD_KEY "/desktop/mate/peripherals/keyboard" - -#define KEY_REPEAT MSD_KEYBOARD_KEY "/repeat" -#define KEY_CLICK MSD_KEYBOARD_KEY "/click" -#define KEY_RATE MSD_KEYBOARD_KEY "/rate" -#define KEY_DELAY MSD_KEYBOARD_KEY "/delay" -#define KEY_CLICK_VOLUME MSD_KEYBOARD_KEY "/click_volume" - -#define KEY_BELL_VOLUME MSD_KEYBOARD_KEY "/bell_volume" -#define KEY_BELL_PITCH MSD_KEYBOARD_KEY "/bell_pitch" -#define KEY_BELL_DURATION MSD_KEYBOARD_KEY "/bell_duration" -#define KEY_BELL_MODE MSD_KEYBOARD_KEY "/bell_mode" - -struct MsdKeyboardManagerPrivate { - gboolean have_xkb; - gint xkb_event_base; - guint notify; -}; - -static void msd_keyboard_manager_class_init (MsdKeyboardManagerClass* klass); -static void msd_keyboard_manager_init (MsdKeyboardManager* keyboard_manager); -static void msd_keyboard_manager_finalize (GObject* object); - -G_DEFINE_TYPE (MsdKeyboardManager, msd_keyboard_manager, G_TYPE_OBJECT) - -static gpointer manager_object = NULL; - - -#ifdef HAVE_X11_EXTENSIONS_XF86MISC_H -static gboolean xfree86_set_keyboard_autorepeat_rate(int delay, int rate) -{ - gboolean res = FALSE; - int event_base_return; - int error_base_return; - - if (XF86MiscQueryExtension (GDK_DISPLAY_XDISPLAY(gdk_display_get_default()), - &event_base_return, - &error_base_return) == True) { - /* load the current settings */ - XF86MiscKbdSettings kbdsettings; - XF86MiscGetKbdSettings (GDK_DISPLAY_XDISPLAY(gdk_display_get_default()), &kbdsettings); - - /* assign the new values */ - kbdsettings.delay = delay; - kbdsettings.rate = rate; - XF86MiscSetKbdSettings (GDK_DISPLAY_XDISPLAY(gdk_display_get_default()), &kbdsettings); - res = TRUE; - } - - return res; -} -#endif /* HAVE_X11_EXTENSIONS_XF86MISC_H */ - -#ifdef HAVE_X11_EXTENSIONS_XKB_H -static gboolean xkb_set_keyboard_autorepeat_rate(int delay, int rate) -{ - int interval = (rate <= 0) ? 1000000 : 1000/rate; - - if (delay <= 0) - { - delay = 1; - } - - return XkbSetAutoRepeatRate(GDK_DISPLAY_XDISPLAY(gdk_display_get_default()), XkbUseCoreKbd, delay, interval); -} -#endif - -static char* msd_keyboard_get_hostname_key (const char *subkey) -{ - char hostname[HOST_NAME_MAX + 1]; - - if (gethostname (hostname, sizeof (hostname)) == 0 && - strcmp (hostname, "localhost") != 0 && - strcmp (hostname, "localhost.localdomain") != 0) { - char *escaped; - char *key; - - escaped = mateconf_escape_key (hostname, -1); - key = g_strconcat (MSD_KEYBOARD_KEY - "/host-", - escaped, - "/0/", - subkey, - NULL); - g_free (escaped); - return key; - } else - return NULL; -} - -#ifdef HAVE_X11_EXTENSIONS_XKB_H - -typedef enum { - NUMLOCK_STATE_OFF = 0, - NUMLOCK_STATE_ON = 1, - NUMLOCK_STATE_UNKNOWN = 2 -} NumLockState; - -static void -numlock_xkb_init (MsdKeyboardManager *manager) -{ - Display *dpy = GDK_DISPLAY_XDISPLAY (gdk_display_get_default ()); - gboolean have_xkb; - int opcode, error_base, major, minor; - - have_xkb = XkbQueryExtension (dpy, - &opcode, - &manager->priv->xkb_event_base, - &error_base, - &major, - &minor) - && XkbUseExtension (dpy, &major, &minor); - - if (have_xkb) { - XkbSelectEventDetails (dpy, - XkbUseCoreKbd, - XkbStateNotifyMask, - XkbModifierLockMask, - XkbModifierLockMask); - } else { - g_warning ("XKB extension not available"); - } - - manager->priv->have_xkb = have_xkb; -} - -static unsigned -numlock_NumLock_modifier_mask (void) -{ - Display *dpy = GDK_DISPLAY_XDISPLAY (gdk_display_get_default ()); - return XkbKeysymToModifiers (dpy, XK_Num_Lock); -} - -static void -numlock_set_xkb_state (NumLockState new_state) -{ - unsigned int num_mask; - Display *dpy = GDK_DISPLAY_XDISPLAY (gdk_display_get_default ()); - if (new_state != NUMLOCK_STATE_ON && new_state != NUMLOCK_STATE_OFF) - return; - num_mask = numlock_NumLock_modifier_mask (); - XkbLockModifiers (dpy, XkbUseCoreKbd, num_mask, new_state ? num_mask : 0); -} - -static char * -numlock_mateconf_state_key (void) -{ - char *key = msd_keyboard_get_hostname_key ("numlock_on"); - if (!key) { - g_message ("NumLock remembering disabled because hostname is set to \"localhost\""); - } - return key; -} - -static NumLockState -numlock_get_mateconf_state (MateConfClient *client) -{ - int curr_state; - GError *err = NULL; - char *key = numlock_mateconf_state_key (); - - if (!key) { - return NUMLOCK_STATE_UNKNOWN; - } - - curr_state = mateconf_client_get_bool (client, key, &err); - if (err) { - curr_state = NUMLOCK_STATE_UNKNOWN; - g_error_free (err); - } - - g_free (key); - return curr_state; -} - -static void numlock_set_mateconf_state(MateConfClient *client, NumLockState new_state) -{ - //printf("numlock_set_mateconf_state\n"); - char* key; - - if (new_state != NUMLOCK_STATE_ON && new_state != NUMLOCK_STATE_OFF) { - return; - } - - key = numlock_mateconf_state_key (); - - if (key) { - mateconf_client_set_bool (client, 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); - MateConfClient *client = mateconf_client_get_default (); - numlock_set_mateconf_state (client, numlock_state); - g_object_unref (client); - } - } - return GDK_FILTER_CONTINUE; -} - -static void -numlock_install_xkb_callback (MsdKeyboardManager *manager) -{ - if (!manager->priv->have_xkb) - return; - - gdk_window_add_filter (NULL, - numlock_xkb_callback, - GINT_TO_POINTER (manager->priv->xkb_event_base)); -} - -#endif /* HAVE_X11_EXTENSIONS_XKB_H */ - -static void -apply_settings (MateConfClient *client, - guint cnxn_id, - MateConfEntry *entry, - MsdKeyboardManager *manager) -{ - XKeyboardControl kbdcontrol; - gboolean repeat; - gboolean click; - int rate; - int delay; - int click_volume; - int bell_volume; - int bell_pitch; - int bell_duration; - char *volume_string; -#ifdef HAVE_X11_EXTENSIONS_XKB_H - gboolean rnumlock; -#endif /* HAVE_X11_EXTENSIONS_XKB_H */ - - repeat = mateconf_client_get_bool (client, KEY_REPEAT, NULL); - click = mateconf_client_get_bool (client, KEY_CLICK, NULL); - rate = mateconf_client_get_int (client, KEY_RATE, NULL); - delay = mateconf_client_get_int (client, KEY_DELAY, NULL); - click_volume = mateconf_client_get_int (client, KEY_CLICK_VOLUME, NULL); -#if 0 - bell_volume = mateconf_client_get_int (client, KEY_BELL_VOLUME, NULL); -#endif - bell_pitch = mateconf_client_get_int (client, KEY_BELL_PITCH, NULL); - bell_duration = mateconf_client_get_int (client, KEY_BELL_DURATION, NULL); - - volume_string = mateconf_client_get_string (client, KEY_BELL_MODE, NULL); - bell_volume = (volume_string && !strcmp (volume_string, "on")) ? 50 : 0; - g_free (volume_string); - -#ifdef HAVE_X11_EXTENSIONS_XKB_H - rnumlock = mateconf_client_get_bool (client, MSD_KEYBOARD_KEY "/remember_numlock_state", NULL); -#endif /* HAVE_X11_EXTENSIONS_XKB_H */ - - gdk_error_trap_push (); - if (repeat) { - gboolean rate_set = FALSE; - - XAutoRepeatOn (GDK_DISPLAY_XDISPLAY(gdk_display_get_default())); - /* Use XKB in preference */ -#ifdef HAVE_X11_EXTENSIONS_XKB_H - rate_set = xkb_set_keyboard_autorepeat_rate (delay, rate); -#endif -#ifdef HAVE_X11_EXTENSIONS_XF86MISC_H - if (!rate_set) - rate_set = xfree86_set_keyboard_autorepeat_rate (delay, rate); -#endif - if (!rate_set) - g_warning ("Neither XKeyboard not Xfree86's keyboard extensions are available,\n" - "no way to support keyboard autorepeat rate settings"); - } else { - XAutoRepeatOff (GDK_DISPLAY_XDISPLAY(gdk_display_get_default())); - } - - /* as percentage from 0..100 inclusive */ - if (click_volume < 0) { - click_volume = 0; - } else if (click_volume > 100) { - click_volume = 100; - } - kbdcontrol.key_click_percent = click ? click_volume : 0; - kbdcontrol.bell_percent = bell_volume; - kbdcontrol.bell_pitch = bell_pitch; - kbdcontrol.bell_duration = bell_duration; - XChangeKeyboardControl (GDK_DISPLAY_XDISPLAY(gdk_display_get_default()), - KBKeyClickPercent | KBBellPercent | KBBellPitch | KBBellDuration, - &kbdcontrol); - -#ifdef HAVE_X11_EXTENSIONS_XKB_H - if (manager->priv->have_xkb && rnumlock) { - numlock_set_xkb_state (numlock_get_mateconf_state (client)); - } -#endif /* HAVE_X11_EXTENSIONS_XKB_H */ - - XSync (GDK_DISPLAY_XDISPLAY(gdk_display_get_default()), FALSE); - gdk_error_trap_pop (); -} - -void -msd_keyboard_manager_apply_settings (MsdKeyboardManager *manager) -{ - MateConfClient *client; - - client = mateconf_client_get_default (); - apply_settings (client, 0, NULL, manager); - g_object_unref (client); -} - -static gboolean -start_keyboard_idle_cb (MsdKeyboardManager *manager) -{ - MateConfClient *client; - - mate_settings_profile_start (NULL); - - g_debug ("Starting keyboard manager"); - - manager->priv->have_xkb = 0; - client = mateconf_client_get_default (); - - mateconf_client_add_dir (client, MSD_KEYBOARD_KEY, MATECONF_CLIENT_PRELOAD_RECURSIVE, NULL); - - /* Essential - xkb initialization should happen before */ - msd_keyboard_xkb_set_post_activation_callback ((PostActivationCallback) msd_load_modmap_files, NULL); - msd_keyboard_xkb_init (client, manager); - -#ifdef HAVE_X11_EXTENSIONS_XKB_H - numlock_xkb_init (manager); -#endif /* HAVE_X11_EXTENSIONS_XKB_H */ - - /* apply current settings before we install the callback */ - msd_keyboard_manager_apply_settings (manager); - - manager->priv->notify = mateconf_client_notify_add (client, MSD_KEYBOARD_KEY, - (MateConfClientNotifyFunc) apply_settings, manager, - NULL, NULL); - - g_object_unref (client); - -#ifdef HAVE_X11_EXTENSIONS_XKB_H - numlock_install_xkb_callback (manager); -#endif /* HAVE_X11_EXTENSIONS_XKB_H */ - - mate_settings_profile_end (NULL); - - return FALSE; -} - -gboolean -msd_keyboard_manager_start (MsdKeyboardManager *manager, - GError **error) -{ - mate_settings_profile_start (NULL); - - g_idle_add ((GSourceFunc) start_keyboard_idle_cb, manager); - - mate_settings_profile_end (NULL); - - return TRUE; -} - -void -msd_keyboard_manager_stop (MsdKeyboardManager *manager) -{ - MsdKeyboardManagerPrivate *p = manager->priv; - - g_debug ("Stopping keyboard manager"); - - if (p->notify != 0) { - MateConfClient *client = mateconf_client_get_default (); - mateconf_client_remove_dir (client, MSD_KEYBOARD_KEY, NULL); - mateconf_client_notify_remove (client, p->notify); - g_object_unref (client); - p->notify = 0; - } - -#if HAVE_X11_EXTENSIONS_XKB_H - if (p->have_xkb) { - gdk_window_remove_filter (NULL, - numlock_xkb_callback, - GINT_TO_POINTER (p->xkb_event_base)); - } -#endif /* HAVE_X11_EXTENSIONS_XKB_H */ - - msd_keyboard_xkb_shutdown (); -} - -static void -msd_keyboard_manager_set_property (GObject *object, - guint prop_id, - const GValue *value, - GParamSpec *pspec) -{ - MsdKeyboardManager *self; - - self = MSD_KEYBOARD_MANAGER (object); - - switch (prop_id) { - default: - G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); - break; - } -} - -static void -msd_keyboard_manager_get_property (GObject *object, - guint prop_id, - GValue *value, - GParamSpec *pspec) -{ - MsdKeyboardManager *self; - - self = MSD_KEYBOARD_MANAGER (object); - - switch (prop_id) { - default: - G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); - break; - } -} - -static GObject * -msd_keyboard_manager_constructor (GType type, - guint n_construct_properties, - GObjectConstructParam *construct_properties) -{ - MsdKeyboardManager *keyboard_manager; - MsdKeyboardManagerClass *klass; - - klass = MSD_KEYBOARD_MANAGER_CLASS (g_type_class_peek (MSD_TYPE_KEYBOARD_MANAGER)); - - keyboard_manager = MSD_KEYBOARD_MANAGER (G_OBJECT_CLASS (msd_keyboard_manager_parent_class)->constructor (type, - n_construct_properties, - construct_properties)); - - return G_OBJECT (keyboard_manager); -} - -static void -msd_keyboard_manager_dispose (GObject *object) -{ - MsdKeyboardManager *keyboard_manager; - - keyboard_manager = MSD_KEYBOARD_MANAGER (object); - - G_OBJECT_CLASS (msd_keyboard_manager_parent_class)->dispose (object); -} - -static void -msd_keyboard_manager_class_init (MsdKeyboardManagerClass *klass) -{ - GObjectClass *object_class = G_OBJECT_CLASS (klass); - - object_class->get_property = msd_keyboard_manager_get_property; - object_class->set_property = msd_keyboard_manager_set_property; - object_class->constructor = msd_keyboard_manager_constructor; - object_class->dispose = msd_keyboard_manager_dispose; - object_class->finalize = msd_keyboard_manager_finalize; - - g_type_class_add_private (klass, sizeof (MsdKeyboardManagerPrivate)); -} - -static void -msd_keyboard_manager_init (MsdKeyboardManager *manager) -{ - manager->priv = MSD_KEYBOARD_MANAGER_GET_PRIVATE (manager); -} - -static void -msd_keyboard_manager_finalize (GObject *object) -{ - MsdKeyboardManager *keyboard_manager; - - g_return_if_fail (object != NULL); - g_return_if_fail (MSD_IS_KEYBOARD_MANAGER (object)); - - keyboard_manager = MSD_KEYBOARD_MANAGER (object); - - g_return_if_fail (keyboard_manager->priv != NULL); - - G_OBJECT_CLASS (msd_keyboard_manager_parent_class)->finalize (object); -} - -MsdKeyboardManager * -msd_keyboard_manager_new (void) -{ - if (manager_object != NULL) { - g_object_ref (manager_object); - } else { - manager_object = g_object_new (MSD_TYPE_KEYBOARD_MANAGER, NULL); - g_object_add_weak_pointer (manager_object, - (gpointer *) &manager_object); - } - - return MSD_KEYBOARD_MANAGER (manager_object); -} diff --git a/plugins/keyboard/gsd-keyboard-manager.h b/plugins/keyboard/gsd-keyboard-manager.h deleted file mode 100644 index aa3ae95..0000000 --- a/plugins/keyboard/gsd-keyboard-manager.h +++ /dev/null @@ -1,62 +0,0 @@ -/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 8 -*- - * - * Copyright (C) 2007 William Jon McCann - * - * 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. - * - */ - -#ifndef __MSD_KEYBOARD_MANAGER_H -#define __MSD_KEYBOARD_MANAGER_H - -#include - -#ifdef __cplusplus -extern "C" { -#endif - -#define MSD_TYPE_KEYBOARD_MANAGER (msd_keyboard_manager_get_type ()) -#define MSD_KEYBOARD_MANAGER(o) (G_TYPE_CHECK_INSTANCE_CAST ((o), MSD_TYPE_KEYBOARD_MANAGER, MsdKeyboardManager)) -#define MSD_KEYBOARD_MANAGER_CLASS(k) (G_TYPE_CHECK_CLASS_CAST((k), MSD_TYPE_KEYBOARD_MANAGER, MsdKeyboardManagerClass)) -#define MSD_IS_KEYBOARD_MANAGER(o) (G_TYPE_CHECK_INSTANCE_TYPE ((o), MSD_TYPE_KEYBOARD_MANAGER)) -#define MSD_IS_KEYBOARD_MANAGER_CLASS(k) (G_TYPE_CHECK_CLASS_TYPE ((k), MSD_TYPE_KEYBOARD_MANAGER)) -#define MSD_KEYBOARD_MANAGER_GET_CLASS(o) (G_TYPE_INSTANCE_GET_CLASS ((o), MSD_TYPE_KEYBOARD_MANAGER, MsdKeyboardManagerClass)) - -typedef struct MsdKeyboardManagerPrivate MsdKeyboardManagerPrivate; - -typedef struct -{ - GObject parent; - MsdKeyboardManagerPrivate *priv; -} MsdKeyboardManager; - -typedef struct -{ - GObjectClass parent_class; -} MsdKeyboardManagerClass; - -GType msd_keyboard_manager_get_type (void); - -MsdKeyboardManager * msd_keyboard_manager_new (void); -gboolean msd_keyboard_manager_start (MsdKeyboardManager *manager, - GError **error); -void msd_keyboard_manager_stop (MsdKeyboardManager *manager); -void msd_keyboard_manager_apply_settings (MsdKeyboardManager *manager); - -#ifdef __cplusplus -} -#endif - -#endif /* __MSD_KEYBOARD_MANAGER_H */ diff --git a/plugins/keyboard/gsd-keyboard-plugin.c b/plugins/keyboard/gsd-keyboard-plugin.c deleted file mode 100644 index 5f89ca2..0000000 --- a/plugins/keyboard/gsd-keyboard-plugin.c +++ /dev/null @@ -1,104 +0,0 @@ -/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 8 -*- - * - * Copyright (C) 2007 William Jon McCann - * - * 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, 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 -#include - -#include "mate-settings-plugin.h" -#include "msd-keyboard-plugin.h" -#include "msd-keyboard-manager.h" - -struct MsdKeyboardPluginPrivate { - MsdKeyboardManager *manager; -}; - -#define MSD_KEYBOARD_PLUGIN_GET_PRIVATE(object) (G_TYPE_INSTANCE_GET_PRIVATE ((object), MSD_TYPE_KEYBOARD_PLUGIN, MsdKeyboardPluginPrivate)) - -MATE_SETTINGS_PLUGIN_REGISTER (MsdKeyboardPlugin, msd_keyboard_plugin) - -static void -msd_keyboard_plugin_init (MsdKeyboardPlugin *plugin) -{ - plugin->priv = MSD_KEYBOARD_PLUGIN_GET_PRIVATE (plugin); - - g_debug ("MsdKeyboardPlugin initializing"); - - plugin->priv->manager = msd_keyboard_manager_new (); -} - -static void -msd_keyboard_plugin_finalize (GObject *object) -{ - MsdKeyboardPlugin *plugin; - - g_return_if_fail (object != NULL); - g_return_if_fail (MSD_IS_KEYBOARD_PLUGIN (object)); - - g_debug ("MsdKeyboardPlugin finalizing"); - - plugin = MSD_KEYBOARD_PLUGIN (object); - - g_return_if_fail (plugin->priv != NULL); - - if (plugin->priv->manager != NULL) { - g_object_unref (plugin->priv->manager); - } - - G_OBJECT_CLASS (msd_keyboard_plugin_parent_class)->finalize (object); -} - -static void -impl_activate (MateSettingsPlugin *plugin) -{ - gboolean res; - GError *error; - - g_debug ("Activating keyboard plugin"); - - error = NULL; - res = msd_keyboard_manager_start (MSD_KEYBOARD_PLUGIN (plugin)->priv->manager, &error); - if (! res) { - g_warning ("Unable to start keyboard manager: %s", error->message); - g_error_free (error); - } -} - -static void -impl_deactivate (MateSettingsPlugin *plugin) -{ - g_debug ("Deactivating keyboard plugin"); - msd_keyboard_manager_stop (MSD_KEYBOARD_PLUGIN (plugin)->priv->manager); -} - -static void -msd_keyboard_plugin_class_init (MsdKeyboardPluginClass *klass) -{ - GObjectClass *object_class = G_OBJECT_CLASS (klass); - MateSettingsPluginClass *plugin_class = MATE_SETTINGS_PLUGIN_CLASS (klass); - - object_class->finalize = msd_keyboard_plugin_finalize; - - plugin_class->activate = impl_activate; - plugin_class->deactivate = impl_deactivate; - - g_type_class_add_private (klass, sizeof (MsdKeyboardPluginPrivate)); -} diff --git a/plugins/keyboard/gsd-keyboard-plugin.h b/plugins/keyboard/gsd-keyboard-plugin.h deleted file mode 100644 index 84f2420..0000000 --- a/plugins/keyboard/gsd-keyboard-plugin.h +++ /dev/null @@ -1,63 +0,0 @@ -/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 8 -*- - * - * Copyright (C) 2007 William Jon McCann - * - * 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, 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. - * - */ - -#ifndef __MSD_KEYBOARD_PLUGIN_H__ -#define __MSD_KEYBOARD_PLUGIN_H__ - -#include -#include -#include - -#include "mate-settings-plugin.h" - -#ifdef __cplusplus -extern "C" { -#endif - -#define MSD_TYPE_KEYBOARD_PLUGIN (msd_keyboard_plugin_get_type ()) -#define MSD_KEYBOARD_PLUGIN(o) (G_TYPE_CHECK_INSTANCE_CAST ((o), MSD_TYPE_KEYBOARD_PLUGIN, MsdKeyboardPlugin)) -#define MSD_KEYBOARD_PLUGIN_CLASS(k) (G_TYPE_CHECK_CLASS_CAST((k), MSD_TYPE_KEYBOARD_PLUGIN, MsdKeyboardPluginClass)) -#define MSD_IS_KEYBOARD_PLUGIN(o) (G_TYPE_CHECK_INSTANCE_TYPE ((o), MSD_TYPE_KEYBOARD_PLUGIN)) -#define MSD_IS_KEYBOARD_PLUGIN_CLASS(k) (G_TYPE_CHECK_CLASS_TYPE ((k), MSD_TYPE_KEYBOARD_PLUGIN)) -#define MSD_KEYBOARD_PLUGIN_GET_CLASS(o) (G_TYPE_INSTANCE_GET_CLASS ((o), MSD_TYPE_KEYBOARD_PLUGIN, MsdKeyboardPluginClass)) - -typedef struct MsdKeyboardPluginPrivate MsdKeyboardPluginPrivate; - -typedef struct -{ - MateSettingsPlugin parent; - MsdKeyboardPluginPrivate *priv; -} MsdKeyboardPlugin; - -typedef struct -{ - MateSettingsPluginClass parent_class; -} MsdKeyboardPluginClass; - -GType msd_keyboard_plugin_get_type (void) G_GNUC_CONST; - -/* All the plugins must implement this function */ -G_MODULE_EXPORT GType register_mate_settings_plugin (GTypeModule *module); - -#ifdef __cplusplus -} -#endif - -#endif /* __MSD_KEYBOARD_PLUGIN_H__ */ diff --git a/plugins/keyboard/gsd-keyboard-xkb.c b/plugins/keyboard/gsd-keyboard-xkb.c deleted file mode 100644 index 9042f03..0000000 --- a/plugins/keyboard/gsd-keyboard-xkb.c +++ /dev/null @@ -1,918 +0,0 @@ -/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 8 -*- - * - * Copyright (C) 2001 Udaltsoft - * - * Written by Sergey V. Oudaltsov - * - * 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, 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 -#include - -#include -#include -#include -#include -#include - -#include -#include -#include -#include -#include - -#include "msd-xmodmap.h" -#include "msd-keyboard-xkb.h" -#include "delayed-dialog.h" -#include "mate-settings-profile.h" - -#define GTK_RESPONSE_PRINT 2 - -static MsdKeyboardManager* manager = NULL; - -static XklEngine* xkl_engine; -static XklConfigRegistry* xkl_registry = NULL; - -static MatekbdDesktopConfig current_config; -static MatekbdKeyboardConfig current_kbd_config; - -/* never terminated */ -static MatekbdKeyboardConfig initial_sys_kbd_config; - -static gboolean inited_ok = FALSE; - -static guint notify_desktop = 0; -static guint notify_keyboard = 0; - -static PostActivationCallback pa_callback = NULL; -static void *pa_callback_user_data = NULL; - -static const char KNOWN_FILES_KEY[] = "/desktop/mate/peripherals/keyboard/general/known_file_list"; - -static const char DISABLE_INDICATOR_KEY[] = "/desktop/mate/peripherals/keyboard/general/disable_indicator"; - -static const char DUPLICATE_LEDS_KEY[] = "/desktop/mate/peripherals/keyboard/general/duplicate_leds"; - -static const char* mdm_keyboard_layout = NULL; - -static GtkStatusIcon* icon = NULL; - -static GHashTable* preview_dialogs = NULL; - -static Atom caps_lock; -static Atom num_lock; -static Atom scroll_lock; - -static GtkStatusIcon* indicator_icons[3]; -static const gchar* indicator_on_icon_names[] = { - "kbd-scrolllock-on", - "kbd-numlock-on", - "kbd-capslock-on" -}; - -static const gchar* indicator_off_icon_names[] = { - "kbd-scrolllock-off", - "kbd-numlock-off", - "kbd-capslock-off" -}; - -//#define noMSDKX - -#ifdef MSDKX -static FILE *logfile; - -static void msd_keyboard_log_appender(const char file[], const char function[], int level, const char format[], va_list args) -{ - time_t now = time (NULL); - fprintf (logfile, "[%08ld,%03d,%s:%s/] \t", now, - level, file, function); - vfprintf (logfile, format, args); - fflush (logfile); -} -#endif - -static void -activation_error (void) -{ - char const *vendor = ServerVendor (GDK_DISPLAY_XDISPLAY(gdk_display_get_default())); - int release = VendorRelease (GDK_DISPLAY_XDISPLAY(gdk_display_get_default())); - GtkWidget *dialog; - gboolean badXFree430Release; - - badXFree430Release = (vendor != NULL) - && (0 == strcmp (vendor, "The XFree86 Project, Inc")) - && (release / 100000 == 403); - - /* VNC viewers will not work, do not barrage them with warnings */ - if (NULL != vendor && NULL != strstr (vendor, "VNC")) - return; - - dialog = gtk_message_dialog_new_with_markup (NULL, - 0, - GTK_MESSAGE_ERROR, - GTK_BUTTONS_CLOSE, - _ - ("Error activating XKB configuration.\n" - "It can happen under various circumstances:\n" - " • a bug in libxklavier library\n" - " • a bug in X server (xkbcomp, xmodmap utilities)\n" - " • X server with incompatible libxkbfile implementation\n\n" - "X server version data:\n%s\n%d\n%s\n" - "If you report this situation as a bug, please include:\n" - " • The result of %s\n" - " • The result of %s"), - vendor, - release, - badXFree430Release - ? - _ - ("You are using XFree 4.3.0.\n" - "There are known problems with complex XKB configurations.\n" - "Try using a simpler configuration or using a later version of the XFree software.") - : "", - "xprop -root | grep XKB", - "mateconftool-2 -R /desktop/mate/peripherals/keyboard/kbd"); - g_signal_connect (dialog, "response", - G_CALLBACK (gtk_widget_destroy), NULL); - msd_delayed_show_dialog (dialog); -} - -static void -apply_desktop_settings (void) -{ - MateConfClient *conf_client; - gboolean show_leds; - int i; - if (!inited_ok) - return; - - msd_keyboard_manager_apply_settings (manager); - matekbd_desktop_config_load_from_mateconf (¤t_config); - /* again, probably it would be nice to compare things - before activating them */ - matekbd_desktop_config_activate (¤t_config); - - conf_client = mateconf_client_get_default (); - show_leds = - mateconf_client_get_bool (conf_client, DUPLICATE_LEDS_KEY, NULL); - g_object_unref (conf_client); - for (i = sizeof (indicator_icons) / sizeof (indicator_icons[0]); - --i >= 0;) { - gtk_status_icon_set_visible (indicator_icons[i], - show_leds); - } -} - -static void -popup_menu_launch_capplet () -{ - GError *error = NULL; - - gdk_spawn_command_line_on_screen (gdk_screen_get_default (), - "mate-keyboard-properties", - &error); - - if (error != NULL) { - g_warning - ("Could not execute keyboard properties capplet: [%s]\n", - error->message); - g_error_free (error); - } -} - -static void -show_layout_destroy (GtkWidget * dialog, gint group) -{ - g_hash_table_remove (preview_dialogs, GINT_TO_POINTER (group)); -} - -static void -popup_menu_show_layout () -{ - GtkWidget *dialog; - XklEngine *engine = xkl_engine_get_instance (GDK_DISPLAY_XDISPLAY(gdk_display_get_default())); - XklState *xkl_state = xkl_engine_get_current_state (engine); - gpointer p = g_hash_table_lookup (preview_dialogs, - GINT_TO_POINTER - (xkl_state->group)); - gchar **group_names = matekbd_status_get_group_names (); - - if (xkl_state->group < 0 - || xkl_state->group >= g_strv_length (group_names)) { - return; - } - - if (p != NULL) { - /* existing window */ - gtk_window_present (GTK_WINDOW (p)); - return; - } - - dialog = - matekbd_keyboard_drawing_new_dialog (xkl_state->group, - group_names - [xkl_state->group]); - g_signal_connect (GTK_OBJECT (dialog), "destroy", - G_CALLBACK (show_layout_destroy), - GINT_TO_POINTER (xkl_state->group)); - g_hash_table_insert (preview_dialogs, - GINT_TO_POINTER (xkl_state->group), dialog); -} - -static void -popup_menu_set_group (GtkMenuItem * item, gpointer param) -{ - gint group_number = GPOINTER_TO_INT (param); - XklEngine *engine = matekbd_status_get_xkl_engine (); - XklState st; - Window cur; - - st.group = group_number; - xkl_engine_allow_one_switch_to_secondary_group (engine); - cur = xkl_engine_get_current_window (engine); - if (cur != (Window) NULL) { - xkl_debug (150, "Enforcing the state %d for window %lx\n", - st.group, cur); - xkl_engine_save_state (engine, - xkl_engine_get_current_window - (engine), &st); -/* XSetInputFocus(GDK_DISPLAY_XDISPLAY(gdk_display_get_default()), cur, RevertToNone, CurrentTime );*/ - } else { - xkl_debug (150, - "??? Enforcing the state %d for unknown window\n", - st.group); - /* strange situation - bad things can happen */ - } - xkl_engine_lock_group (engine, st.group); -} - -static void -status_icon_popup_menu_cb (GtkStatusIcon * icon, guint button, guint time) -{ - GtkMenu *popup_menu = GTK_MENU (gtk_menu_new ()); - GtkMenu *groups_menu = GTK_MENU (gtk_menu_new ()); - int i = 0; - gchar **current_name = matekbd_status_get_group_names (); - - GtkWidget *item = gtk_menu_item_new_with_mnemonic (_("_Layouts")); - gtk_widget_show (item); - gtk_menu_shell_append (GTK_MENU_SHELL (popup_menu), item); - gtk_menu_item_set_submenu (GTK_MENU_ITEM (item), - GTK_WIDGET (groups_menu)); - - item = - gtk_menu_item_new_with_mnemonic (_("Keyboard _Preferences")); - gtk_widget_show (item); - g_signal_connect (item, "activate", popup_menu_launch_capplet, - NULL); - gtk_menu_shell_append (GTK_MENU_SHELL (popup_menu), item); - - item = gtk_menu_item_new_with_mnemonic (_("Show _Current Layout")); - gtk_widget_show (item); - g_signal_connect (item, "activate", popup_menu_show_layout, NULL); - gtk_menu_shell_append (GTK_MENU_SHELL (popup_menu), item); - - for (i = 0; *current_name; i++, current_name++) { - gchar *image_file = matekbd_status_get_image_filename (i); - - if (image_file == NULL) { - item = - gtk_menu_item_new_with_label (*current_name); - } else { - GdkPixbuf *pixbuf = - gdk_pixbuf_new_from_file_at_size (image_file, - 24, 24, - NULL); - GtkWidget *img = - gtk_image_new_from_pixbuf (pixbuf); - item = - gtk_image_menu_item_new_with_label - (*current_name); - gtk_widget_show (img); - gtk_image_menu_item_set_image (GTK_IMAGE_MENU_ITEM - (item), img); - gtk_image_menu_item_set_always_show_image - (GTK_IMAGE_MENU_ITEM (item), TRUE); - g_free (image_file); - } - gtk_widget_show (item); - gtk_menu_shell_append (GTK_MENU_SHELL (groups_menu), item); - g_signal_connect (item, "activate", - G_CALLBACK (popup_menu_set_group), - GINT_TO_POINTER (i)); - } - - gtk_menu_popup (popup_menu, NULL, NULL, - gtk_status_icon_position_menu, - (gpointer) icon, button, time); -} - -static void -show_hide_icon () -{ - if (g_slist_length (current_kbd_config.layouts_variants) > 1) { - if (icon == NULL) { - MateConfClient *conf_client = - mateconf_client_get_default (); - gboolean disable = - mateconf_client_get_bool (conf_client, - DISABLE_INDICATOR_KEY, - NULL); - g_object_unref (conf_client); - if (disable) - return; - - xkl_debug (150, "Creating new icon\n"); - icon = matekbd_status_new (); - g_signal_connect (icon, "popup-menu", - G_CALLBACK - (status_icon_popup_menu_cb), - NULL); - - } - } else { - if (icon != NULL) { - xkl_debug (150, "Destroying icon\n"); - g_object_unref (icon); - icon = NULL; - } - } -} - -static gboolean -try_activating_xkb_config_if_new (MatekbdKeyboardConfig * - current_sys_kbd_config) -{ - /* Activate - only if different! */ - if (!matekbd_keyboard_config_equals - (¤t_kbd_config, current_sys_kbd_config)) { - if (matekbd_keyboard_config_activate (¤t_kbd_config)) { - if (pa_callback != NULL) { - (*pa_callback) (pa_callback_user_data); - return TRUE; - } - } else { - return FALSE; - } - } - return TRUE; -} - -static gboolean -filter_xkb_config (void) -{ - XklConfigItem *item; - gchar *lname; - gchar *vname; - GSList *lv; - GSList *filtered; - gboolean any_change = FALSE; - - xkl_debug (100, "Filtering configuration against the registry\n"); - if (!xkl_registry) { - xkl_registry = - xkl_config_registry_get_instance (xkl_engine); - /* load all materials, unconditionally! */ - if (!xkl_config_registry_load (xkl_registry, TRUE)) { - g_object_unref (xkl_registry); - xkl_registry = NULL; - return FALSE; - } - } - lv = current_kbd_config.layouts_variants; - item = xkl_config_item_new (); - while (lv) { - xkl_debug (100, "Checking [%s]\n", lv->data); - if (matekbd_keyboard_config_split_items - (lv->data, &lname, &vname)) { - g_snprintf (item->name, sizeof (item->name), "%s", - lname); - if (!xkl_config_registry_find_layout - (xkl_registry, item)) { - xkl_debug (100, "Bad layout [%s]\n", - lname); - filtered = lv; - lv = lv->next; - g_free (filtered->data); - current_kbd_config.layouts_variants = - g_slist_delete_link - (current_kbd_config.layouts_variants, - filtered); - any_change = TRUE; - continue; - } - if (vname) { - g_snprintf (item->name, - sizeof (item->name), "%s", - vname); - if (!xkl_config_registry_find_variant - (xkl_registry, lname, item)) { - xkl_debug (100, - "Bad variant [%s(%s)]\n", - lname, vname); - filtered = lv; - lv = lv->next; - g_free (filtered->data); - current_kbd_config.layouts_variants - = - g_slist_delete_link - (current_kbd_config.layouts_variants, - filtered); - any_change = TRUE; - continue; - } - } - } - lv = lv->next; - } - g_object_unref (item); - return any_change; -} - -static void -apply_xkb_settings (void) -{ - MateConfClient *conf_client; - MatekbdKeyboardConfig current_sys_kbd_config; - int group_to_activate = -1; - char *mdm_layout; - char *s; - - if (!inited_ok) - return; - - conf_client = mateconf_client_get_default (); - - /* With MDM the user can already set a layout from the login - * screen. Try to keep that setting. - * We clear mdm_keyboard_layout early, so we don't risk - * recursion from mateconf notification. - */ - mdm_layout = g_strdup (mdm_keyboard_layout); - mdm_keyboard_layout = NULL; - - /* mdm's configuration and $MDM_KEYBOARD_LAYOUT separates layout and - * variant with a space, but mateconf uses tabs; so convert to be robust - * with both */ - for (s = mdm_layout; s && *s; ++s) { - if (*s == ' ') { - *s = '\t'; - } - } - - if (mdm_layout != NULL) { - GSList *layouts; - GSList *found_node; - int max_groups; - - max_groups = - MAX (xkl_engine_get_max_num_groups (xkl_engine), 1); - layouts = - mateconf_client_get_list (conf_client, - MATEKBD_KEYBOARD_CONFIG_KEY_LAYOUTS, - MATECONF_VALUE_STRING, NULL); - - /* Use system layouts as a default if we do not have - * user configuration */ - if (layouts == NULL) { - GSList *i; - int len; - - for (i = initial_sys_kbd_config.layouts_variants; - i; i = g_slist_next (i)) { - s = g_strdup (i->data); - - /* chop off empty variants to avoid duplicates */ - len = strlen (s); - if (s[len - 1] == '\t') - s[len - 1] = '\0'; - layouts = g_slist_append (layouts, s); - } - } - - /* Add the layout if it doesn't already exist. XKB limits the - * total number of layouts. If we already have the maximum - * number of layouts configured, we replace the last one. This - * prevents the list from becoming full if the user has a habit - * of selecting many different keyboard layouts in MDM. */ - - found_node = - g_slist_find_custom (layouts, mdm_layout, - (GCompareFunc) g_strcmp0); - - if (!found_node) { - /* Insert at the last valid place, or at the end of - * list, whichever comes first */ - layouts = - g_slist_insert (layouts, g_strdup (mdm_layout), - max_groups - 1); - if (g_slist_length (layouts) > max_groups) { - GSList *last; - GSList *free_layouts; - - last = - g_slist_nth (layouts, max_groups - 1); - free_layouts = last->next; - last->next = NULL; - - g_slist_foreach (free_layouts, - (GFunc) g_free, NULL); - g_slist_free (free_layouts); - } - - mateconf_client_set_list (conf_client, - MATEKBD_KEYBOARD_CONFIG_KEY_LAYOUTS, - MATECONF_VALUE_STRING, layouts, - NULL); - } - - g_slist_foreach (layouts, (GFunc) g_free, NULL); - g_slist_free (layouts); - } - - matekbd_keyboard_config_init (¤t_sys_kbd_config, - conf_client, xkl_engine); - - matekbd_keyboard_config_load_from_mateconf (¤t_kbd_config, - &initial_sys_kbd_config); - - matekbd_keyboard_config_load_from_x_current (¤t_sys_kbd_config, - NULL); - - if (!try_activating_xkb_config_if_new (¤t_sys_kbd_config)) { - if (filter_xkb_config ()) { - if (!try_activating_xkb_config_if_new - (¤t_sys_kbd_config)) { - g_warning - ("Could not activate the filtered XKB configuration"); - activation_error (); - } - } else { - g_warning - ("Could not activate the XKB configuration"); - activation_error (); - } - } else - xkl_debug (100, - "Actual KBD configuration was not changed: redundant notification\n"); - - if (mdm_layout != NULL) { - /* If there are multiple layouts, - * try to find the one closest to the mdm layout - */ - GSList *l; - int i; - size_t len = strlen (mdm_layout); - for (i = 0, l = current_kbd_config.layouts_variants; l; - i++, l = l->next) { - char *lv = l->data; - if (strncmp (lv, mdm_layout, len) == 0 - && (lv[len] == '\0' || lv[len] == '\t')) { - group_to_activate = i; - break; - } - } - } - - g_free (mdm_layout); - - if (group_to_activate != -1) - xkl_engine_lock_group (current_config.engine, - group_to_activate); - matekbd_keyboard_config_term (¤t_sys_kbd_config); - show_hide_icon (); -} - -static void -msd_keyboard_xkb_analyze_sysconfig (void) -{ - MateConfClient *conf_client; - - if (!inited_ok) - return; - - conf_client = mateconf_client_get_default (); - matekbd_keyboard_config_init (&initial_sys_kbd_config, - conf_client, xkl_engine); - matekbd_keyboard_config_load_from_x_initial (&initial_sys_kbd_config, - NULL); - g_object_unref (conf_client); -} - -static gboolean -msd_chk_file_list (void) -{ - GDir *home_dir; - const char *fname; - GSList *file_list = NULL; - GSList *last_login_file_list = NULL; - GSList *tmp = NULL; - GSList *tmp_l = NULL; - gboolean new_file_exist = FALSE; - MateConfClient *conf_client; - - home_dir = g_dir_open (g_get_home_dir (), 0, NULL); - while ((fname = g_dir_read_name (home_dir)) != NULL) { - if (g_strrstr (fname, "modmap")) { - file_list = - g_slist_append (file_list, g_strdup (fname)); - } - } - g_dir_close (home_dir); - - conf_client = mateconf_client_get_default (); - - last_login_file_list = mateconf_client_get_list (conf_client, - KNOWN_FILES_KEY, - MATECONF_VALUE_STRING, - NULL); - - /* Compare between the two file list, currently available modmap files - and the files available in the last log in */ - tmp = file_list; - while (tmp != NULL) { - tmp_l = last_login_file_list; - new_file_exist = TRUE; - while (tmp_l != NULL) { - if (strcmp (tmp->data, tmp_l->data) == 0) { - new_file_exist = FALSE; - break; - } else { - tmp_l = tmp_l->next; - } - } - if (new_file_exist) { - break; - } else { - tmp = tmp->next; - } - } - - if (new_file_exist) { - mateconf_client_set_list (conf_client, - KNOWN_FILES_KEY, - MATECONF_VALUE_STRING, - file_list, NULL); - } - - g_object_unref (conf_client); - - g_slist_foreach (file_list, (GFunc) g_free, NULL); - g_slist_free (file_list); - - g_slist_foreach (last_login_file_list, (GFunc) g_free, NULL); - g_slist_free (last_login_file_list); - - return new_file_exist; - -} - -static void -msd_keyboard_xkb_chk_lcl_xmm (void) -{ - if (msd_chk_file_list ()) { - msd_modmap_dialog_call (); - } - msd_load_modmap_files (); -} - -void -msd_keyboard_xkb_set_post_activation_callback (PostActivationCallback fun, - void *user_data) -{ - pa_callback = fun; - pa_callback_user_data = user_data; -} - -static GdkFilterReturn -msd_keyboard_xkb_evt_filter (GdkXEvent * xev, GdkEvent * event) -{ - XEvent *xevent = (XEvent *) xev; - xkl_engine_filter_events (xkl_engine, xevent); - return GDK_FILTER_CONTINUE; -} - -static guint -register_config_callback (MateConfClient * client, - const char *path, MateConfClientNotifyFunc func) -{ - mateconf_client_add_dir (client, path, MATECONF_CLIENT_PRELOAD_ONELEVEL, - NULL); - return mateconf_client_notify_add (client, path, func, NULL, NULL, - NULL); -} - -/* When new Keyboard is plugged in - reload the settings */ -static void -msd_keyboard_new_device (XklEngine * engine) -{ - apply_desktop_settings (); - apply_xkb_settings (); -} - -static void -msd_keyboard_update_indicator_icons () -{ - Bool state; - int new_state, i; - Display *display = GDK_DISPLAY_XDISPLAY(gdk_display_get_default()); - XkbGetNamedIndicator (display, caps_lock, NULL, &state, - NULL, NULL); - new_state = state ? 1 : 0; - XkbGetNamedIndicator (display, num_lock, NULL, &state, NULL, NULL); - new_state <<= 1; - new_state |= (state ? 1 : 0); - XkbGetNamedIndicator (display, scroll_lock, NULL, &state, - NULL, NULL); - new_state <<= 1; - new_state |= (state ? 1 : 0); - xkl_debug (160, "Indicators state: %d\n", new_state); - - - for (i = sizeof (indicator_icons) / sizeof (indicator_icons[0]); - --i >= 0;) { - gtk_status_icon_set_from_icon_name (indicator_icons[i], - (new_state & (1 << i)) - ? - indicator_on_icon_names - [i] : - indicator_off_icon_names - [i]); - } -} - -static void -msd_keyboard_state_changed (XklEngine * engine, XklEngineStateChange type, - gint new_group, gboolean restore) -{ - xkl_debug (160, - "State changed: type %d, new group: %d, restore: %d.\n", - type, new_group, restore); - if (type == INDICATORS_CHANGED) { - msd_keyboard_update_indicator_icons (); - } -} - -void -msd_keyboard_xkb_init (MateConfClient * client, - MsdKeyboardManager * kbd_manager) -{ - int i; - Display *display = GDK_DISPLAY_XDISPLAY(gdk_display_get_default()); - mate_settings_profile_start (NULL); - - gtk_icon_theme_append_search_path (gtk_icon_theme_get_default (), - DATADIR G_DIR_SEPARATOR_S - "icons"); - - caps_lock = XInternAtom (display, "Caps Lock", False); - num_lock = XInternAtom (display, "Num Lock", False); - scroll_lock = XInternAtom (display, "Scroll Lock", False); - - for (i = sizeof (indicator_icons) / sizeof (indicator_icons[0]); - --i >= 0;) { - indicator_icons[i] = - gtk_status_icon_new_from_icon_name - (indicator_off_icon_names[i]); - } - - msd_keyboard_update_indicator_icons (); - -#ifdef MSDKX - xkl_set_debug_level (200); - logfile = fopen ("/tmp/msdkx.log", "a"); - xkl_set_log_appender (msd_keyboard_log_appender); -#endif - manager = kbd_manager; - mate_settings_profile_start ("xkl_engine_get_instance"); - xkl_engine = xkl_engine_get_instance (display); - mate_settings_profile_end ("xkl_engine_get_instance"); - if (xkl_engine) { - inited_ok = TRUE; - - mdm_keyboard_layout = g_getenv ("MDM_KEYBOARD_LAYOUT"); - - matekbd_desktop_config_init (¤t_config, - client, xkl_engine); - matekbd_keyboard_config_init (¤t_kbd_config, - client, xkl_engine); - xkl_engine_backup_names_prop (xkl_engine); - msd_keyboard_xkb_analyze_sysconfig (); - mate_settings_profile_start - ("msd_keyboard_xkb_chk_lcl_xmm"); - msd_keyboard_xkb_chk_lcl_xmm (); - mate_settings_profile_end - ("msd_keyboard_xkb_chk_lcl_xmm"); - - notify_desktop = - register_config_callback (client, - MATEKBD_DESKTOP_CONFIG_DIR, - (MateConfClientNotifyFunc) - apply_desktop_settings); - - notify_keyboard = - register_config_callback (client, - MATEKBD_KEYBOARD_CONFIG_DIR, - (MateConfClientNotifyFunc) - apply_xkb_settings); - - gdk_window_add_filter (NULL, (GdkFilterFunc) - msd_keyboard_xkb_evt_filter, NULL); - - if (xkl_engine_get_features (xkl_engine) & - XKLF_DEVICE_DISCOVERY) - g_signal_connect (xkl_engine, "X-new-device", - G_CALLBACK - (msd_keyboard_new_device), NULL); - g_signal_connect (xkl_engine, "X-state-changed", - G_CALLBACK - (msd_keyboard_state_changed), NULL); - - mate_settings_profile_start ("xkl_engine_start_listen"); - xkl_engine_start_listen (xkl_engine, - XKLL_MANAGE_LAYOUTS | - XKLL_MANAGE_WINDOW_STATES); - mate_settings_profile_end ("xkl_engine_start_listen"); - - mate_settings_profile_start ("apply_desktop_settings"); - apply_desktop_settings (); - mate_settings_profile_end ("apply_desktop_settings"); - mate_settings_profile_start ("apply_xkb_settings"); - apply_xkb_settings (); - mate_settings_profile_end ("apply_xkb_settings"); - } - preview_dialogs = g_hash_table_new (g_direct_hash, g_direct_equal); - - mate_settings_profile_end (NULL); -} - -void -msd_keyboard_xkb_shutdown (void) -{ - MateConfClient *client; - int i; - - pa_callback = NULL; - pa_callback_user_data = NULL; - manager = NULL; - - for (i = sizeof (indicator_icons) / sizeof (indicator_icons[0]); - --i >= 0;) { - g_object_unref (G_OBJECT (indicator_icons[i])); - indicator_icons[i] = NULL; - } - - g_hash_table_destroy (preview_dialogs); - - if (!inited_ok) - return; - - xkl_engine_stop_listen (xkl_engine, - XKLL_MANAGE_LAYOUTS | - XKLL_MANAGE_WINDOW_STATES); - - gdk_window_remove_filter (NULL, (GdkFilterFunc) - msd_keyboard_xkb_evt_filter, NULL); - - client = mateconf_client_get_default (); - - if (notify_desktop != 0) { - mateconf_client_remove_dir (client, MATEKBD_DESKTOP_CONFIG_DIR, - NULL); - mateconf_client_notify_remove (client, notify_desktop); - notify_desktop = 0; - } - - if (notify_keyboard != 0) { - mateconf_client_remove_dir (client, MATEKBD_KEYBOARD_CONFIG_DIR, - NULL); - mateconf_client_notify_remove (client, notify_keyboard); - notify_keyboard = 0; - } - - if (xkl_registry) { - g_object_unref (xkl_registry); - } - - g_object_unref (client); - g_object_unref (xkl_engine); - - xkl_engine = NULL; - inited_ok = FALSE; -} diff --git a/plugins/keyboard/gsd-keyboard-xkb.h b/plugins/keyboard/gsd-keyboard-xkb.h deleted file mode 100644 index 7d2d558..0000000 --- a/plugins/keyboard/gsd-keyboard-xkb.h +++ /dev/null @@ -1,40 +0,0 @@ -/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 8 -*- - * mate-settings-keyboard-xkb.h - * - * Copyright (C) 2001 Udaltsoft - * - * Written by Sergey V. Oudaltsov - * - * 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, 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. - */ - -#ifndef __MSD_KEYBOARD_XKB_H -#define __MSD_KEYBOARD_XKB_H - -#include -#include - -#include -#include "msd-keyboard-manager.h" - -void msd_keyboard_xkb_init(MateConfClient* client, MsdKeyboardManager* manager); -void msd_keyboard_xkb_shutdown(void); - -typedef void (*PostActivationCallback) (void* userData); - -void msd_keyboard_xkb_set_post_activation_callback(PostActivationCallback fun, void* userData); - -#endif diff --git a/plugins/keyboard/gsd-xmodmap.c b/plugins/keyboard/gsd-xmodmap.c deleted file mode 100644 index 5baf37c..0000000 --- a/plugins/keyboard/gsd-xmodmap.c +++ /dev/null @@ -1,399 +0,0 @@ -/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 8 -*- - * - * Copyright © 2005 Novell Inc. - * - * Written by Shakti Sen - * - * 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, 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 - -#include -#include -#include - -#include "msd-xmodmap.h" - -static const char DISABLE_XMM_WARNING_KEY[] = - "/desktop/mate/peripherals/keyboard/disable_xmm_and_xkb_warning"; - -static const char LOADED_FILES_KEY[] = - "/desktop/mate/peripherals/keyboard/general/update_handlers"; - - -static void -check_button_callback (GtkWidget *chk_button, - gpointer data) -{ - MateConfClient *client; - - client = mateconf_client_get_default (); - - mateconf_client_set_bool (client, - DISABLE_XMM_WARNING_KEY, - gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (chk_button)), - NULL); - - g_object_unref (client); -} - -void -msd_load_modmap_files (void) -{ - MateConfClient *client; - GSList *tmp; - GSList *loaded_file_list; - - client = mateconf_client_get_default (); - - loaded_file_list = mateconf_client_get_list (client, LOADED_FILES_KEY, MATECONF_VALUE_STRING, NULL); - - for (tmp = loaded_file_list; tmp != NULL; tmp = tmp->next) { - gchar *file; - gchar *command; - - file = g_build_filename (g_get_home_dir (), (gchar *) tmp->data, NULL); - command = g_strconcat ("xmodmap ", file, NULL); - g_free (file); - - g_spawn_command_line_async (command, NULL); - - g_free (command); - g_free (tmp->data); - } - - g_slist_free (loaded_file_list); - g_object_unref (client); -} - -static void -response_callback (GtkWidget *dialog, - int id, - void *data) -{ - if (id == GTK_RESPONSE_OK) { - GtkWidget *chk_button = g_object_get_data (G_OBJECT (dialog), "check_button"); - check_button_callback (chk_button, NULL); - msd_load_modmap_files (); - } - gtk_widget_destroy (dialog); -} - -static void -get_selected_files_func (GtkTreeModel *model, - GtkTreePath *path, - GtkTreeIter *iter, - gpointer data) -{ - GSList **list = data; - gchar *filename; - - filename = NULL; - gtk_tree_model_get (model, - iter, - 0, - &filename, - -1); - - *list = g_slist_prepend (*list, filename); -} - -static GSList* -remove_string_from_list (GSList *list, - const char *str) -{ - GSList *tmp; - - for (tmp = list; tmp != NULL; tmp = tmp->next) { - if (strcmp (tmp->data, str) == 0) { - g_free (tmp->data); - list = g_slist_delete_link (list, tmp); - break; - } - } - - return list; -} - - -static void -remove_button_clicked_callback (GtkWidget *button, - void *data) -{ - GtkWidget *dialog; - GtkListStore *tree = NULL; - GtkTreeSelection *selection; - GtkWidget *treeview; - MateConfClient *client; - GSList *filenames = NULL; - GSList *tmp = NULL; - GSList *loaded_files = NULL; - - dialog = data; - - treeview = g_object_get_data (G_OBJECT (dialog), "treeview1"); - - selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (treeview)); - gtk_tree_selection_selected_foreach (selection, - get_selected_files_func, - &filenames); - - if (!filenames) - return; - - /* Remove the selected file */ - - client = mateconf_client_get_default (); - - loaded_files = mateconf_client_get_list (client, - LOADED_FILES_KEY, - MATECONF_VALUE_STRING, - NULL); - loaded_files = remove_string_from_list (loaded_files, (char *)filenames->data); - - mateconf_client_set_list (client, - LOADED_FILES_KEY, - MATECONF_VALUE_STRING, - loaded_files, - NULL); - g_object_unref (client); - - tree = g_object_get_data (G_OBJECT (dialog), "tree"); - - gtk_list_store_clear (tree); - for (tmp = loaded_files; tmp != NULL; tmp = tmp->next) { - GtkTreeIter iter; - gtk_list_store_append (tree, &iter); - gtk_list_store_set (tree, &iter, - 0, - tmp->data, - -1); - } - - g_slist_foreach (loaded_files, (GFunc) g_free, NULL); - g_slist_free (loaded_files); -} - -static void -load_button_clicked_callback (GtkWidget *button, - void *data) -{ - GtkWidget *dialog; - GtkListStore *tree = NULL; - GtkTreeSelection *selection; - GtkWidget *treeview; - GSList *filenames = NULL; - GSList *tmp = NULL; - GSList *loaded_files = NULL; - MateConfClient *client; - - dialog = data; - - treeview = g_object_get_data (G_OBJECT (dialog), - "loaded-treeview"); - selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (treeview)); - gtk_tree_selection_selected_foreach (selection, - get_selected_files_func, - &filenames); - - if (!filenames) - return; - - /* Add the files to left-tree-view */ - client = mateconf_client_get_default (); - - loaded_files = mateconf_client_get_list (client, - LOADED_FILES_KEY, - MATECONF_VALUE_STRING, - NULL); - - if (g_slist_find_custom (loaded_files, filenames->data, (GCompareFunc) strcmp)) { - g_free (filenames->data); - g_slist_free (filenames); - goto out; - } - - loaded_files = g_slist_append (loaded_files, filenames->data); - mateconf_client_set_list (client, - LOADED_FILES_KEY, - MATECONF_VALUE_STRING, - loaded_files, - NULL); - - - tree = g_object_get_data (G_OBJECT (dialog), "tree"); - - gtk_list_store_clear (tree); - for (tmp = loaded_files; tmp != NULL; tmp = tmp->next) { - GtkTreeIter iter; - gtk_list_store_append (tree, &iter); - gtk_list_store_set (tree, &iter, - 0, - tmp->data, - -1); - } - -out: - g_object_unref (client); - g_slist_foreach (loaded_files, (GFunc) g_free, NULL); - g_slist_free (loaded_files); -} - -void -msd_modmap_dialog_call (void) -{ - GtkBuilder *builder; - guint res; - GError *error; - GtkWidget *load_dialog; - GtkListStore *tree; - GtkCellRenderer *cell_renderer; - GtkTreeIter parent_iter; - GtkTreeIter iter; - GtkTreeModel *sort_model; - GtkTreeSelection *selection; - GtkWidget *treeview; - GtkWidget *treeview1; - GtkTreeViewColumn *column; - GtkWidget *add_button; - GtkWidget *remove_button; - GtkWidget *chk_button; - GSList *tmp; - GDir *homeDir; - GSList *loaded_files; - const char *fname; - MateConfClient *client; - - homeDir = g_dir_open (g_get_home_dir (), 0, NULL); - if (homeDir == NULL) - return; - - error = NULL; - builder = gtk_builder_new (); - res = gtk_builder_add_from_file (builder, - DATADIR "/modmap-dialog.ui", - &error); - - if (res == 0) { - g_warning ("Could not load UI file: %s", error->message); - g_error_free (error); - g_object_unref (builder); - g_dir_close (homeDir); - return; - } - - load_dialog = GTK_WIDGET (gtk_builder_get_object (builder, "dialog1")); - gtk_window_set_modal (GTK_WINDOW (load_dialog), TRUE); - g_signal_connect (load_dialog, - "response", - G_CALLBACK (response_callback), - builder); - add_button = GTK_WIDGET (gtk_builder_get_object (builder, "button7")); - g_signal_connect (add_button, - "clicked", - G_CALLBACK (load_button_clicked_callback), - load_dialog); - remove_button = GTK_WIDGET (gtk_builder_get_object (builder, - "button6")); - g_signal_connect (remove_button, - "clicked", - G_CALLBACK (remove_button_clicked_callback), - load_dialog); - chk_button = GTK_WIDGET (gtk_builder_get_object (builder, - "checkbutton1")); - g_signal_connect (chk_button, - "toggled", - G_CALLBACK (check_button_callback), - NULL); - g_object_set_data (G_OBJECT (load_dialog), "check_button", chk_button); - treeview = GTK_WIDGET (gtk_builder_get_object (builder, "treeview1")); - g_object_set_data (G_OBJECT (load_dialog), "treeview1", treeview); - treeview = GTK_WIDGET (gtk_builder_get_object (builder, "treeview2")); - g_object_set_data (G_OBJECT (load_dialog), "loaded-treeview", treeview); - tree = gtk_list_store_new (1, G_TYPE_STRING); - cell_renderer = gtk_cell_renderer_text_new (); - column = gtk_tree_view_column_new_with_attributes ("modmap", - cell_renderer, - "text", 0, - NULL); - gtk_tree_view_append_column (GTK_TREE_VIEW (treeview), column); - gtk_tree_view_column_set_sort_column_id (column, 0); - - /* Add the data */ - while ((fname = g_dir_read_name (homeDir)) != NULL) { - if (g_strrstr (fname, "modmap")) { - gtk_list_store_append (tree, &parent_iter); - gtk_list_store_set (tree, &parent_iter, - 0, - fname, - -1); - } - } - sort_model = gtk_tree_model_sort_new_with_model (GTK_TREE_MODEL (tree)); - gtk_tree_sortable_set_sort_column_id (GTK_TREE_SORTABLE (sort_model), - 0, - GTK_SORT_ASCENDING); - gtk_tree_view_set_model (GTK_TREE_VIEW (treeview), sort_model); - g_object_unref (G_OBJECT (tree)); - selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (treeview)); - gtk_tree_selection_set_mode (GTK_TREE_SELECTION (selection), - GTK_SELECTION_MULTIPLE); - gtk_widget_show (load_dialog); - - g_dir_close (homeDir); - - /* Left treeview */ - treeview1 = GTK_WIDGET (gtk_builder_get_object (builder, "treeview1")); - tree = gtk_list_store_new (1, G_TYPE_STRING); - cell_renderer = gtk_cell_renderer_text_new (); - column = gtk_tree_view_column_new_with_attributes ("modmap", - cell_renderer, - "text", 0, - NULL); - gtk_tree_view_append_column (GTK_TREE_VIEW (treeview1), column); - gtk_tree_view_column_set_sort_column_id (column, 0); - - client = mateconf_client_get_default (); - loaded_files = mateconf_client_get_list (client, LOADED_FILES_KEY, MATECONF_VALUE_STRING, NULL); - g_object_unref (client); - - /* Add the data */ - for (tmp = loaded_files; tmp != NULL; tmp = tmp->next) { - gtk_list_store_append (tree, &iter); - gtk_list_store_set (tree, &iter, - 0, - tmp->data, - -1); - } - - g_slist_foreach (loaded_files, (GFunc) g_free, NULL); - g_slist_free (loaded_files); - - sort_model = gtk_tree_model_sort_new_with_model (GTK_TREE_MODEL (tree)); - gtk_tree_sortable_set_sort_column_id (GTK_TREE_SORTABLE (sort_model), - 0, - GTK_SORT_ASCENDING); - gtk_tree_view_set_model (GTK_TREE_VIEW (treeview1), sort_model); - g_object_unref (G_OBJECT (tree)); - selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (treeview1)); - gtk_tree_selection_set_mode (GTK_TREE_SELECTION (selection), - GTK_SELECTION_MULTIPLE); - g_object_set_data (G_OBJECT (load_dialog), "tree", tree); - g_object_unref (builder); -} diff --git a/plugins/keyboard/gsd-xmodmap.h b/plugins/keyboard/gsd-xmodmap.h deleted file mode 100644 index 04b4505..0000000 --- a/plugins/keyboard/gsd-xmodmap.h +++ /dev/null @@ -1,29 +0,0 @@ -/* mate-settings-xmodmap.h - * - * Copyright © 2005 Novell Inc. - * - * Written by Shakti Sen - * - * 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, 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. - */ - -#ifndef XMODMAP_H -#define XMODMAP_H - -void msd_load_modmap_files (void); -void msd_modmap_dialog_call (void); - -#endif diff --git a/plugins/keyboard/msd-keyboard-manager.c b/plugins/keyboard/msd-keyboard-manager.c new file mode 100644 index 0000000..0969459 --- /dev/null +++ b/plugins/keyboard/msd-keyboard-manager.c @@ -0,0 +1,569 @@ +/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 8 -*- + * + * Copyright © 2001 Ximian, Inc. + * Copyright (C) 2007 William Jon McCann + * + * 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 +#include +#include +#include +#include +#include +#include + +#include + +#include +#include +#include +#include +#include + +#ifdef HAVE_X11_EXTENSIONS_XF86MISC_H + #include +#endif + +#ifdef HAVE_X11_EXTENSIONS_XKB_H + #include + #include +#endif + +#include "mate-settings-profile.h" +#include "msd-keyboard-manager.h" + +#include "msd-keyboard-xkb.h" +#include "msd-xmodmap.h" + +#define MSD_KEYBOARD_MANAGER_GET_PRIVATE(o) \ + (G_TYPE_INSTANCE_GET_PRIVATE((o), MSD_TYPE_KEYBOARD_MANAGER, MsdKeyboardManagerPrivate)) + +#ifndef HOST_NAME_MAX + #define HOST_NAME_MAX 255 +#endif + +#define MSD_KEYBOARD_KEY "/desktop/mate/peripherals/keyboard" + +#define KEY_REPEAT MSD_KEYBOARD_KEY "/repeat" +#define KEY_CLICK MSD_KEYBOARD_KEY "/click" +#define KEY_RATE MSD_KEYBOARD_KEY "/rate" +#define KEY_DELAY MSD_KEYBOARD_KEY "/delay" +#define KEY_CLICK_VOLUME MSD_KEYBOARD_KEY "/click_volume" + +#define KEY_BELL_VOLUME MSD_KEYBOARD_KEY "/bell_volume" +#define KEY_BELL_PITCH MSD_KEYBOARD_KEY "/bell_pitch" +#define KEY_BELL_DURATION MSD_KEYBOARD_KEY "/bell_duration" +#define KEY_BELL_MODE MSD_KEYBOARD_KEY "/bell_mode" + +struct MsdKeyboardManagerPrivate { + gboolean have_xkb; + gint xkb_event_base; + guint notify; +}; + +static void msd_keyboard_manager_class_init (MsdKeyboardManagerClass* klass); +static void msd_keyboard_manager_init (MsdKeyboardManager* keyboard_manager); +static void msd_keyboard_manager_finalize (GObject* object); + +G_DEFINE_TYPE (MsdKeyboardManager, msd_keyboard_manager, G_TYPE_OBJECT) + +static gpointer manager_object = NULL; + + +#ifdef HAVE_X11_EXTENSIONS_XF86MISC_H +static gboolean xfree86_set_keyboard_autorepeat_rate(int delay, int rate) +{ + gboolean res = FALSE; + int event_base_return; + int error_base_return; + + if (XF86MiscQueryExtension (GDK_DISPLAY_XDISPLAY(gdk_display_get_default()), + &event_base_return, + &error_base_return) == True) { + /* load the current settings */ + XF86MiscKbdSettings kbdsettings; + XF86MiscGetKbdSettings (GDK_DISPLAY_XDISPLAY(gdk_display_get_default()), &kbdsettings); + + /* assign the new values */ + kbdsettings.delay = delay; + kbdsettings.rate = rate; + XF86MiscSetKbdSettings (GDK_DISPLAY_XDISPLAY(gdk_display_get_default()), &kbdsettings); + res = TRUE; + } + + return res; +} +#endif /* HAVE_X11_EXTENSIONS_XF86MISC_H */ + +#ifdef HAVE_X11_EXTENSIONS_XKB_H +static gboolean xkb_set_keyboard_autorepeat_rate(int delay, int rate) +{ + int interval = (rate <= 0) ? 1000000 : 1000/rate; + + if (delay <= 0) + { + delay = 1; + } + + return XkbSetAutoRepeatRate(GDK_DISPLAY_XDISPLAY(gdk_display_get_default()), XkbUseCoreKbd, delay, interval); +} +#endif + +static char* msd_keyboard_get_hostname_key (const char *subkey) +{ + char hostname[HOST_NAME_MAX + 1]; + + if (gethostname (hostname, sizeof (hostname)) == 0 && + strcmp (hostname, "localhost") != 0 && + strcmp (hostname, "localhost.localdomain") != 0) { + char *escaped; + char *key; + + escaped = mateconf_escape_key (hostname, -1); + key = g_strconcat (MSD_KEYBOARD_KEY + "/host-", + escaped, + "/0/", + subkey, + NULL); + g_free (escaped); + return key; + } else + return NULL; +} + +#ifdef HAVE_X11_EXTENSIONS_XKB_H + +typedef enum { + NUMLOCK_STATE_OFF = 0, + NUMLOCK_STATE_ON = 1, + NUMLOCK_STATE_UNKNOWN = 2 +} NumLockState; + +static void +numlock_xkb_init (MsdKeyboardManager *manager) +{ + Display *dpy = GDK_DISPLAY_XDISPLAY (gdk_display_get_default ()); + gboolean have_xkb; + int opcode, error_base, major, minor; + + have_xkb = XkbQueryExtension (dpy, + &opcode, + &manager->priv->xkb_event_base, + &error_base, + &major, + &minor) + && XkbUseExtension (dpy, &major, &minor); + + if (have_xkb) { + XkbSelectEventDetails (dpy, + XkbUseCoreKbd, + XkbStateNotifyMask, + XkbModifierLockMask, + XkbModifierLockMask); + } else { + g_warning ("XKB extension not available"); + } + + manager->priv->have_xkb = have_xkb; +} + +static unsigned +numlock_NumLock_modifier_mask (void) +{ + Display *dpy = GDK_DISPLAY_XDISPLAY (gdk_display_get_default ()); + return XkbKeysymToModifiers (dpy, XK_Num_Lock); +} + +static void +numlock_set_xkb_state (NumLockState new_state) +{ + unsigned int num_mask; + Display *dpy = GDK_DISPLAY_XDISPLAY (gdk_display_get_default ()); + if (new_state != NUMLOCK_STATE_ON && new_state != NUMLOCK_STATE_OFF) + return; + num_mask = numlock_NumLock_modifier_mask (); + XkbLockModifiers (dpy, XkbUseCoreKbd, num_mask, new_state ? num_mask : 0); +} + +static char * +numlock_mateconf_state_key (void) +{ + char *key = msd_keyboard_get_hostname_key ("numlock_on"); + if (!key) { + g_message ("NumLock remembering disabled because hostname is set to \"localhost\""); + } + return key; +} + +static NumLockState +numlock_get_mateconf_state (MateConfClient *client) +{ + int curr_state; + GError *err = NULL; + char *key = numlock_mateconf_state_key (); + + if (!key) { + return NUMLOCK_STATE_UNKNOWN; + } + + curr_state = mateconf_client_get_bool (client, key, &err); + if (err) { + curr_state = NUMLOCK_STATE_UNKNOWN; + g_error_free (err); + } + + g_free (key); + return curr_state; +} + +static void numlock_set_mateconf_state(MateConfClient *client, NumLockState new_state) +{ + //printf("numlock_set_mateconf_state\n"); + char* key; + + if (new_state != NUMLOCK_STATE_ON && new_state != NUMLOCK_STATE_OFF) { + return; + } + + key = numlock_mateconf_state_key (); + + if (key) { + mateconf_client_set_bool (client, 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); + MateConfClient *client = mateconf_client_get_default (); + numlock_set_mateconf_state (client, numlock_state); + g_object_unref (client); + } + } + return GDK_FILTER_CONTINUE; +} + +static void +numlock_install_xkb_callback (MsdKeyboardManager *manager) +{ + if (!manager->priv->have_xkb) + return; + + gdk_window_add_filter (NULL, + numlock_xkb_callback, + GINT_TO_POINTER (manager->priv->xkb_event_base)); +} + +#endif /* HAVE_X11_EXTENSIONS_XKB_H */ + +static void +apply_settings (MateConfClient *client, + guint cnxn_id, + MateConfEntry *entry, + MsdKeyboardManager *manager) +{ + XKeyboardControl kbdcontrol; + gboolean repeat; + gboolean click; + int rate; + int delay; + int click_volume; + int bell_volume; + int bell_pitch; + int bell_duration; + char *volume_string; +#ifdef HAVE_X11_EXTENSIONS_XKB_H + gboolean rnumlock; +#endif /* HAVE_X11_EXTENSIONS_XKB_H */ + + repeat = mateconf_client_get_bool (client, KEY_REPEAT, NULL); + click = mateconf_client_get_bool (client, KEY_CLICK, NULL); + rate = mateconf_client_get_int (client, KEY_RATE, NULL); + delay = mateconf_client_get_int (client, KEY_DELAY, NULL); + click_volume = mateconf_client_get_int (client, KEY_CLICK_VOLUME, NULL); +#if 0 + bell_volume = mateconf_client_get_int (client, KEY_BELL_VOLUME, NULL); +#endif + bell_pitch = mateconf_client_get_int (client, KEY_BELL_PITCH, NULL); + bell_duration = mateconf_client_get_int (client, KEY_BELL_DURATION, NULL); + + volume_string = mateconf_client_get_string (client, KEY_BELL_MODE, NULL); + bell_volume = (volume_string && !strcmp (volume_string, "on")) ? 50 : 0; + g_free (volume_string); + +#ifdef HAVE_X11_EXTENSIONS_XKB_H + rnumlock = mateconf_client_get_bool (client, MSD_KEYBOARD_KEY "/remember_numlock_state", NULL); +#endif /* HAVE_X11_EXTENSIONS_XKB_H */ + + gdk_error_trap_push (); + if (repeat) { + gboolean rate_set = FALSE; + + XAutoRepeatOn (GDK_DISPLAY_XDISPLAY(gdk_display_get_default())); + /* Use XKB in preference */ +#ifdef HAVE_X11_EXTENSIONS_XKB_H + rate_set = xkb_set_keyboard_autorepeat_rate (delay, rate); +#endif +#ifdef HAVE_X11_EXTENSIONS_XF86MISC_H + if (!rate_set) + rate_set = xfree86_set_keyboard_autorepeat_rate (delay, rate); +#endif + if (!rate_set) + g_warning ("Neither XKeyboard not Xfree86's keyboard extensions are available,\n" + "no way to support keyboard autorepeat rate settings"); + } else { + XAutoRepeatOff (GDK_DISPLAY_XDISPLAY(gdk_display_get_default())); + } + + /* as percentage from 0..100 inclusive */ + if (click_volume < 0) { + click_volume = 0; + } else if (click_volume > 100) { + click_volume = 100; + } + kbdcontrol.key_click_percent = click ? click_volume : 0; + kbdcontrol.bell_percent = bell_volume; + kbdcontrol.bell_pitch = bell_pitch; + kbdcontrol.bell_duration = bell_duration; + XChangeKeyboardControl (GDK_DISPLAY_XDISPLAY(gdk_display_get_default()), + KBKeyClickPercent | KBBellPercent | KBBellPitch | KBBellDuration, + &kbdcontrol); + +#ifdef HAVE_X11_EXTENSIONS_XKB_H + if (manager->priv->have_xkb && rnumlock) { + numlock_set_xkb_state (numlock_get_mateconf_state (client)); + } +#endif /* HAVE_X11_EXTENSIONS_XKB_H */ + + XSync (GDK_DISPLAY_XDISPLAY(gdk_display_get_default()), FALSE); + gdk_error_trap_pop (); +} + +void +msd_keyboard_manager_apply_settings (MsdKeyboardManager *manager) +{ + MateConfClient *client; + + client = mateconf_client_get_default (); + apply_settings (client, 0, NULL, manager); + g_object_unref (client); +} + +static gboolean +start_keyboard_idle_cb (MsdKeyboardManager *manager) +{ + MateConfClient *client; + + mate_settings_profile_start (NULL); + + g_debug ("Starting keyboard manager"); + + manager->priv->have_xkb = 0; + client = mateconf_client_get_default (); + + mateconf_client_add_dir (client, MSD_KEYBOARD_KEY, MATECONF_CLIENT_PRELOAD_RECURSIVE, NULL); + + /* Essential - xkb initialization should happen before */ + msd_keyboard_xkb_set_post_activation_callback ((PostActivationCallback) msd_load_modmap_files, NULL); + msd_keyboard_xkb_init (client, manager); + +#ifdef HAVE_X11_EXTENSIONS_XKB_H + numlock_xkb_init (manager); +#endif /* HAVE_X11_EXTENSIONS_XKB_H */ + + /* apply current settings before we install the callback */ + msd_keyboard_manager_apply_settings (manager); + + manager->priv->notify = mateconf_client_notify_add (client, MSD_KEYBOARD_KEY, + (MateConfClientNotifyFunc) apply_settings, manager, + NULL, NULL); + + g_object_unref (client); + +#ifdef HAVE_X11_EXTENSIONS_XKB_H + numlock_install_xkb_callback (manager); +#endif /* HAVE_X11_EXTENSIONS_XKB_H */ + + mate_settings_profile_end (NULL); + + return FALSE; +} + +gboolean +msd_keyboard_manager_start (MsdKeyboardManager *manager, + GError **error) +{ + mate_settings_profile_start (NULL); + + g_idle_add ((GSourceFunc) start_keyboard_idle_cb, manager); + + mate_settings_profile_end (NULL); + + return TRUE; +} + +void +msd_keyboard_manager_stop (MsdKeyboardManager *manager) +{ + MsdKeyboardManagerPrivate *p = manager->priv; + + g_debug ("Stopping keyboard manager"); + + if (p->notify != 0) { + MateConfClient *client = mateconf_client_get_default (); + mateconf_client_remove_dir (client, MSD_KEYBOARD_KEY, NULL); + mateconf_client_notify_remove (client, p->notify); + g_object_unref (client); + p->notify = 0; + } + +#if HAVE_X11_EXTENSIONS_XKB_H + if (p->have_xkb) { + gdk_window_remove_filter (NULL, + numlock_xkb_callback, + GINT_TO_POINTER (p->xkb_event_base)); + } +#endif /* HAVE_X11_EXTENSIONS_XKB_H */ + + msd_keyboard_xkb_shutdown (); +} + +static void +msd_keyboard_manager_set_property (GObject *object, + guint prop_id, + const GValue *value, + GParamSpec *pspec) +{ + MsdKeyboardManager *self; + + self = MSD_KEYBOARD_MANAGER (object); + + switch (prop_id) { + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); + break; + } +} + +static void +msd_keyboard_manager_get_property (GObject *object, + guint prop_id, + GValue *value, + GParamSpec *pspec) +{ + MsdKeyboardManager *self; + + self = MSD_KEYBOARD_MANAGER (object); + + switch (prop_id) { + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); + break; + } +} + +static GObject * +msd_keyboard_manager_constructor (GType type, + guint n_construct_properties, + GObjectConstructParam *construct_properties) +{ + MsdKeyboardManager *keyboard_manager; + MsdKeyboardManagerClass *klass; + + klass = MSD_KEYBOARD_MANAGER_CLASS (g_type_class_peek (MSD_TYPE_KEYBOARD_MANAGER)); + + keyboard_manager = MSD_KEYBOARD_MANAGER (G_OBJECT_CLASS (msd_keyboard_manager_parent_class)->constructor (type, + n_construct_properties, + construct_properties)); + + return G_OBJECT (keyboard_manager); +} + +static void +msd_keyboard_manager_dispose (GObject *object) +{ + MsdKeyboardManager *keyboard_manager; + + keyboard_manager = MSD_KEYBOARD_MANAGER (object); + + G_OBJECT_CLASS (msd_keyboard_manager_parent_class)->dispose (object); +} + +static void +msd_keyboard_manager_class_init (MsdKeyboardManagerClass *klass) +{ + GObjectClass *object_class = G_OBJECT_CLASS (klass); + + object_class->get_property = msd_keyboard_manager_get_property; + object_class->set_property = msd_keyboard_manager_set_property; + object_class->constructor = msd_keyboard_manager_constructor; + object_class->dispose = msd_keyboard_manager_dispose; + object_class->finalize = msd_keyboard_manager_finalize; + + g_type_class_add_private (klass, sizeof (MsdKeyboardManagerPrivate)); +} + +static void +msd_keyboard_manager_init (MsdKeyboardManager *manager) +{ + manager->priv = MSD_KEYBOARD_MANAGER_GET_PRIVATE (manager); +} + +static void +msd_keyboard_manager_finalize (GObject *object) +{ + MsdKeyboardManager *keyboard_manager; + + g_return_if_fail (object != NULL); + g_return_if_fail (MSD_IS_KEYBOARD_MANAGER (object)); + + keyboard_manager = MSD_KEYBOARD_MANAGER (object); + + g_return_if_fail (keyboard_manager->priv != NULL); + + G_OBJECT_CLASS (msd_keyboard_manager_parent_class)->finalize (object); +} + +MsdKeyboardManager * +msd_keyboard_manager_new (void) +{ + if (manager_object != NULL) { + g_object_ref (manager_object); + } else { + manager_object = g_object_new (MSD_TYPE_KEYBOARD_MANAGER, NULL); + g_object_add_weak_pointer (manager_object, + (gpointer *) &manager_object); + } + + return MSD_KEYBOARD_MANAGER (manager_object); +} diff --git a/plugins/keyboard/msd-keyboard-manager.h b/plugins/keyboard/msd-keyboard-manager.h new file mode 100644 index 0000000..aa3ae95 --- /dev/null +++ b/plugins/keyboard/msd-keyboard-manager.h @@ -0,0 +1,62 @@ +/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 8 -*- + * + * Copyright (C) 2007 William Jon McCann + * + * 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. + * + */ + +#ifndef __MSD_KEYBOARD_MANAGER_H +#define __MSD_KEYBOARD_MANAGER_H + +#include + +#ifdef __cplusplus +extern "C" { +#endif + +#define MSD_TYPE_KEYBOARD_MANAGER (msd_keyboard_manager_get_type ()) +#define MSD_KEYBOARD_MANAGER(o) (G_TYPE_CHECK_INSTANCE_CAST ((o), MSD_TYPE_KEYBOARD_MANAGER, MsdKeyboardManager)) +#define MSD_KEYBOARD_MANAGER_CLASS(k) (G_TYPE_CHECK_CLASS_CAST((k), MSD_TYPE_KEYBOARD_MANAGER, MsdKeyboardManagerClass)) +#define MSD_IS_KEYBOARD_MANAGER(o) (G_TYPE_CHECK_INSTANCE_TYPE ((o), MSD_TYPE_KEYBOARD_MANAGER)) +#define MSD_IS_KEYBOARD_MANAGER_CLASS(k) (G_TYPE_CHECK_CLASS_TYPE ((k), MSD_TYPE_KEYBOARD_MANAGER)) +#define MSD_KEYBOARD_MANAGER_GET_CLASS(o) (G_TYPE_INSTANCE_GET_CLASS ((o), MSD_TYPE_KEYBOARD_MANAGER, MsdKeyboardManagerClass)) + +typedef struct MsdKeyboardManagerPrivate MsdKeyboardManagerPrivate; + +typedef struct +{ + GObject parent; + MsdKeyboardManagerPrivate *priv; +} MsdKeyboardManager; + +typedef struct +{ + GObjectClass parent_class; +} MsdKeyboardManagerClass; + +GType msd_keyboard_manager_get_type (void); + +MsdKeyboardManager * msd_keyboard_manager_new (void); +gboolean msd_keyboard_manager_start (MsdKeyboardManager *manager, + GError **error); +void msd_keyboard_manager_stop (MsdKeyboardManager *manager); +void msd_keyboard_manager_apply_settings (MsdKeyboardManager *manager); + +#ifdef __cplusplus +} +#endif + +#endif /* __MSD_KEYBOARD_MANAGER_H */ diff --git a/plugins/keyboard/msd-keyboard-plugin.c b/plugins/keyboard/msd-keyboard-plugin.c new file mode 100644 index 0000000..5f89ca2 --- /dev/null +++ b/plugins/keyboard/msd-keyboard-plugin.c @@ -0,0 +1,104 @@ +/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 8 -*- + * + * Copyright (C) 2007 William Jon McCann + * + * 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, 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 +#include + +#include "mate-settings-plugin.h" +#include "msd-keyboard-plugin.h" +#include "msd-keyboard-manager.h" + +struct MsdKeyboardPluginPrivate { + MsdKeyboardManager *manager; +}; + +#define MSD_KEYBOARD_PLUGIN_GET_PRIVATE(object) (G_TYPE_INSTANCE_GET_PRIVATE ((object), MSD_TYPE_KEYBOARD_PLUGIN, MsdKeyboardPluginPrivate)) + +MATE_SETTINGS_PLUGIN_REGISTER (MsdKeyboardPlugin, msd_keyboard_plugin) + +static void +msd_keyboard_plugin_init (MsdKeyboardPlugin *plugin) +{ + plugin->priv = MSD_KEYBOARD_PLUGIN_GET_PRIVATE (plugin); + + g_debug ("MsdKeyboardPlugin initializing"); + + plugin->priv->manager = msd_keyboard_manager_new (); +} + +static void +msd_keyboard_plugin_finalize (GObject *object) +{ + MsdKeyboardPlugin *plugin; + + g_return_if_fail (object != NULL); + g_return_if_fail (MSD_IS_KEYBOARD_PLUGIN (object)); + + g_debug ("MsdKeyboardPlugin finalizing"); + + plugin = MSD_KEYBOARD_PLUGIN (object); + + g_return_if_fail (plugin->priv != NULL); + + if (plugin->priv->manager != NULL) { + g_object_unref (plugin->priv->manager); + } + + G_OBJECT_CLASS (msd_keyboard_plugin_parent_class)->finalize (object); +} + +static void +impl_activate (MateSettingsPlugin *plugin) +{ + gboolean res; + GError *error; + + g_debug ("Activating keyboard plugin"); + + error = NULL; + res = msd_keyboard_manager_start (MSD_KEYBOARD_PLUGIN (plugin)->priv->manager, &error); + if (! res) { + g_warning ("Unable to start keyboard manager: %s", error->message); + g_error_free (error); + } +} + +static void +impl_deactivate (MateSettingsPlugin *plugin) +{ + g_debug ("Deactivating keyboard plugin"); + msd_keyboard_manager_stop (MSD_KEYBOARD_PLUGIN (plugin)->priv->manager); +} + +static void +msd_keyboard_plugin_class_init (MsdKeyboardPluginClass *klass) +{ + GObjectClass *object_class = G_OBJECT_CLASS (klass); + MateSettingsPluginClass *plugin_class = MATE_SETTINGS_PLUGIN_CLASS (klass); + + object_class->finalize = msd_keyboard_plugin_finalize; + + plugin_class->activate = impl_activate; + plugin_class->deactivate = impl_deactivate; + + g_type_class_add_private (klass, sizeof (MsdKeyboardPluginPrivate)); +} diff --git a/plugins/keyboard/msd-keyboard-plugin.h b/plugins/keyboard/msd-keyboard-plugin.h new file mode 100644 index 0000000..84f2420 --- /dev/null +++ b/plugins/keyboard/msd-keyboard-plugin.h @@ -0,0 +1,63 @@ +/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 8 -*- + * + * Copyright (C) 2007 William Jon McCann + * + * 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, 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. + * + */ + +#ifndef __MSD_KEYBOARD_PLUGIN_H__ +#define __MSD_KEYBOARD_PLUGIN_H__ + +#include +#include +#include + +#include "mate-settings-plugin.h" + +#ifdef __cplusplus +extern "C" { +#endif + +#define MSD_TYPE_KEYBOARD_PLUGIN (msd_keyboard_plugin_get_type ()) +#define MSD_KEYBOARD_PLUGIN(o) (G_TYPE_CHECK_INSTANCE_CAST ((o), MSD_TYPE_KEYBOARD_PLUGIN, MsdKeyboardPlugin)) +#define MSD_KEYBOARD_PLUGIN_CLASS(k) (G_TYPE_CHECK_CLASS_CAST((k), MSD_TYPE_KEYBOARD_PLUGIN, MsdKeyboardPluginClass)) +#define MSD_IS_KEYBOARD_PLUGIN(o) (G_TYPE_CHECK_INSTANCE_TYPE ((o), MSD_TYPE_KEYBOARD_PLUGIN)) +#define MSD_IS_KEYBOARD_PLUGIN_CLASS(k) (G_TYPE_CHECK_CLASS_TYPE ((k), MSD_TYPE_KEYBOARD_PLUGIN)) +#define MSD_KEYBOARD_PLUGIN_GET_CLASS(o) (G_TYPE_INSTANCE_GET_CLASS ((o), MSD_TYPE_KEYBOARD_PLUGIN, MsdKeyboardPluginClass)) + +typedef struct MsdKeyboardPluginPrivate MsdKeyboardPluginPrivate; + +typedef struct +{ + MateSettingsPlugin parent; + MsdKeyboardPluginPrivate *priv; +} MsdKeyboardPlugin; + +typedef struct +{ + MateSettingsPluginClass parent_class; +} MsdKeyboardPluginClass; + +GType msd_keyboard_plugin_get_type (void) G_GNUC_CONST; + +/* All the plugins must implement this function */ +G_MODULE_EXPORT GType register_mate_settings_plugin (GTypeModule *module); + +#ifdef __cplusplus +} +#endif + +#endif /* __MSD_KEYBOARD_PLUGIN_H__ */ diff --git a/plugins/keyboard/msd-keyboard-xkb.c b/plugins/keyboard/msd-keyboard-xkb.c new file mode 100644 index 0000000..9042f03 --- /dev/null +++ b/plugins/keyboard/msd-keyboard-xkb.c @@ -0,0 +1,918 @@ +/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 8 -*- + * + * Copyright (C) 2001 Udaltsoft + * + * Written by Sergey V. Oudaltsov + * + * 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, 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 +#include + +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include + +#include "msd-xmodmap.h" +#include "msd-keyboard-xkb.h" +#include "delayed-dialog.h" +#include "mate-settings-profile.h" + +#define GTK_RESPONSE_PRINT 2 + +static MsdKeyboardManager* manager = NULL; + +static XklEngine* xkl_engine; +static XklConfigRegistry* xkl_registry = NULL; + +static MatekbdDesktopConfig current_config; +static MatekbdKeyboardConfig current_kbd_config; + +/* never terminated */ +static MatekbdKeyboardConfig initial_sys_kbd_config; + +static gboolean inited_ok = FALSE; + +static guint notify_desktop = 0; +static guint notify_keyboard = 0; + +static PostActivationCallback pa_callback = NULL; +static void *pa_callback_user_data = NULL; + +static const char KNOWN_FILES_KEY[] = "/desktop/mate/peripherals/keyboard/general/known_file_list"; + +static const char DISABLE_INDICATOR_KEY[] = "/desktop/mate/peripherals/keyboard/general/disable_indicator"; + +static const char DUPLICATE_LEDS_KEY[] = "/desktop/mate/peripherals/keyboard/general/duplicate_leds"; + +static const char* mdm_keyboard_layout = NULL; + +static GtkStatusIcon* icon = NULL; + +static GHashTable* preview_dialogs = NULL; + +static Atom caps_lock; +static Atom num_lock; +static Atom scroll_lock; + +static GtkStatusIcon* indicator_icons[3]; +static const gchar* indicator_on_icon_names[] = { + "kbd-scrolllock-on", + "kbd-numlock-on", + "kbd-capslock-on" +}; + +static const gchar* indicator_off_icon_names[] = { + "kbd-scrolllock-off", + "kbd-numlock-off", + "kbd-capslock-off" +}; + +//#define noMSDKX + +#ifdef MSDKX +static FILE *logfile; + +static void msd_keyboard_log_appender(const char file[], const char function[], int level, const char format[], va_list args) +{ + time_t now = time (NULL); + fprintf (logfile, "[%08ld,%03d,%s:%s/] \t", now, + level, file, function); + vfprintf (logfile, format, args); + fflush (logfile); +} +#endif + +static void +activation_error (void) +{ + char const *vendor = ServerVendor (GDK_DISPLAY_XDISPLAY(gdk_display_get_default())); + int release = VendorRelease (GDK_DISPLAY_XDISPLAY(gdk_display_get_default())); + GtkWidget *dialog; + gboolean badXFree430Release; + + badXFree430Release = (vendor != NULL) + && (0 == strcmp (vendor, "The XFree86 Project, Inc")) + && (release / 100000 == 403); + + /* VNC viewers will not work, do not barrage them with warnings */ + if (NULL != vendor && NULL != strstr (vendor, "VNC")) + return; + + dialog = gtk_message_dialog_new_with_markup (NULL, + 0, + GTK_MESSAGE_ERROR, + GTK_BUTTONS_CLOSE, + _ + ("Error activating XKB configuration.\n" + "It can happen under various circumstances:\n" + " • a bug in libxklavier library\n" + " • a bug in X server (xkbcomp, xmodmap utilities)\n" + " • X server with incompatible libxkbfile implementation\n\n" + "X server version data:\n%s\n%d\n%s\n" + "If you report this situation as a bug, please include:\n" + " • The result of %s\n" + " • The result of %s"), + vendor, + release, + badXFree430Release + ? + _ + ("You are using XFree 4.3.0.\n" + "There are known problems with complex XKB configurations.\n" + "Try using a simpler configuration or using a later version of the XFree software.") + : "", + "xprop -root | grep XKB", + "mateconftool-2 -R /desktop/mate/peripherals/keyboard/kbd"); + g_signal_connect (dialog, "response", + G_CALLBACK (gtk_widget_destroy), NULL); + msd_delayed_show_dialog (dialog); +} + +static void +apply_desktop_settings (void) +{ + MateConfClient *conf_client; + gboolean show_leds; + int i; + if (!inited_ok) + return; + + msd_keyboard_manager_apply_settings (manager); + matekbd_desktop_config_load_from_mateconf (¤t_config); + /* again, probably it would be nice to compare things + before activating them */ + matekbd_desktop_config_activate (¤t_config); + + conf_client = mateconf_client_get_default (); + show_leds = + mateconf_client_get_bool (conf_client, DUPLICATE_LEDS_KEY, NULL); + g_object_unref (conf_client); + for (i = sizeof (indicator_icons) / sizeof (indicator_icons[0]); + --i >= 0;) { + gtk_status_icon_set_visible (indicator_icons[i], + show_leds); + } +} + +static void +popup_menu_launch_capplet () +{ + GError *error = NULL; + + gdk_spawn_command_line_on_screen (gdk_screen_get_default (), + "mate-keyboard-properties", + &error); + + if (error != NULL) { + g_warning + ("Could not execute keyboard properties capplet: [%s]\n", + error->message); + g_error_free (error); + } +} + +static void +show_layout_destroy (GtkWidget * dialog, gint group) +{ + g_hash_table_remove (preview_dialogs, GINT_TO_POINTER (group)); +} + +static void +popup_menu_show_layout () +{ + GtkWidget *dialog; + XklEngine *engine = xkl_engine_get_instance (GDK_DISPLAY_XDISPLAY(gdk_display_get_default())); + XklState *xkl_state = xkl_engine_get_current_state (engine); + gpointer p = g_hash_table_lookup (preview_dialogs, + GINT_TO_POINTER + (xkl_state->group)); + gchar **group_names = matekbd_status_get_group_names (); + + if (xkl_state->group < 0 + || xkl_state->group >= g_strv_length (group_names)) { + return; + } + + if (p != NULL) { + /* existing window */ + gtk_window_present (GTK_WINDOW (p)); + return; + } + + dialog = + matekbd_keyboard_drawing_new_dialog (xkl_state->group, + group_names + [xkl_state->group]); + g_signal_connect (GTK_OBJECT (dialog), "destroy", + G_CALLBACK (show_layout_destroy), + GINT_TO_POINTER (xkl_state->group)); + g_hash_table_insert (preview_dialogs, + GINT_TO_POINTER (xkl_state->group), dialog); +} + +static void +popup_menu_set_group (GtkMenuItem * item, gpointer param) +{ + gint group_number = GPOINTER_TO_INT (param); + XklEngine *engine = matekbd_status_get_xkl_engine (); + XklState st; + Window cur; + + st.group = group_number; + xkl_engine_allow_one_switch_to_secondary_group (engine); + cur = xkl_engine_get_current_window (engine); + if (cur != (Window) NULL) { + xkl_debug (150, "Enforcing the state %d for window %lx\n", + st.group, cur); + xkl_engine_save_state (engine, + xkl_engine_get_current_window + (engine), &st); +/* XSetInputFocus(GDK_DISPLAY_XDISPLAY(gdk_display_get_default()), cur, RevertToNone, CurrentTime );*/ + } else { + xkl_debug (150, + "??? Enforcing the state %d for unknown window\n", + st.group); + /* strange situation - bad things can happen */ + } + xkl_engine_lock_group (engine, st.group); +} + +static void +status_icon_popup_menu_cb (GtkStatusIcon * icon, guint button, guint time) +{ + GtkMenu *popup_menu = GTK_MENU (gtk_menu_new ()); + GtkMenu *groups_menu = GTK_MENU (gtk_menu_new ()); + int i = 0; + gchar **current_name = matekbd_status_get_group_names (); + + GtkWidget *item = gtk_menu_item_new_with_mnemonic (_("_Layouts")); + gtk_widget_show (item); + gtk_menu_shell_append (GTK_MENU_SHELL (popup_menu), item); + gtk_menu_item_set_submenu (GTK_MENU_ITEM (item), + GTK_WIDGET (groups_menu)); + + item = + gtk_menu_item_new_with_mnemonic (_("Keyboard _Preferences")); + gtk_widget_show (item); + g_signal_connect (item, "activate", popup_menu_launch_capplet, + NULL); + gtk_menu_shell_append (GTK_MENU_SHELL (popup_menu), item); + + item = gtk_menu_item_new_with_mnemonic (_("Show _Current Layout")); + gtk_widget_show (item); + g_signal_connect (item, "activate", popup_menu_show_layout, NULL); + gtk_menu_shell_append (GTK_MENU_SHELL (popup_menu), item); + + for (i = 0; *current_name; i++, current_name++) { + gchar *image_file = matekbd_status_get_image_filename (i); + + if (image_file == NULL) { + item = + gtk_menu_item_new_with_label (*current_name); + } else { + GdkPixbuf *pixbuf = + gdk_pixbuf_new_from_file_at_size (image_file, + 24, 24, + NULL); + GtkWidget *img = + gtk_image_new_from_pixbuf (pixbuf); + item = + gtk_image_menu_item_new_with_label + (*current_name); + gtk_widget_show (img); + gtk_image_menu_item_set_image (GTK_IMAGE_MENU_ITEM + (item), img); + gtk_image_menu_item_set_always_show_image + (GTK_IMAGE_MENU_ITEM (item), TRUE); + g_free (image_file); + } + gtk_widget_show (item); + gtk_menu_shell_append (GTK_MENU_SHELL (groups_menu), item); + g_signal_connect (item, "activate", + G_CALLBACK (popup_menu_set_group), + GINT_TO_POINTER (i)); + } + + gtk_menu_popup (popup_menu, NULL, NULL, + gtk_status_icon_position_menu, + (gpointer) icon, button, time); +} + +static void +show_hide_icon () +{ + if (g_slist_length (current_kbd_config.layouts_variants) > 1) { + if (icon == NULL) { + MateConfClient *conf_client = + mateconf_client_get_default (); + gboolean disable = + mateconf_client_get_bool (conf_client, + DISABLE_INDICATOR_KEY, + NULL); + g_object_unref (conf_client); + if (disable) + return; + + xkl_debug (150, "Creating new icon\n"); + icon = matekbd_status_new (); + g_signal_connect (icon, "popup-menu", + G_CALLBACK + (status_icon_popup_menu_cb), + NULL); + + } + } else { + if (icon != NULL) { + xkl_debug (150, "Destroying icon\n"); + g_object_unref (icon); + icon = NULL; + } + } +} + +static gboolean +try_activating_xkb_config_if_new (MatekbdKeyboardConfig * + current_sys_kbd_config) +{ + /* Activate - only if different! */ + if (!matekbd_keyboard_config_equals + (¤t_kbd_config, current_sys_kbd_config)) { + if (matekbd_keyboard_config_activate (¤t_kbd_config)) { + if (pa_callback != NULL) { + (*pa_callback) (pa_callback_user_data); + return TRUE; + } + } else { + return FALSE; + } + } + return TRUE; +} + +static gboolean +filter_xkb_config (void) +{ + XklConfigItem *item; + gchar *lname; + gchar *vname; + GSList *lv; + GSList *filtered; + gboolean any_change = FALSE; + + xkl_debug (100, "Filtering configuration against the registry\n"); + if (!xkl_registry) { + xkl_registry = + xkl_config_registry_get_instance (xkl_engine); + /* load all materials, unconditionally! */ + if (!xkl_config_registry_load (xkl_registry, TRUE)) { + g_object_unref (xkl_registry); + xkl_registry = NULL; + return FALSE; + } + } + lv = current_kbd_config.layouts_variants; + item = xkl_config_item_new (); + while (lv) { + xkl_debug (100, "Checking [%s]\n", lv->data); + if (matekbd_keyboard_config_split_items + (lv->data, &lname, &vname)) { + g_snprintf (item->name, sizeof (item->name), "%s", + lname); + if (!xkl_config_registry_find_layout + (xkl_registry, item)) { + xkl_debug (100, "Bad layout [%s]\n", + lname); + filtered = lv; + lv = lv->next; + g_free (filtered->data); + current_kbd_config.layouts_variants = + g_slist_delete_link + (current_kbd_config.layouts_variants, + filtered); + any_change = TRUE; + continue; + } + if (vname) { + g_snprintf (item->name, + sizeof (item->name), "%s", + vname); + if (!xkl_config_registry_find_variant + (xkl_registry, lname, item)) { + xkl_debug (100, + "Bad variant [%s(%s)]\n", + lname, vname); + filtered = lv; + lv = lv->next; + g_free (filtered->data); + current_kbd_config.layouts_variants + = + g_slist_delete_link + (current_kbd_config.layouts_variants, + filtered); + any_change = TRUE; + continue; + } + } + } + lv = lv->next; + } + g_object_unref (item); + return any_change; +} + +static void +apply_xkb_settings (void) +{ + MateConfClient *conf_client; + MatekbdKeyboardConfig current_sys_kbd_config; + int group_to_activate = -1; + char *mdm_layout; + char *s; + + if (!inited_ok) + return; + + conf_client = mateconf_client_get_default (); + + /* With MDM the user can already set a layout from the login + * screen. Try to keep that setting. + * We clear mdm_keyboard_layout early, so we don't risk + * recursion from mateconf notification. + */ + mdm_layout = g_strdup (mdm_keyboard_layout); + mdm_keyboard_layout = NULL; + + /* mdm's configuration and $MDM_KEYBOARD_LAYOUT separates layout and + * variant with a space, but mateconf uses tabs; so convert to be robust + * with both */ + for (s = mdm_layout; s && *s; ++s) { + if (*s == ' ') { + *s = '\t'; + } + } + + if (mdm_layout != NULL) { + GSList *layouts; + GSList *found_node; + int max_groups; + + max_groups = + MAX (xkl_engine_get_max_num_groups (xkl_engine), 1); + layouts = + mateconf_client_get_list (conf_client, + MATEKBD_KEYBOARD_CONFIG_KEY_LAYOUTS, + MATECONF_VALUE_STRING, NULL); + + /* Use system layouts as a default if we do not have + * user configuration */ + if (layouts == NULL) { + GSList *i; + int len; + + for (i = initial_sys_kbd_config.layouts_variants; + i; i = g_slist_next (i)) { + s = g_strdup (i->data); + + /* chop off empty variants to avoid duplicates */ + len = strlen (s); + if (s[len - 1] == '\t') + s[len - 1] = '\0'; + layouts = g_slist_append (layouts, s); + } + } + + /* Add the layout if it doesn't already exist. XKB limits the + * total number of layouts. If we already have the maximum + * number of layouts configured, we replace the last one. This + * prevents the list from becoming full if the user has a habit + * of selecting many different keyboard layouts in MDM. */ + + found_node = + g_slist_find_custom (layouts, mdm_layout, + (GCompareFunc) g_strcmp0); + + if (!found_node) { + /* Insert at the last valid place, or at the end of + * list, whichever comes first */ + layouts = + g_slist_insert (layouts, g_strdup (mdm_layout), + max_groups - 1); + if (g_slist_length (layouts) > max_groups) { + GSList *last; + GSList *free_layouts; + + last = + g_slist_nth (layouts, max_groups - 1); + free_layouts = last->next; + last->next = NULL; + + g_slist_foreach (free_layouts, + (GFunc) g_free, NULL); + g_slist_free (free_layouts); + } + + mateconf_client_set_list (conf_client, + MATEKBD_KEYBOARD_CONFIG_KEY_LAYOUTS, + MATECONF_VALUE_STRING, layouts, + NULL); + } + + g_slist_foreach (layouts, (GFunc) g_free, NULL); + g_slist_free (layouts); + } + + matekbd_keyboard_config_init (¤t_sys_kbd_config, + conf_client, xkl_engine); + + matekbd_keyboard_config_load_from_mateconf (¤t_kbd_config, + &initial_sys_kbd_config); + + matekbd_keyboard_config_load_from_x_current (¤t_sys_kbd_config, + NULL); + + if (!try_activating_xkb_config_if_new (¤t_sys_kbd_config)) { + if (filter_xkb_config ()) { + if (!try_activating_xkb_config_if_new + (¤t_sys_kbd_config)) { + g_warning + ("Could not activate the filtered XKB configuration"); + activation_error (); + } + } else { + g_warning + ("Could not activate the XKB configuration"); + activation_error (); + } + } else + xkl_debug (100, + "Actual KBD configuration was not changed: redundant notification\n"); + + if (mdm_layout != NULL) { + /* If there are multiple layouts, + * try to find the one closest to the mdm layout + */ + GSList *l; + int i; + size_t len = strlen (mdm_layout); + for (i = 0, l = current_kbd_config.layouts_variants; l; + i++, l = l->next) { + char *lv = l->data; + if (strncmp (lv, mdm_layout, len) == 0 + && (lv[len] == '\0' || lv[len] == '\t')) { + group_to_activate = i; + break; + } + } + } + + g_free (mdm_layout); + + if (group_to_activate != -1) + xkl_engine_lock_group (current_config.engine, + group_to_activate); + matekbd_keyboard_config_term (¤t_sys_kbd_config); + show_hide_icon (); +} + +static void +msd_keyboard_xkb_analyze_sysconfig (void) +{ + MateConfClient *conf_client; + + if (!inited_ok) + return; + + conf_client = mateconf_client_get_default (); + matekbd_keyboard_config_init (&initial_sys_kbd_config, + conf_client, xkl_engine); + matekbd_keyboard_config_load_from_x_initial (&initial_sys_kbd_config, + NULL); + g_object_unref (conf_client); +} + +static gboolean +msd_chk_file_list (void) +{ + GDir *home_dir; + const char *fname; + GSList *file_list = NULL; + GSList *last_login_file_list = NULL; + GSList *tmp = NULL; + GSList *tmp_l = NULL; + gboolean new_file_exist = FALSE; + MateConfClient *conf_client; + + home_dir = g_dir_open (g_get_home_dir (), 0, NULL); + while ((fname = g_dir_read_name (home_dir)) != NULL) { + if (g_strrstr (fname, "modmap")) { + file_list = + g_slist_append (file_list, g_strdup (fname)); + } + } + g_dir_close (home_dir); + + conf_client = mateconf_client_get_default (); + + last_login_file_list = mateconf_client_get_list (conf_client, + KNOWN_FILES_KEY, + MATECONF_VALUE_STRING, + NULL); + + /* Compare between the two file list, currently available modmap files + and the files available in the last log in */ + tmp = file_list; + while (tmp != NULL) { + tmp_l = last_login_file_list; + new_file_exist = TRUE; + while (tmp_l != NULL) { + if (strcmp (tmp->data, tmp_l->data) == 0) { + new_file_exist = FALSE; + break; + } else { + tmp_l = tmp_l->next; + } + } + if (new_file_exist) { + break; + } else { + tmp = tmp->next; + } + } + + if (new_file_exist) { + mateconf_client_set_list (conf_client, + KNOWN_FILES_KEY, + MATECONF_VALUE_STRING, + file_list, NULL); + } + + g_object_unref (conf_client); + + g_slist_foreach (file_list, (GFunc) g_free, NULL); + g_slist_free (file_list); + + g_slist_foreach (last_login_file_list, (GFunc) g_free, NULL); + g_slist_free (last_login_file_list); + + return new_file_exist; + +} + +static void +msd_keyboard_xkb_chk_lcl_xmm (void) +{ + if (msd_chk_file_list ()) { + msd_modmap_dialog_call (); + } + msd_load_modmap_files (); +} + +void +msd_keyboard_xkb_set_post_activation_callback (PostActivationCallback fun, + void *user_data) +{ + pa_callback = fun; + pa_callback_user_data = user_data; +} + +static GdkFilterReturn +msd_keyboard_xkb_evt_filter (GdkXEvent * xev, GdkEvent * event) +{ + XEvent *xevent = (XEvent *) xev; + xkl_engine_filter_events (xkl_engine, xevent); + return GDK_FILTER_CONTINUE; +} + +static guint +register_config_callback (MateConfClient * client, + const char *path, MateConfClientNotifyFunc func) +{ + mateconf_client_add_dir (client, path, MATECONF_CLIENT_PRELOAD_ONELEVEL, + NULL); + return mateconf_client_notify_add (client, path, func, NULL, NULL, + NULL); +} + +/* When new Keyboard is plugged in - reload the settings */ +static void +msd_keyboard_new_device (XklEngine * engine) +{ + apply_desktop_settings (); + apply_xkb_settings (); +} + +static void +msd_keyboard_update_indicator_icons () +{ + Bool state; + int new_state, i; + Display *display = GDK_DISPLAY_XDISPLAY(gdk_display_get_default()); + XkbGetNamedIndicator (display, caps_lock, NULL, &state, + NULL, NULL); + new_state = state ? 1 : 0; + XkbGetNamedIndicator (display, num_lock, NULL, &state, NULL, NULL); + new_state <<= 1; + new_state |= (state ? 1 : 0); + XkbGetNamedIndicator (display, scroll_lock, NULL, &state, + NULL, NULL); + new_state <<= 1; + new_state |= (state ? 1 : 0); + xkl_debug (160, "Indicators state: %d\n", new_state); + + + for (i = sizeof (indicator_icons) / sizeof (indicator_icons[0]); + --i >= 0;) { + gtk_status_icon_set_from_icon_name (indicator_icons[i], + (new_state & (1 << i)) + ? + indicator_on_icon_names + [i] : + indicator_off_icon_names + [i]); + } +} + +static void +msd_keyboard_state_changed (XklEngine * engine, XklEngineStateChange type, + gint new_group, gboolean restore) +{ + xkl_debug (160, + "State changed: type %d, new group: %d, restore: %d.\n", + type, new_group, restore); + if (type == INDICATORS_CHANGED) { + msd_keyboard_update_indicator_icons (); + } +} + +void +msd_keyboard_xkb_init (MateConfClient * client, + MsdKeyboardManager * kbd_manager) +{ + int i; + Display *display = GDK_DISPLAY_XDISPLAY(gdk_display_get_default()); + mate_settings_profile_start (NULL); + + gtk_icon_theme_append_search_path (gtk_icon_theme_get_default (), + DATADIR G_DIR_SEPARATOR_S + "icons"); + + caps_lock = XInternAtom (display, "Caps Lock", False); + num_lock = XInternAtom (display, "Num Lock", False); + scroll_lock = XInternAtom (display, "Scroll Lock", False); + + for (i = sizeof (indicator_icons) / sizeof (indicator_icons[0]); + --i >= 0;) { + indicator_icons[i] = + gtk_status_icon_new_from_icon_name + (indicator_off_icon_names[i]); + } + + msd_keyboard_update_indicator_icons (); + +#ifdef MSDKX + xkl_set_debug_level (200); + logfile = fopen ("/tmp/msdkx.log", "a"); + xkl_set_log_appender (msd_keyboard_log_appender); +#endif + manager = kbd_manager; + mate_settings_profile_start ("xkl_engine_get_instance"); + xkl_engine = xkl_engine_get_instance (display); + mate_settings_profile_end ("xkl_engine_get_instance"); + if (xkl_engine) { + inited_ok = TRUE; + + mdm_keyboard_layout = g_getenv ("MDM_KEYBOARD_LAYOUT"); + + matekbd_desktop_config_init (¤t_config, + client, xkl_engine); + matekbd_keyboard_config_init (¤t_kbd_config, + client, xkl_engine); + xkl_engine_backup_names_prop (xkl_engine); + msd_keyboard_xkb_analyze_sysconfig (); + mate_settings_profile_start + ("msd_keyboard_xkb_chk_lcl_xmm"); + msd_keyboard_xkb_chk_lcl_xmm (); + mate_settings_profile_end + ("msd_keyboard_xkb_chk_lcl_xmm"); + + notify_desktop = + register_config_callback (client, + MATEKBD_DESKTOP_CONFIG_DIR, + (MateConfClientNotifyFunc) + apply_desktop_settings); + + notify_keyboard = + register_config_callback (client, + MATEKBD_KEYBOARD_CONFIG_DIR, + (MateConfClientNotifyFunc) + apply_xkb_settings); + + gdk_window_add_filter (NULL, (GdkFilterFunc) + msd_keyboard_xkb_evt_filter, NULL); + + if (xkl_engine_get_features (xkl_engine) & + XKLF_DEVICE_DISCOVERY) + g_signal_connect (xkl_engine, "X-new-device", + G_CALLBACK + (msd_keyboard_new_device), NULL); + g_signal_connect (xkl_engine, "X-state-changed", + G_CALLBACK + (msd_keyboard_state_changed), NULL); + + mate_settings_profile_start ("xkl_engine_start_listen"); + xkl_engine_start_listen (xkl_engine, + XKLL_MANAGE_LAYOUTS | + XKLL_MANAGE_WINDOW_STATES); + mate_settings_profile_end ("xkl_engine_start_listen"); + + mate_settings_profile_start ("apply_desktop_settings"); + apply_desktop_settings (); + mate_settings_profile_end ("apply_desktop_settings"); + mate_settings_profile_start ("apply_xkb_settings"); + apply_xkb_settings (); + mate_settings_profile_end ("apply_xkb_settings"); + } + preview_dialogs = g_hash_table_new (g_direct_hash, g_direct_equal); + + mate_settings_profile_end (NULL); +} + +void +msd_keyboard_xkb_shutdown (void) +{ + MateConfClient *client; + int i; + + pa_callback = NULL; + pa_callback_user_data = NULL; + manager = NULL; + + for (i = sizeof (indicator_icons) / sizeof (indicator_icons[0]); + --i >= 0;) { + g_object_unref (G_OBJECT (indicator_icons[i])); + indicator_icons[i] = NULL; + } + + g_hash_table_destroy (preview_dialogs); + + if (!inited_ok) + return; + + xkl_engine_stop_listen (xkl_engine, + XKLL_MANAGE_LAYOUTS | + XKLL_MANAGE_WINDOW_STATES); + + gdk_window_remove_filter (NULL, (GdkFilterFunc) + msd_keyboard_xkb_evt_filter, NULL); + + client = mateconf_client_get_default (); + + if (notify_desktop != 0) { + mateconf_client_remove_dir (client, MATEKBD_DESKTOP_CONFIG_DIR, + NULL); + mateconf_client_notify_remove (client, notify_desktop); + notify_desktop = 0; + } + + if (notify_keyboard != 0) { + mateconf_client_remove_dir (client, MATEKBD_KEYBOARD_CONFIG_DIR, + NULL); + mateconf_client_notify_remove (client, notify_keyboard); + notify_keyboard = 0; + } + + if (xkl_registry) { + g_object_unref (xkl_registry); + } + + g_object_unref (client); + g_object_unref (xkl_engine); + + xkl_engine = NULL; + inited_ok = FALSE; +} diff --git a/plugins/keyboard/msd-keyboard-xkb.h b/plugins/keyboard/msd-keyboard-xkb.h new file mode 100644 index 0000000..7d2d558 --- /dev/null +++ b/plugins/keyboard/msd-keyboard-xkb.h @@ -0,0 +1,40 @@ +/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 8 -*- + * mate-settings-keyboard-xkb.h + * + * Copyright (C) 2001 Udaltsoft + * + * Written by Sergey V. Oudaltsov + * + * 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, 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. + */ + +#ifndef __MSD_KEYBOARD_XKB_H +#define __MSD_KEYBOARD_XKB_H + +#include +#include + +#include +#include "msd-keyboard-manager.h" + +void msd_keyboard_xkb_init(MateConfClient* client, MsdKeyboardManager* manager); +void msd_keyboard_xkb_shutdown(void); + +typedef void (*PostActivationCallback) (void* userData); + +void msd_keyboard_xkb_set_post_activation_callback(PostActivationCallback fun, void* userData); + +#endif diff --git a/plugins/keyboard/msd-xmodmap.c b/plugins/keyboard/msd-xmodmap.c new file mode 100644 index 0000000..5baf37c --- /dev/null +++ b/plugins/keyboard/msd-xmodmap.c @@ -0,0 +1,399 @@ +/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 8 -*- + * + * Copyright © 2005 Novell Inc. + * + * Written by Shakti Sen + * + * 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, 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 + +#include +#include +#include + +#include "msd-xmodmap.h" + +static const char DISABLE_XMM_WARNING_KEY[] = + "/desktop/mate/peripherals/keyboard/disable_xmm_and_xkb_warning"; + +static const char LOADED_FILES_KEY[] = + "/desktop/mate/peripherals/keyboard/general/update_handlers"; + + +static void +check_button_callback (GtkWidget *chk_button, + gpointer data) +{ + MateConfClient *client; + + client = mateconf_client_get_default (); + + mateconf_client_set_bool (client, + DISABLE_XMM_WARNING_KEY, + gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (chk_button)), + NULL); + + g_object_unref (client); +} + +void +msd_load_modmap_files (void) +{ + MateConfClient *client; + GSList *tmp; + GSList *loaded_file_list; + + client = mateconf_client_get_default (); + + loaded_file_list = mateconf_client_get_list (client, LOADED_FILES_KEY, MATECONF_VALUE_STRING, NULL); + + for (tmp = loaded_file_list; tmp != NULL; tmp = tmp->next) { + gchar *file; + gchar *command; + + file = g_build_filename (g_get_home_dir (), (gchar *) tmp->data, NULL); + command = g_strconcat ("xmodmap ", file, NULL); + g_free (file); + + g_spawn_command_line_async (command, NULL); + + g_free (command); + g_free (tmp->data); + } + + g_slist_free (loaded_file_list); + g_object_unref (client); +} + +static void +response_callback (GtkWidget *dialog, + int id, + void *data) +{ + if (id == GTK_RESPONSE_OK) { + GtkWidget *chk_button = g_object_get_data (G_OBJECT (dialog), "check_button"); + check_button_callback (chk_button, NULL); + msd_load_modmap_files (); + } + gtk_widget_destroy (dialog); +} + +static void +get_selected_files_func (GtkTreeModel *model, + GtkTreePath *path, + GtkTreeIter *iter, + gpointer data) +{ + GSList **list = data; + gchar *filename; + + filename = NULL; + gtk_tree_model_get (model, + iter, + 0, + &filename, + -1); + + *list = g_slist_prepend (*list, filename); +} + +static GSList* +remove_string_from_list (GSList *list, + const char *str) +{ + GSList *tmp; + + for (tmp = list; tmp != NULL; tmp = tmp->next) { + if (strcmp (tmp->data, str) == 0) { + g_free (tmp->data); + list = g_slist_delete_link (list, tmp); + break; + } + } + + return list; +} + + +static void +remove_button_clicked_callback (GtkWidget *button, + void *data) +{ + GtkWidget *dialog; + GtkListStore *tree = NULL; + GtkTreeSelection *selection; + GtkWidget *treeview; + MateConfClient *client; + GSList *filenames = NULL; + GSList *tmp = NULL; + GSList *loaded_files = NULL; + + dialog = data; + + treeview = g_object_get_data (G_OBJECT (dialog), "treeview1"); + + selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (treeview)); + gtk_tree_selection_selected_foreach (selection, + get_selected_files_func, + &filenames); + + if (!filenames) + return; + + /* Remove the selected file */ + + client = mateconf_client_get_default (); + + loaded_files = mateconf_client_get_list (client, + LOADED_FILES_KEY, + MATECONF_VALUE_STRING, + NULL); + loaded_files = remove_string_from_list (loaded_files, (char *)filenames->data); + + mateconf_client_set_list (client, + LOADED_FILES_KEY, + MATECONF_VALUE_STRING, + loaded_files, + NULL); + g_object_unref (client); + + tree = g_object_get_data (G_OBJECT (dialog), "tree"); + + gtk_list_store_clear (tree); + for (tmp = loaded_files; tmp != NULL; tmp = tmp->next) { + GtkTreeIter iter; + gtk_list_store_append (tree, &iter); + gtk_list_store_set (tree, &iter, + 0, + tmp->data, + -1); + } + + g_slist_foreach (loaded_files, (GFunc) g_free, NULL); + g_slist_free (loaded_files); +} + +static void +load_button_clicked_callback (GtkWidget *button, + void *data) +{ + GtkWidget *dialog; + GtkListStore *tree = NULL; + GtkTreeSelection *selection; + GtkWidget *treeview; + GSList *filenames = NULL; + GSList *tmp = NULL; + GSList *loaded_files = NULL; + MateConfClient *client; + + dialog = data; + + treeview = g_object_get_data (G_OBJECT (dialog), + "loaded-treeview"); + selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (treeview)); + gtk_tree_selection_selected_foreach (selection, + get_selected_files_func, + &filenames); + + if (!filenames) + return; + + /* Add the files to left-tree-view */ + client = mateconf_client_get_default (); + + loaded_files = mateconf_client_get_list (client, + LOADED_FILES_KEY, + MATECONF_VALUE_STRING, + NULL); + + if (g_slist_find_custom (loaded_files, filenames->data, (GCompareFunc) strcmp)) { + g_free (filenames->data); + g_slist_free (filenames); + goto out; + } + + loaded_files = g_slist_append (loaded_files, filenames->data); + mateconf_client_set_list (client, + LOADED_FILES_KEY, + MATECONF_VALUE_STRING, + loaded_files, + NULL); + + + tree = g_object_get_data (G_OBJECT (dialog), "tree"); + + gtk_list_store_clear (tree); + for (tmp = loaded_files; tmp != NULL; tmp = tmp->next) { + GtkTreeIter iter; + gtk_list_store_append (tree, &iter); + gtk_list_store_set (tree, &iter, + 0, + tmp->data, + -1); + } + +out: + g_object_unref (client); + g_slist_foreach (loaded_files, (GFunc) g_free, NULL); + g_slist_free (loaded_files); +} + +void +msd_modmap_dialog_call (void) +{ + GtkBuilder *builder; + guint res; + GError *error; + GtkWidget *load_dialog; + GtkListStore *tree; + GtkCellRenderer *cell_renderer; + GtkTreeIter parent_iter; + GtkTreeIter iter; + GtkTreeModel *sort_model; + GtkTreeSelection *selection; + GtkWidget *treeview; + GtkWidget *treeview1; + GtkTreeViewColumn *column; + GtkWidget *add_button; + GtkWidget *remove_button; + GtkWidget *chk_button; + GSList *tmp; + GDir *homeDir; + GSList *loaded_files; + const char *fname; + MateConfClient *client; + + homeDir = g_dir_open (g_get_home_dir (), 0, NULL); + if (homeDir == NULL) + return; + + error = NULL; + builder = gtk_builder_new (); + res = gtk_builder_add_from_file (builder, + DATADIR "/modmap-dialog.ui", + &error); + + if (res == 0) { + g_warning ("Could not load UI file: %s", error->message); + g_error_free (error); + g_object_unref (builder); + g_dir_close (homeDir); + return; + } + + load_dialog = GTK_WIDGET (gtk_builder_get_object (builder, "dialog1")); + gtk_window_set_modal (GTK_WINDOW (load_dialog), TRUE); + g_signal_connect (load_dialog, + "response", + G_CALLBACK (response_callback), + builder); + add_button = GTK_WIDGET (gtk_builder_get_object (builder, "button7")); + g_signal_connect (add_button, + "clicked", + G_CALLBACK (load_button_clicked_callback), + load_dialog); + remove_button = GTK_WIDGET (gtk_builder_get_object (builder, + "button6")); + g_signal_connect (remove_button, + "clicked", + G_CALLBACK (remove_button_clicked_callback), + load_dialog); + chk_button = GTK_WIDGET (gtk_builder_get_object (builder, + "checkbutton1")); + g_signal_connect (chk_button, + "toggled", + G_CALLBACK (check_button_callback), + NULL); + g_object_set_data (G_OBJECT (load_dialog), "check_button", chk_button); + treeview = GTK_WIDGET (gtk_builder_get_object (builder, "treeview1")); + g_object_set_data (G_OBJECT (load_dialog), "treeview1", treeview); + treeview = GTK_WIDGET (gtk_builder_get_object (builder, "treeview2")); + g_object_set_data (G_OBJECT (load_dialog), "loaded-treeview", treeview); + tree = gtk_list_store_new (1, G_TYPE_STRING); + cell_renderer = gtk_cell_renderer_text_new (); + column = gtk_tree_view_column_new_with_attributes ("modmap", + cell_renderer, + "text", 0, + NULL); + gtk_tree_view_append_column (GTK_TREE_VIEW (treeview), column); + gtk_tree_view_column_set_sort_column_id (column, 0); + + /* Add the data */ + while ((fname = g_dir_read_name (homeDir)) != NULL) { + if (g_strrstr (fname, "modmap")) { + gtk_list_store_append (tree, &parent_iter); + gtk_list_store_set (tree, &parent_iter, + 0, + fname, + -1); + } + } + sort_model = gtk_tree_model_sort_new_with_model (GTK_TREE_MODEL (tree)); + gtk_tree_sortable_set_sort_column_id (GTK_TREE_SORTABLE (sort_model), + 0, + GTK_SORT_ASCENDING); + gtk_tree_view_set_model (GTK_TREE_VIEW (treeview), sort_model); + g_object_unref (G_OBJECT (tree)); + selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (treeview)); + gtk_tree_selection_set_mode (GTK_TREE_SELECTION (selection), + GTK_SELECTION_MULTIPLE); + gtk_widget_show (load_dialog); + + g_dir_close (homeDir); + + /* Left treeview */ + treeview1 = GTK_WIDGET (gtk_builder_get_object (builder, "treeview1")); + tree = gtk_list_store_new (1, G_TYPE_STRING); + cell_renderer = gtk_cell_renderer_text_new (); + column = gtk_tree_view_column_new_with_attributes ("modmap", + cell_renderer, + "text", 0, + NULL); + gtk_tree_view_append_column (GTK_TREE_VIEW (treeview1), column); + gtk_tree_view_column_set_sort_column_id (column, 0); + + client = mateconf_client_get_default (); + loaded_files = mateconf_client_get_list (client, LOADED_FILES_KEY, MATECONF_VALUE_STRING, NULL); + g_object_unref (client); + + /* Add the data */ + for (tmp = loaded_files; tmp != NULL; tmp = tmp->next) { + gtk_list_store_append (tree, &iter); + gtk_list_store_set (tree, &iter, + 0, + tmp->data, + -1); + } + + g_slist_foreach (loaded_files, (GFunc) g_free, NULL); + g_slist_free (loaded_files); + + sort_model = gtk_tree_model_sort_new_with_model (GTK_TREE_MODEL (tree)); + gtk_tree_sortable_set_sort_column_id (GTK_TREE_SORTABLE (sort_model), + 0, + GTK_SORT_ASCENDING); + gtk_tree_view_set_model (GTK_TREE_VIEW (treeview1), sort_model); + g_object_unref (G_OBJECT (tree)); + selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (treeview1)); + gtk_tree_selection_set_mode (GTK_TREE_SELECTION (selection), + GTK_SELECTION_MULTIPLE); + g_object_set_data (G_OBJECT (load_dialog), "tree", tree); + g_object_unref (builder); +} diff --git a/plugins/keyboard/msd-xmodmap.h b/plugins/keyboard/msd-xmodmap.h new file mode 100644 index 0000000..04b4505 --- /dev/null +++ b/plugins/keyboard/msd-xmodmap.h @@ -0,0 +1,29 @@ +/* mate-settings-xmodmap.h + * + * Copyright © 2005 Novell Inc. + * + * Written by Shakti Sen + * + * 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, 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. + */ + +#ifndef XMODMAP_H +#define XMODMAP_H + +void msd_load_modmap_files (void); +void msd_modmap_dialog_call (void); + +#endif -- cgit v1.2.1