[gnome-settings-daemon] media-keys: Make key list more extensible



commit b4ad800608950c4725bfed5b8f9affda6dde3236
Author: Bastien Nocera <hadess hadess net>
Date:   Wed Nov 2 15:06:23 2011 +0000

    media-keys: Make key list more extensible
    
    By not keying the shortcut type enum to the number of shortcuts
    that we hard-code. Also refactor a few functions to reduce duplication.

 plugins/media-keys/acme.h                   |  104 +++++++-------
 plugins/media-keys/gsd-media-keys-manager.c |  199 ++++++++++++++-------------
 2 files changed, 156 insertions(+), 147 deletions(-)
---
diff --git a/plugins/media-keys/acme.h b/plugins/media-keys/acme.h
index 055c807..c3616fc 100644
--- a/plugins/media-keys/acme.h
+++ b/plugins/media-keys/acme.h
@@ -80,62 +80,60 @@ static struct {
         MediaKeyType key_type;
         const char *settings_key;
         const char *hard_coded;
-        Key *key;
-} keys[] = {
-        { TOUCHPAD_KEY, NULL, "XF86TouchpadToggle", NULL },
-	{ TOUCHPAD_ON_KEY, NULL, "XF86TouchpadOn", NULL },
-	{ TOUCHPAD_OFF_KEY, NULL, "XF86TouchpadOff", NULL },
-        { MUTE_KEY, "volume-mute", NULL, NULL },
-        { VOLUME_DOWN_KEY, "volume-down", NULL, NULL },
-        { VOLUME_UP_KEY, "volume-up", NULL, NULL },
-        { MUTE_QUIET_KEY, NULL, "<Alt>XF86AudioMute", NULL },
-        { VOLUME_DOWN_QUIET_KEY, NULL, "<Alt>XF86AudioLowerVolume", NULL },
-        { VOLUME_UP_QUIET_KEY, NULL, "<Alt>XF86AudioRaiseVolume", NULL },
-        { LOGOUT_KEY, "logout", NULL, NULL },
-        { EJECT_KEY, "eject", NULL, NULL },
-        { HOME_KEY, "home", NULL, NULL },
-        { MEDIA_KEY, "media", NULL, NULL },
-        { CALCULATOR_KEY, "calculator", NULL, NULL },
-        { SEARCH_KEY, "search", NULL, NULL },
-        { EMAIL_KEY, "email", NULL, NULL },
-        { SCREENSAVER_KEY, "screensaver", NULL, NULL },
-        { SCREENSAVER_KEY, NULL, "XF86ScreenSaver", NULL },
-        { HELP_KEY, "help", NULL, NULL },
-        { WWW_KEY, "www", NULL, NULL },
-        { PLAY_KEY, "play", NULL, NULL },
-        { PAUSE_KEY, "pause", NULL, NULL },
-        { STOP_KEY, "stop", NULL, NULL },
-        { PREVIOUS_KEY, "previous", NULL, NULL },
-        { NEXT_KEY, "next", NULL, NULL },
-        /* Those are not configurable in the UI */
-        { REWIND_KEY, NULL, "XF86AudioRewind", NULL },
-        { FORWARD_KEY, NULL, "XF86AudioForward", NULL },
-        { REPEAT_KEY, NULL, "XF86AudioRepeat", NULL },
-        { RANDOM_KEY, NULL, "XF86AudioRandomPlay", NULL},
-        { VIDEO_OUT_KEY, NULL, "<Super>p", NULL },
+} media_keys[] = {
+        { TOUCHPAD_KEY, NULL, "XF86TouchpadToggle" },
+        { TOUCHPAD_ON_KEY, NULL, "XF86TouchpadOn" },
+        { TOUCHPAD_OFF_KEY, NULL, "XF86TouchpadOff" },
+        { MUTE_KEY, "volume-mute", NULL },
+        { VOLUME_DOWN_KEY, "volume-down", NULL },
+        { VOLUME_UP_KEY, "volume-up", NULL },
+        { MUTE_QUIET_KEY, NULL, "<Alt>XF86AudioMute" },
+        { VOLUME_DOWN_QUIET_KEY, NULL, "<Alt>XF86AudioLowerVolume" },
+        { VOLUME_UP_QUIET_KEY, NULL, "<Alt>XF86AudioRaiseVolume" },
+        { LOGOUT_KEY, "logout", NULL },
+        { EJECT_KEY, "eject", NULL },
+        { HOME_KEY, "home", NULL },
+        { MEDIA_KEY, "media", NULL },
+        { CALCULATOR_KEY, "calculator", NULL },
+        { SEARCH_KEY, "search", NULL },
+        { EMAIL_KEY, "email", NULL },
+        { SCREENSAVER_KEY, "screensaver", NULL },
+        { SCREENSAVER_KEY, NULL, "XF86ScreenSaver" },
+        { HELP_KEY, "help", NULL },
+        { WWW_KEY, "www", NULL },
+        { PLAY_KEY, "play", NULL },
+        { PAUSE_KEY, "pause", NULL },
+        { STOP_KEY, "stop", NULL },
+        { PREVIOUS_KEY, "previous", NULL },
+        { NEXT_KEY, "next", NULL },
+        { REWIND_KEY, NULL, "XF86AudioRewind" },
+        { FORWARD_KEY, NULL, "XF86AudioForward" },
+        { REPEAT_KEY, NULL, "XF86AudioRepeat" },
+        { RANDOM_KEY, NULL, "XF86AudioRandomPlay"},
+        { VIDEO_OUT_KEY, NULL, "<Super>p" },
         /* Key code of the XF86Display key (Fn-F7 on Thinkpads, Fn-F4 on HP machines, etc.) */
-        { VIDEO_OUT_KEY, NULL, "XF86Display", NULL },
+        { VIDEO_OUT_KEY, NULL, "XF86Display" },
         /* Key code of the XF86RotateWindows key (present on some tablets) */
-        { ROTATE_VIDEO_KEY, NULL, "XF86RotateWindows", NULL },
-	{ MAGNIFIER_KEY, "magnifier", NULL, NULL },
-	{ SCREENREADER_KEY, "screenreader", NULL, NULL },
-	{ ON_SCREEN_KEYBOARD_KEY, "on-screen-keyboard", NULL, NULL },
-	{ INCREASE_TEXT_KEY, "increase-text-size", NULL, NULL },
-	{ DECREASE_TEXT_KEY, "decrease-text-size", NULL, NULL },
-	{ TOGGLE_CONTRAST_KEY, "toggle-contrast", NULL, NULL },
-	{ MAGNIFIER_ZOOM_IN_KEY, "magnifier-zoom-in", NULL, NULL },
-	{ MAGNIFIER_ZOOM_OUT_KEY, "magnifier-zoom-out", NULL, NULL },
-        { POWER_KEY, NULL, "XF86PowerOff", NULL },
+        { ROTATE_VIDEO_KEY, NULL, "XF86RotateWindows" },
+        { MAGNIFIER_KEY, "magnifier", NULL },
+        { SCREENREADER_KEY, "screenreader", NULL },
+        { ON_SCREEN_KEYBOARD_KEY, "on-screen-keyboard", NULL },
+        { INCREASE_TEXT_KEY, "increase-text-size", NULL },
+        { DECREASE_TEXT_KEY, "decrease-text-size", NULL },
+        { TOGGLE_CONTRAST_KEY, "toggle-contrast", NULL },
+        { MAGNIFIER_ZOOM_IN_KEY, "magnifier-zoom-in", NULL },
+        { MAGNIFIER_ZOOM_OUT_KEY, "magnifier-zoom-out", NULL },
+        { POWER_KEY, NULL, "XF86PowerOff" },
         /* the kernel / Xorg names really are like this... */
-        { SLEEP_KEY, NULL, "XF86Suspend", NULL },
-        { SUSPEND_KEY, NULL, "XF86Sleep", NULL },
-        { HIBERNATE_KEY, NULL, "XF86Hibernate", NULL },
-        { SCREEN_BRIGHTNESS_UP_KEY, NULL, "XF86MonBrightnessUp", NULL },
-        { SCREEN_BRIGHTNESS_DOWN_KEY, NULL, "XF86MonBrightnessDown", NULL },
-        { KEYBOARD_BRIGHTNESS_UP_KEY, NULL, "XF86KbdBrightnessUp", NULL },
-        { KEYBOARD_BRIGHTNESS_DOWN_KEY, NULL, "XF86KbdBrightnessDown", NULL },
-        { KEYBOARD_BRIGHTNESS_TOGGLE_KEY, NULL, "XF86KbdLightOnOff", NULL },
-        { BATTERY_KEY, NULL, "XF86Battery", NULL },
+        { SLEEP_KEY, NULL, "XF86Suspend" },
+        { SUSPEND_KEY, NULL, "XF86Sleep" },
+        { HIBERNATE_KEY, NULL, "XF86Hibernate" },
+        { SCREEN_BRIGHTNESS_UP_KEY, NULL, "XF86MonBrightnessUp" },
+        { SCREEN_BRIGHTNESS_DOWN_KEY, NULL, "XF86MonBrightnessDown" },
+        { KEYBOARD_BRIGHTNESS_UP_KEY, NULL, "XF86KbdBrightnessUp" },
+        { KEYBOARD_BRIGHTNESS_DOWN_KEY, NULL, "XF86KbdBrightnessDown" },
+        { KEYBOARD_BRIGHTNESS_TOGGLE_KEY, NULL, "XF86KbdLightOnOff" },
+        { BATTERY_KEY, NULL, "XF86Battery" },
 };
 
 #endif /* __ACME_H__ */
