Commit a88d12ce authored by Daniel P. Berrange's avatar Daniel P. Berrange Committed by Daniel P. Berrange

Disable extended key events if keymap is unknown

Currently if we cannot determine the GDK keymap, we default to
the XT keymap. This is not a good choice because is causes
definite breakage on several platforms. If the keymap cannot
be determined, it is safer to disable the extended key event
support completely & rely on traditional VNC keysyms.

Also rename the x2pc methods to be gdk2rfb, since that's what
the conversion is actually doing.
parent b1ee8a0b
......@@ -752,8 +752,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);
guint16 scancode = vnc_display_keymap_gdk2rfb(priv->keycode_map,
key->hardware_keycode);
/*
* ..send the key release event we're dealing with
*
......@@ -774,8 +774,8 @@ 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);
guint16 scancode = vnc_display_keymap_gdk2rfb(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 */
......@@ -839,8 +839,8 @@ 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]);
guint16 scancode = vnc_display_keymap_gdk2rfb(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], scancode);
......@@ -1334,6 +1334,9 @@ static void on_initialized(VncConnection *conn G_GNUC_UNUSED,
REMOVE_ENCODING(VNC_CONNECTION_ENCODING_TIGHT);
}
if (priv->keycode_map == NULL)
REMOVE_ENCODING(VNC_CONNECTION_ENCODING_EXT_KEY_EVENT);
VNC_DEBUG("Sending %d encodings", n_encodings);
if (!vnc_connection_set_encodings(priv->conn, n_encodings, encodings))
goto error;
......@@ -1441,7 +1444,7 @@ static guint get_scancode_from_keyval(VncDisplay *obj, guint keyval)
g_free(keys);
}
return vnc_display_keymap_x2pc(priv->keycode_map, keycode);
return vnc_display_keymap_gdk2rfb(priv->keycode_map, keycode);
}
void vnc_display_send_keys_ex(VncDisplay *obj, const guint *keyvals,
......@@ -1940,7 +1943,7 @@ static void vnc_display_init(VncDisplay *display)
g_signal_connect(G_OBJECT(priv->conn), "vnc-disconnected",
G_CALLBACK(on_disconnected), display);
priv->keycode_map = vnc_display_keymap_x2pc_table();
priv->keycode_map = vnc_display_keymap_gdk2rfb_table();
}
gboolean vnc_display_set_credential(VncDisplay *obj, int type, const gchar *data)
......
......@@ -37,7 +37,7 @@
* THE SOFTWARE.
*/
static const guint8 x_keycode_to_pc_keycode_table[61] = {
static const guint8 xkbd_keycode_to_rfb_keycode_table[61] = {
0xc7, /* 97 Home */
0xc8, /* 98 Up */
0xc9, /* 99 PgUp */
......@@ -106,7 +106,7 @@ static const guint8 x_keycode_to_pc_keycode_table[61] = {
* and /usr/share/X11/xkb/keycodes/xfree86
*/
static const guint8 evdev_keycode_to_pc_keycode[61] = {
static const guint8 xevdev_keycode_to_rfb_keycode[61] = {
0, /* 97 EVDEV - RO ("Internet" Keyboards) */
0, /* 98 EVDEV - KATA (Katakana) */
0, /* 99 EVDEV - HIRA (Hiragana) */
......@@ -185,7 +185,7 @@ 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
#if defined(GDK_WINDOWING_X11)
#include <gdk/gdkx.h>
#include <X11/XKBlib.h>
#include <stdbool.h>
......@@ -193,47 +193,54 @@ static unsigned int ref_count_for_untranslated_keys = 0;
#define STRPREFIX(a,b) (strncmp((a),(b),strlen((b))) == 0)
static gboolean check_for_evdev(void)
const guint8 const *vnc_display_keymap_gdk2rfb_table(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;
return NULL;
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;
if (keycodes == NULL) {
g_warning("could not lookup keycode name\n");
return NULL;
} else if (STRPREFIX(keycodes, "e2vdev_")) {
VNC_DEBUG("Using evdev keycode mapping");
return xevdev_keycode_to_rfb_keycode;
} else if (STRPREFIX(keycodes, "xfr2ee86_")) {
VNC_DEBUG("Using xfree86 keycode mapping");
return xkbd_keycode_to_rfb_keycode_table;
} else {
g_warning("Unknown keycode mapping.\n"
"Please report to gtk-vnc-list@gnome.org\n"
"including the following information:\n"
"\n"
" - Operating system\n"
" - GTK build\n"
" - X11 Server\n"
" - xprop -root\n"
" - xdpyinfo\n");
return NULL;
}
}
#else
static gboolean check_for_evdev(void)
const guint8 const *vnc_display_keymap_gdk2rfb_table(void)
{
return FALSE;
g_warning("Unsupported GDK Windowing platform.\n"
"Please report to gtk-vnc-list@gnome.org\n"
"including the following information:\n"
"\n"
" - Operating system\n"
" - GTK Windowing system build\n");
return NULL;
}
#endif
const guint8 const *vnc_display_keymap_x2pc_table(void)
{
if (check_for_evdev()) {
VNC_DEBUG("Using evdev keycode mapping");
return evdev_keycode_to_pc_keycode;
} else {
VNC_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:
......@@ -245,9 +252,12 @@ const guint8 const *vnc_display_keymap_x2pc_table(void)
#define VKC_PAUSE 0x100
guint16 vnc_display_keymap_x2pc(const guint8 const *keycode_map,
guint16 keycode)
guint16 vnc_display_keymap_gdk2rfb(const guint8 const *keycode_map,
guint16 keycode)
{
if (keycode_map == NULL)
return 0;
if (keycode == GDK_Pause)
return VKC_PAUSE;
......
......@@ -24,9 +24,9 @@
#include <glib.h>
const guint8 const *vnc_display_keymap_x2pc_table(void);
guint16 vnc_display_keymap_x2pc(const guint8 *keycode_map,
guint16 keycode);
const guint8 const *vnc_display_keymap_gdk2rfb_table(void);
guint16 vnc_display_keymap_gdk2rfb(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);
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment