From 2a29324294fa7c669313658fb305a59da3a99262 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Martin=20Gr=C3=A4=C3=9Flin?= Date: Fri, 6 Feb 2015 15:17:56 +0100 Subject: [PATCH] [tabbox] Port keysym and modifier mapping to XCB REVIEW: 122454 --- tabbox/tabbox.cpp | 49 ++++++++++++++++++++++++++++++++++++++--------- xcbutils.h | 37 +++++++++++++++++++++++++++++++++++ 2 files changed, 77 insertions(+), 9 deletions(-) diff --git a/tabbox/tabbox.cpp b/tabbox/tabbox.cpp index 03d47ce354..d48139dce4 100644 --- a/tabbox/tabbox.cpp +++ b/tabbox/tabbox.cpp @@ -55,6 +55,8 @@ along with this program. If not, see . // X11 #include #include +// xcb +#include // specify externals before namespace @@ -900,19 +902,40 @@ void TabBox::grabbedKeyEvent(QKeyEvent* event) m_tabBox->grabbedKeyEvent(event); } +struct KeySymbolsDeleter +{ + static inline void cleanup(xcb_key_symbols_t *symbols) + { + xcb_key_symbols_free(symbols); + } +}; + /*! Handles alt-tab / control-tab */ static bool areKeySymXsDepressed(bool bAll, const uint keySyms[], int nKeySyms) { - char keymap[32]; qDebug() << "areKeySymXsDepressed: " << (bAll ? "all of " : "any of ") << nKeySyms; - XQueryKeymap(display(), keymap); + Xcb::QueryKeymap keys; + + QScopedPointer symbols(xcb_key_symbols_alloc(connection())); + if (symbols.isNull() || !keys) { + return false; + } + const auto keymap = keys->keys; for (int iKeySym = 0; iKeySym < nKeySyms; iKeySym++) { uint keySymX = keySyms[ iKeySym ]; - uchar keyCodeX = XKeysymToKeycode(display(), keySymX); + xcb_keycode_t *keyCodes = xcb_key_symbols_get_keycode(symbols.data(), keySymX); + if (!keyCodes) { + continue; + } + xcb_keycode_t keyCodeX = keyCodes[0]; + free(keyCodes); + if (keyCodeX == XCB_NO_SYMBOL) { + continue; + } int i = keyCodeX / 8; char mask = 1 << (keyCodeX - (i * 8)); @@ -1440,12 +1463,20 @@ void TabBox::keyRelease(const xcb_key_release_event_t *ev) if (mod_index == -1) release = true; else { - XModifierKeymap* xmk = XGetModifierMapping(display()); - for (int i = 0; i < xmk->max_keypermod; i++) - if (xmk->modifiermap[xmk->max_keypermod * mod_index + i] - == ev->detail) - release = true; - XFreeModifiermap(xmk); + Xcb::ModifierMapping xmk; + if (xmk) { + xcb_keycode_t *keycodes = xmk.keycodes(); + const int maxIndex = xmk.size(); + for (int i = 0; i < xmk->keycodes_per_modifier; ++i) { + const int index = xmk->keycodes_per_modifier * mod_index + i; + if (index >= maxIndex) { + continue; + } + if (keycodes[index] == ev->detail) { + release = true; + } + } + } } if (!release) return; diff --git a/xcbutils.h b/xcbutils.h index c5143fdae6..dae3b97e46 100644 --- a/xcbutils.h +++ b/xcbutils.h @@ -605,6 +605,43 @@ public: } }; +struct QueryKeymapData : public WrapperData< xcb_query_keymap_reply_t, xcb_query_keymap_cookie_t > +{ + static constexpr request_func requestFunc = &xcb_query_keymap_unchecked; + static constexpr reply_func replyFunc = &xcb_query_keymap_reply; +}; + +class QueryKeymap : public Wrapper +{ +public: + QueryKeymap() : Wrapper() {} +}; + +struct ModifierMappingData : public WrapperData< xcb_get_modifier_mapping_reply_t, xcb_get_modifier_mapping_cookie_t > +{ + static constexpr request_func requestFunc = &xcb_get_modifier_mapping_unchecked; + static constexpr reply_func replyFunc = &xcb_get_modifier_mapping_reply; +}; + +class ModifierMapping : public Wrapper +{ +public: + ModifierMapping() : Wrapper() {} + + inline xcb_keycode_t *keycodes() { + if (isNull()) { + return nullptr; + } + return xcb_get_modifier_mapping_keycodes(data()); + } + inline int size() { + if (isNull()) { + return 0; + } + return xcb_get_modifier_mapping_keycodes_length(data()); + } +}; + XCB_WRAPPER_DATA(PropertyData, xcb_get_property, uint8_t, xcb_window_t, xcb_atom_t, xcb_atom_t, uint32_t, uint32_t) class Property : public Wrapper {