diff --git a/plugins/media-keys/gsd-media-keys-manager.c b/plugins/media-keys/gsd-media-keys-manager.c
index 8cf52a4..cfe4991 100644
--- a/plugins/media-keys/gsd-media-keys-manager.c
+++ b/plugins/media-keys/gsd-media-keys-manager.c
@@ -104,6 +104,13 @@ typedef struct {
         guint   watch_id;
 } MediaPlayer;
 
+typedef struct {
+        MediaKeyType key_type;
+        const char *settings_key;
+        const char *hard_coded;
+        Key *key;
+} MediaKey;
+
 struct GsdMediaKeysManagerPrivate
 {
         /* Volume bits */
@@ -119,6 +126,8 @@ struct GsdMediaKeysManagerPrivate
         GtkWidget       *dialog;
         GSettings       *settings;
 
+        GPtrArray       *keys;
+
         /* HighContrast theme settings */
         GSettings       *interface_settings;
         char            *icon_theme;
@@ -175,6 +184,14 @@ init_screens (GsdMediaKeysManager *manager)
         manager->priv->current_screen = manager->priv->screens->data;
 }
 
+static void
+media_key_free (MediaKey *key)
+{
+        if (key == NULL)
+                return;
+        free_key (key->key);
+        g_free (key);
+}
 
 static void
 acme_error (char * msg)
