Get modifier mapping using standard X, no need for libxkbcommon here.
Reviewed-by: Samuel Rødal
This commit is contained in:
parent
bd781231b2
commit
06c56cb464
@ -41,19 +41,10 @@
|
|||||||
|
|
||||||
#include "qxcbkeyboard.h"
|
#include "qxcbkeyboard.h"
|
||||||
#include "qxcbwindow.h"
|
#include "qxcbwindow.h"
|
||||||
|
|
||||||
#include <xcb/xcb_keysyms.h>
|
#include <xcb/xcb_keysyms.h>
|
||||||
|
|
||||||
#include <X11/keysym.h>
|
#include <X11/keysym.h>
|
||||||
|
|
||||||
#ifndef QT_NO_XCB_XKB
|
|
||||||
typedef unsigned char KeyCode;
|
|
||||||
#include <X11/extensions/XKBcommon.h>
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#include <QtGui/QWindowSystemInterface>
|
#include <QtGui/QWindowSystemInterface>
|
||||||
#include <QtCore/QTextCodec>
|
#include <QtCore/QTextCodec>
|
||||||
|
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
|
|
||||||
#ifndef XK_ISO_Left_Tab
|
#ifndef XK_ISO_Left_Tab
|
||||||
@ -904,13 +895,9 @@ QString QXcbKeyboard::translateKeySym(xcb_keysym_t keysym, uint xmodifiers,
|
|||||||
|
|
||||||
QXcbKeyboard::QXcbKeyboard(QXcbConnection *connection)
|
QXcbKeyboard::QXcbKeyboard(QXcbConnection *connection)
|
||||||
: QXcbObject(connection)
|
: QXcbObject(connection)
|
||||||
, m_alt_mask(0)
|
|
||||||
, m_super_mask(0)
|
|
||||||
, m_hyper_mask(0)
|
|
||||||
, m_meta_mask(0)
|
|
||||||
{
|
{
|
||||||
m_key_symbols = xcb_key_symbols_alloc(xcb_connection());
|
m_key_symbols = xcb_key_symbols_alloc(xcb_connection());
|
||||||
initXkb();
|
setupModifiers();
|
||||||
}
|
}
|
||||||
|
|
||||||
QXcbKeyboard::~QXcbKeyboard()
|
QXcbKeyboard::~QXcbKeyboard()
|
||||||
@ -918,27 +905,58 @@ QXcbKeyboard::~QXcbKeyboard()
|
|||||||
xcb_key_symbols_free(m_key_symbols);
|
xcb_key_symbols_free(m_key_symbols);
|
||||||
}
|
}
|
||||||
|
|
||||||
void QXcbKeyboard::initXkb()
|
void QXcbKeyboard::setupModifiers()
|
||||||
{
|
{
|
||||||
#ifndef QT_NO_XCB_XKB
|
m_alt_mask = 0;
|
||||||
struct xkb_rule_names names;
|
m_super_mask = 0;
|
||||||
names.rules = "evdev";
|
m_hyper_mask = 0;
|
||||||
names.model = "pc105";
|
m_meta_mask = 0;
|
||||||
names.layout = "us";
|
m_mode_switch_mask = 0;
|
||||||
names.variant = "";
|
m_num_lock_mask = 0;
|
||||||
names.options = "";
|
|
||||||
m_xkb = xkb_compile_keymap_from_rules(&names);
|
xcb_generic_error_t *error = 0;
|
||||||
for (int i = m_xkb->min_key_code; i < m_xkb->max_key_code; ++i) {
|
xcb_connection_t *conn = xcb_connection();
|
||||||
const uint mask = m_xkb->map->modmap ? m_xkb->map->modmap[i] : 0;
|
xcb_get_modifier_mapping_cookie_t modMapCookie = xcb_get_modifier_mapping(conn);
|
||||||
if (!mask)
|
xcb_get_modifier_mapping_reply_t *modMapReply =
|
||||||
continue;
|
xcb_get_modifier_mapping_reply(conn, modMapCookie, &error);
|
||||||
for (int j = 0; j < XkbKeyGroupsWidth(m_xkb, i); ++j) {
|
if (error) {
|
||||||
uint32_t keySym = XkbKeySym(m_xkb, i, j);
|
qWarning("xcb keyboard: failed to get modifier mapping");
|
||||||
if (keySym)
|
free(error);
|
||||||
setMask(keySym, mask);
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Figure out the modifier mapping, ICCCM 6.6
|
||||||
|
typedef QPair<uint, xcb_keycode_t *> SymCodes;
|
||||||
|
QList<SymCodes> modKeyCodes;
|
||||||
|
|
||||||
|
// for Alt and Meta L and R are the same
|
||||||
|
modKeyCodes << SymCodes(XK_Alt_L, xcb_key_symbols_get_keycode(m_key_symbols, XK_Alt_L));
|
||||||
|
modKeyCodes << SymCodes(XK_Meta_L, xcb_key_symbols_get_keycode(m_key_symbols, XK_Meta_L));
|
||||||
|
modKeyCodes << SymCodes(XK_Super_L, xcb_key_symbols_get_keycode(m_key_symbols, XK_Super_L));
|
||||||
|
modKeyCodes << SymCodes(XK_Super_R, xcb_key_symbols_get_keycode(m_key_symbols, XK_Super_R));
|
||||||
|
modKeyCodes << SymCodes(XK_Hyper_L, xcb_key_symbols_get_keycode(m_key_symbols, XK_Hyper_L));
|
||||||
|
modKeyCodes << SymCodes(XK_Hyper_R, xcb_key_symbols_get_keycode(m_key_symbols, XK_Hyper_R));
|
||||||
|
modKeyCodes << SymCodes(XK_Num_Lock, xcb_key_symbols_get_keycode(m_key_symbols, XK_Num_Lock));
|
||||||
|
modKeyCodes << SymCodes(XK_Mode_switch, xcb_key_symbols_get_keycode(m_key_symbols, XK_Mode_switch));
|
||||||
|
|
||||||
|
xcb_keycode_t *modMap = xcb_get_modifier_mapping_keycodes(modMapReply);
|
||||||
|
const int w = modMapReply->keycodes_per_modifier;
|
||||||
|
for (int i = 0; i < modKeyCodes.count(); ++i) {
|
||||||
|
for (int bit = 0; bit < 8; ++bit) {
|
||||||
|
uint mask = 1 << bit;
|
||||||
|
for (int x = 0; x < w; ++x) {
|
||||||
|
xcb_keycode_t keyCode = modMap[x + bit * w];
|
||||||
|
xcb_keycode_t *itk = modKeyCodes.at(i).second;
|
||||||
|
while (itk && *itk != XCB_NO_SYMBOL)
|
||||||
|
if (*itk++ == keyCode)
|
||||||
|
setMask(modKeyCodes.at(i).first, mask);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#endif
|
|
||||||
|
for (int i = 0; i < modKeyCodes.count(); ++i)
|
||||||
|
free(modKeyCodes.at(i).second);
|
||||||
|
free(modMapReply);
|
||||||
}
|
}
|
||||||
|
|
||||||
void QXcbKeyboard::setMask(uint sym, uint mask)
|
void QXcbKeyboard::setMask(uint sym, uint mask)
|
||||||
@ -1045,4 +1063,5 @@ void QXcbKeyboard::handleKeyReleaseEvent(QXcbWindow *window, const xcb_key_relea
|
|||||||
void QXcbKeyboard::handleMappingNotifyEvent(const xcb_mapping_notify_event_t *event)
|
void QXcbKeyboard::handleMappingNotifyEvent(const xcb_mapping_notify_event_t *event)
|
||||||
{
|
{
|
||||||
xcb_refresh_keyboard_mapping(m_key_symbols, const_cast<xcb_mapping_notify_event_t *>(event));
|
xcb_refresh_keyboard_mapping(m_key_symbols, const_cast<xcb_mapping_notify_event_t *>(event));
|
||||||
|
setupModifiers();
|
||||||
}
|
}
|
||||||
|
@ -70,7 +70,7 @@ private:
|
|||||||
QString translateKeySym(xcb_keysym_t keysym, uint xmodifiers,
|
QString translateKeySym(xcb_keysym_t keysym, uint xmodifiers,
|
||||||
int &code, Qt::KeyboardModifiers &modifiers,
|
int &code, Qt::KeyboardModifiers &modifiers,
|
||||||
QByteArray &chars, int &count);
|
QByteArray &chars, int &count);
|
||||||
void initXkb();
|
void setupModifiers();
|
||||||
void setMask(uint sym, uint mask);
|
void setMask(uint sym, uint mask);
|
||||||
|
|
||||||
uint m_alt_mask;
|
uint m_alt_mask;
|
||||||
|
Loading…
Reference in New Issue
Block a user