From b75ba2ef0d61d0d356a3a0fe9e581e5aaf29b7a4 Mon Sep 17 00:00:00 2001 From: Roman Savochenko Date: Sun, 4 Aug 2019 16:38:55 +0300 Subject: krfb: Add a function for appending new symbols to the actual X-server keymap This resolves bug 3014 and issue #11 Signed-off-by: Roman Savochenko --- krfb/krfb/rfbcontroller.cc | 53 ++++++++++++++++++++++++++++++++++++++++++++++ krfb/krfb/rfbcontroller.h | 1 + 2 files changed, 54 insertions(+) diff --git a/krfb/krfb/rfbcontroller.cc b/krfb/krfb/rfbcontroller.cc index 750d2ecc..2e14837b 100644 --- a/krfb/krfb/rfbcontroller.cc +++ b/krfb/krfb/rfbcontroller.cc @@ -186,9 +186,13 @@ const int KeyboardEvent::RIGHTSHIFT = 2; const int KeyboardEvent::ALTGR = 4; char KeyboardEvent::ModifierState; +static KeySym added_keysyms[0x100]; + KeyboardEvent::KeyboardEvent(bool d, KeySym k) : down(d), keySym(k) { + + if(k && !IsModifierKey(k)) add_keysym(k); } void KeyboardEvent::initKeycodes() { @@ -223,6 +227,55 @@ void KeyboardEvent::initKeycodes() { XFree ((char *)keymap); } +int KeyboardEvent::add_keysym( KeySym keysym ) +{ + static int first = 1; + if(first) { + for(int n = 0; n < 0x100; n++) + added_keysyms[n] = NoSymbol; + first = 0; + } + + if(keysym == NoSymbol) return 0; + + /* there can be a race before MappingNotify */ + for(int n = 0; n < 0x100; n++) + if(added_keysyms[n] == keysym) return n; + + int minkey, maxkey, syms_per_keycode, kc, ret = 0; + XDisplayKeycodes(dpy, &minkey, &maxkey); + KeySym *keymap = XGetKeyboardMapping(dpy, minkey, (maxkey-minkey+1), &syms_per_keycode); + + for(int kc = minkey+1; kc <= maxkey; kc++) { + int j, didmsg = 0, is_empty = 1; + char *str; + KeySym newks[8]; + + for(int n = 0; n < syms_per_keycode; n++) { + if(keymap[(kc-minkey)*syms_per_keycode+n] != NoSymbol) + { is_empty = 0; break; } + } + if(!is_empty) continue; + + for(int i = 0; i < 8; i++) newks[i] = NoSymbol; + for(int i = 0; i < syms_per_keycode; i++) { + newks[i] = keysym; + if(i >= 7) break; + } + + XChangeKeyboardMapping(dpy, kc, syms_per_keycode, newks, 1); + + XFlush(dpy); + added_keysyms[kc] = keysym; + ret = kc; + break; + } + + XFree(keymap); + + return ret; +} + /* this function adjusts the modifiers according to mod (as from modifiers) and ModifierState */ void KeyboardEvent::tweakModifiers(signed char mod, bool down) { diff --git a/krfb/krfb/rfbcontroller.h b/krfb/krfb/rfbcontroller.h index e5595311..3d3cd73c 100644 --- a/krfb/krfb/rfbcontroller.h +++ b/krfb/krfb/rfbcontroller.h @@ -74,6 +74,7 @@ public: static void initKeycodes(); KeyboardEvent(bool d, KeySym k); + int add_keysym( KeySym keysym ); virtual void exec(); }; -- cgit v1.2.3