1// Copyright (C) 2021 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#ifndef QEVDEVKEYBOARDHANDLER_P_H
5#define QEVDEVKEYBOARDHANDLER_P_H
6
7//
8// W A R N I N G
9// -------------
10//
11// This file is not part of the Qt API. It exists purely as an
12// implementation detail. This header file may change from version to
13// version without notice, or even be removed.
14//
15// We mean it.
16//
17
18#include <qobject.h>
19#include <QTimer>
20#include <QDataStream>
21#include <private/qglobal_p.h>
22
23#include <memory>
24
25QT_BEGIN_NAMESPACE
26
27class QSocketNotifier;
28
29namespace QEvdevKeyboardMap {
30 const quint32 FileMagic = 0x514d4150; // 'QMAP'
31
32 struct Mapping {
33 quint16 keycode;
34 quint16 unicode;
35 quint32 qtcode;
36 quint8 modifiers;
37 quint8 flags;
38 quint16 special;
39
40 };
41
42 enum Flags {
43 IsDead = 0x01,
44 IsLetter = 0x02,
45 IsModifier = 0x04,
46 IsSystem = 0x08
47 };
48
49 enum System {
50 SystemConsoleFirst = 0x0100,
51 SystemConsoleMask = 0x007f,
52 SystemConsoleLast = 0x017f,
53 SystemConsolePrevious = 0x0180,
54 SystemConsoleNext = 0x0181,
55 SystemReboot = 0x0200,
56 SystemZap = 0x0300
57 };
58
59 struct Composing {
60 quint16 first;
61 quint16 second;
62 quint16 result;
63 };
64
65 enum Modifiers {
66 ModPlain = 0x00,
67 ModShift = 0x01,
68 ModAltGr = 0x02,
69 ModControl = 0x04,
70 ModAlt = 0x08,
71 ModShiftL = 0x10,
72 ModShiftR = 0x20,
73 ModCtrlL = 0x40,
74 ModCtrlR = 0x80
75 // ModCapsShift = 0x100, // not supported!
76 };
77}
78
79inline QDataStream &operator>>(QDataStream &ds, QEvdevKeyboardMap::Mapping &m)
80{
81 return ds >> m.keycode >> m.unicode >> m.qtcode >> m.modifiers >> m.flags >> m.special;
82}
83
84inline QDataStream &operator<<(QDataStream &ds, const QEvdevKeyboardMap::Mapping &m)
85{
86 return ds << m.keycode << m.unicode << m.qtcode << m.modifiers << m.flags << m.special;
87}
88
89inline QDataStream &operator>>(QDataStream &ds, QEvdevKeyboardMap::Composing &c)
90{
91 return ds >> c.first >> c.second >> c.result;
92}
93
94inline QDataStream &operator<<(QDataStream &ds, const QEvdevKeyboardMap::Composing &c)
95{
96 return ds << c.first << c.second << c.result;
97}
98
99class QFdContainer
100{
101 int m_fd;
102 Q_DISABLE_COPY_MOVE(QFdContainer);
103public:
104 Q_NODISCARD_CTOR explicit QFdContainer(int fd = -1) noexcept : m_fd(fd) {}
105 ~QFdContainer() { reset(); }
106
107 int get() const noexcept { return m_fd; }
108
109 int release() noexcept { int result = m_fd; m_fd = -1; return result; }
110 void reset() noexcept;
111 void reset(int fd) { reset(); m_fd = fd; }
112};
113
114class QEvdevKeyboardHandler : public QObject
115{
116public:
117 QEvdevKeyboardHandler(const QString &device, QFdContainer &fd, bool disableZap, bool enableCompose, const QString &keymapFile);
118 ~QEvdevKeyboardHandler();
119
120 enum KeycodeAction {
121 None = 0,
122
123 CapsLockOff = 0x01000000,
124 CapsLockOn = 0x01000001,
125 NumLockOff = 0x02000000,
126 NumLockOn = 0x02000001,
127 ScrollLockOff = 0x03000000,
128 ScrollLockOn = 0x03000001,
129
130 Reboot = 0x04000000,
131
132 PreviousConsole = 0x05000000,
133 NextConsole = 0x05000001,
134 SwitchConsoleFirst = 0x06000000,
135 SwitchConsoleLast = 0x0600007f,
136 SwitchConsoleMask = 0x0000007f
137 };
138
139 static std::unique_ptr<QEvdevKeyboardHandler> create(const QString &device,
140 const QString &specification,
141 const QString &defaultKeymapFile = QString());
142
143 static Qt::KeyboardModifiers toQtModifiers(quint8 mod)
144 {
145 Qt::KeyboardModifiers qtmod = Qt::NoModifier;
146
147 if (mod & (QEvdevKeyboardMap::ModShift | QEvdevKeyboardMap::ModShiftL | QEvdevKeyboardMap::ModShiftR))
148 qtmod |= Qt::ShiftModifier;
149 if (mod & (QEvdevKeyboardMap::ModControl | QEvdevKeyboardMap::ModCtrlL | QEvdevKeyboardMap::ModCtrlR))
150 qtmod |= Qt::ControlModifier;
151 if (mod & QEvdevKeyboardMap::ModAlt)
152 qtmod |= Qt::AltModifier;
153
154 return qtmod;
155 }
156
157 bool loadKeymap(const QString &file);
158 void unloadKeymap();
159
160 void readKeycode();
161 KeycodeAction processKeycode(quint16 keycode, bool pressed, bool autorepeat);
162
163 void switchLang();
164
165private:
166 void processKeyEvent(int nativecode, int unicode, int qtcode,
167 Qt::KeyboardModifiers modifiers, bool isPress, bool autoRepeat);
168 void switchLed(int, bool);
169
170 QString m_device;
171 QFdContainer m_fd;
172 QSocketNotifier *m_notify;
173
174 // keymap handling
175 quint8 m_modifiers;
176 quint8 m_locks[3];
177 int m_composing;
178 quint16 m_dead_unicode;
179 quint8 m_langLock;
180
181 bool m_no_zap;
182 bool m_do_compose;
183
184 const QEvdevKeyboardMap::Mapping *m_keymap;
185 int m_keymap_size;
186 const QEvdevKeyboardMap::Composing *m_keycompose;
187 int m_keycompose_size;
188
189 static const QEvdevKeyboardMap::Mapping s_keymap_default[];
190 static const QEvdevKeyboardMap::Composing s_keycompose_default[];
191};
192
193
194QT_END_NAMESPACE
195
196#endif // QEVDEVKEYBOARDHANDLER_P_H
197

source code of qtbase/src/platformsupport/input/evdevkeyboard/qevdevkeyboardhandler_p.h