[virt-tools-list] [PATCH virt-viewer 9/9] spice: teach customizable key bindings with controller
Marc-André Lureau
marcandre.lureau at gmail.com
Wed Feb 15 00:30:00 UTC 2012
Tested with RHEVM 3.0 instance with custom bindings for fullscreen &
ungrab.
---
src/remote-viewer.c | 150 +++++++++++++++++++++++++++++++++++++++++++++++++++
1 files changed, 150 insertions(+), 0 deletions(-)
diff --git a/src/remote-viewer.c b/src/remote-viewer.c
index 1fddad4..3b8f168 100644
--- a/src/remote-viewer.c
+++ b/src/remote-viewer.c
@@ -337,6 +337,119 @@ remote_viewer_get_spice_session(RemoteViewer *self)
#define G_VALUE_INIT { 0, { { 0 } } }
#endif
+static gchar *
+ctrl_key_to_gtk_key(const gchar *key)
+{
+ int i;
+
+ static const struct {
+ const char *ctrl;
+ const char *gtk;
+ } keys[] = {
+ /* FIXME: right alt, right ctrl, right shift, cmds */
+ { "alt", "<Alt>" },
+ { "ralt", "<Alt>" },
+ { "rightalt", "<Alt>" },
+ { "right-alt", "<Alt>" },
+ { "lalt", "<Alt>" },
+ { "leftalt", "<Alt>" },
+ { "left-alt", "<Alt>" },
+
+ { "ctrl", "<Ctrl>" },
+ { "rctrl", "<Ctrl>" },
+ { "rightctrl", "<Ctrl>" },
+ { "right-ctrl", "<Ctrl>" },
+ { "lctrl", "<Ctrl>" },
+ { "leftctrl", "<Ctrl>" },
+ { "left-ctrl", "<Ctrl>" },
+
+ { "shift", "<Shift>" },
+ { "rshift", "<Shift>" },
+ { "rightshift", "<Shift>" },
+ { "right-shift", "<Shift>" },
+ { "lshift", "<Shift>" },
+ { "leftshift", "<Shift>" },
+ { "left-shift", "<Shift>" },
+
+ { "cmd", "<Ctrl>" },
+ { "rcmd", "<Ctrl>" },
+ { "rightcmd", "<Ctrl>" },
+ { "right-cmd", "<Ctrl>" },
+ { "lcmd", "<Ctrl>" },
+ { "leftcmd", "<Ctrl>" },
+ { "left-cmd", "<Ctrl>" },
+
+ { "win", "<Super>" },
+ { "rwin", "<Super>" },
+ { "rightwin", "<Super>" },
+ { "right-win", "<Super>" },
+ { "lwin", "<Super>" },
+ { "leftwin", "<Super>" },
+ { "left-win", "<Super>" },
+
+ { "esc", "Escape" },
+ /* { "escape", "Escape" }, */
+
+ { "ins", "Insert" },
+ /* { "insert", "Insert" }, */
+
+ { "del", "Delete" },
+ /* { "delete", "Delete" }, */
+
+ { "pgup", "Page_Up" },
+ { "pageup", "Page_Up" },
+ { "pgdn", "Page_Down" },
+ { "pagedown", "Page_Down" },
+
+ /* { "home", "home" }, */
+ /* { "end", "end" }, */
+ /* { "space", "space" }, */
+
+ { "enter", "Return" },
+
+ /* { "tab", "tab" }, */
+ /* { "f1", "F1" }, */
+ /* { "f2", "F2" }, */
+ /* { "f3", "F3" }, */
+ /* { "f4", "F4" }, */
+ /* { "f5", "F5" }, */
+ /* { "f6", "F6" }, */
+ /* { "f7", "F7" }, */
+ /* { "f8", "F8" }, */
+ /* { "f9", "F9" }, */
+ /* { "f10", "F10" }, */
+ /* { "f11", "F11" }, */
+ /* { "f12", "F12" } */
+ };
+
+ for (i = 0; i < G_N_ELEMENTS(keys); ++i) {
+ if (g_ascii_strcasecmp(keys[i].ctrl, key) == 0)
+ return g_strdup(keys[i].gtk);
+ }
+
+ return g_ascii_strup(key, -1);
+}
+
+static gchar*
+ctrl_key_to_gtk_accelerator(const gchar *key)
+{
+ gchar *accel, **k, **keyv;
+
+ keyv = g_strsplit(key, "+", -1);
+ g_return_val_if_fail(keyv != NULL, NULL);
+
+ for (k = keyv; *k != NULL; k++) {
+ gchar *tmp = *k;
+ *k = ctrl_key_to_gtk_key(tmp);
+ g_free(tmp);
+ }
+
+ accel = g_strjoinv(NULL, keyv);
+ g_strfreev(keyv);
+
+ return accel;
+}
+
static void
spice_ctrl_notified(SpiceCtrlController *ctrl,
GParamSpec *pspec,
@@ -373,6 +486,42 @@ spice_ctrl_notified(SpiceCtrlController *ctrl,
/* g_object_set(G_OBJECT(self), "resize-guest", auto_res, NULL); */
} else if (g_str_equal(pspec->name, "menu")) {
spice_ctrl_menu_updated(self, g_value_get_object(&value));
+ } else if (g_str_equal(pspec->name, "hotkeys")) {
+ gchar **hotkey, **hotkeys = g_strsplit(g_value_get_string(&value), ",", -1);
+ if (!hotkeys || g_strv_length(hotkeys) == 0) {
+ g_object_set(app, "enable-accel", FALSE, NULL);
+ goto end;
+ }
+
+ for (hotkey = hotkeys; *hotkey != NULL; hotkey++) {
+ gchar *key = strstr(*hotkey, "=");
+ if (key == NULL) {
+ g_warn_if_reached();
+ continue;
+ }
+ *key = '\0';
+
+ gchar *accel = ctrl_key_to_gtk_accelerator(key + 1);
+ guint accel_key;
+ GdkModifierType accel_mods;
+ gtk_accelerator_parse(accel, &accel_key, &accel_mods);
+ g_free(accel);
+
+ if (g_str_equal(*hotkey, "toggle-fullscreen")) {
+ gtk_accel_map_change_entry("<virt-viewer>/view/fullscreen", accel_key, accel_mods, TRUE);
+ } else if (g_str_equal(*hotkey, "release-cursor")) {
+ gtk_accel_map_change_entry("<virt-viewer>/view/release-cursor", accel_key, accel_mods, TRUE);
+ } else if (g_str_equal(*hotkey, "smartcard-insert")) {
+ gtk_accel_map_change_entry("<virt-viewer>/file/smartcard-insert", accel_key, accel_mods, TRUE);
+ } else if (g_str_equal(*hotkey, "smartcard-remove")) {
+ gtk_accel_map_change_entry("<virt-viewer>/file/smartcard-remove", accel_key, accel_mods, TRUE);
+ } else {
+ g_warning("Unknown hotkey command %s", *hotkey);
+ }
+ }
+ g_strfreev(hotkeys);
+
+ g_object_set(app, "enable-accel", TRUE, NULL);
} else {
gchar *content = g_strdup_value_contents(&value);
@@ -380,6 +529,7 @@ spice_ctrl_notified(SpiceCtrlController *ctrl,
g_free(content);
}
+end:
g_object_unref(session);
g_value_unset(&value);
}
--
1.7.7.6
More information about the virt-tools-list
mailing list