From 0255e1b004fe6518c650e9d12b8862c2b2dad30b Mon Sep 17 00:00:00 2001 From: Pierre Ossman Date: Mon, 26 Nov 2018 15:40:30 +0100 Subject: [PATCH] Avoid using "fake" key codes There is a range of key codes that are never sent by a real keyboard and are therefore used by layouts to hide "fake" mappings. Make sure to only use these as a fallback as some applications get confused when they see these codes. --- unix/xserver/hw/vnc/InputXKB.c | 44 ++++++++++++++++++++++++++++++---- 1 file changed, 40 insertions(+), 4 deletions(-) diff --git a/unix/xserver/hw/vnc/InputXKB.c b/unix/xserver/hw/vnc/InputXKB.c index 50a21309..f84a6e4f 100644 --- a/unix/xserver/hw/vnc/InputXKB.c +++ b/unix/xserver/hw/vnc/InputXKB.c @@ -1,6 +1,6 @@ /* Copyright (C) 2009 TightVNC Team * Copyright (C) 2009 Red Hat, Inc. - * Copyright 2013-2015 Pierre Ossman for Cendio AB + * Copyright 2013-2018 Pierre Ossman for Cendio AB * * This is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -52,6 +52,14 @@ extern DeviceIntPtr vncKeyboardDev; +static const KeyCode fakeKeys[] = { +#ifdef __linux__ + 92, 203, 204, 205, 206, 207 +#else + 8, 124, 125, 156, 127, 128 +#endif + }; + static void vncXkbProcessDeviceEvent(int screenNum, InternalEvent *event, DeviceIntPtr dev); @@ -430,17 +438,20 @@ size_t vncReleaseLevelThree(KeyCode *keys, size_t maxKeys) KeyCode vncKeysymToKeycode(KeySym keysym, unsigned state, unsigned *new_state) { XkbDescPtr xkb; - unsigned int key; + unsigned int key; // KeyCode has insufficient range for the loop + KeyCode fallback; KeySym ks; unsigned level_three_mask; if (new_state != NULL) *new_state = state; + fallback = 0; xkb = GetMaster(vncKeyboardDev, KEYBOARD_OR_FLOAT)->key->xkbInfo->desc; for (key = xkb->min_key_code; key <= xkb->max_key_code; key++) { unsigned int state_out; KeySym dummy; + size_t fakeIdx; XkbTranslateKeyCode(xkb, key, state, &state_out, &ks); if (ks == NoSymbol) @@ -456,10 +467,35 @@ KeyCode vncKeysymToKeycode(KeySym keysym, unsigned state, unsigned *new_state) if (state_out & LockMask) XkbConvertCase(ks, &dummy, &ks); - if (ks == keysym) - return key; + if (ks != keysym) + continue; + + /* + * Some keys are never sent by a real keyboard and are + * used in the default layouts as a fallback for + * modifiers. Make sure we use them last as some + * applications can be confused by these normally + * unused keys. + */ + for (fakeIdx = 0; + fakeIdx < sizeof(fakeKeys)/sizeof(fakeKeys[0]); + fakeIdx++) { + if (key == fakeKeys[fakeIdx]) { + if (fallback == 0) + fallback = key; + break; + } + } + if (fakeIdx < sizeof(fakeKeys)/sizeof(fakeKeys[0])) + continue; + + return key; } + /* Use the fallback key, if one was found */ + if (fallback != 0) + return fallback; + if (new_state == NULL) return 0; -- 2.39.5