diff options
author | Sebastien Braun | 2010-10-10 01:33:59 +0200 |
---|---|---|
committer | Sebastien Braun | 2010-10-10 14:05:35 +0200 |
commit | 1233d9c40fdf20b2c5157eee89d995817b0c1c3b (patch) | |
tree | 21f9f8cbbcfa7f3719edf8d08b76dc67b04f179a | |
parent | Actually install pvsprivinputd (diff) | |
download | pvs-1233d9c40fdf20b2c5157eee89d995817b0c1c3b.tar.gz pvs-1233d9c40fdf20b2c5157eee89d995817b0c1c3b.tar.xz pvs-1233d9c40fdf20b2c5157eee89d995817b0c1c3b.zip |
Code cleanup for X11FakeKeyboardHandler.cpp
- CamelCase names
- Add more comments
- Remove unused stuff
-rw-r--r-- | src/input/x11FakeKeyboardHandler.cpp | 409 |
1 files changed, 184 insertions, 225 deletions
diff --git a/src/input/x11FakeKeyboardHandler.cpp b/src/input/x11FakeKeyboardHandler.cpp index eab4498..a136e45 100644 --- a/src/input/x11FakeKeyboardHandler.cpp +++ b/src/input/x11FakeKeyboardHandler.cpp @@ -9,7 +9,7 @@ # # General information about OpenSLX can be found at http://openslx.org/ # -------------------------------------------------------------------------- - # x11FakeKeyboardHandler.h: + # x11FakeKeyboardHandler.cpp: # - Handle keyboard events on X11 - interface # -------------------------------------------------------------------------- */ @@ -36,10 +36,10 @@ #include <src/util/consoleLogger.h> #include "x11InputUtils.h" -//////////////////////// INPUT EVENT TRANSLATION ///////////////////////////////// - -typedef unsigned char xmodifier_type; +// X11 supports 8 modifiers, so a bitmask of modifiers fits into a byte: +typedef unsigned char XModifiers; +// For debugging output, these are the names of modifier keys: char modifiernames[][8] = { "SHIFT", "LOCK", @@ -51,7 +51,7 @@ char modifiernames[][8] = { "MOD5" }; -QString modifiers_to_string(xmodifier_type mods) +QString modifiersToString(XModifiers mods) { QString s; for(int i = 0; i < 8; i++) @@ -66,15 +66,22 @@ QString modifiers_to_string(xmodifier_type mods) return s; } +///////////////////////////////////////////////////////////////////////// +// Input event translation code +///////////////////////////////////////////////////////////////////////// + +// We need to translate between Qt's keycodes and X11's keycodes. +// Unfortunately, there does not seem to be a direct correspondence +// between them, so we are stuck with storing a lookup table: +typedef std::map<quint32, KeySym> KeycodeLookupTable; +KeycodeLookupTable keysyms; -typedef std::map<quint32, KeySym> lookup_table_type; -typedef lookup_table_type::const_iterator lookup_table_const_iterator; -typedef lookup_table_type::iterator lookup_table_iterator; -lookup_table_type keysyms; -void initialize_keysyms() { +// The following code has been partially autogenerated by +// an insane sed(1) script and then hand-edited to make +// the errors go away. +void initializeKeycodeLookupTable() { keysyms[Qt::Key_Escape] = XK_Escape; keysyms[Qt::Key_Tab] = XK_Tab; -// keysyms[Qt::Key_Backtab] = XK_Backtab; keysyms[Qt::Key_Backspace] = XK_BackSpace; keysyms[Qt::Key_Return] = XK_Return; keysyms[Qt::Key_Enter] = XK_KP_Enter; @@ -140,8 +147,6 @@ void initialize_keysyms() { keysyms[Qt::Key_Hyper_L] = XK_Hyper_L; keysyms[Qt::Key_Hyper_R] = XK_Hyper_R; keysyms[Qt::Key_Help] = XK_Help; -// keysyms[Qt::Key_Direction_L] = XK_Direction_L; -// keysyms[Qt::Key_Direction_R] = XK_Direction_R; keysyms[Qt::Key_Space] = XK_space; keysyms[Qt::Key_Exclam] = XK_exclam; keysyms[Qt::Key_QuoteDbl] = XK_quotedbl; @@ -314,10 +319,8 @@ void initialize_keysyms() { keysyms[Qt::Key_MultipleCandidate] = XK_MultipleCandidate; keysyms[Qt::Key_PreviousCandidate] = XK_PreviousCandidate; keysyms[Qt::Key_Mode_switch] = XK_Mode_switch; -// keysyms[Qt::Key_script_switch] = XK_script_switch; keysyms[Qt::Key_Kanji] = XK_Kanji; keysyms[Qt::Key_Muhenkan] = XK_Muhenkan; -// keysyms[Qt::Key_Henkan_Mode] = XK_Henkan_Mode; keysyms[Qt::Key_Henkan] = XK_Henkan; keysyms[Qt::Key_Romaji] = XK_Romaji; keysyms[Qt::Key_Hiragana] = XK_Hiragana; @@ -332,9 +335,6 @@ void initialize_keysyms() { keysyms[Qt::Key_Kana_Shift] = XK_Kana_Shift; keysyms[Qt::Key_Eisu_Shift] = XK_Eisu_Shift; keysyms[Qt::Key_Eisu_toggle] = XK_Eisu_toggle; -// keysyms[Qt::Key_Kanji_Bangou] = XK_Kanji_Bangou; -// keysyms[Qt::Key_Zen_Koho] = XK_Zen_Koho; -// keysyms[Qt::Key_Mae_Koho] = XK_Mae_Koho; keysyms[Qt::Key_Hangul] = XK_Hangul; keysyms[Qt::Key_Hangul_Hanja] = XK_Hangul_Hanja; keysyms[Qt::Key_Hangul] = XK_Hangul; @@ -343,16 +343,11 @@ void initialize_keysyms() { keysyms[Qt::Key_Hangul_Hanja] = XK_Hangul_Hanja; keysyms[Qt::Key_Hangul_Jamo] = XK_Hangul_Jamo; keysyms[Qt::Key_Hangul_Romaja] = XK_Hangul_Romaja; -// keysyms[Qt::Key_Hangul_Codeinput] = XK_Hangul_Codeinput; keysyms[Qt::Key_Hangul_Jeonja] = XK_Hangul_Jeonja; keysyms[Qt::Key_Hangul_Banja] = XK_Hangul_Banja; keysyms[Qt::Key_Hangul_PreHanja] = XK_Hangul_PreHanja; keysyms[Qt::Key_Hangul_PostHanja] = XK_Hangul_PostHanja; -// keysyms[Qt::Key_Hangul_SingleCandidate] = XK_Hangul_SingleCandidate; -// keysyms[Qt::Key_Hangul_MultipleCandidate] = XK_Hangul_MultipleCandidate; -// keysyms[Qt::Key_Hangul_PreviousCandidate] = XK_Hangul_PreviousCandidate; keysyms[Qt::Key_Hangul_Special] = XK_Hangul_Special; -// keysyms[Qt::Key_Hangul_switch] = XK_Hangul_switch; keysyms[Qt::Key_Dead_Grave] = XK_dead_grave; keysyms[Qt::Key_Dead_Acute] = XK_dead_acute; keysyms[Qt::Key_Dead_Circumflex] = XK_dead_circumflex; @@ -372,94 +367,33 @@ void initialize_keysyms() { keysyms[Qt::Key_Dead_Belowdot] = XK_dead_belowdot; keysyms[Qt::Key_Dead_Hook] = XK_dead_hook; keysyms[Qt::Key_Dead_Horn] = XK_dead_horn; -// keysyms[Qt::Key_Back] = XK_Back; -// keysyms[Qt::Key_Forward] = XK_Forward; -// keysyms[Qt::Key_Stop] = XK_Stop; -// keysyms[Qt::Key_Refresh] = XK_Refresh; -// keysyms[Qt::Key_VolumeDown] = XK_VolumeDown; -// keysyms[Qt::Key_VolumeMute] = XK_VolumeMute; -// keysyms[Qt::Key_VolumeUp] = XK_VolumeUp; -// keysyms[Qt::Key_BassBoost] = XK_BassBoost; -// keysyms[Qt::Key_BassUp] = XK_BassUp; -// keysyms[Qt::Key_BassDown] = XK_BassDown; -// keysyms[Qt::Key_TrebleUp] = XK_TrebleUp; -// keysyms[Qt::Key_TrebleDown] = XK_TrebleDown; -// keysyms[Qt::Key_MediaPlay] = XK_MediaPlay; -// keysyms[Qt::Key_MediaStop] = XK_MediaStop; -// keysyms[Qt::Key_MediaPrevious] = XK_MediaPrevious; -// keysyms[Qt::Key_MediaNext] = XK_MediaNext; -// keysyms[Qt::Key_MediaRecord] = XK_MediaRecord; -// keysyms[Qt::Key_HomePage] = XK_HomePage; -// keysyms[Qt::Key_Favorites] = XK_Favorites; -// keysyms[Qt::Key_Search] = XK_Search; -// keysyms[Qt::Key_Standby] = XK_Standby; -// keysyms[Qt::Key_OpenUrl] = XK_OpenUrl; -// keysyms[Qt::Key_LaunchMail] = XK_LaunchMail; -// keysyms[Qt::Key_LaunchMedia] = XK_LaunchMedia; -// keysyms[Qt::Key_Launch0] = XK_Launch0; -// keysyms[Qt::Key_Launch1] = XK_Launch1; -// keysyms[Qt::Key_Launch2] = XK_Launch2; -// keysyms[Qt::Key_Launch3] = XK_Launch3; -// keysyms[Qt::Key_Launch4] = XK_Launch4; -// keysyms[Qt::Key_Launch5] = XK_Launch5; -// keysyms[Qt::Key_Launch6] = XK_Launch6; -// keysyms[Qt::Key_Launch7] = XK_Launch7; -// keysyms[Qt::Key_Launch8] = XK_Launch8; -// keysyms[Qt::Key_Launch9] = XK_Launch9; -// keysyms[Qt::Key_LaunchA] = XK_LaunchA; -// keysyms[Qt::Key_LaunchB] = XK_LaunchB; -// keysyms[Qt::Key_LaunchC] = XK_LaunchC; -// keysyms[Qt::Key_LaunchD] = XK_LaunchD; -// keysyms[Qt::Key_LaunchE] = XK_LaunchE; -// keysyms[Qt::Key_LaunchF] = XK_LaunchF; -// keysyms[Qt::Key_Display] = XK_Display; -// keysyms[Qt::Key_MediaLast] = XK_MediaLast; keysyms[Qt::Key_Select] = XK_Select; -// keysyms[Qt::Key_Yes] = XK_Yes; -// keysyms[Qt::Key_No] = XK_No; keysyms[Qt::Key_Cancel] = XK_Cancel; -// keysyms[Qt::Key_Printer] = XK_Printer; keysyms[Qt::Key_Execute] = XK_Execute; -// keysyms[Qt::Key_Sleep] = XK_Sleep; -// keysyms[Qt::Key_MediaPlay] = XK_MediaPlay; -// keysyms[Qt::Key_Zoom] = XK_Zoom; -// keysyms[Qt::Key_Jisho] = XK_Jisho; -// keysyms[Qt::Key_Oyayubi_Left] = XK_Oyayubi_Left; -// keysyms[Qt::Key_Oyayubi_Right] = XK_Oyayubi_Right; -// keysyms[Qt::Key_Context1] = XK_Context1; -// keysyms[Qt::Key_Context2] = XK_Context2; -// keysyms[Qt::Key_Context3] = XK_Context3; -// keysyms[Qt::Key_Context4] = XK_Context4; -// keysyms[Qt::Key_Call] = XK_Call; -// keysyms[Qt::Key_Hangup] = XK_Hangup; -// keysyms[Qt::Key_Flip] = XK_Flip; keysyms[Qt::Key_unknown] = XK_VoidSymbol; } -/* Store Keycodes for "normal" Latin1 keys: */ -int basic_keycodes[0x100]; -int basic_modifiers[0x100]; - -int modifier_keycodes[8]; -Qt::KeyboardModifier modifier_meaning[8]; +// every keysym with a value under 256 corresponds +// directly to an ISO-Latin1 Character. We need +// to store how to generate those characters: +int basicKeycodes[0x100]; // What key do we need to press? +int basicModifiers[0x100]; // What modifiers are required? -int xmodifier_from_qtmodifier(Qt::KeyboardModifier m) { - for(int i = 0; i < 8; i++) { - if(m == modifier_meaning[i]) - return i; - } - return -1; -} +// What keys do we need to press to generate the +// modifiers? +int modifierKeycodes[8]; +// How do the X11 modifiers relate to Qt's KeyboardModifiers? +Qt::KeyboardModifier modifierMeaning[8]; -typedef std::map<Qt::KeyboardModifier, xmodifier_type> qt_to_xmodifier_type; -typedef std::map<xmodifier_type, Qt::KeyboardModifier> x_to_qtmodifier_type; -qt_to_xmodifier_type qt_to_xmodifier; -x_to_qtmodifier_type x_to_qtmodifier; +// How do the X11 modifiers correspond to Qt's KeyboardModifiers? +typedef std::map<XModifiers, Qt::KeyboardModifier> XToQtModifierMap; +XToQtModifierMap XToQtModifier; -typedef std::multimap<xmodifier_type, int> modifier_to_keycode_map; -modifier_to_keycode_map modifier_to_keycode; -typedef std::map<int, xmodifier_type> keycode_to_modifier_map; -keycode_to_modifier_map keycode_to_modifier; +// And how do the modifiers relate to Keycodes? +typedef std::multimap<XModifiers, int> ModifierToKeycodeMap; +ModifierToKeycodeMap ModifierToKeycode; +typedef std::map<int, XModifiers> KeycodeToModifierMap; +KeycodeToModifierMap KeycodeToModifier; // We need to query the input devices, preferrable through XInput2, but // if that is not available we will contend ourselves with XInput1: @@ -491,56 +425,72 @@ keycode_to_modifier_map keycode_to_modifier; } #endif - -void initialize_basic_keycodes() +// Initialize the above data structures: +void initializeBasicKeycodes() { + // Mark everything as unknown initially for(int i = 0; i < 8; i++) { - modifier_keycodes[i] = -1; + modifierKeycodes[i] = -1; } for(int i = 0; i < 0x100; i++) { - basic_keycodes[i] = -1; + basicKeycodes[i] = -1; } Display* dpy = X11InputUtils::display(); - int min_keycode, max_keycode; - XDisplayKeycodes(dpy, &min_keycode, &max_keycode); - - int xkb_opcode, xkb_event, xkb_error, xkb_major, xkb_minor; - bool xkb_present = XkbQueryExtension(dpy, &xkb_opcode, &xkb_event, &xkb_error, &xkb_major, &xkb_minor); - if(!xkb_present) { - int keysyms_per_code; - const int count = max_keycode - min_keycode + 1; - KeySym* mapping = XGetKeyboardMapping(dpy, min_keycode, count, &keysyms_per_code); + + // Find out the valid range of keycodes + int minKeycode, maxKeycode; + XDisplayKeycodes(dpy, &minKeycode, &maxKeycode); + + // Initialize the XKB client-side code, and find out whether + // the XKB extension is present in the server. + int xkbOpcode, xkbEvent, xkbError, xkbMajor, xkbMinor; + bool xkbPresent = XkbQueryExtension(dpy, &xkbOpcode, &xkbEvent, &xkbError, &xkbMajor, &xkbMinor); + + if(!xkbPresent) { + // No XKB. This is probably not a very recent + // system, but we will do the best we can. + // Retrieve the keyboard mapping + int keysymsPerCode; + const int count = maxKeycode - minKeycode + 1; + KeySym* mapping = XGetKeyboardMapping(dpy, minKeycode, count, &keysymsPerCode); + + // and traverse every entry for(int i = 0; i < count; i++) { - for(int j = 0; j < keysyms_per_code; j++) + for(int j = 0; j < keysymsPerCode; j++) { - const int idx = i * keysyms_per_code + j; + const int idx = i * keysymsPerCode + j; const KeySym ks = mapping[idx]; - const int keycode = min_keycode + i; + const int keycode = minKeycode + i; + // to find out if there is a Latin1 character there, if(ks >= ' ' && ks < 0x100) { - if(ks == XK_at) { - ConsoleLog writeLine(QString("Keycode %1 (%2) gives `@' with modifiers `%3', but it is really `%4'").arg(keycode).arg(XKeysymToString(XKeycodeToKeysym(dpy, keycode, 0))).arg(modifiers_to_string(j)).arg(XKeysymToString(XKeycodeToKeysym(dpy, keycode, j)))); - - } - - if(basic_keycodes[ks] != -1) + // that we have not yet found, + if(basicKeycodes[ks] != -1) continue; // already found - basic_keycodes[ks] = keycode; - basic_modifiers[ks] = j; + // and record its keycode and needed modifiers. + basicKeycodes[ks] = keycode; + basicModifiers[ks] = j; } } } + + // We are finished, free the mapping structure. XFree(mapping); } else { - // Try to find out what device XTest will send events on: + // XKB is present. + + // As different input devices can have different keymaps, + // we need to find out what device XTest will send events on: unsigned int xkbDeviceId = XkbUseCoreKbd; Atom xtestDeviceProp = XInternAtom(dpy, "XTEST Device", false); + + // Find the list of input devices: int ndevinfos; XIDeviceInfo* devinfos = XIQueryDevice(dpy, XIAllDevices, &ndevinfos); if(devinfos) @@ -578,6 +528,9 @@ void initialize_basic_keycodes() # undef deviceid #endif } + // at this point, xkbDeviceId contains the identifier + // of the XTEST Device, or xkbUseCoreKbd if none was + // found. // Okay, we know which device to query. Now get its keymap: XkbDescPtr keybDesc = XkbGetKeyboard(dpy, XkbAllComponentsMask, xkbDeviceId); @@ -586,7 +539,9 @@ void initialize_basic_keycodes() qWarning("Unable to retrieve keyboard description for device %d. Falling back to unreliable global mapping", xkbDeviceId); } - for(int i = min_keycode; i <= max_keycode; i++) + // This is basically the same loop as above, it just queries XKB + // instead of the old core Xlib routines. + for(int i = minKeycode; i <= maxKeycode; i++) { for(int j = 0; j <= 0xff; j++) { @@ -605,17 +560,11 @@ void initialize_basic_keycodes() if(ks && (ks < 0x100)) { -// ConsoleLog writeLine(QString("Keycode %1 (%2) seems to give `%3' with modifiers `%4', of which `%5' are unconsumed") -// .arg(i) -// .arg(XKeysymToString(XKeycodeToKeysym(dpy, i, 0))) -// .arg(XKeysymToString(ks)) -// .arg(modifiers_to_string(j)) -// .arg(modifiers_to_string(unconsumed))); - if(basic_keycodes[ks] != -1) + if(basicKeycodes[ks] != -1) continue; - basic_keycodes[ks] = i; - basic_modifiers[ks] = unconsumed & j; + basicKeycodes[ks] = i; + basicModifiers[ks] = unconsumed & j; } } } @@ -631,56 +580,57 @@ void initialize_basic_keycodes() XModifierKeymap* modkm; modkm = XGetModifierMapping(dpy); - const int shift_kc = XKeysymToKeycode(dpy, XK_Shift_L); - const int control_kc = XKeysymToKeycode(dpy, XK_Control_L); - const int alt_kc = XKeysymToKeycode(dpy, XK_Alt_L); - const int meta_kc = XKeysymToKeycode(dpy, XK_Meta_L); - const int switch_kc = XKeysymToKeycode(dpy, XK_Mode_switch); + const int shiftCode = XKeysymToKeycode(dpy, XK_Shift_L); + const int controlCode = XKeysymToKeycode(dpy, XK_Control_L); + const int altCode = XKeysymToKeycode(dpy, XK_Alt_L); + const int metaCode = XKeysymToKeycode(dpy, XK_Meta_L); + const int switchCode = XKeysymToKeycode(dpy, XK_Mode_switch); + // and use this information to find out which + // X11 modifiers correspond to Qt's modifiers: for(int i = 0; i < 8; i++) { for(int j = 0; j < modkm->max_keypermod; j++) { const int idx = i * modkm->max_keypermod + j; const int kc = modkm->modifiermap[idx]; - modifier_to_keycode.insert(std::make_pair((1<<i), kc)); - keycode_to_modifier[kc] = (1<<i); -#define remember_modifier(qmod) do { \ - qt_to_xmodifier[Qt::qmod##Modifier] = 1<<i; \ - x_to_qtmodifier[1<<i] = Qt::qmod##Modifier; \ -} while(false) - if(kc == shift_kc) { - remember_modifier(Shift); - } else if(kc == control_kc) { - remember_modifier(Control); - } else if(kc == alt_kc) { - remember_modifier(Alt); - } else if(kc == meta_kc) { - remember_modifier(Meta); - } else if(kc == switch_kc) { - remember_modifier(GroupSwitch); + ModifierToKeycode.insert(std::make_pair((1<<i), kc)); + KeycodeToModifier[kc] = (1<<i); + if(kc == shiftCode) { + XToQtModifier[1<<i] = Qt::ShiftModifier; + } else if(kc == controlCode) { + XToQtModifier[1<<i] = Qt::ControlModifier; + } else if(kc == altCode) { + XToQtModifier[1<<i] = Qt::ShiftModifier; + } else if(kc == metaCode) { + XToQtModifier[1<<i] = Qt::MetaModifier; + } else if(kc == switchCode) { + XToQtModifier[1<<i] = Qt::GroupSwitchModifier; } -#undef remember_modifier - if(modifier_keycodes[i] != -1) { + // and record the keycode we need to press/release + // to activate or deactivate a modifier: + if(modifierKeycodes[i] != -1) { continue; // already found } // select one arbitrarily - modifier_keycodes[i] = kc; + modifierKeycodes[i] = kc; } } XFreeModifiermap(modkm); } -xmodifier_type translate_modifiers(quint32 mods) +// Translate a Qt KeyboardModifiers flag to +// its corresponding X11 modifier bitmask +XModifiers translateModifiers(quint32 mods) { - xmodifier_type ret = 0; + XModifiers ret = 0; for(int j = 1; j < 8; j++) { - xmodifier_type i = 1<<j; + XModifiers i = 1<<j; - if(mods & x_to_qtmodifier[i]) + if(mods & XToQtModifier[i]) { ret |= i; } @@ -689,88 +639,94 @@ xmodifier_type translate_modifiers(quint32 mods) return ret; } -typedef std::set<int> int_set_type; -int_set_type pressed_modifier_keys; -xmodifier_type current_modifiers; +// We need to keep track of which modifiers +// are currently active +typedef std::set<int> IntSet; +IntSet pressedModifierKeys; +XModifiers currentModifiers; void trackModifiers(int keycode, bool down) { // is this a modifier key? - const bool is_modifier = keycode_to_modifier.find(keycode) != keycode_to_modifier.end(); + const bool isModifier = KeycodeToModifier.find(keycode) != KeycodeToModifier.end(); - if(!is_modifier) + if(!isModifier) { return; } if(down) { - pressed_modifier_keys.insert(keycode); + pressedModifierKeys.insert(keycode); } else { - pressed_modifier_keys.erase(keycode); + pressedModifierKeys.erase(keycode); } - int_set_type::iterator i, end = pressed_modifier_keys.end(); - xmodifier_type modifs = 0; - for(i = pressed_modifier_keys.begin(); i != end; i++) + IntSet::iterator i, end = pressedModifierKeys.end(); + XModifiers modifs = 0; + for(i = pressedModifierKeys.begin(); i != end; i++) { - keycode_to_modifier_map::iterator found_kc = keycode_to_modifier.find(*i); - if(found_kc != keycode_to_modifier.end()) + KeycodeToModifierMap::iterator foundCode = KeycodeToModifier.find(*i); + if(foundCode != KeycodeToModifier.end()) { - modifs |= (*found_kc).second; + modifs |= (*foundCode).second; } } - current_modifiers = modifs; + currentModifiers = modifs; - ConsoleLog writeLine(QString("[trackModifiers] current modifiers: %1").arg(modifiers_to_string(modifs))); + ConsoleLog writeLine(QString("[trackModifiers] current modifiers: %1").arg(modifiersToString(modifs))); } -typedef std::pair<int, bool> modifier_tweak_type; -typedef std::vector<modifier_tweak_type> tweak_sequence_type; +// And, if we need to tweak the modifiers to generate +// a particular keysym, we need to keep track of which +// ones we pressed or released. +typedef std::pair<int, bool> ModifierTweak; +typedef std::vector<ModifierTweak> TweakSequence; -void tweakModifiers(Display* dpy, xmodifier_type neededState, xmodifier_type actualState, tweak_sequence_type& tracker) +// Tweak the modifiers to reach the neededState, from actualState +// and record tweaks in the tracker. +void tweakModifiers(Display* dpy, XModifiers neededState, XModifiers actualState, TweakSequence& tracker) { - ConsoleLog writeLine(QString("tweakModifiers: Trying to get to `%1' from `%2'").arg(modifiers_to_string(neededState)).arg(modifiers_to_string(actualState))); + ConsoleLog writeLine(QString("tweakModifiers: Trying to get to `%1' from `%2'").arg(modifiersToString(neededState)).arg(modifiersToString(actualState))); for(int j = 0; j < 8; j++) { - xmodifier_type i = 1<<j; + XModifiers i = 1<<j; - ConsoleLog writeLine(QString("Checking for %1...").arg(modifiers_to_string(i))); + ConsoleLog writeLine(QString("Checking for %1...").arg(modifiersToString(i))); + // Do we need to activate the modifier? if((i & neededState) && !(i & actualState)) { ConsoleLog writeLine(QString("tweakModifiers: Modifier %1 needs to be pressed").arg(modifiernames[j])); - // needs to be pressed + //find the keycode + ModifierToKeycodeMap::iterator iter = ModifierToKeycode.find(i); - //find the keycode: - int kc; - modifier_to_keycode_map::iterator iter = modifier_to_keycode.find(i); - - if((iter == modifier_to_keycode.end()) || ((*iter).first != i)) + if((iter == ModifierToKeycode.end()) || ((*iter).first != i)) { - continue; // we don't know a key that triggers this modifier + // we don't know a key that triggers this modifier + continue; } ConsoleLog writeLine(QString(" pressing key %1").arg((*iter).second)); XTestFakeKeyEvent(dpy, (*iter).second, 1, CurrentTime); + // record the tweak tracker.push_back(std::make_pair((*iter).second, true)); } + // or do we need to deactivate it? else if((!(i & neededState)) && (i & actualState)) { ConsoleLog writeLine(QString("tweakModifiers: Modifier %1 needs to be released").arg(modifiernames[j])); - // needs to be released - int kc = -1; - // first, check whether any of the currently pressed keys has triggered this modifier: - int_set_type::iterator iter, end = pressed_modifier_keys.end(); - for(iter = pressed_modifier_keys.begin(); iter != end; iter++) + // first, check whether any of the currently pressed keys has triggered this modifier: + IntSet::iterator iter, end = pressedModifierKeys.end(); + for(iter = pressedModifierKeys.begin(); iter != end; iter++) { - keycode_to_modifier_map::iterator modmap_iter = keycode_to_modifier.find(*iter); - if(modmap_iter != keycode_to_modifier.end()) { - if(modmap_iter->second == i) { + KeycodeToModifierMap::iterator modmapIter = KeycodeToModifier.find(*iter); + if(modmapIter != KeycodeToModifier.end()) { + if(modmapIter->second == i) { kc = *iter; // release this key: @@ -790,29 +746,33 @@ void tweakModifiers(Display* dpy, xmodifier_type neededState, xmodifier_type act } } -void untweakModifiers(Display* dpy, tweak_sequence_type& tracker) +// Undo a recorded sequence of modifier tweaks +void untweakModifiers(Display* dpy, TweakSequence& tracker) { - tweak_sequence_type::iterator i, end = tracker.end(); + TweakSequence::iterator i, end = tracker.end(); for(i = tracker.begin(); i != end; i++) { - modifier_tweak_type& t = *i; + ModifierTweak& t = *i; XTestFakeKeyEvent(dpy, t.first, !t.second, CurrentTime); } } +// initialize the handler void X11FakeKeyboardHandler::initialize() { - initialize_keysyms(); - initialize_basic_keycodes(); - pressed_modifier_keys.clear(); - current_modifiers = 0; + initializeKeycodeLookupTable(); + initializeBasicKeycodes(); + pressedModifierKeys.clear(); + currentModifiers = 0; } +// actually try our best to generate the correct input sequence +// for the event void X11FakeKeyboardHandler::doHandle(InputEvent const& evt, InputEventContext const*) { Display* dpy = X11InputUtils::display(); // find out which keysym caused this event: - lookup_table_const_iterator i = keysyms.find(evt.qt_keysym()); + KeycodeLookupTable::const_iterator i = keysyms.find(evt.qt_keysym()); if(i == keysyms.end()) { // Special cases. We don't know how to directly translate those, so we will try to emulate them. switch(evt.qt_keysym()) @@ -829,44 +789,43 @@ void X11FakeKeyboardHandler::doHandle(InputEvent const& evt, InputEventContext c // is it a "normal" key? if(ks >= ' ' && ks < 0x100) { - if(basic_keycodes[ks] != -1) + if(basicKeycodes[ks] != -1) { if(evt.isPress()) { // Try the simple way first: // Does the keycode with current modifiers yield the requested symbol? - KeySym unmod_ks = XKeycodeToKeysym(dpy, basic_keycodes[ks], current_modifiers); - ConsoleLog writeLine(QString("Pressing the key for %1 would yield %2 right now.").arg(XKeysymToString(ks)).arg(XKeysymToString(unmod_ks))); + KeySym unmodSym = XKeycodeToKeysym(dpy, basicKeycodes[ks], currentModifiers); + ConsoleLog writeLine(QString("Pressing the key for %1 would yield %2 right now.").arg(XKeysymToString(ks)).arg(XKeysymToString(unmodSym))); - if(ks == XKeycodeToKeysym(dpy, basic_keycodes[ks], current_modifiers)) + if(ks == XKeycodeToKeysym(dpy, basicKeycodes[ks], currentModifiers)) { - XTestFakeKeyEvent(dpy, basic_keycodes[ks], 1, CurrentTime); + XTestFakeKeyEvent(dpy, basicKeycodes[ks], 1, CurrentTime); } else { // what modifier keys do we need to press? - xmodifier_type mods = translate_modifiers(evt.qt_modifiers()); + XModifiers mods = translateModifiers(evt.qt_modifiers()); // we may need to press additional modifiers to generate this keysym: if(QChar(ks, 0).isLetter()) { - // but, since we do not differentiate upper and lower case, - // and instead let the sender handle those modifiers, - // we need to AND ShiftModifier and LockModifier out. - mods |= basic_modifiers[ks] & ~(1<<ShiftMapIndex) & ~(1<<LockMapIndex); + // but, since Qt does not differentiate upper and lower case, + // we need to preserve Shift and Lock in their current state. + mods |= basicModifiers[ks] & ~(1<<ShiftMapIndex) & ~(1<<LockMapIndex); } else { - // Not an alpha character. We do need to respect Shift and Lock for those: - mods |= basic_modifiers[ks]; + // Not a letter. We do need to respect Shift and Lock for those: + mods |= basicModifiers[ks]; } // now, tweak the modifiers - tweak_sequence_type tweaks; - tweakModifiers(dpy, mods, current_modifiers, tweaks); + TweakSequence tweaks; + tweakModifiers(dpy, mods, currentModifiers, tweaks); // press the key: - XTestFakeKeyEvent(dpy, basic_keycodes[ks], 1, CurrentTime); + XTestFakeKeyEvent(dpy, basicKeycodes[ks], 1, CurrentTime); // and release the modifiers: untweakModifiers(dpy, tweaks); @@ -875,7 +834,7 @@ void X11FakeKeyboardHandler::doHandle(InputEvent const& evt, InputEventContext c else { // just release the key. - XTestFakeKeyEvent(dpy, basic_keycodes[ks], 0, CurrentTime); + XTestFakeKeyEvent(dpy, basicKeycodes[ks], 0, CurrentTime); } } else |