]> source.dussan.org Git - tigervnc.git/commitdiff
Avoid using "fake" key codes 772/head
authorPierre Ossman <ossman@cendio.se>
Mon, 26 Nov 2018 14:40:30 +0000 (15:40 +0100)
committerPierre Ossman <ossman@cendio.se>
Fri, 30 Nov 2018 14:42:51 +0000 (15:42 +0100)
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

index 50a21309f2391e10d26c521aac15a5b318cbdb1f..f84a6e4f2a1b726765ec73f27a5168f86791d19f 100644 (file)
@@ -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
 
 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;