Browse Source

Respect modifiers in x0vncserver

Using XKeysymToKeycode() often gives the incorrect keycode as it
doesn't respect the current modifier state. Use XKB to find the
proper key instead.

This however also means that we need to track the mapping for all
pressed keys to make sure we know the correct keycode when it is
time to release the key.
tags/v1.8.90
Pierre Ossman 6 years ago
parent
commit
ac73038232
1 changed files with 55 additions and 4 deletions
  1. 55
    4
      unix/x0vncserver/x0vncserver.cxx

+ 55
- 4
unix/x0vncserver/x0vncserver.cxx View File

@@ -39,6 +39,7 @@
#include <X11/X.h>
#include <X11/Xlib.h>
#include <X11/Xutil.h>
#include <X11/XKBlib.h>
#ifdef HAVE_XTEST
#include <X11/extensions/XTest.h>
#endif
@@ -253,12 +254,61 @@ public:
#endif
}

#ifdef HAVE_XTEST
KeyCode XkbKeysymToKeycode(Display* dpy, KeySym keysym) {
XkbDescPtr xkb;
XkbStateRec state;
unsigned keycode;

xkb = XkbGetMap(dpy, XkbAllComponentsMask, XkbUseCoreKbd);
if (!xkb)
return 0;

XkbGetState(dpy, XkbUseCoreKbd, &state);

for (keycode = xkb->min_key_code;
keycode <= xkb->max_key_code;
keycode++) {
KeySym cursym;
unsigned int mods;
XkbTranslateKeyCode(xkb, keycode, state.compat_state, &mods, &cursym);
if (cursym == keysym)
break;
}

if (keycode > xkb->max_key_code)
keycode = 0;

XkbFreeKeyboard(xkb, XkbAllComponentsMask, True);

return keycode;
}
#endif

virtual void keyEvent(rdr::U32 key, bool down) {
#ifdef HAVE_XTEST
if (!haveXtest) return;
int keycode = XKeysymToKeycode(dpy, key);
if (keycode)
XTestFakeKeyEvent(dpy, keycode, down, CurrentTime);
int keycode;

if (!haveXtest)
return;

if (down) {
if (pressedKeys.find(key) != pressedKeys.end())
keycode = pressedKeys[key];
else {
// XKeysymToKeycode() doesn't respect state, so we have to use
// something slightly more complex
keycode = XkbKeysymToKeycode(dpy, key);
if (!keycode)
return;
pressedKeys[key] = keycode;
}
} else {
keycode = pressedKeys[key];
pressedKeys.erase(key);
}

XTestFakeKeyEvent(dpy, keycode, down, CurrentTime);
#endif
}

@@ -301,6 +351,7 @@ protected:
bool haveXtest;
bool haveDamage;
int maxButtons;
std::map<KeySym, KeyCode> pressedKeys;
bool running;
#ifdef HAVE_XDAMAGE
Damage damage;

Loading…
Cancel
Save