Absolute File Name: | /home/qt/qt5_coco/qt5/qtbase/src/platformsupport/input/evdevkeyboard/qevdevkeyboardhandler.cpp |
Switch to Source code | Preprocessed file |
Line | Source | Count | ||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
1 | - | |||||||||||||
2 | - | |||||||||||||
3 | - | |||||||||||||
4 | - | |||||||||||||
5 | - | |||||||||||||
6 | - | |||||||||||||
7 | const QLoggingCategory &qLcEvdevKey() { static const QLoggingCategory category("qt.qpa.input"); return category; } | - | ||||||||||||
8 | const QLoggingCategory &qLcEvdevKeyMap() { static const QLoggingCategory category("qt.qpa.input.keymap"); return category; } | - | ||||||||||||
9 | - | |||||||||||||
10 | - | |||||||||||||
11 | - | |||||||||||||
12 | void QFdContainer::reset() noexcept | - | ||||||||||||
13 | { | - | ||||||||||||
14 | if (m_fd >= 0
| 0 | ||||||||||||
15 | qt_safe_close(m_fd); never executed: qt_safe_close(m_fd); | 0 | ||||||||||||
16 | m_fd = -1; | - | ||||||||||||
17 | } never executed: end of block | 0 | ||||||||||||
18 | - | |||||||||||||
19 | QEvdevKeyboardHandler::QEvdevKeyboardHandler(const QString &device, QFdContainer &fd, bool disableZap, bool enableCompose, const QString &keymapFile) | - | ||||||||||||
20 | : m_device(device), m_fd(fd.release()), m_notify(nullptr), | - | ||||||||||||
21 | m_modifiers(0), m_composing(0), m_dead_unicode(0xffff), | - | ||||||||||||
22 | m_no_zap(disableZap), m_do_compose(enableCompose), | - | ||||||||||||
23 | m_keymap(0), m_keymap_size(0), m_keycompose(0), m_keycompose_size(0) | - | ||||||||||||
24 | { | - | ||||||||||||
25 | for (bool qt_category_enabled = qLcEvdevKey().isDebugEnabled(); qt_category_enabled; qt_category_enabled = false) QMessageLogger(__FILE__, 6875, __PRETTY_FUNCTION__, qLcEvdevKey().categoryName()).debug() << "Create keyboard handler with for device" << device; | - | ||||||||||||
26 | - | |||||||||||||
27 | setObjectName(QLatin1String("LinuxInput Keyboard Handler")); | - | ||||||||||||
28 | - | |||||||||||||
29 | memset(m_locks, 0, sizeof(m_locks)); | - | ||||||||||||
30 | - | |||||||||||||
31 | if (keymapFile.isEmpty() || !loadKeymap(keymapFile)) | - | ||||||||||||
32 | unloadKeymap(); | - | ||||||||||||
33 | - | |||||||||||||
34 | - | |||||||||||||
35 | m_notify = new QSocketNotifier(m_fd.get(), QSocketNotifier::Read, this); | - | ||||||||||||
36 | connect(m_notify, qFlagLocation("2""activated(int)" "\0" __FILE__ ":" "79""86"), this, qFlagLocation("1""readKeycode()" "\0" __FILE__ ":" "79""86")); | - | ||||||||||||
37 | } | - | ||||||||||||
38 | - | |||||||||||||
39 | QEvdevKeyboardHandler::~QEvdevKeyboardHandler() | - | ||||||||||||
40 | { | - | ||||||||||||
41 | unloadKeymap(); | - | ||||||||||||
42 | } | - | ||||||||||||
43 | - | |||||||||||||
44 | QEvdevKeyboardHandler *QEvdevKeyboardHandler::create(const QString &device, | - | ||||||||||||
45 | const QString &specification, | - | ||||||||||||
46 | const QString &defaultKeymapFile) | - | ||||||||||||
47 | { | - | ||||||||||||
48 | for (bool qt_category_enabled = qLcEvdevKey().isDebugEnabled(); qt_category_enabled
never executed: QMessageLogger(__FILE__, 98, __PRETTY_FUNCTION__, qLcEvdevKey().categoryName()).debug() << "Try to create keyboard handler for" << device << specification; | 0 | ||||||||||||
49 | - | |||||||||||||
50 | QString keymapFile = defaultKeymapFile; | - | ||||||||||||
51 | int repeatDelay = 400; | - | ||||||||||||
52 | int repeatRate = 80; | - | ||||||||||||
53 | bool disableZap = false; | - | ||||||||||||
54 | bool enableCompose = false; | - | ||||||||||||
55 | int grab = 0; | - | ||||||||||||
56 | - | |||||||||||||
57 | QStringListconst auto args = specification.splitsplitRef(QLatin1Char(':')); | - | ||||||||||||
for (QForeachContainer<typename QtPrivate::remove_reference<decltype(args)>::type> _container_((args)); | ||||||||||||||
58 | _container_.control && _container_.i != _container_.e; ++_container_.i, _container_.control ^= 1)for (const QStringQStringRef &arg = *_container_.i; _container_.control; _container_.control = 0: args) { | - | ||||||||||||
59 | if (arg.startsWith(QLatin1String("keymap="))
| 0 | ||||||||||||
60 | keymapFile = arg.mid(7);).toString(); never executed: keymapFile = arg.mid(7).toString(); | 0 | ||||||||||||
61 | else if (arg == QLatin1String("disable-zap")
| 0 | ||||||||||||
62 | disableZap = true; never executed: disableZap = true; | 0 | ||||||||||||
63 | else if (arg == QLatin1String("enable-compose")
| 0 | ||||||||||||
64 | enableCompose = true; never executed: enableCompose = true; | 0 | ||||||||||||
65 | else if (arg.startsWith(QLatin1String("repeat-delay="))
| 0 | ||||||||||||
66 | repeatDelay = arg.mid(13).toInt(); never executed: repeatDelay = arg.mid(13).toInt(); | 0 | ||||||||||||
67 | else if (arg.startsWith(QLatin1String("repeat-rate="))
| 0 | ||||||||||||
68 | repeatRate = arg.mid(12).toInt(); never executed: repeatRate = arg.mid(12).toInt(); | 0 | ||||||||||||
69 | else if (arg.startsWith(QLatin1String("grab="))
| 0 | ||||||||||||
70 | grab = arg.mid(5).toInt(); never executed: grab = arg.mid(5).toInt(); | 0 | ||||||||||||
71 | } never executed: end of block | 0 | ||||||||||||
72 | - | |||||||||||||
73 | for (bool qt_category_enabled = qLcEvdevKey().isDebugEnabled(); qt_category_enabled
never executed: QMessageLogger(__FILE__, 123, __PRETTY_FUNCTION__, qLcEvdevKey().categoryName()).debug() << "Opening keyboard at" << device; | 0 | ||||||||||||
74 | - | |||||||||||||
75 | QFdContainer fd(qt_safe_open(device.toLocal8Bit().constData(), 00 | 04000, 0)); | - | ||||||||||||
76 | if (fd.get() >= 0
| 0 | ||||||||||||
77 | ::ioctl(fd.get(), (((1U) << (((0 +8)+8)+14)) | ((('E')) << (0 +8)) | (((0x90)) << 0) | ((((sizeof(int)))) << ((0 +8)+8))), grab); | - | ||||||||||||
78 | if (repeatDelay > 0
| 0 | ||||||||||||
79 | int kbdrep[2] = { repeatDelay, repeatRate }; | - | ||||||||||||
80 | ::ioctl(fd.get(), (((1U) << (((0 +8)+8)+14)) | ((('E')) << (0 +8)) | (((0x03)) << 0) | ((((sizeof(unsigned int[2])))) << ((0 +8)+8))), kbdrep); | - | ||||||||||||
81 | } never executed: end of block | 0 | ||||||||||||
82 | - | |||||||||||||
83 | return never executed: new QEvdevKeyboardHandler(device, fd, disableZap, enableCompose, keymapFile);return new QEvdevKeyboardHandler(device, fd, disableZap, enableCompose, keymapFile); never executed: return new QEvdevKeyboardHandler(device, fd, disableZap, enableCompose, keymapFile); | 0 | ||||||||||||
84 | } else { | - | ||||||||||||
85 | QMessageLogger(__FILE__, 128135, __PRETTY_FUNCTION__).warning("Cannot open keyboard input device '%s': %s", QString(device).toLocal8Bit().constData(), strerror((*__errno_location ()))); | - | ||||||||||||
86 | return never executed: 0;return 0; never executed: return 0; | 0 | ||||||||||||
87 | } | - | ||||||||||||
88 | } | - | ||||||||||||
89 | - | |||||||||||||
90 | void QEvdevKeyboardHandler::switchLed(int led, bool state) | - | ||||||||||||
91 | { | - | ||||||||||||
92 | for (bool qt_category_enabled = qLcEvdevKey().isDebugEnabled(); qt_category_enabled; qt_category_enabled = false) QMessageLogger(__FILE__, 135142, __PRETTY_FUNCTION__, qLcEvdevKey().categoryName()).debug() << "switchLed" << led << state; | - | ||||||||||||
93 | - | |||||||||||||
94 | struct ::input_event led_ie; | - | ||||||||||||
95 | ::gettimeofday(&led_ie.time, 0); | - | ||||||||||||
96 | led_ie.type = 0x11; | - | ||||||||||||
97 | led_ie.code = led; | - | ||||||||||||
98 | led_ie.value = state; | - | ||||||||||||
99 | - | |||||||||||||
100 | qt_safe_write(m_fd.get(), &led_ie, sizeof(led_ie)); | - | ||||||||||||
101 | } | - | ||||||||||||
102 | - | |||||||||||||
103 | void QEvdevKeyboardHandler::readKeycode() | - | ||||||||||||
104 | { | - | ||||||||||||
105 | struct ::input_event buffer[32]; | - | ||||||||||||
106 | int n = 0; | - | ||||||||||||
107 | - | |||||||||||||
108 | for(;;) { | - | ||||||||||||
109 | int result = qt_safe_read(m_fd.get(), reinterpret_cast<char *>(buffer) + n, sizeof(buffer) - n); | - | ||||||||||||
110 | - | |||||||||||||
111 | if (result == 0) { | - | ||||||||||||
112 | QMessageLogger(__FILE__, 155162, __PRETTY_FUNCTION__).warning("evdevkeyboard: Got EOF from the input device"); | - | ||||||||||||
113 | return; | - | ||||||||||||
114 | } else if (result < 0) { | - | ||||||||||||
115 | if ((*__errno_location ()) != 4 && (*__errno_location ()) != 11) { | - | ||||||||||||
116 | qErrnoWarning((*__errno_location ()), "evdevkeyboard: Could not read from input device"); | - | ||||||||||||
117 | - | |||||||||||||
118 | - | |||||||||||||
119 | if ((*__errno_location ()) == 19) { | - | ||||||||||||
120 | delete m_notify; | - | ||||||||||||
121 | m_notify = nullptr; | - | ||||||||||||
122 | m_fd.reset(); | - | ||||||||||||
123 | } | - | ||||||||||||
124 | return; | - | ||||||||||||
125 | } | - | ||||||||||||
126 | } else { | - | ||||||||||||
127 | n += result; | - | ||||||||||||
128 | if (n % sizeof(buffer[0]) == 0) | - | ||||||||||||
129 | break; | - | ||||||||||||
130 | } | - | ||||||||||||
131 | } | - | ||||||||||||
132 | - | |||||||||||||
133 | n /= sizeof(buffer[0]); | - | ||||||||||||
134 | - | |||||||||||||
135 | for (int i = 0; i < n; ++i) { | - | ||||||||||||
136 | if (buffer[i].type != 0x01) | - | ||||||||||||
137 | continue; | - | ||||||||||||
138 | - | |||||||||||||
139 | quint16 code = buffer[i].code; | - | ||||||||||||
140 | qint32 value = buffer[i].value; | - | ||||||||||||
141 | - | |||||||||||||
142 | QEvdevKeyboardHandler::KeycodeAction ka; | - | ||||||||||||
143 | ka = processKeycode(code, value != 0, value == 2); | - | ||||||||||||
144 | - | |||||||||||||
145 | switch (ka) { | - | ||||||||||||
146 | case QEvdevKeyboardHandler::CapsLockOn: | - | ||||||||||||
147 | case QEvdevKeyboardHandler::CapsLockOff: | - | ||||||||||||
148 | switchLed(0x01, ka == QEvdevKeyboardHandler::CapsLockOn); | - | ||||||||||||
149 | break; | - | ||||||||||||
150 | - | |||||||||||||
151 | case QEvdevKeyboardHandler::NumLockOn: | - | ||||||||||||
152 | case QEvdevKeyboardHandler::NumLockOff: | - | ||||||||||||
153 | switchLed(0x00, ka == QEvdevKeyboardHandler::NumLockOn); | - | ||||||||||||
154 | break; | - | ||||||||||||
155 | - | |||||||||||||
156 | case QEvdevKeyboardHandler::ScrollLockOn: | - | ||||||||||||
157 | case QEvdevKeyboardHandler::ScrollLockOff: | - | ||||||||||||
158 | switchLed(0x02, ka == QEvdevKeyboardHandler::ScrollLockOn); | - | ||||||||||||
159 | break; | - | ||||||||||||
160 | - | |||||||||||||
161 | default: | - | ||||||||||||
162 | - | |||||||||||||
163 | break; | - | ||||||||||||
164 | } | - | ||||||||||||
165 | } | - | ||||||||||||
166 | } | - | ||||||||||||
167 | - | |||||||||||||
168 | void QEvdevKeyboardHandler::processKeyEvent(int nativecode, int unicode, int qtcode, | - | ||||||||||||
169 | Qt::KeyboardModifiers modifiers, bool isPress, bool autoRepeat) | - | ||||||||||||
170 | { | - | ||||||||||||
171 | QWindowSystemInterface::handleExtendedKeyEvent(0, (isPress ? QEvent::KeyPress : QEvent::KeyRelease), | - | ||||||||||||
172 | qtcode, modifiers, nativecode + 8, 0, int(modifiers), | - | ||||||||||||
173 | (unicode != 0xffff ) ? QString(unicode) : QString(), autoRepeat); | - | ||||||||||||
174 | } | - | ||||||||||||
175 | - | |||||||||||||
176 | QEvdevKeyboardHandler::KeycodeAction QEvdevKeyboardHandler::processKeycode(quint16 keycode, bool pressed, bool autorepeat) | - | ||||||||||||
177 | { | - | ||||||||||||
178 | KeycodeAction result = None; | - | ||||||||||||
179 | bool first_press = pressed && !autorepeat; | - | ||||||||||||
180 | - | |||||||||||||
181 | const QEvdevKeyboardMap::Mapping *map_plain = 0; | - | ||||||||||||
182 | const QEvdevKeyboardMap::Mapping *map_withmod = 0; | - | ||||||||||||
183 | - | |||||||||||||
184 | quint8 modifiers = m_modifiers; | - | ||||||||||||
185 | - | |||||||||||||
186 | - | |||||||||||||
187 | for (int i = 0; i < m_keymap_size && !(map_plain && map_withmod); ++i) { | - | ||||||||||||
188 | const QEvdevKeyboardMap::Mapping *m = m_keymap + i; | - | ||||||||||||
189 | if (m->keycode == keycode) { | - | ||||||||||||
190 | if (m->modifiers == 0) | - | ||||||||||||
191 | map_plain = m; | - | ||||||||||||
192 | - | |||||||||||||
193 | quint8 testmods = m_modifiers; | - | ||||||||||||
194 | if (m_locks[0] && (m->flags & QEvdevKeyboardMap::IsLetter)) | - | ||||||||||||
195 | testmods ^= QEvdevKeyboardMap::ModShift; | - | ||||||||||||
196 | if (m->modifiers == testmods) | - | ||||||||||||
197 | map_withmod = m; | - | ||||||||||||
198 | } | - | ||||||||||||
199 | } | - | ||||||||||||
200 | - | |||||||||||||
201 | if (m_locks[0] && map_withmod && (map_withmod->flags & QEvdevKeyboardMap::IsLetter)) | - | ||||||||||||
202 | modifiers ^= QEvdevKeyboardMap::ModShift; | - | ||||||||||||
203 | - | |||||||||||||
204 | for (bool qt_category_enabled = qLcEvdevKeyMap().isDebugEnabled(); qt_category_enabled; qt_category_enabled = false) QMessageLogger( | - | ||||||||||||
205 | - | |||||||||||||
206 | - | |||||||||||||
207 | - | |||||||||||||
208 | __FILE__ | - | ||||||||||||
209 | , | - | ||||||||||||
210 | - | |||||||||||||
211 | - | |||||||||||||
212 | - | |||||||||||||
213 | 251258 | - | ||||||||||||
214 | , __PRETTY_FUNCTION__, qLcEvdevKeyMap().categoryName()).debug("Processing key event: keycode=%3d, modifiers=%02x pressed=%d, autorepeat=%d | plain=%d, withmod=%d, size=%d", keycode, modifiers, pressed ? 1 : 0, autorepeat ? 1 : 0, int(map_plain ? map_plain - m_keymap : -1), int(map_withmod ? map_withmod - m_keymap : -1), m_keymap_size) | - | ||||||||||||
215 | - | |||||||||||||
216 | - | |||||||||||||
217 | - | |||||||||||||
218 | ; | - | ||||||||||||
219 | - | |||||||||||||
220 | const QEvdevKeyboardMap::Mapping *it = map_withmod ? map_withmod : map_plain; | - | ||||||||||||
221 | - | |||||||||||||
222 | if (!it) { | - | ||||||||||||
223 | - | |||||||||||||
224 | for (bool qt_category_enabled = qLcEvdevKeyMap().isDebugEnabled(); qt_category_enabled; qt_category_enabled = false) QMessageLogger(__FILE__, 257264, __PRETTY_FUNCTION__, qLcEvdevKeyMap().categoryName()).debug("Could not find a suitable mapping for keycode: %3d, modifiers: %02x", keycode, modifiers); | - | ||||||||||||
225 | return result; | - | ||||||||||||
226 | } | - | ||||||||||||
227 | - | |||||||||||||
228 | bool skip = false; | - | ||||||||||||
229 | quint16 unicode = it->unicode; | - | ||||||||||||
230 | quint32 qtcode = it->qtcode; | - | ||||||||||||
231 | - | |||||||||||||
232 | if ((it->flags & QEvdevKeyboardMap::IsModifier) && it->special) { | - | ||||||||||||
233 | - | |||||||||||||
234 | if (pressed) | - | ||||||||||||
235 | m_modifiers |= quint8(it->special); | - | ||||||||||||
236 | else | - | ||||||||||||
237 | m_modifiers &= ~quint8(it->special); | - | ||||||||||||
238 | } else if (qtcode >= Qt::Key_CapsLock && qtcode <= Qt::Key_ScrollLock) { | - | ||||||||||||
239 | - | |||||||||||||
240 | if (first_press) { | - | ||||||||||||
241 | quint8 &lock = m_locks[qtcode - Qt::Key_CapsLock]; | - | ||||||||||||
242 | lock ^= 1; | - | ||||||||||||
243 | - | |||||||||||||
244 | switch (qtcode) { | - | ||||||||||||
245 | case Qt::Key_CapsLock : result = lock ? CapsLockOn : CapsLockOff; break; | - | ||||||||||||
246 | case Qt::Key_NumLock : result = lock ? NumLockOn : NumLockOff; break; | - | ||||||||||||
247 | case Qt::Key_ScrollLock: result = lock ? ScrollLockOn : ScrollLockOff; break; | - | ||||||||||||
248 | default : break; | - | ||||||||||||
249 | } | - | ||||||||||||
250 | } | - | ||||||||||||
251 | } else if ((it->flags & QEvdevKeyboardMap::IsSystem) && it->special && first_press) { | - | ||||||||||||
252 | switch (it->special) { | - | ||||||||||||
253 | case QEvdevKeyboardMap::SystemReboot: | - | ||||||||||||
254 | result = Reboot; | - | ||||||||||||
255 | break; | - | ||||||||||||
256 | - | |||||||||||||
257 | case QEvdevKeyboardMap::SystemZap: | - | ||||||||||||
258 | if (!m_no_zap) | - | ||||||||||||
259 | QCoreApplication::instance()->quit(); | - | ||||||||||||
260 | break; | - | ||||||||||||
261 | - | |||||||||||||
262 | case QEvdevKeyboardMap::SystemConsolePrevious: | - | ||||||||||||
263 | result = PreviousConsole; | - | ||||||||||||
264 | break; | - | ||||||||||||
265 | - | |||||||||||||
266 | case QEvdevKeyboardMap::SystemConsoleNext: | - | ||||||||||||
267 | result = NextConsole; | - | ||||||||||||
268 | break; | - | ||||||||||||
269 | - | |||||||||||||
270 | default: | - | ||||||||||||
271 | if (it->special >= QEvdevKeyboardMap::SystemConsoleFirst && | - | ||||||||||||
272 | it->special <= QEvdevKeyboardMap::SystemConsoleLast) { | - | ||||||||||||
273 | result = KeycodeAction(SwitchConsoleFirst + ((it->special & QEvdevKeyboardMap::SystemConsoleMask) & SwitchConsoleMask)); | - | ||||||||||||
274 | } | - | ||||||||||||
275 | break; | - | ||||||||||||
276 | } | - | ||||||||||||
277 | - | |||||||||||||
278 | skip = true; | - | ||||||||||||
279 | } else if ((qtcode == Qt::Key_Multi_key) && m_do_compose) { | - | ||||||||||||
280 | - | |||||||||||||
281 | if (first_press) | - | ||||||||||||
282 | m_composing = 2; | - | ||||||||||||
283 | skip = true; | - | ||||||||||||
284 | } else if ((it->flags & QEvdevKeyboardMap::IsDead) && m_do_compose) { | - | ||||||||||||
285 | - | |||||||||||||
286 | if (first_press && m_composing == 1 && m_dead_unicode == unicode) { | - | ||||||||||||
287 | m_composing = 0; | - | ||||||||||||
288 | qtcode = Qt::Key_unknown; | - | ||||||||||||
289 | } else if (first_press && unicode != 0xffff) { | - | ||||||||||||
290 | m_dead_unicode = unicode; | - | ||||||||||||
291 | m_composing = 1; | - | ||||||||||||
292 | skip = true; | - | ||||||||||||
293 | } else { | - | ||||||||||||
294 | skip = true; | - | ||||||||||||
295 | } | - | ||||||||||||
296 | } | - | ||||||||||||
297 | - | |||||||||||||
298 | if (!skip) { | - | ||||||||||||
299 | - | |||||||||||||
300 | const int modmask = Qt::ShiftModifier | Qt::ControlModifier | Qt::AltModifier | Qt::MetaModifier | Qt::KeypadModifier; | - | ||||||||||||
301 | - | |||||||||||||
302 | - | |||||||||||||
303 | - | |||||||||||||
304 | - | |||||||||||||
305 | if ((it == map_plain && it != map_withmod) || | - | ||||||||||||
306 | (map_withmod && !(map_withmod->qtcode & modmask))) { | - | ||||||||||||
307 | qtcode |= QEvdevKeyboardHandler::toQtModifiers(modifiers); | - | ||||||||||||
308 | } | - | ||||||||||||
309 | - | |||||||||||||
310 | if (m_composing == 2 && first_press && !(it->flags & QEvdevKeyboardMap::IsModifier)) { | - | ||||||||||||
311 | - | |||||||||||||
312 | if (unicode != 0xffff) { | - | ||||||||||||
313 | int idx = 0; | - | ||||||||||||
314 | - | |||||||||||||
315 | for ( ; idx < m_keycompose_size; ++idx) { | - | ||||||||||||
316 | if (m_keycompose[idx].first == unicode) | - | ||||||||||||
317 | break; | - | ||||||||||||
318 | } | - | ||||||||||||
319 | if (idx < m_keycompose_size) { | - | ||||||||||||
320 | - | |||||||||||||
321 | m_dead_unicode = unicode; | - | ||||||||||||
322 | unicode = 0xffff; | - | ||||||||||||
323 | m_composing = 1; | - | ||||||||||||
324 | skip = true; | - | ||||||||||||
325 | } else { | - | ||||||||||||
326 | m_composing = 0; | - | ||||||||||||
327 | } | - | ||||||||||||
328 | } else { | - | ||||||||||||
329 | m_composing = 0; | - | ||||||||||||
330 | } | - | ||||||||||||
331 | } else if (m_composing == 1 && first_press && !(it->flags & QEvdevKeyboardMap::IsModifier)) { | - | ||||||||||||
332 | - | |||||||||||||
333 | bool valid = false; | - | ||||||||||||
334 | if (unicode != 0xffff) { | - | ||||||||||||
335 | int idx = 0; | - | ||||||||||||
336 | - | |||||||||||||
337 | for ( ; idx < m_keycompose_size; ++idx) { | - | ||||||||||||
338 | if (m_keycompose[idx].first == m_dead_unicode && m_keycompose[idx].second == unicode) | - | ||||||||||||
339 | break; | - | ||||||||||||
340 | } | - | ||||||||||||
341 | if (idx < m_keycompose_size) { | - | ||||||||||||
342 | quint16 composed = m_keycompose[idx].result; | - | ||||||||||||
343 | if (composed != 0xffff) { | - | ||||||||||||
344 | unicode = composed; | - | ||||||||||||
345 | qtcode = Qt::Key_unknown; | - | ||||||||||||
346 | valid = true; | - | ||||||||||||
347 | } | - | ||||||||||||
348 | } | - | ||||||||||||
349 | } | - | ||||||||||||
350 | if (!valid) { | - | ||||||||||||
351 | unicode = m_dead_unicode; | - | ||||||||||||
352 | qtcode = Qt::Key_unknown; | - | ||||||||||||
353 | } | - | ||||||||||||
354 | m_composing = 0; | - | ||||||||||||
355 | } | - | ||||||||||||
356 | - | |||||||||||||
357 | if (!skip) { | - | ||||||||||||
358 | - | |||||||||||||
359 | Qt::KeyboardModifiers qtmods = Qt::KeyboardModifiers(qtcode & modmask); | - | ||||||||||||
360 | qtcode &= ~modmask; | - | ||||||||||||
361 | - | |||||||||||||
362 | for (bool qt_category_enabled = qLcEvdevKeyMap().isDebugEnabled(); qt_category_enabled; qt_category_enabled = false) QMessageLogger(__FILE__, 395402, __PRETTY_FUNCTION__, qLcEvdevKeyMap().categoryName()).debug("Processing: uni=%04x, qt=%08x, qtmod=%08x", unicode, qtcode, int(qtmods)); | - | ||||||||||||
363 | - | |||||||||||||
364 | - | |||||||||||||
365 | if (!m_locks[1] && (qtmods & Qt::KeypadModifier) && | - | ||||||||||||
366 | keycode >= 71 && | - | ||||||||||||
367 | keycode <= 83 && | - | ||||||||||||
368 | keycode != 74 && | - | ||||||||||||
369 | keycode != 78) { | - | ||||||||||||
370 | - | |||||||||||||
371 | unicode = 0xffff; | - | ||||||||||||
372 | switch (keycode) { | - | ||||||||||||
373 | case 71: | - | ||||||||||||
374 | qtcode = Qt::Key_Home; | - | ||||||||||||
375 | break; | - | ||||||||||||
376 | case 72: | - | ||||||||||||
377 | qtcode = Qt::Key_Up; | - | ||||||||||||
378 | break; | - | ||||||||||||
379 | case 73: | - | ||||||||||||
380 | qtcode = Qt::Key_PageUp; | - | ||||||||||||
381 | break; | - | ||||||||||||
382 | case 75: | - | ||||||||||||
383 | qtcode = Qt::Key_Left; | - | ||||||||||||
384 | break; | - | ||||||||||||
385 | case 76: | - | ||||||||||||
386 | qtcode = Qt::Key_Clear; | - | ||||||||||||
387 | break; | - | ||||||||||||
388 | case 77: | - | ||||||||||||
389 | qtcode = Qt::Key_Right; | - | ||||||||||||
390 | break; | - | ||||||||||||
391 | case 79: | - | ||||||||||||
392 | qtcode = Qt::Key_End; | - | ||||||||||||
393 | break; | - | ||||||||||||
394 | case 80: | - | ||||||||||||
395 | qtcode = Qt::Key_Down; | - | ||||||||||||
396 | break; | - | ||||||||||||
397 | case 81: | - | ||||||||||||
398 | qtcode = Qt::Key_PageDown; | - | ||||||||||||
399 | break; | - | ||||||||||||
400 | case 82: | - | ||||||||||||
401 | qtcode = Qt::Key_Insert; | - | ||||||||||||
402 | break; | - | ||||||||||||
403 | case 83: | - | ||||||||||||
404 | qtcode = Qt::Key_Delete; | - | ||||||||||||
405 | break; | - | ||||||||||||
406 | } | - | ||||||||||||
407 | } | - | ||||||||||||
408 | - | |||||||||||||
409 | - | |||||||||||||
410 | if (qtcode == Qt::Key_Tab && (qtmods & Qt::ShiftModifier) == Qt::ShiftModifier) | - | ||||||||||||
411 | qtcode = Qt::Key_Backtab; | - | ||||||||||||
412 | - | |||||||||||||
413 | - | |||||||||||||
414 | processKeyEvent(keycode, unicode, qtcode, qtmods, pressed, autorepeat); | - | ||||||||||||
415 | } | - | ||||||||||||
416 | } | - | ||||||||||||
417 | return result; | - | ||||||||||||
418 | } | - | ||||||||||||
419 | - | |||||||||||||
420 | void QEvdevKeyboardHandler::unloadKeymap() | - | ||||||||||||
421 | { | - | ||||||||||||
422 | for (bool qt_category_enabled = qLcEvdevKey().isDebugEnabled(); qt_category_enabled; qt_category_enabled = false) QMessageLogger(__FILE__, 455462, __PRETTY_FUNCTION__, qLcEvdevKey().categoryName()).debug() << "Unload current keymap and restore built-in"; | - | ||||||||||||
423 | - | |||||||||||||
424 | if (m_keymap && m_keymap != s_keymap_default) | - | ||||||||||||
425 | delete [] m_keymap; | - | ||||||||||||
426 | if (m_keycompose && m_keycompose != s_keycompose_default) | - | ||||||||||||
427 | delete [] m_keycompose; | - | ||||||||||||
428 | - | |||||||||||||
429 | m_keymap = s_keymap_default; | - | ||||||||||||
430 | m_keymap_size = sizeof(s_keymap_default) / sizeof(s_keymap_default[0]); | - | ||||||||||||
431 | m_keycompose = s_keycompose_default; | - | ||||||||||||
432 | m_keycompose_size = sizeof(s_keycompose_default) / sizeof(s_keycompose_default[0]); | - | ||||||||||||
433 | - | |||||||||||||
434 | - | |||||||||||||
435 | m_modifiers = 0; | - | ||||||||||||
436 | memset(m_locks, 0, sizeof(m_locks)); | - | ||||||||||||
437 | m_composing = 0; | - | ||||||||||||
438 | m_dead_unicode = 0xffff; | - | ||||||||||||
439 | - | |||||||||||||
440 | - | |||||||||||||
441 | quint16 ledbits[1]; | - | ||||||||||||
442 | memset(ledbits, 0, sizeof(ledbits)); | - | ||||||||||||
443 | if (::ioctl(m_fd.get(), (((2U) << (((0 +8)+8)+14)) | (('E') << (0 +8)) | ((0x19) << 0) | ((sizeof(ledbits)) << ((0 +8)+8))), ledbits) < 0) { | - | ||||||||||||
444 | QMessageLogger(__FILE__, 477484, __PRETTY_FUNCTION__).warning("evdevkeyboard: Failed to query led states"); | - | ||||||||||||
445 | switchLed(0x00,false); | - | ||||||||||||
446 | switchLed(0x01, false); | - | ||||||||||||
447 | switchLed(0x02,false); | - | ||||||||||||
448 | } else { | - | ||||||||||||
449 | - | |||||||||||||
450 | if ((ledbits[0]&0x02) > 0) | - | ||||||||||||
451 | m_locks[0] = 1; | - | ||||||||||||
452 | - | |||||||||||||
453 | if ((ledbits[0]&0x01) > 0) | - | ||||||||||||
454 | m_locks[1] = 1; | - | ||||||||||||
455 | - | |||||||||||||
456 | if ((ledbits[0]&0x04) > 0) | - | ||||||||||||
457 | m_locks[2] = 1; | - | ||||||||||||
458 | for (bool qt_category_enabled = qLcEvdevKey().isDebugEnabled(); qt_category_enabled; qt_category_enabled = false) QMessageLogger(__FILE__, 491498, __PRETTY_FUNCTION__, qLcEvdevKey().categoryName()).debug("numlock=%d , capslock=%d, scrolllock=%d", m_locks[1], m_locks[0], m_locks[2]); | - | ||||||||||||
459 | } | - | ||||||||||||
460 | } | - | ||||||||||||
461 | - | |||||||||||||
462 | bool QEvdevKeyboardHandler::loadKeymap(const QString &file) | - | ||||||||||||
463 | { | - | ||||||||||||
464 | for (bool qt_category_enabled = qLcEvdevKey().isDebugEnabled(); qt_category_enabled; qt_category_enabled = false) QMessageLogger(__FILE__, 497504, __PRETTY_FUNCTION__, qLcEvdevKey().categoryName()).debug() << "Loading keymap" << file; | - | ||||||||||||
465 | - | |||||||||||||
466 | QFile f(file); | - | ||||||||||||
467 | - | |||||||||||||
468 | if (!f.open(QIODevice::ReadOnly)) { | - | ||||||||||||
469 | QMessageLogger(__FILE__, 502509, __PRETTY_FUNCTION__).warning("Could not open keymap file '%s'", QString(file).toLocal8Bit().constData()); | - | ||||||||||||
470 | return false; | - | ||||||||||||
471 | } | - | ||||||||||||
472 | quint32 qmap_magic, qmap_version, qmap_keymap_size, qmap_keycompose_size; | - | ||||||||||||
473 | - | |||||||||||||
474 | QDataStream ds(&f); | - | ||||||||||||
475 | - | |||||||||||||
476 | ds >> qmap_magic >> qmap_version >> qmap_keymap_size >> qmap_keycompose_size; | - | ||||||||||||
477 | - | |||||||||||||
478 | if (ds.status() != QDataStream::Ok || qmap_magic != QEvdevKeyboardMap::FileMagic || qmap_version != 1 || qmap_keymap_size == 0) { | - | ||||||||||||
479 | QMessageLogger(__FILE__, 521528, __PRETTY_FUNCTION__).warning("'%s' is not a valid .qmap keymap file", QString(file).toLocal8Bit().constData()); | - | ||||||||||||
480 | return false; | - | ||||||||||||
481 | } | - | ||||||||||||
482 | - | |||||||||||||
483 | QEvdevKeyboardMap::Mapping *qmap_keymap = new QEvdevKeyboardMap::Mapping[qmap_keymap_size]; | - | ||||||||||||
484 | QEvdevKeyboardMap::Composing *qmap_keycompose = qmap_keycompose_size ? new QEvdevKeyboardMap::Composing[qmap_keycompose_size] : 0; | - | ||||||||||||
485 | - | |||||||||||||
486 | for (quint32 i = 0; i < qmap_keymap_size; ++i) | - | ||||||||||||
487 | ds >> qmap_keymap[i]; | - | ||||||||||||
488 | for (quint32 i = 0; i < qmap_keycompose_size; ++i) | - | ||||||||||||
489 | ds >> qmap_keycompose[i]; | - | ||||||||||||
490 | - | |||||||||||||
491 | if (ds.status() != QDataStream::Ok) { | - | ||||||||||||
492 | delete [] qmap_keymap; | - | ||||||||||||
493 | delete [] qmap_keycompose; | - | ||||||||||||
494 | - | |||||||||||||
495 | QMessageLogger(__FILE__, 537544, __PRETTY_FUNCTION__).warning("Keymap file '%s' can not be loaded.", QString(file).toLocal8Bit().constData()); | - | ||||||||||||
496 | return false; | - | ||||||||||||
497 | } | - | ||||||||||||
498 | - | |||||||||||||
499 | - | |||||||||||||
500 | unloadKeymap(); | - | ||||||||||||
501 | - | |||||||||||||
502 | m_keymap = qmap_keymap; | - | ||||||||||||
503 | m_keymap_size = qmap_keymap_size; | - | ||||||||||||
504 | m_keycompose = qmap_keycompose; | - | ||||||||||||
505 | m_keycompose_size = qmap_keycompose_size; | - | ||||||||||||
506 | - | |||||||||||||
507 | m_do_compose = true; | - | ||||||||||||
508 | - | |||||||||||||
509 | return true; | - | ||||||||||||
510 | } | - | ||||||||||||
511 | - | |||||||||||||
512 | - | |||||||||||||
Switch to Source code | Preprocessed file |