[gtk-vnc] Move X keycode -> PC scancode conversion into VncDisplay
- From: Daniel P. Berrange <dberrange src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gtk-vnc] Move X keycode -> PC scancode conversion into VncDisplay
- Date: Sat, 20 Mar 2010 21:30:59 +0000 (UTC)
commit dee099d33ee070df318086659960245d54bce571
Author: Daniel P. Berrange <berrange redhat com>
Date: Sat Nov 21 11:48:56 2009 +0000
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/{x_keymap.c => vncdisplaykeymap.c} | 24 ++++++++++++++++------
src/{x_keymap.h => vncdisplaykeymap.h} | 18 ++++++++--------
6 files changed, 50 insertions(+), 68 deletions(-)
---
diff --git a/src/Makefile.am b/src/Makefile.am
index cfc5e3f..de75886 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -34,8 +34,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/vncconnection.c b/src/vncconnection.c
index 8fad4d4..94fb170 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);
@@ -1417,8 +1414,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);
@@ -2494,7 +2489,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 8736948..afd59c2 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;
}
}
@@ -815,9 +820,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;
}
@@ -1310,7 +1317,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))
@@ -1371,7 +1377,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;
@@ -1477,8 +1482,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;
@@ -1490,7 +1496,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,
@@ -1504,13 +1510,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]));
}
}
@@ -1575,6 +1581,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);
}
@@ -1894,6 +1902,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 |
@@ -1966,6 +1976,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/x_keymap.c b/src/vncdisplaykeymap.c
similarity index 93%
rename from src/x_keymap.c
rename to src/vncdisplaykeymap.c
index 00e9e45..1c5ecc8 100644
--- a/src/x_keymap.c
+++ b/src/vncdisplaykeymap.c
@@ -7,10 +7,10 @@
*
*/
+#include <gdk/gdk.h>
#include <gdk/gdkkeysyms.h>
-#include "x_keymap.h"
+#include "vncdisplaykeymap.h"
#include "utils.h"
-#include "vnc_keycodes.h"
/*
* This table is taken from QEMU x_keymap.c, under the terms:
@@ -223,7 +223,7 @@ static gboolean check_for_evdev(void)
}
#endif
-const guint8 const *x_keycode_to_pc_keycode_map(void)
+const guint8 const *vnc_display_keymap_x2pc_table(void)
{
if (check_for_evdev()) {
GVNC_DEBUG("Using evdev keycode mapping");
@@ -234,7 +234,17 @@ const guint8 const *x_keycode_to_pc_keycode_map(void)
}
}
-guint16 x_keycode_to_pc_keycode(const guint8 const *keycode_map,
+/* 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)
@@ -259,7 +269,7 @@ guint16 x_keycode_to_pc_keycode(const guint8 const *keycode_map,
}
/* Set the keymap entries */
-void x_keymap_set_keymap_entries()
+void vnc_display_keyval_set_entries(void)
{
size_t i;
if (ref_count_for_untranslated_keys == 0)
@@ -272,7 +282,7 @@ void x_keymap_set_keymap_entries()
}
/* Free the keymap entries */
-void x_keymap_free_keymap_entries()
+void vnc_display_keyval_free_entries(void)
{
size_t i;
@@ -287,7 +297,7 @@ void x_keymap_free_keymap_entries()
}
/* Get the keyval from the keycode without the level. */
-guint x_keymap_get_keyval_from_keycode(guint keycode, guint keyval)
+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++) {
diff --git a/src/x_keymap.h b/src/vncdisplaykeymap.h
similarity index 69%
rename from src/x_keymap.h
rename to src/vncdisplaykeymap.h
index b67fe27..4b31e5f 100644
--- a/src/x_keymap.h
+++ b/src/vncdisplaykeymap.h
@@ -18,16 +18,16 @@
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
-#ifndef _GTK_VNC_X_KEYMAP_H
-#define _GTK_VNC_X_KEYMAP_H
+#ifndef VNC_DISPLAY_KEYMAP_H
+#define VNC_DISPLAY_KEYMAP_H
-#include <gdk/gdk.h>
+#include <glib.h>
-const guint8 const *x_keycode_to_pc_keycode_map(void);
-guint16 x_keycode_to_pc_keycode(const guint8 *keycode_map,
+const guint8 const *vnc_display_keymap_x2pc_table(void);
+guint16 vnc_display_keymap_x2pc(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);
+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
+#endif /* VNC_DISPLAY_KEYMAP_H */
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]