1 | // Copyright (C) 2016 The Qt Company Ltd. |
2 | // SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only |
3 | |
4 | #pragma once |
5 | |
6 | #include "qxcbobject.h" |
7 | |
8 | #include <xcb/xcb_keysyms.h> |
9 | #define explicit dont_use_cxx_explicit |
10 | #include <xcb/xkb.h> |
11 | #undef explicit |
12 | |
13 | #include <QtGui/private/qxkbcommon_p.h> |
14 | #include <xkbcommon/xkbcommon-x11.h> |
15 | |
16 | #include <qpa/qplatformkeymapper.h> |
17 | |
18 | #include <QEvent> |
19 | |
20 | QT_BEGIN_NAMESPACE |
21 | |
22 | class QXcbKeyboard : public QXcbObject, public QPlatformKeyMapper |
23 | { |
24 | public: |
25 | QXcbKeyboard(QXcbConnection *connection); |
26 | |
27 | ~QXcbKeyboard(); |
28 | |
29 | void initialize(); |
30 | void selectEvents(); |
31 | |
32 | void handleKeyPressEvent(const xcb_key_press_event_t *event); |
33 | void handleKeyReleaseEvent(const xcb_key_release_event_t *event); |
34 | |
35 | Qt::KeyboardModifiers translateModifiers(int s) const; |
36 | void updateKeymap(xcb_mapping_notify_event_t *event); |
37 | void updateKeymap(); |
38 | |
39 | QList<QKeyCombination> possibleKeyCombinations(const QKeyEvent *event) const override; |
40 | Qt::KeyboardModifiers queryKeyboardModifiers() const override; |
41 | |
42 | void updateXKBMods(); |
43 | xkb_mod_mask_t xkbModMask(quint16 state); |
44 | void updateXKBStateFromCore(quint16 state); |
45 | void updateXKBStateFromXI(void *modInfo, void *groupInfo); |
46 | |
47 | int coreDeviceId() const { return core_device_id; } |
48 | void updateXKBState(xcb_xkb_state_notify_event_t *state); |
49 | |
50 | void handleStateChanges(xkb_state_component changedComponents); |
51 | |
52 | protected: |
53 | void handleKeyEvent(xcb_window_t sourceWindow, QEvent::Type type, xcb_keycode_t code, |
54 | quint16 state, xcb_timestamp_t time, bool fromSendEvent); |
55 | |
56 | void resolveMaskConflicts(); |
57 | |
58 | typedef QMap<xcb_keysym_t, int> KeysymModifierMap; |
59 | struct xkb_keymap *keymapFromCore(const KeysymModifierMap &keysymMods); |
60 | |
61 | void updateModifiers(const KeysymModifierMap &keysymMods); |
62 | KeysymModifierMap keysymsToModifiers(); |
63 | |
64 | void updateVModMapping(); |
65 | void updateVModToRModMapping(); |
66 | |
67 | private: |
68 | bool m_config = false; |
69 | bool m_isAutoRepeat = false; |
70 | xcb_keycode_t m_autoRepeatCode = 0; |
71 | |
72 | struct _mod_masks { |
73 | uint alt; |
74 | uint altgr; |
75 | uint meta; |
76 | uint super; |
77 | uint hyper; |
78 | }; |
79 | |
80 | _mod_masks rmod_masks; |
81 | |
82 | xcb_key_symbols_t *m_key_symbols = nullptr; |
83 | struct _xkb_mods { |
84 | xkb_mod_index_t shift; |
85 | xkb_mod_index_t lock; |
86 | xkb_mod_index_t control; |
87 | xkb_mod_index_t mod1; |
88 | xkb_mod_index_t mod2; |
89 | xkb_mod_index_t mod3; |
90 | xkb_mod_index_t mod4; |
91 | xkb_mod_index_t mod5; |
92 | }; |
93 | _xkb_mods xkb_mods; |
94 | |
95 | _mod_masks vmod_masks; |
96 | int core_device_id; |
97 | |
98 | QXkbCommon::ScopedXKBState m_xkbState; |
99 | QXkbCommon::ScopedXKBKeymap m_xkbKeymap; |
100 | QXkbCommon::ScopedXKBContext m_xkbContext; |
101 | |
102 | bool m_superAsMeta = false; |
103 | bool m_hyperAsMeta = false; |
104 | }; |
105 | |
106 | QT_END_NAMESPACE |
107 | |