diff options
author | Stanislaw Halik <sthalik@misaki.pl> | 2017-05-30 20:08:49 +0200 |
---|---|---|
committer | Stanislaw Halik <sthalik@misaki.pl> | 2017-05-30 20:08:49 +0200 |
commit | f018bf4beeb15f346177dcee2b9e1a023627e7c4 (patch) | |
tree | 94aa371f97ff9e6a5b5db9c3804103aa782fe1ae /qxt-mini/x11-keymap.cpp | |
parent | c52b5ad0a8340012fab7982f0c670a46c3e5d93d (diff) |
qxt-mini: finish up X11 shortcuts
It didn't work without XLookupString.
Diffstat (limited to 'qxt-mini/x11-keymap.cpp')
-rw-r--r-- | qxt-mini/x11-keymap.cpp | 209 |
1 files changed, 185 insertions, 24 deletions
diff --git a/qxt-mini/x11-keymap.cpp b/qxt-mini/x11-keymap.cpp index b4438a3c..16e55368 100644 --- a/qxt-mini/x11-keymap.cpp +++ b/qxt-mini/x11-keymap.cpp @@ -1,16 +1,21 @@ #include "x11-keymap.hpp" -#ifndef __APPLE__ +#if !defined __APPLE__ && !defined _WIN32 -#include <tuple> +#include <QMutex> #define XK_MISCELLANY #define XK_LATIN1 + #include <X11/keysymdef.h> -using tt = std::tuple<Qt::Key, unsigned>; -static tt keymap[] = +struct tt { + Qt::Key qt; + quint32 keysym; +}; + +static const tt keymap[] = { { Qt::Key_Return, XK_Return }, { Qt::Key_Enter, XK_Return }, @@ -18,6 +23,7 @@ static tt keymap[] = { Qt::Key_Pause, XK_Pause }, { Qt::Key_SysReq, XK_Sys_Req }, { Qt::Key_Home, XK_Home }, + { Qt::Key_Insert, XK_Insert }, { Qt::Key_End, XK_End }, { Qt::Key_Left, XK_Left }, { Qt::Key_Up, XK_Up }, @@ -25,6 +31,7 @@ static tt keymap[] = { Qt::Key_Down, XK_Down }, { Qt::Key_PageUp, XK_Prior }, { Qt::Key_PageDown, XK_Next }, + { Qt::Key_Tab, XK_Tab }, { Qt::Key_F1, XK_F1 }, { Qt::Key_F2, XK_F2 }, @@ -40,24 +47,41 @@ static tt keymap[] = { Qt::Key_F12, XK_F12 }, { Qt::Key_Space, XK_space }, - { Qt::Key_Exclam, XK_exclam }, { Qt::Key_QuoteDbl, XK_quotedbl }, + +#if 1 + { Qt::Key_Exclam, XK_exclam }, + { Qt::Key_At, XK_at }, { Qt::Key_NumberSign, XK_numbersign }, { Qt::Key_Dollar, XK_dollar }, { Qt::Key_Percent, XK_percent }, + { Qt::Key_AsciiCircum, XK_asciicircum }, { Qt::Key_Ampersand, XK_ampersand }, - { Qt::Key_Apostrophe, XK_apostrophe }, + { Qt::Key_Asterisk, XK_asterisk }, { Qt::Key_ParenLeft, XK_parenleft }, { Qt::Key_ParenRight, XK_parenright }, - { Qt::Key_Asterisk, XK_asterisk }, +#else + { Qt::Key_Exclam, XK_1 }, + { Qt::Key_At, XK_2 }, + { Qt::Key_NumberSign, XK_3 }, + { Qt::Key_Dollar, XK_4 }, + { Qt::Key_Percent, XK_5 }, + { Qt::Key_AsciiCircum, XK_6 }, + { Qt::Key_Ampersand, XK_7 }, + { Qt::Key_Asterisk, XK_8 }, + { Qt::Key_ParenLeft, XK_9 }, + { Qt::Key_ParenRight, XK_0 }, +#endif + { Qt::Key_Minus, XK_minus }, + { Qt::Key_Equal, XK_equal }, + { Qt::Key_Apostrophe, XK_apostrophe }, { Qt::Key_Plus, XK_plus }, { Qt::Key_Comma, XK_comma }, - { Qt::Key_Minus, XK_minus }, { Qt::Key_Period, XK_period }, { Qt::Key_Slash, XK_slash }, { Qt::Key_0, XK_0 }, - { Qt::Key_1, XK_1}, + { Qt::Key_1, XK_1 }, { Qt::Key_2, XK_2 }, { Qt::Key_3, XK_3 }, { Qt::Key_4, XK_4 }, @@ -70,10 +94,8 @@ static tt keymap[] = { Qt::Key_Colon, XK_colon }, { Qt::Key_Semicolon, XK_semicolon }, { Qt::Key_Less, XK_less }, - { Qt::Key_Equal, XK_equal }, { Qt::Key_Greater, XK_greater }, { Qt::Key_Question, XK_question }, - { Qt::Key_At, XK_at }, { Qt::Key_A, XK_a }, { Qt::Key_B, XK_b }, @@ -105,32 +127,171 @@ static tt keymap[] = { Qt::Key_BracketLeft, XK_bracketleft }, { Qt::Key_Backslash, XK_backslash }, { Qt::Key_BracketRight, XK_bracketright }, - { Qt::Key_AsciiCircum, XK_asciicircum }, { Qt::Key_Underscore, XK_underscore }, { Qt::Key_QuoteLeft, XK_grave }, +#if 0 +}; +static tt numpad_keymap[] = { +#endif + { Qt::Key_0, XK_KP_0 }, + { Qt::Key_1, XK_KP_1 }, + { Qt::Key_2, XK_KP_2 }, + { Qt::Key_3, XK_KP_3 }, + { Qt::Key_4, XK_KP_4 }, + { Qt::Key_5, XK_KP_5 }, + { Qt::Key_6, XK_KP_6 }, + { Qt::Key_7, XK_KP_7 }, + { Qt::Key_8, XK_KP_8 }, + { Qt::Key_9, XK_KP_9 }, + { Qt::Key_5, XK_KP_Begin }, + { Qt::Key_Space, XK_KP_Space }, + { Qt::Key_Tab, XK_KP_Tab }, + { Qt::Key_F1, XK_KP_F1 }, + { Qt::Key_F2, XK_KP_F2 }, + { Qt::Key_F3, XK_KP_F3 }, + { Qt::Key_F4, XK_KP_F4 }, + { Qt::Key_Home, XK_KP_Home }, + { Qt::Key_End, XK_KP_End }, + { Qt::Key_Left, XK_KP_Left }, + { Qt::Key_Right, XK_KP_Right }, + { Qt::Key_Up, XK_KP_Up }, + { Qt::Key_Down, XK_KP_Down }, + { Qt::Key_PageUp, XK_KP_Page_Up }, + { Qt::Key_PageUp, XK_KP_Prior }, + { Qt::Key_PageDown, XK_KP_Page_Down }, + { Qt::Key_PageDown, XK_KP_Next }, + { Qt::Key_Insert, XK_KP_Insert }, + { Qt::Key_Delete, XK_KP_Delete }, + { Qt::Key_Equal, XK_KP_Equal }, + { Qt::Key_Asterisk, XK_KP_Multiply }, + { Qt::Key_Plus, XK_KP_Add }, + { Qt::Key_Comma, XK_KP_Separator }, + { Qt::Key_Minus, XK_KP_Subtract }, + { Qt::Key_Period, XK_KP_Decimal }, + { Qt::Key_Slash, XK_KP_Divide }, }; -unsigned qt_key_to_x11(Display* disp, Qt::Key k) +QXT_GUI_EXPORT +quint32 qt_mods_to_x11(Qt::KeyboardModifiers modifiers) { - Qt::Key k_; - unsigned keysym; + quint32 mods = 0; + + if (modifiers & Qt::AltModifier) + mods |= Mod1Mask; + if (modifiers & Qt::ControlModifier) + mods |= ControlMask; + if (modifiers & Qt::ShiftModifier) + mods |= ShiftMask; + if (modifiers & Qt::KeypadModifier) + mods |= Mod2Mask; + if (modifiers & Qt::MetaModifier) // Super aka Windows key + mods |= Mod4Mask; + + return mods; +} + +QXT_GUI_EXPORT +std::vector<quint32> qt_key_to_x11(Display*, Qt::Key k, Qt::KeyboardModifiers) +{ + std::vector<quint32> ret; for (const tt& tuple : keymap) { - std::tie(k_, keysym) = tuple; + Qt::Key k_ = tuple.qt; + unsigned keycode = tuple.keysym; if (k == k_) - { - const unsigned ret = XKeysymToKeycode(disp, keysym); + ret.push_back(keycode); + } - if (ret == 0) - return unsigned(-1); + if (ret.size() == 0) + qDebug() << "qxt-mini: no keysym for" << k; - return ret; - } + return ret; +} +QXT_GUI_EXPORT +static Qt::KeyboardModifiers x11_mods_to_qt(quint32 mods) +{ + Qt::KeyboardModifiers ret(0); + + if (mods & Mod1Mask) + ret |= Qt::AltModifier; + if (mods & ControlMask) + ret |= Qt::ControlModifier; + if (mods & Mod4Mask) + ret |= Qt::MetaModifier; + if (mods & ShiftMask) + ret |= Qt::ShiftModifier; + + return ret; +} + +QXT_GUI_EXPORT +std::tuple<Qt::Key, Qt::KeyboardModifiers> x11_key_to_qt(Display* disp, quint32 keycode, quint32 mods) +{ + (void)disp; + using t = std::tuple<Qt::Key, Qt::KeyboardModifiers>; + + for (const tt& tuple : keymap) + { + const Qt::Key k = tuple.qt; + + if (keycode == tuple.keysym) + return t(k, x11_mods_to_qt(mods)); } - qDebug() << "qxt-mini: no keysym for" << k; - return unsigned(-1); + return t(Qt::Key(0), Qt::KeyboardModifiers(0)); +} + + +QXT_GUI_EXPORT +QPair<KeySym, KeySym> keycode_to_keysym(Display* disp, + quint32 keycode, quint32 keystate, + xcb_key_press_event_t const* kev) +{ + using pair = QPair<quint32, quint32>; + + static QMutex lock; + static QHash<pair, QPair<KeySym, KeySym>> values; + + QMutexLocker l(&lock); + + auto it = values.find(pair(keycode, keystate)); + + if (it != values.end()) + return *it; + + XKeyEvent ev{}; + ev.serial = kev->sequence; + ev.send_event = False; + ev.display = disp; + ev.window = kev->root; + ev.subwindow = kev->child; + ev.window = kev->event; + ev.time = kev->time; + ev.x = kev->event_x; + ev.y = kev->event_x; + ev.x_root = kev->root_x; + ev.y_root = kev->root_y; + ev.state = keystate; + ev.keycode = keycode; + ev.same_screen = kev->same_screen; + + static char bytes[255+1]; + KeySym sym = 0; + int len = XLookupString(&ev, bytes, 255, &sym, NULL); + if (len <= 0 || len > 255) + { + len = 0; + sym = 0; + } + + KeySym sym2 = XLookupKeysym(&ev, 0); + + QPair<KeySym, KeySym> ret(sym, sym2); + + values[pair(keycode, keystate)] = ret; + + return ret; } #endif |