@@ -302,68 +319,85 @@ dialog_init (GsdMediaKeysManager *manager)
         }
 }
 
+static void
+print_key_parse_error (MediaKey      *key,
+		       const char    *str,
+		       EggParseError  error)
+{
+	if (error == EGG_PARSE_ERROR_NONE)
+		return;
+	if (key->settings_key != NULL)
+		g_debug ("Unable to parse key '%s' for GSettings entry '%s' (%d)", str, key->settings_key, error);
+	else
+		g_debug ("Unable to parse hard-coded key '%s' (%d)", key->hard_coded, error);
+}
+
+static char *
+get_key_string (GsdMediaKeysManager *manager,
+		MediaKey            *key)
+{
+	if (key->settings_key != NULL)
+		return g_settings_get_string (manager->priv->settings, key->settings_key);
+	else
+		return g_strdup (key->hard_coded);
+}
+
 static gboolean
-is_valid_shortcut (const char *string)
+grab_media_key (MediaKey            *key,
+		GsdMediaKeysManager *manager)
 {
-        if (string == NULL || string[0] == '\0') {
-                return FALSE;
-        }
-        if (strcmp (string, "disabled") == 0) {
-                return FALSE;
-        }
+	char *tmp;
+	EggParseError ret;
+	gboolean need_flush;
 
-        return TRUE;
+	need_flush = FALSE;
+
+	if (key->key != NULL) {
+		need_flush = TRUE;
+		grab_key_unsafe (key->key, FALSE, manager->priv->screens);
+	}
+
+	free_key (key->key);
+	key->key = NULL;
+
+	tmp = get_key_string (manager, key);
+
+	key->key = parse_key (tmp, &ret);
+	if (key->key == NULL) {
+		print_key_parse_error (key, tmp, ret);
+		g_free (tmp);
+		return need_flush;
+	}
+
+	grab_key_unsafe (key->key, TRUE, manager->priv->screens);
+
+	g_free (tmp);
+
+	return TRUE;
 }
 
 static void
 update_kbd_cb (GSettings           *settings,
-               const gchar         *key,
+               const gchar         *settings_key,
                GsdMediaKeysManager *manager)
 {
         int      i;
         gboolean need_flush = TRUE;
 
-        g_return_if_fail (key != NULL);
-
         gdk_error_trap_push ();
 
         /* Find the key that was modified */
-        for (i = 0; i < G_N_ELEMENTS (keys); i++) {
+        for (i = 0; i < manager->priv->keys->len; i++) {
+                MediaKey *key;
+
+                key = g_ptr_array_index (manager->priv->keys, i);
+
                 /* Skip over hard-coded keys */
-                if (keys[i].settings_key == NULL)
+                if (key->settings_key == NULL)
                         continue;
-                if (strcmp (key, keys[i].settings_key) == 0) {
-                        char *tmp;
-                        Key  *key;
-
-                        if (keys[i].key != NULL) {
+                if (strcmp (settings_key, key->settings_key) == 0) {
+                        if (grab_media_key (key, manager))
                                 need_flush = TRUE;
-                                grab_key_unsafe (keys[i].key, FALSE, manager->priv->screens);
-                        }
-
-                        g_free (keys[i].key);
-                        keys[i].key = NULL;
-
-                        tmp = g_settings_get_string (manager->priv->settings, keys[i].settings_key);
-                        if (is_valid_shortcut (tmp) == FALSE) {
-                                g_free (tmp);
-                                break;
-                        }
-
-                        key = g_new0 (Key, 1);
-                        if (egg_accelerator_parse_virtual (tmp, &key->keysym, &key->keycodes, &key->state) != EGG_PARSE_ERROR_NONE) {
-                                g_free (tmp);
-                                g_free (key);
-                                break;
-                        }
-
-                        need_flush = TRUE;
-                        grab_key_unsafe (key, TRUE, manager->priv->screens);
-                        keys[i].key = key;
-
-                        g_free (tmp);
-
-                        break;
                 }
         }
 
@@ -383,44 +417,20 @@ init_kbd (GsdMediaKeysManager *manager)
 
         gdk_error_trap_push ();
 
-        for (i = 0; i < G_N_ELEMENTS (keys); i++) {
-                char *tmp;
-                Key  *key;
-                EggParseError ret;
+        manager->priv->keys = g_ptr_array_new_with_free_func ((GDestroyNotify) media_key_free);
 
-                if (keys[i].settings_key != NULL) {
-                        tmp = g_settings_get_string (manager->priv->settings, keys[i].settings_key);
-                } else {
-                        tmp = g_strdup (keys[i].hard_coded);
-                }
+        for (i = 0; i < G_N_ELEMENTS (media_keys); i++) {
+                MediaKey *key;
 
-                if (!is_valid_shortcut (tmp)) {
-                        if (*tmp != '\0')
-                                g_debug ("Not a valid shortcut: '%s'", tmp);
-                        g_free (tmp);
-                        continue;
-                }
-
-                key = g_new0 (Key, 1);
-                ret = egg_accelerator_parse_virtual (tmp, &key->keysym, &key->keycodes, &key->state);
-                if (ret != EGG_PARSE_ERROR_NONE) {
-                        if (ret != EGG_PARSE_ERROR_NOT_IN_KEYMAP) {
-                                if (keys[i].settings_key != NULL)
-                                        g_debug ("Unable to parse key '%s' for GSettings entry '%s' (%d)", tmp, keys[i].settings_key, ret);
-                                else
-                                        g_debug ("Unable to parse hard-coded key '%s' (%d)", keys[i].hard_coded, ret);
-                        }
-                        g_free (tmp);
-                        g_free (key);
-                        continue;
-                }
+                key = g_new0 (MediaKey, 1);
+                key->key_type = media_keys[i].key_type;
+                key->settings_key = media_keys[i].settings_key;
+                key->hard_coded = media_keys[i].hard_coded;
 
-                g_free (tmp);
+                g_ptr_array_add (manager->priv->keys, key);
 
-                keys[i].key = key;
-
-                need_flush = TRUE;
-                grab_key_unsafe (key, TRUE, manager->priv->screens);
+                if (grab_media_key (key, manager))
+                        need_flush = TRUE;
         }
 
         if (need_flush)
@@ -1764,9 +1774,13 @@ acme_filter_events (XEvent              *xevent,
 
 	deviceid = xev->sourceid;
 
-        for (i = 0; i < G_N_ELEMENTS (keys); i++) {
-                if (match_xi2_key (keys[i].key, xev)) {
-                        switch (keys[i].key_type) {
+        for (i = 0; i < manager->priv->keys->len; i++) {
+                MediaKey *key;
+
+                key = g_ptr_array_index (manager->priv->keys, i);
+
+                if (match_xi2_key (key->key, xev)) {
+                        switch (key->key_type) {
                         case VOLUME_DOWN_KEY:
                         case VOLUME_UP_KEY:
                         case VOLUME_DOWN_QUIET_KEY:
@@ -1783,7 +1797,7 @@ acme_filter_events (XEvent              *xevent,
 
                         manager->priv->current_screen = acme_get_screen_from_root (manager, xev->root);
 
-                        if (do_action (manager, deviceid, keys[i].key_type, xev->time) == FALSE) {
+                        if (do_action (manager, deviceid, key->key_type, xev->time) == FALSE) {
                                 return GDK_FILTER_REMOVE;
                         } else {
                                 return GDK_FILTER_CONTINUE;
@@ -1941,7 +1955,6 @@ gsd_media_keys_manager_stop (GsdMediaKeysManager *manager)
         GSList *ls;
         GList *l;
         int i;
-        gboolean need_flush;
 
         g_debug ("Stopping media_keys manager");
 
@@ -2017,22 +2030,20 @@ gsd_media_keys_manager_stop (GsdMediaKeysManager *manager)
                 priv->connection = NULL;
         }
 
-        need_flush = FALSE;
         gdk_error_trap_push ();
 
-        for (i = 0; i < G_N_ELEMENTS (keys); ++i) {
-                if (keys[i].key) {
-                        need_flush = TRUE;
-                        grab_key_unsafe (keys[i].key, FALSE, priv->screens);
+        for (i = 0; i < priv->keys->len; ++i) {
+                MediaKey *key;
 
-                        g_free (keys[i].key->keycodes);
-                        g_free (keys[i].key);
-                        keys[i].key = NULL;
-                }
+                key = g_ptr_array_index (manager->priv->keys, i);
+
+                if (key->key)
+                        grab_key_unsafe (key->key, FALSE, priv->screens);
         }
+        g_ptr_array_free (priv->keys, TRUE);
+        priv->keys = NULL;
 
-        if (need_flush)
-                gdk_flush ();
+        gdk_flush ();
         gdk_error_trap_pop_ignored ();
 
         if (priv->screens != NULL) {



[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]