summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorSebastien Braun2010-10-10 01:33:59 +0200
committerSebastien Braun2010-10-10 14:05:35 +0200
commit1233d9c40fdf20b2c5157eee89d995817b0c1c3b (patch)
tree21f9f8cbbcfa7f3719edf8d08b76dc67b04f179a
parentActually install pvsprivinputd (diff)
downloadpvs-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.cpp409
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