[PATCH 24/25] Move X keycode -> PC scancode conversion into VncDisplay
- From: "Daniel P. Berrange" <berrange redhat com>
- To: gtk-vnc-list gnome org
- Cc: "Daniel P. Berrange" <berrange redhat com>
- Subject: [PATCH 24/25] Move X keycode -> PC scancode conversion into VncDisplay
- Date: Sat, 21 Nov 2009 13:28:13 +0000
The VncConnection class should not depend on anything from GDK.
The X keycode to PC scancode conversion uses GDK. Therefore it
had to be moved into the VncDisplay class
---
src/Makefile.am | 2 +-
src/vnc_keycodes.h | 34 -----
src/vncconnection.c | 6 -
src/vncdisplay.c | 34 ++++--
src/vncdisplaykeymap.c | 317 ++++++++++++++++++++++++++++++++++++++++++++++++
src/vncdisplaykeymap.h | 33 +++++
src/x_keymap.c | 307 ----------------------------------------------
src/x_keymap.h | 33 -----
8 files changed, 374 insertions(+), 392 deletions(-)
delete mode 100644 src/vnc_keycodes.h
create mode 100644 src/vncdisplaykeymap.c
create mode 100644 src/vncdisplaykeymap.h
delete mode 100644 src/x_keymap.c
delete mode 100644 src/x_keymap.h
diff --git a/src/Makefile.am b/src/Makefile.am
index f496e56..c5df08d 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -32,8 +32,8 @@ libgtk_vnc_1_0_la_SOURCES = blt.h blt1.h \
vncconnectionenums.h vncconnectionenums.c \
vncdisplay.h vncdisplay.c \
vncdisplayenums.h vncdisplayenums.c \
+ vncdisplaykeymap.h vncdisplaykeymap.c \
vncmarshal.h vncmarshal.c \
- x_keymap.h x_keymap.c vnc_keycodes.h \
utils.h
if WITH_UCONTEXT
diff --git a/src/vnc_keycodes.h b/src/vnc_keycodes.h
deleted file mode 100644
index bfede2e..0000000
--- a/src/vnc_keycodes.h
+++ /dev/null
@@ -1,34 +0,0 @@
-/*
- * GTK VNC Widget
- *
- * Copyright (C) 2006 Anthony Liguori <anthony codemonkey ws>
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 2.0 of the License, or (at your option) any later version.
- *
- * This library 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
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
- */
-
-#ifndef _GTK_VNC_KEYCODES
-#define _GTK_VNC_KEYCODES
-
-/* All keycodes from 0 to 0xFF correspond to the hardware keycodes generated
- * by a US101 PC keyboard with the following encoding:
- *
- * 0) Sequences of XX are replaced with XX
- * 1) Sequences of 0xe0 XX are replaces with XX | 0x80
- * 2) All other keys are defined below
- */
-
-#define VKC_PAUSE 0x100
-
-#endif
diff --git a/src/vncconnection.c b/src/vncconnection.c
index 299164a..9952997 100644
--- a/src/vncconnection.c
+++ b/src/vncconnection.c
@@ -42,8 +42,6 @@
#include "coroutine.h"
#include "d3des.h"
-#include "x_keymap.h"
-
#include "utils.h"
#include <gnutls/gnutls.h>
#include <gnutls/x509.h>
@@ -186,7 +184,6 @@ struct _VncConnectionPrivate
int zrle_pi_bits;
gboolean has_ext_key_event;
- const guint8 const *keycode_map;
};
G_DEFINE_TYPE(VncConnection, vnc_connection, G_TYPE_OBJECT);
@@ -1372,8 +1369,6 @@ gboolean vnc_connection_key_event(VncConnection *conn, guint8 down_flag,
GVNC_DEBUG("Key event %d %d %d %d", key, scancode, down_flag, priv->has_ext_key_event);
if (priv->has_ext_key_event) {
- scancode = x_keycode_to_pc_keycode(priv->keycode_map, scancode);
-
vnc_connection_buffered_write_u8(conn, 255);
vnc_connection_buffered_write_u8(conn, 0);
vnc_connection_buffered_write_u16(conn, down_flag);
@@ -2449,7 +2444,6 @@ static void vnc_connection_ext_key_event(VncConnection *conn)
VncConnectionPrivate *priv = conn->priv;
priv->has_ext_key_event = TRUE;
- priv->keycode_map = x_keycode_to_pc_keycode_map();
}
static void vnc_connection_framebuffer_update(VncConnection *conn, gint32 etype,
diff --git a/src/vncdisplay.c b/src/vncdisplay.c
index 09a84a8..fd038bb 100644
--- a/src/vncdisplay.c
+++ b/src/vncdisplay.c
@@ -28,7 +28,7 @@
#include "utils.h"
#include "vncmarshal.h"
#include "config.h"
-#include "x_keymap.h"
+#include "vncdisplaykeymap.h"
#include "vncdisplayenums.h"
#include <gtk/gtk.h>
@@ -90,6 +90,7 @@ struct _VncDisplayPrivate
gboolean force_size;
GSList *preferable_auths;
+ const guint8 const *keycode_map;
};
/* Delayed signal emission.
@@ -700,7 +701,7 @@ static gboolean key_event(GtkWidget *widget, GdkEventKey *key)
key->type == GDK_KEY_PRESS ? "press" : "release",
key->hardware_keycode, key->state, key->group, keyval);
- keyval = x_keymap_get_keyval_from_keycode(key->hardware_keycode, keyval);
+ keyval = vnc_display_keyval_from_keycode(key->hardware_keycode, keyval);
/*
* Some VNC suckiness with key state & modifiers in particular
@@ -730,6 +731,8 @@ static gboolean key_event(GtkWidget *widget, GdkEventKey *key)
for (i = 0 ; i < (int)(sizeof(priv->down_keyval)/sizeof(priv->down_keyval[0])) ; i++) {
/* We were pressed, and now we're released, so... */
if (priv->down_scancode[i] == key->hardware_keycode) {
+ guint16 scancode = vnc_display_keymap_x2pc(priv->keycode_map,
+ key->hardware_keycode);
/*
* ..send the key release event we're dealing with
*
@@ -740,7 +743,7 @@ static gboolean key_event(GtkWidget *widget, GdkEventKey *key)
* true, with "Tab" generating Tab on press, and
* ISO_Prev_Group on release.
*/
- vnc_connection_key_event(priv->conn, 0, priv->down_keyval[i], key->hardware_keycode);
+ vnc_connection_key_event(priv->conn, 0, priv->down_keyval[i], scancode);
priv->down_keyval[i] = 0;
priv->down_scancode[i] = 0;
break;
@@ -750,10 +753,12 @@ static gboolean key_event(GtkWidget *widget, GdkEventKey *key)
if (key->type == GDK_KEY_PRESS) {
for (i = 0 ; i < (int)(sizeof(priv->down_keyval)/sizeof(priv->down_keyval[0])) ; i++) {
if (priv->down_scancode[i] == 0) {
+ guint16 scancode = vnc_display_keymap_x2pc(priv->keycode_map,
+ key->hardware_keycode);
priv->down_keyval[i] = keyval;
priv->down_scancode[i] = key->hardware_keycode;
/* Send the actual key event we're dealing with */
- vnc_connection_key_event(priv->conn, 1, keyval, key->hardware_keycode);
+ vnc_connection_key_event(priv->conn, 1, keyval, scancode);
break;
}
}
@@ -812,9 +817,11 @@ static gboolean focus_event(GtkWidget *widget, GdkEventFocus *focus G_GNUC_UNUSE
for (i = 0 ; i < (int)(sizeof(priv->down_keyval)/sizeof(priv->down_keyval[0])) ; i++) {
/* We are currently pressed so... */
if (priv->down_scancode[i] != 0) {
+ guint16 scancode = vnc_display_keymap_x2pc(priv->keycode_map,
+ priv->down_scancode[i]);
/* ..send the fake key release event to match */
vnc_connection_key_event(priv->conn, 0,
- priv->down_keyval[i], priv->down_scancode[i]);
+ priv->down_keyval[i], scancode);
priv->down_keyval[i] = 0;
priv->down_scancode[i] = 0;
}
@@ -1307,7 +1314,6 @@ static void *vnc_coroutine(void *opaque)
}
GVNC_DEBUG("Started background coroutine");
- x_keymap_set_keymap_entries();
if (priv->fd != -1) {
if (!vnc_connection_open_fd(priv->conn, priv->fd))
@@ -1368,7 +1374,6 @@ static void *vnc_coroutine(void *opaque)
vnc_connection_close(priv->conn);
emit_signal_delayed(obj, VNC_DISCONNECTED, &s);
g_idle_add(delayed_unref_object, obj);
- x_keymap_free_keymap_entries();
/* Co-routine exits now - the VncDisplay object may no longer exist,
so don't do anything else now unless you like SEGVs */
return NULL;
@@ -1474,8 +1479,9 @@ void vnc_display_send_keys(VncDisplay *obj, const guint *keyvals, int nkeyvals)
nkeyvals, VNC_DISPLAY_KEY_EVENT_CLICK);
}
-static guint get_keycode_from_keyval(guint keyval)
+static guint get_scancode_from_keyval(VncDisplay *obj, guint keyval)
{
+ VncDisplayPrivate *priv = obj->priv;
guint keycode = 0;
GdkKeymapKey *keys = NULL;
gint n_keys = 0;
@@ -1487,7 +1493,7 @@ static guint get_keycode_from_keyval(guint keyval)
g_free(keys);
}
- return keycode;
+ return vnc_display_keymap_x2pc(priv->keycode_map, keycode);
}
void vnc_display_send_keys_ex(VncDisplay *obj, const guint *keyvals,
@@ -1501,13 +1507,13 @@ void vnc_display_send_keys_ex(VncDisplay *obj, const guint *keyvals,
if (kind & VNC_DISPLAY_KEY_EVENT_PRESS) {
for (i = 0 ; i < nkeyvals ; i++)
vnc_connection_key_event(obj->priv->conn, 1, keyvals[i],
- get_keycode_from_keyval(keyvals[i]));
+ get_scancode_from_keyval(obj, keyvals[i]));
}
if (kind & VNC_DISPLAY_KEY_EVENT_RELEASE) {
for (i = (nkeyvals-1) ; i >= 0 ; i--)
vnc_connection_key_event(obj->priv->conn, 0, keyvals[i],
- get_keycode_from_keyval(keyvals[i]));
+ get_scancode_from_keyval(obj, keyvals[i]));
}
}
@@ -1572,6 +1578,8 @@ static void vnc_display_finalize (GObject *obj)
g_slist_free (priv->preferable_auths);
+ vnc_display_keyval_free_entries();
+
G_OBJECT_CLASS (vnc_display_parent_class)->finalize (obj);
}
@@ -1891,6 +1899,8 @@ static void vnc_display_init(VncDisplay *display)
GTK_WIDGET_SET_FLAGS(obj, GTK_CAN_FOCUS);
+ vnc_display_keyval_set_entries();
+
gtk_widget_add_events(widget,
GDK_POINTER_MOTION_MASK |
GDK_BUTTON_PRESS_MASK |
@@ -1963,6 +1973,8 @@ static void vnc_display_init(VncDisplay *display)
G_CALLBACK(on_auth_choose_type), display);
g_signal_connect(G_OBJECT(priv->conn), "vnc-auth-choose-subtype",
G_CALLBACK(on_auth_choose_subtype), display);
+
+ priv->keycode_map = vnc_display_keymap_x2pc_table();
}
gboolean vnc_display_set_credential(VncDisplay *obj, int type, const gchar *data)
diff --git a/src/vncdisplaykeymap.c b/src/vncdisplaykeymap.c
new file mode 100644
index 0000000..1c5ecc8
--- /dev/null
+++ b/src/vncdisplaykeymap.c
@@ -0,0 +1,317 @@
+/*
+ * Copyright (C) 2008 Anthony Liguori <anthony codemonkey ws>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ */
+
+#include <gdk/gdk.h>
+#include <gdk/gdkkeysyms.h>
+#include "vncdisplaykeymap.h"
+#include "utils.h"
+
+/*
+ * This table is taken from QEMU x_keymap.c, under the terms:
+ *
+ * Copyright (c) 2003 Fabrice Bellard
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ */
+
+static const guint8 x_keycode_to_pc_keycode_table[61] = {
+ 0xc7, /* 97 Home */
+ 0xc8, /* 98 Up */
+ 0xc9, /* 99 PgUp */
+ 0xcb, /* 100 Left */
+ 0x4c, /* 101 KP-5 */
+ 0xcd, /* 102 Right */
+ 0xcf, /* 103 End */
+ 0xd0, /* 104 Down */
+ 0xd1, /* 105 PgDn */
+ 0xd2, /* 106 Ins */
+ 0xd3, /* 107 Del */
+ 0x9c, /* 108 Enter */
+ 0x9d, /* 109 Ctrl-R */
+ 0, /* 110 Pause */
+ 0xb7, /* 111 Print */
+ 0xb5, /* 112 Divide */
+ 0xb8, /* 113 Alt-R */
+ 0xc6, /* 114 Break */
+ 0, /* 115 */
+ 0, /* 116 */
+ 0, /* 117 */
+ 0, /* 118 */
+ 0, /* 119 */
+ 0, /* 120 */
+ 0, /* 121 */
+ 0, /* 122 */
+ 0, /* 123 */
+ 0, /* 124 */
+ 0, /* 125 */
+ 0, /* 126 */
+ 0, /* 127 */
+ 0, /* 128 */
+ 0x79, /* 129 Henkan */
+ 0, /* 130 */
+ 0x7b, /* 131 Muhenkan */
+ 0, /* 132 */
+ 0x7d, /* 133 Yen */
+ 0, /* 134 */
+ 0, /* 135 */
+ 0x47, /* 136 KP_7 */
+ 0x48, /* 137 KP_8 */
+ 0x49, /* 138 KP_9 */
+ 0x4b, /* 139 KP_4 */
+ 0x4c, /* 140 KP_5 */
+ 0x4d, /* 141 KP_6 */
+ 0x4f, /* 142 KP_1 */
+ 0x50, /* 143 KP_2 */
+ 0x51, /* 144 KP_3 */
+ 0x52, /* 145 KP_0 */
+ 0x53, /* 146 KP_. */
+ 0x47, /* 147 KP_HOME */
+ 0x48, /* 148 KP_UP */
+ 0x49, /* 149 KP_PgUp */
+ 0x4b, /* 150 KP_Left */
+ 0x4c, /* 151 KP_ */
+ 0x4d, /* 152 KP_Right */
+ 0x4f, /* 153 KP_End */
+ 0x50, /* 154 KP_Down */
+ 0x51, /* 155 KP_PgDn */
+ 0x52, /* 156 KP_Ins */
+ 0x53, /* 157 KP_Del */
+};
+
+/* This table is generated based off the xfree86 -> scancode mapping above
+ * and the keycode mappings in /usr/share/X11/xkb/keycodes/evdev
+ * and /usr/share/X11/xkb/keycodes/xfree86
+ */
+
+static const guint8 evdev_keycode_to_pc_keycode[61] = {
+ 0, /* 97 EVDEV - RO ("Internet" Keyboards) */
+ 0, /* 98 EVDEV - KATA (Katakana) */
+ 0, /* 99 EVDEV - HIRA (Hiragana) */
+ 0x79, /* 100 EVDEV - HENK (Henkan) */
+ 0x70, /* 101 EVDEV - HKTG (Hiragana/Katakana toggle) */
+ 0x7b, /* 102 EVDEV - MUHE (Muhenkan) */
+ 0, /* 103 EVDEV - JPCM (KPJPComma) */
+ 0x9c, /* 104 KPEN */
+ 0x9d, /* 105 RCTL */
+ 0xb5, /* 106 KPDV */
+ 0xb7, /* 107 PRSC */
+ 0xb8, /* 108 RALT */
+ 0, /* 109 EVDEV - LNFD ("Internet" Keyboards) */
+ 0xc7, /* 110 HOME */
+ 0xc8, /* 111 UP */
+ 0xc9, /* 112 PGUP */
+ 0xcb, /* 113 LEFT */
+ 0xcd, /* 114 RGHT */
+ 0xcf, /* 115 END */
+ 0xd0, /* 116 DOWN */
+ 0xd1, /* 117 PGDN */
+ 0xd2, /* 118 INS */
+ 0xd3, /* 119 DELE */
+ 0, /* 120 EVDEV - I120 ("Internet" Keyboards) */
+ 0, /* 121 EVDEV - MUTE */
+ 0, /* 122 EVDEV - VOL- */
+ 0, /* 123 EVDEV - VOL+ */
+ 0, /* 124 EVDEV - POWR */
+ 0, /* 125 EVDEV - KPEQ */
+ 0, /* 126 EVDEV - I126 ("Internet" Keyboards) */
+ 0, /* 127 EVDEV - PAUS */
+ 0, /* 128 EVDEV - ???? */
+ 0, /* 129 EVDEV - I129 ("Internet" Keyboards) */
+ 0xf1, /* 130 EVDEV - HNGL (Korean Hangul Latin toggle) */
+ 0xf2, /* 131 EVDEV - HJCV (Korean Hangul Hanja toggle) */
+ 0x7d, /* 132 AE13 (Yen)*/
+ 0xdb, /* 133 EVDEV - LWIN */
+ 0xdc, /* 134 EVDEV - RWIN */
+ 0xdd, /* 135 EVDEV - MENU */
+ 0, /* 136 EVDEV - STOP */
+ 0, /* 137 EVDEV - AGAI */
+ 0, /* 138 EVDEV - PROP */
+ 0, /* 139 EVDEV - UNDO */
+ 0, /* 140 EVDEV - FRNT */
+ 0, /* 141 EVDEV - COPY */
+ 0, /* 142 EVDEV - OPEN */
+ 0, /* 143 EVDEV - PAST */
+ 0, /* 144 EVDEV - FIND */
+ 0, /* 145 EVDEV - CUT */
+ 0, /* 146 EVDEV - HELP */
+ 0, /* 147 EVDEV - I147 */
+ 0, /* 148 EVDEV - I148 */
+ 0, /* 149 EVDEV - I149 */
+ 0, /* 150 EVDEV - I150 */
+ 0, /* 151 EVDEV - I151 */
+ 0, /* 152 EVDEV - I152 */
+ 0, /* 153 EVDEV - I153 */
+ 0, /* 154 EVDEV - I154 */
+ 0, /* 155 EVDEV - I156 */
+ 0, /* 156 EVDEV - I157 */
+ 0, /* 157 EVDEV - I158 */
+};
+
+
+/* keycode translation for sending ISO_Left_Send
+ * to vncserver
+ */
+static struct {
+ GdkKeymapKey *keys;
+ gint n_keys;
+ guint keyval;
+} untranslated_keys[] = {{NULL, 0, GDK_Tab}};
+
+static unsigned int ref_count_for_untranslated_keys = 0;
+
+/* As best as I can tell, windows passes PC scan codes. This code definitely
+ * won't compile on windows so let's put in a guard anyway */
+
+#ifndef WIN32
+#include <gdk/gdkx.h>
+#include <X11/XKBlib.h>
+#include <stdbool.h>
+#include <string.h>
+
+#define STRPREFIX(a,b) (strncmp((a),(b),strlen((b))) == 0)
+
+static gboolean check_for_evdev(void)
+{
+ XkbDescPtr desc;
+ gboolean has_evdev = FALSE;
+ const gchar *keycodes;
+
+ desc = XkbGetKeyboard(GDK_DISPLAY(), XkbGBN_AllComponentsMask,
+ XkbUseCoreKbd);
+ if (desc == NULL || desc->names == NULL)
+ return FALSE;
+
+ keycodes = gdk_x11_get_xatom_name(desc->names->keycodes);
+ if (keycodes == NULL)
+ g_warning("could not lookup keycode name\n");
+ else if (STRPREFIX(keycodes, "evdev_"))
+ has_evdev = TRUE;
+ else if (!STRPREFIX(keycodes, "xfree86_"))
+ g_warning("unknown keycodes `%s', please report to gtk-vnc-devel\n",
+ keycodes);
+
+ XkbFreeClientMap(desc, XkbGBN_AllComponentsMask, True);
+
+ return has_evdev;
+}
+#else
+static gboolean check_for_evdev(void)
+{
+ return FALSE;
+}
+#endif
+
+const guint8 const *vnc_display_keymap_x2pc_table(void)
+{
+ if (check_for_evdev()) {
+ GVNC_DEBUG("Using evdev keycode mapping");
+ return evdev_keycode_to_pc_keycode;
+ } else {
+ GVNC_DEBUG("Using xfree86 keycode mapping");
+ return x_keycode_to_pc_keycode_table;
+ }
+}
+
+/* All keycodes from 0 to 0xFF correspond to the hardware keycodes generated
+ * by a US101 PC keyboard with the following encoding:
+ *
+ * 0) Sequences of XX are replaced with XX
+ * 1) Sequences of 0xe0 XX are replaces with XX | 0x80
+ * 2) All other keys are defined below
+ */
+
+#define VKC_PAUSE 0x100
+
+guint16 vnc_display_keymap_x2pc(const guint8 const *keycode_map,
+ guint16 keycode)
+{
+ if (keycode == GDK_Pause)
+ return VKC_PAUSE;
+
+ if (keycode < 9)
+ return 0;
+
+ if (keycode < 97)
+ return keycode - 8; /* just an offset */
+
+ if (keycode < 158)
+ return keycode_map[keycode - 97];
+
+ if (keycode == 208) /* Hiragana_Katakana */
+ return 0x70;
+
+ if (keycode == 211) /* backslash */
+ return 0x73;
+
+ return 0;
+}
+
+/* Set the keymap entries */
+void vnc_display_keyval_set_entries(void)
+{
+ size_t i;
+ if (ref_count_for_untranslated_keys == 0)
+ for (i = 0; i < sizeof(untranslated_keys) / sizeof(untranslated_keys[0]); i++)
+ gdk_keymap_get_entries_for_keyval(gdk_keymap_get_default(),
+ untranslated_keys[i].keyval,
+ &untranslated_keys[i].keys,
+ &untranslated_keys[i].n_keys);
+ ref_count_for_untranslated_keys++;
+}
+
+/* Free the keymap entries */
+void vnc_display_keyval_free_entries(void)
+{
+ size_t i;
+
+ if (ref_count_for_untranslated_keys == 0)
+ return;
+
+ ref_count_for_untranslated_keys--;
+ if (ref_count_for_untranslated_keys == 0)
+ for (i = 0; i < sizeof(untranslated_keys) / sizeof(untranslated_keys[0]); i++)
+ g_free(untranslated_keys[i].keys);
+
+}
+
+/* Get the keyval from the keycode without the level. */
+guint vnc_display_keyval_from_keycode(guint keycode, guint keyval)
+{
+ size_t i;
+ for (i = 0; i < sizeof(untranslated_keys) / sizeof(untranslated_keys[0]); i++) {
+ if (keycode == untranslated_keys[i].keys[0].keycode) {
+ return untranslated_keys[i].keyval;
+ }
+ }
+
+ return keyval;
+}
+/*
+ * Local variables:
+ * c-indent-level: 8
+ * c-basic-offset: 8
+ * tab-width: 8
+ * End:
+ */
diff --git a/src/vncdisplaykeymap.h b/src/vncdisplaykeymap.h
new file mode 100644
index 0000000..4b31e5f
--- /dev/null
+++ b/src/vncdisplaykeymap.h
@@ -0,0 +1,33 @@
+/*
+ * GTK VNC Widget
+ *
+ * Copyright (C) 2006 Anthony Liguori <anthony codemonkey ws>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.0 of the License, or (at your option) any later version.
+ *
+ * This library 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#ifndef VNC_DISPLAY_KEYMAP_H
+#define VNC_DISPLAY_KEYMAP_H
+
+#include <glib.h>
+
+const guint8 const *vnc_display_keymap_x2pc_table(void);
+guint16 vnc_display_keymap_x2pc(const guint8 *keycode_map,
+ guint16 keycode);
+void vnc_display_keyval_set_entries(void);
+void vnc_display_keyval_free_entries(void);
+guint vnc_display_keyval_from_keycode(guint keycode, guint keyval);
+
+#endif /* VNC_DISPLAY_KEYMAP_H */
diff --git a/src/x_keymap.c b/src/x_keymap.c
deleted file mode 100644
index 00e9e45..0000000
--- a/src/x_keymap.c
+++ /dev/null
@@ -1,307 +0,0 @@
-/*
- * Copyright (C) 2008 Anthony Liguori <anthony codemonkey ws>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU Lesser General Public License version 2 as
- * published by the Free Software Foundation.
- *
- */
-
-#include <gdk/gdkkeysyms.h>
-#include "x_keymap.h"
-#include "utils.h"
-#include "vnc_keycodes.h"
-
-/*
- * This table is taken from QEMU x_keymap.c, under the terms:
- *
- * Copyright (c) 2003 Fabrice Bellard
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
- * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
- * THE SOFTWARE.
- */
-
-static const guint8 x_keycode_to_pc_keycode_table[61] = {
- 0xc7, /* 97 Home */
- 0xc8, /* 98 Up */
- 0xc9, /* 99 PgUp */
- 0xcb, /* 100 Left */
- 0x4c, /* 101 KP-5 */
- 0xcd, /* 102 Right */
- 0xcf, /* 103 End */
- 0xd0, /* 104 Down */
- 0xd1, /* 105 PgDn */
- 0xd2, /* 106 Ins */
- 0xd3, /* 107 Del */
- 0x9c, /* 108 Enter */
- 0x9d, /* 109 Ctrl-R */
- 0, /* 110 Pause */
- 0xb7, /* 111 Print */
- 0xb5, /* 112 Divide */
- 0xb8, /* 113 Alt-R */
- 0xc6, /* 114 Break */
- 0, /* 115 */
- 0, /* 116 */
- 0, /* 117 */
- 0, /* 118 */
- 0, /* 119 */
- 0, /* 120 */
- 0, /* 121 */
- 0, /* 122 */
- 0, /* 123 */
- 0, /* 124 */
- 0, /* 125 */
- 0, /* 126 */
- 0, /* 127 */
- 0, /* 128 */
- 0x79, /* 129 Henkan */
- 0, /* 130 */
- 0x7b, /* 131 Muhenkan */
- 0, /* 132 */
- 0x7d, /* 133 Yen */
- 0, /* 134 */
- 0, /* 135 */
- 0x47, /* 136 KP_7 */
- 0x48, /* 137 KP_8 */
- 0x49, /* 138 KP_9 */
- 0x4b, /* 139 KP_4 */
- 0x4c, /* 140 KP_5 */
- 0x4d, /* 141 KP_6 */
- 0x4f, /* 142 KP_1 */
- 0x50, /* 143 KP_2 */
- 0x51, /* 144 KP_3 */
- 0x52, /* 145 KP_0 */
- 0x53, /* 146 KP_. */
- 0x47, /* 147 KP_HOME */
- 0x48, /* 148 KP_UP */
- 0x49, /* 149 KP_PgUp */
- 0x4b, /* 150 KP_Left */
- 0x4c, /* 151 KP_ */
- 0x4d, /* 152 KP_Right */
- 0x4f, /* 153 KP_End */
- 0x50, /* 154 KP_Down */
- 0x51, /* 155 KP_PgDn */
- 0x52, /* 156 KP_Ins */
- 0x53, /* 157 KP_Del */
-};
-
-/* This table is generated based off the xfree86 -> scancode mapping above
- * and the keycode mappings in /usr/share/X11/xkb/keycodes/evdev
- * and /usr/share/X11/xkb/keycodes/xfree86
- */
-
-static const guint8 evdev_keycode_to_pc_keycode[61] = {
- 0, /* 97 EVDEV - RO ("Internet" Keyboards) */
- 0, /* 98 EVDEV - KATA (Katakana) */
- 0, /* 99 EVDEV - HIRA (Hiragana) */
- 0x79, /* 100 EVDEV - HENK (Henkan) */
- 0x70, /* 101 EVDEV - HKTG (Hiragana/Katakana toggle) */
- 0x7b, /* 102 EVDEV - MUHE (Muhenkan) */
- 0, /* 103 EVDEV - JPCM (KPJPComma) */
- 0x9c, /* 104 KPEN */
- 0x9d, /* 105 RCTL */
- 0xb5, /* 106 KPDV */
- 0xb7, /* 107 PRSC */
- 0xb8, /* 108 RALT */
- 0, /* 109 EVDEV - LNFD ("Internet" Keyboards) */
- 0xc7, /* 110 HOME */
- 0xc8, /* 111 UP */
- 0xc9, /* 112 PGUP */
- 0xcb, /* 113 LEFT */
- 0xcd, /* 114 RGHT */
- 0xcf, /* 115 END */
- 0xd0, /* 116 DOWN */
- 0xd1, /* 117 PGDN */
- 0xd2, /* 118 INS */
- 0xd3, /* 119 DELE */
- 0, /* 120 EVDEV - I120 ("Internet" Keyboards) */
- 0, /* 121 EVDEV - MUTE */
- 0, /* 122 EVDEV - VOL- */
- 0, /* 123 EVDEV - VOL+ */
- 0, /* 124 EVDEV - POWR */
- 0, /* 125 EVDEV - KPEQ */
- 0, /* 126 EVDEV - I126 ("Internet" Keyboards) */
- 0, /* 127 EVDEV - PAUS */
- 0, /* 128 EVDEV - ???? */
- 0, /* 129 EVDEV - I129 ("Internet" Keyboards) */
- 0xf1, /* 130 EVDEV - HNGL (Korean Hangul Latin toggle) */
- 0xf2, /* 131 EVDEV - HJCV (Korean Hangul Hanja toggle) */
- 0x7d, /* 132 AE13 (Yen)*/
- 0xdb, /* 133 EVDEV - LWIN */
- 0xdc, /* 134 EVDEV - RWIN */
- 0xdd, /* 135 EVDEV - MENU */
- 0, /* 136 EVDEV - STOP */
- 0, /* 137 EVDEV - AGAI */
- 0, /* 138 EVDEV - PROP */
- 0, /* 139 EVDEV - UNDO */
- 0, /* 140 EVDEV - FRNT */
- 0, /* 141 EVDEV - COPY */
- 0, /* 142 EVDEV - OPEN */
- 0, /* 143 EVDEV - PAST */
- 0, /* 144 EVDEV - FIND */
- 0, /* 145 EVDEV - CUT */
- 0, /* 146 EVDEV - HELP */
- 0, /* 147 EVDEV - I147 */
- 0, /* 148 EVDEV - I148 */
- 0, /* 149 EVDEV - I149 */
- 0, /* 150 EVDEV - I150 */
- 0, /* 151 EVDEV - I151 */
- 0, /* 152 EVDEV - I152 */
- 0, /* 153 EVDEV - I153 */
- 0, /* 154 EVDEV - I154 */
- 0, /* 155 EVDEV - I156 */
- 0, /* 156 EVDEV - I157 */
- 0, /* 157 EVDEV - I158 */
-};
-
-
-/* keycode translation for sending ISO_Left_Send
- * to vncserver
- */
-static struct {
- GdkKeymapKey *keys;
- gint n_keys;
- guint keyval;
-} untranslated_keys[] = {{NULL, 0, GDK_Tab}};
-
-static unsigned int ref_count_for_untranslated_keys = 0;
-
-/* As best as I can tell, windows passes PC scan codes. This code definitely
- * won't compile on windows so let's put in a guard anyway */
-
-#ifndef WIN32
-#include <gdk/gdkx.h>
-#include <X11/XKBlib.h>
-#include <stdbool.h>
-#include <string.h>
-
-#define STRPREFIX(a,b) (strncmp((a),(b),strlen((b))) == 0)
-
-static gboolean check_for_evdev(void)
-{
- XkbDescPtr desc;
- gboolean has_evdev = FALSE;
- const gchar *keycodes;
-
- desc = XkbGetKeyboard(GDK_DISPLAY(), XkbGBN_AllComponentsMask,
- XkbUseCoreKbd);
- if (desc == NULL || desc->names == NULL)
- return FALSE;
-
- keycodes = gdk_x11_get_xatom_name(desc->names->keycodes);
- if (keycodes == NULL)
- g_warning("could not lookup keycode name\n");
- else if (STRPREFIX(keycodes, "evdev_"))
- has_evdev = TRUE;
- else if (!STRPREFIX(keycodes, "xfree86_"))
- g_warning("unknown keycodes `%s', please report to gtk-vnc-devel\n",
- keycodes);
-
- XkbFreeClientMap(desc, XkbGBN_AllComponentsMask, True);
-
- return has_evdev;
-}
-#else
-static gboolean check_for_evdev(void)
-{
- return FALSE;
-}
-#endif
-
-const guint8 const *x_keycode_to_pc_keycode_map(void)
-{
- if (check_for_evdev()) {
- GVNC_DEBUG("Using evdev keycode mapping");
- return evdev_keycode_to_pc_keycode;
- } else {
- GVNC_DEBUG("Using xfree86 keycode mapping");
- return x_keycode_to_pc_keycode_table;
- }
-}
-
-guint16 x_keycode_to_pc_keycode(const guint8 const *keycode_map,
- guint16 keycode)
-{
- if (keycode == GDK_Pause)
- return VKC_PAUSE;
-
- if (keycode < 9)
- return 0;
-
- if (keycode < 97)
- return keycode - 8; /* just an offset */
-
- if (keycode < 158)
- return keycode_map[keycode - 97];
-
- if (keycode == 208) /* Hiragana_Katakana */
- return 0x70;
-
- if (keycode == 211) /* backslash */
- return 0x73;
-
- return 0;
-}
-
-/* Set the keymap entries */
-void x_keymap_set_keymap_entries()
-{
- size_t i;
- if (ref_count_for_untranslated_keys == 0)
- for (i = 0; i < sizeof(untranslated_keys) / sizeof(untranslated_keys[0]); i++)
- gdk_keymap_get_entries_for_keyval(gdk_keymap_get_default(),
- untranslated_keys[i].keyval,
- &untranslated_keys[i].keys,
- &untranslated_keys[i].n_keys);
- ref_count_for_untranslated_keys++;
-}
-
-/* Free the keymap entries */
-void x_keymap_free_keymap_entries()
-{
- size_t i;
-
- if (ref_count_for_untranslated_keys == 0)
- return;
-
- ref_count_for_untranslated_keys--;
- if (ref_count_for_untranslated_keys == 0)
- for (i = 0; i < sizeof(untranslated_keys) / sizeof(untranslated_keys[0]); i++)
- g_free(untranslated_keys[i].keys);
-
-}
-
-/* Get the keyval from the keycode without the level. */
-guint x_keymap_get_keyval_from_keycode(guint keycode, guint keyval)
-{
- size_t i;
- for (i = 0; i < sizeof(untranslated_keys) / sizeof(untranslated_keys[0]); i++) {
- if (keycode == untranslated_keys[i].keys[0].keycode) {
- return untranslated_keys[i].keyval;
- }
- }
-
- return keyval;
-}
-/*
- * Local variables:
- * c-indent-level: 8
- * c-basic-offset: 8
- * tab-width: 8
- * End:
- */
diff --git a/src/x_keymap.h b/src/x_keymap.h
deleted file mode 100644
index b67fe27..0000000
--- a/src/x_keymap.h
+++ /dev/null
@@ -1,33 +0,0 @@
-/*
- * GTK VNC Widget
- *
- * Copyright (C) 2006 Anthony Liguori <anthony codemonkey ws>
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 2.0 of the License, or (at your option) any later version.
- *
- * This library 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
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
- */
-
-#ifndef _GTK_VNC_X_KEYMAP_H
-#define _GTK_VNC_X_KEYMAP_H
-
-#include <gdk/gdk.h>
-
-const guint8 const *x_keycode_to_pc_keycode_map(void);
-guint16 x_keycode_to_pc_keycode(const guint8 *keycode_map,
- guint16 keycode);
-void x_keymap_set_keymap_entries(void);
-void x_keymap_free_keymap_entries(void);
-guint x_keymap_get_keyval_from_keycode(guint keycode, guint keyval);
-
-#endif
--
1.6.5.2
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]