summaryrefslogtreecommitdiffstats
path: root/krfb/krfb/rfbcontroller.cc
diff options
context:
space:
mode:
Diffstat (limited to 'krfb/krfb/rfbcontroller.cc')
-rw-r--r--krfb/krfb/rfbcontroller.cc53
1 files changed, 53 insertions, 0 deletions
diff --git a/krfb/krfb/rfbcontroller.cc b/krfb/krfb/rfbcontroller.cc
index 0db57514..4cd0f7fb 100644
--- a/krfb/krfb/rfbcontroller.cc
+++ b/krfb/krfb/rfbcontroller.cc
@@ -184,9 +184,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() {
@@ -221,6 +225,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) {