[PATCH 24/25] Move X keycode -> PC scancode conversion into VncDisplay



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]