KWindowSystem

kkeyserver.cpp
1/*
2 SPDX-FileCopyrightText: 2001 Ellis Whitehead <ellis@kde.org>
3
4 Win32 port:
5 SPDX-FileCopyrightText: 2004 Jarosław Staniek <staniek@kde.org>
6
7 SPDX-License-Identifier: LGPL-2.1-or-later
8*/
9
10#include "kkeyserver.h"
11
12#include "kwindowsystem_xcb_debug.h"
13
14#include <private/qtx11extras_p.h>
15
16#define XK_MISCELLANY
17#define XK_XKB_KEYS
18#include <X11/X.h>
19#include <X11/Xlib.h>
20#include <X11/Xutil.h>
21#include <X11/keysymdef.h>
22#include <xcb/xcb_keysyms.h>
23#define X11_ONLY(arg) arg, // allows to omit an argument
24
25#include <QCoreApplication>
26
27namespace KKeyServer
28{
29//---------------------------------------------------------------------
30// Array Structures
31//---------------------------------------------------------------------
32
33struct ModInfo {
34 int modQt;
35 const char *psName;
36 QString *sLabel; // this struct is used in static objects, so must use a pointer here.
37};
38
39//---------------------------------------------------------------------
40// Arrays
41//---------------------------------------------------------------------
42
43// Key names with this context are extracted elsewhere,
44// no need for I18N_NOOP2's here.
45#define KEYCTXT "keyboard-key-name"
46static ModInfo g_rgModInfo[4] = {
47 {Qt::SHIFT, "Shift", nullptr},
48 {Qt::CTRL, "Ctrl", nullptr},
49 {Qt::ALT, "Alt", nullptr},
50 {Qt::META, "Meta", nullptr},
51};
52
53//---------------------------------------------------------------------
54// Initialization
55//---------------------------------------------------------------------
56static bool g_bInitializedKKeyLabels;
57static bool g_bMacLabels;
58
59static void intializeKKeyLabels()
60{
61 g_rgModInfo[0].sLabel = new QString(QCoreApplication::translate("KKeyServer", (g_rgModInfo[0].psName), KEYCTXT));
62 g_rgModInfo[1].sLabel = new QString(QCoreApplication::translate("KKeyServer", (g_rgModInfo[1].psName), KEYCTXT));
63 g_rgModInfo[2].sLabel = new QString(QCoreApplication::translate("KKeyServer", (g_rgModInfo[2].psName), KEYCTXT));
64 g_rgModInfo[3].sLabel = new QString(QCoreApplication::translate("KKeyServer", (g_rgModInfo[3].psName), KEYCTXT));
65 g_bMacLabels = (*g_rgModInfo[2].sLabel == QLatin1String("Command"));
66 g_bInitializedKKeyLabels = true;
67}
68
69//---------------------------------------------------------------------
70// Public functions
71//---------------------------------------------------------------------
72
73static QString modToString(uint mod, bool bUserSpace)
74{
75 if (bUserSpace && !g_bInitializedKKeyLabels) {
76 intializeKKeyLabels();
77 }
78
79 QString s;
80 for (int i = 3; i >= 0; i--) {
81 if (mod & g_rgModInfo[i].modQt) {
82 if (!s.isEmpty()) {
83 s += QLatin1Char('+');
84 }
85 s += (bUserSpace) ? *g_rgModInfo[i].sLabel : QLatin1String(g_rgModInfo[i].psName);
86 }
87 }
88 return s;
89}
90
92{
93 return modToString(mod, true);
94}
95
96uint stringUserToMod(const QString &mod)
97{
98 for (int i = 3; i >= 0; i--) {
99 if (mod.toLower() == g_rgModInfo[i].sLabel->toLower()) {
100 return g_rgModInfo[i].modQt;
101 }
102 }
103 return 0;
104}
105
107{
108 // remove any modifiers
109 keyQt &= ~Qt::KeyboardModifierMask;
110
111 // Shift only works as a modifier with certain keys. It's not possible
112 // to enter the SHIFT+5 key sequence for me because this is handled as
113 // '%' by qt on my keyboard.
114 // The working keys are all hardcoded here :-(
115 if (keyQt >= Qt::Key_F1 && keyQt <= Qt::Key_F35) {
116 return true;
117 }
118
119 // Returns false if not a unicode code point
120 if (QChar::isLetter(keyQt)) {
121 return true;
122 }
123
124 switch (keyQt) {
125 case Qt::Key_Return:
126 case Qt::Key_Space:
128 case Qt::Key_Tab:
129 case Qt::Key_Backtab:
130 case Qt::Key_Escape:
131 case Qt::Key_Print:
133 case Qt::Key_Pause:
134 case Qt::Key_PageUp:
135 case Qt::Key_PageDown:
136 case Qt::Key_Insert:
137 case Qt::Key_Delete:
138 case Qt::Key_Home:
139 case Qt::Key_End:
140 case Qt::Key_Up:
141 case Qt::Key_Down:
142 case Qt::Key_Left:
143 case Qt::Key_Right:
144 case Qt::Key_Enter:
145 case Qt::Key_SysReq:
146 case Qt::Key_CapsLock:
147 case Qt::Key_NumLock:
148 case Qt::Key_Help:
149 case Qt::Key_Back:
150 case Qt::Key_Forward:
151 case Qt::Key_Stop:
152 case Qt::Key_Refresh:
155 case Qt::Key_OpenUrl:
156 case Qt::Key_HomePage:
157 case Qt::Key_Search:
160 case Qt::Key_VolumeUp:
162 case Qt::Key_BassUp:
163 case Qt::Key_BassDown:
164 case Qt::Key_TrebleUp:
175 case Qt::Key_Memo:
176 case Qt::Key_ToDoList:
177 case Qt::Key_Calendar:
180 case Qt::Key_Standby:
186 case Qt::Key_PowerOff:
187 case Qt::Key_WakeUp:
188 case Qt::Key_Eject:
190 case Qt::Key_WWW:
191 case Qt::Key_Sleep:
193 case Qt::Key_Shop:
194 case Qt::Key_History:
196 case Qt::Key_HotLinks:
198 case Qt::Key_Finance:
204 case Qt::Key_Book:
205 case Qt::Key_CD:
206 case Qt::Key_Clear:
208 case Qt::Key_Close:
209 case Qt::Key_Copy:
210 case Qt::Key_Cut:
211 case Qt::Key_Display:
212 case Qt::Key_DOS:
214 case Qt::Key_Excel:
215 case Qt::Key_Explorer:
216 case Qt::Key_Game:
217 case Qt::Key_Go:
218 case Qt::Key_iTouch:
219 case Qt::Key_LogOff:
220 case Qt::Key_Market:
221 case Qt::Key_Meeting:
222 case Qt::Key_MenuKB:
223 case Qt::Key_MenuPB:
224 case Qt::Key_MySites:
225 case Qt::Key_News:
227 case Qt::Key_Option:
228 case Qt::Key_Paste:
229 case Qt::Key_Phone:
230 case Qt::Key_Reply:
231 case Qt::Key_Reload:
235 case Qt::Key_Save:
236 case Qt::Key_Send:
237 case Qt::Key_Spell:
239 case Qt::Key_Support:
240 case Qt::Key_TaskPane:
241 case Qt::Key_Terminal:
242 case Qt::Key_Tools:
243 case Qt::Key_Travel:
244 case Qt::Key_Video:
245 case Qt::Key_Word:
246 case Qt::Key_Xfer:
247 case Qt::Key_ZoomIn:
248 case Qt::Key_ZoomOut:
249 case Qt::Key_Away:
251 case Qt::Key_WebCam:
253 case Qt::Key_Pictures:
254 case Qt::Key_Music:
255 case Qt::Key_Battery:
257 case Qt::Key_WLAN:
258 case Qt::Key_UWB:
262 case Qt::Key_Subtitle:
264 case Qt::Key_Time:
265 case Qt::Key_Select:
266 case Qt::Key_View:
267 case Qt::Key_TopMenu:
268 case Qt::Key_Suspend:
270 case Qt::Key_Launch0:
271 case Qt::Key_Launch1:
272 case Qt::Key_Launch2:
273 case Qt::Key_Launch3:
274 case Qt::Key_Launch4:
275 case Qt::Key_Launch5:
276 case Qt::Key_Launch6:
277 case Qt::Key_Launch7:
278 case Qt::Key_Launch8:
279 case Qt::Key_Launch9:
280 case Qt::Key_LaunchA:
281 case Qt::Key_LaunchB:
282 case Qt::Key_LaunchC:
283 case Qt::Key_LaunchD:
284 case Qt::Key_LaunchE:
285 case Qt::Key_LaunchF:
286 case Qt::Key_Shift:
287 case Qt::Key_Control:
288 case Qt::Key_Meta:
289 case Qt::Key_Alt:
290 case Qt::Key_Super_L:
291 case Qt::Key_Super_R:
292 return true;
293
294 default:
295 return false;
296 }
297}
298
299// #define KKEYSERVER_DEBUG 1
300
301//---------------------------------------------------------------------
302// Data Structures
303//---------------------------------------------------------------------
304
305struct Mod {
306 int m_mod;
307};
308
309//---------------------------------------------------------------------
310// Array Structures
311//---------------------------------------------------------------------
312
313struct X11ModInfo {
314 int modQt;
315 int modX;
316};
317
318struct SymVariation {
319 uint sym, symVariation;
320 bool bActive;
321};
322
323struct SymName {
324 uint sym;
325 const char *psName;
326};
327
328struct TransKey {
329 int keySymQt;
330 uint keySymX;
331};
332
333//---------------------------------------------------------------------
334// Arrays
335//---------------------------------------------------------------------
336// clang-format off
337
338static X11ModInfo g_rgX11ModInfo[4] = {
339 { Qt::SHIFT, X11_ONLY(ShiftMask) },
340 { Qt::CTRL, X11_ONLY(ControlMask) },
341 { Qt::ALT, X11_ONLY(Mod1Mask) },
342 { Qt::META, X11_ONLY(Mod4Mask) }
343};
344
345// These are the X equivalents to the Qt keycodes 0x1000 - 0x1026
346static const TransKey g_rgQtToSymX[] = {
347 { Qt::Key_Escape, XK_Escape },
348 { Qt::Key_Tab, XK_Tab },
349 { Qt::Key_Backtab, XK_ISO_Left_Tab },
350 { Qt::Key_Backspace, XK_BackSpace },
351 { Qt::Key_Return, XK_Return },
352 { Qt::Key_Insert, XK_Insert },
353 { Qt::Key_Delete, XK_Delete },
354 { Qt::Key_Pause, XK_Pause },
355#ifdef sun
356 { Qt::Key_Print, XK_F22 },
357#else
358 { Qt::Key_Print, XK_Print },
359#endif
360 { Qt::Key_SysReq, XK_Sys_Req },
361 { Qt::Key_Home, XK_Home },
362 { Qt::Key_End, XK_End },
363 { Qt::Key_Left, XK_Left },
364 { Qt::Key_Up, XK_Up },
365 { Qt::Key_Right, XK_Right },
366 { Qt::Key_Down, XK_Down },
367 { Qt::Key_PageUp, XK_Prior },
368 { Qt::Key_PageDown, XK_Next },
369 { Qt::Key_Shift, XK_Shift_L },
370 { Qt::Key_Shift, XK_Shift_R },
371 { Qt::Key_Shift, XK_Shift_Lock },
372 { Qt::Key_Control, XK_Control_L },
373 { Qt::Key_Control, XK_Control_R },
374 { Qt::Key_Meta, XK_Meta_L },
375 { Qt::Key_Meta, XK_Meta_R },
376 { Qt::Key_Alt, XK_Alt_L },
377 { Qt::Key_Alt, XK_Alt_R },
378 { Qt::Key_CapsLock, XK_Caps_Lock },
379 { Qt::Key_NumLock, XK_Num_Lock },
380 { Qt::Key_ScrollLock, XK_Scroll_Lock },
381 { Qt::Key_F1, XK_F1 },
382 { Qt::Key_F2, XK_F2 },
383 { Qt::Key_F3, XK_F3 },
384 { Qt::Key_F4, XK_F4 },
385 { Qt::Key_F5, XK_F5 },
386 { Qt::Key_F6, XK_F6 },
387 { Qt::Key_F7, XK_F7 },
388 { Qt::Key_F8, XK_F8 },
389 { Qt::Key_F9, XK_F9 },
390 { Qt::Key_F10, XK_F10 },
391 { Qt::Key_F11, XK_F11 },
392 { Qt::Key_F12, XK_F12 },
393 { Qt::Key_F13, XK_F13 },
394 { Qt::Key_F14, XK_F14 },
395 { Qt::Key_F15, XK_F15 },
396 { Qt::Key_F16, XK_F16 },
397 { Qt::Key_F17, XK_F17 },
398 { Qt::Key_F18, XK_F18 },
399 { Qt::Key_F19, XK_F19 },
400 { Qt::Key_F20, XK_F20 },
401 { Qt::Key_F21, XK_F21 },
402 { Qt::Key_F22, XK_F22 },
403 { Qt::Key_F23, XK_F23 },
404 { Qt::Key_F24, XK_F24 },
405 { Qt::Key_F25, XK_F25 },
406 { Qt::Key_F26, XK_F26 },
407 { Qt::Key_F27, XK_F27 },
408 { Qt::Key_F28, XK_F28 },
409 { Qt::Key_F29, XK_F29 },
410 { Qt::Key_F30, XK_F30 },
411 { Qt::Key_F31, XK_F31 },
412 { Qt::Key_F32, XK_F32 },
413 { Qt::Key_F33, XK_F33 },
414 { Qt::Key_F34, XK_F34 },
415 { Qt::Key_F35, XK_F35 },
416 { Qt::Key_Super_L, XK_Super_L },
417 { Qt::Key_Super_R, XK_Super_R },
418 { Qt::Key_Menu, XK_Menu },
419 { Qt::Key_Hyper_L, XK_Hyper_L },
420 { Qt::Key_Hyper_R, XK_Hyper_R },
421 { Qt::Key_Help, XK_Help },
422 //{ Qt::Key_Direction_L, XK_Direction_L }, These keys don't exist in X11
423 //{ Qt::Key_Direction_R, XK_Direction_R },
424
425 { Qt::Key_Space, XK_KP_Space },
426 { Qt::Key_Tab, XK_KP_Tab },
427 { Qt::Key_Enter, XK_KP_Enter },
428 { Qt::Key_Home, XK_KP_Home },
429 { Qt::Key_Left, XK_KP_Left },
430 { Qt::Key_Up, XK_KP_Up },
431 { Qt::Key_Right, XK_KP_Right },
432 { Qt::Key_Down, XK_KP_Down },
433 { Qt::Key_PageUp, XK_KP_Prior },
434 { Qt::Key_PageDown, XK_KP_Next },
435 { Qt::Key_End, XK_KP_End },
436 { Qt::Key_Clear, XK_KP_Begin },
437 { Qt::Key_Insert, XK_KP_Insert },
438 { Qt::Key_Delete, XK_KP_Delete },
439 { Qt::Key_Equal, XK_KP_Equal },
440 { Qt::Key_Asterisk, XK_KP_Multiply },
441 { Qt::Key_Plus, XK_KP_Add },
442 { Qt::Key_Comma, XK_KP_Separator },
443 { Qt::Key_Minus, XK_KP_Subtract },
444 { Qt::Key_Period, XK_KP_Decimal },
445 { Qt::Key_Slash, XK_KP_Divide },
446
447// the next lines are taken on 01/2024 from X.org (X11/XF86keysym.h), defining some special
448// multimedia keys. They are included here as not every system has them.
449#define XF86XK_ModeLock 0x1008ff01 /* Mode Switch Lock */
450
451/* Backlight controls. */
452#define XF86XK_MonBrightnessUp 0x1008ff02 /* Monitor/panel brightness */
453#define XF86XK_MonBrightnessDown 0x1008ff03 /* Monitor/panel brightness */
454#define XF86XK_KbdLightOnOff 0x1008ff04 /* Keyboards may be lit */
455#define XF86XK_KbdBrightnessUp 0x1008ff05 /* Keyboards may be lit */
456#define XF86XK_KbdBrightnessDown 0x1008ff06 /* Keyboards may be lit */
457#define XF86XK_MonBrightnessCycle 0x1008ff07 /* Monitor/panel brightness */
458
459/*
460 * Keys found on some "Internet" keyboards.
461 */
462#define XF86XK_Standby 0x1008ff10 /* System into standby mode */
463#define XF86XK_AudioLowerVolume 0x1008ff11 /* Volume control down */
464#define XF86XK_AudioMute 0x1008ff12 /* Mute sound from the system */
465#define XF86XK_AudioRaiseVolume 0x1008ff13 /* Volume control up */
466#define XF86XK_AudioPlay 0x1008ff14 /* Start playing of audio > */
467#define XF86XK_AudioStop 0x1008ff15 /* Stop playing audio */
468#define XF86XK_AudioPrev 0x1008ff16 /* Previous track */
469#define XF86XK_AudioNext 0x1008ff17 /* Next track */
470#define XF86XK_HomePage 0x1008ff18 /* Display user's home page */
471#define XF86XK_Mail 0x1008ff19 /* Invoke user's mail program */
472#define XF86XK_Start 0x1008ff1a /* Start application */
473#define XF86XK_Search 0x1008ff1b /* Search */
474#define XF86XK_AudioRecord 0x1008ff1c /* Record audio application */
475
476/* These are sometimes found on PDA's (e.g. Palm, PocketPC or elsewhere) */
477#define XF86XK_Calculator 0x1008ff1d /* Invoke calculator program */
478#define XF86XK_Memo 0x1008ff1e /* Invoke Memo taking program */
479#define XF86XK_ToDoList 0x1008ff1f /* Invoke To Do List program */
480#define XF86XK_Calendar 0x1008ff20 /* Invoke Calendar program */
481#define XF86XK_PowerDown 0x1008ff21 /* Deep sleep the system */
482#define XF86XK_ContrastAdjust 0x1008ff22 /* Adjust screen contrast */
483#define XF86XK_RockerUp 0x1008ff23 /* Rocker switches exist up */
484#define XF86XK_RockerDown 0x1008ff24 /* and down */
485#define XF86XK_RockerEnter 0x1008ff25 /* and let you press them */
486
487/* Some more "Internet" keyboard symbols */
488#define XF86XK_Back 0x1008ff26 /* Like back on a browser */
489#define XF86XK_Forward 0x1008ff27 /* Like forward on a browser */
490#define XF86XK_Stop 0x1008ff28 /* Stop current operation */
491#define XF86XK_Refresh 0x1008ff29 /* Refresh the page */
492#define XF86XK_PowerOff 0x1008ff2a /* Power off system entirely */
493#define XF86XK_WakeUp 0x1008ff2b /* Wake up system from sleep */
494#define XF86XK_Eject 0x1008ff2c /* Eject device (e.g. DVD) */
495#define XF86XK_ScreenSaver 0x1008ff2d /* Invoke screensaver */
496#define XF86XK_WWW 0x1008ff2e /* Invoke web browser */
497#define XF86XK_Sleep 0x1008ff2f /* Put system to sleep */
498#define XF86XK_Favorites 0x1008ff30 /* Show favorite locations */
499#define XF86XK_AudioPause 0x1008ff31 /* Pause audio playing */
500#define XF86XK_AudioMedia 0x1008ff32 /* Launch media collection app */
501#define XF86XK_MyComputer 0x1008ff33 /* Display "My Computer" window */
502#define XF86XK_VendorHome 0x1008ff34 /* Display vendor home web site */
503#define XF86XK_LightBulb 0x1008ff35 /* Light bulb keys exist */
504#define XF86XK_Shop 0x1008ff36 /* Display shopping web site */
505#define XF86XK_History 0x1008ff37 /* Show history of web surfing */
506#define XF86XK_OpenURL 0x1008ff38 /* Open selected URL */
507#define XF86XK_AddFavorite 0x1008ff39 /* Add URL to favorites list */
508#define XF86XK_HotLinks 0x1008ff3a /* Show "hot" links */
509#define XF86XK_BrightnessAdjust 0x1008ff3b /* Invoke brightness adj. UI */
510#define XF86XK_Finance 0x1008ff3c /* Display financial site */
511#define XF86XK_Community 0x1008ff3d /* Display user's community */
512#define XF86XK_AudioRewind 0x1008ff3e /* "rewind" audio track */
513#define XF86XK_BackForward 0x1008ff3f /* ??? */
514#define XF86XK_Launch0 0x1008ff40 /* Launch Application */
515#define XF86XK_Launch1 0x1008ff41 /* Launch Application */
516#define XF86XK_Launch2 0x1008ff42 /* Launch Application */
517#define XF86XK_Launch3 0x1008ff43 /* Launch Application */
518#define XF86XK_Launch4 0x1008ff44 /* Launch Application */
519#define XF86XK_Launch5 0x1008ff45 /* Launch Application */
520#define XF86XK_Launch6 0x1008ff46 /* Launch Application */
521#define XF86XK_Launch7 0x1008ff47 /* Launch Application */
522#define XF86XK_Launch8 0x1008ff48 /* Launch Application */
523#define XF86XK_Launch9 0x1008ff49 /* Launch Application */
524#define XF86XK_LaunchA 0x1008ff4a /* Launch Application */
525#define XF86XK_LaunchB 0x1008ff4b /* Launch Application */
526#define XF86XK_LaunchC 0x1008ff4c /* Launch Application */
527#define XF86XK_LaunchD 0x1008ff4d /* Launch Application */
528#define XF86XK_LaunchE 0x1008ff4e /* Launch Application */
529#define XF86XK_LaunchF 0x1008ff4f /* Launch Application */
530
531#define XF86XK_ApplicationLeft 0x1008ff50 /* switch to application, left */
532#define XF86XK_ApplicationRight 0x1008ff51 /* switch to application, right*/
533#define XF86XK_Book 0x1008ff52 /* Launch bookreader */
534#define XF86XK_CD 0x1008ff53 /* Launch CD/DVD player */
535#define XF86XK_Calculater 0x1008ff54 /* Launch Calculater */
536#define XF86XK_Clear 0x1008ff55 /* Clear window, screen */
537#define XF86XK_Close 0x1008ff56 /* Close window */
538#define XF86XK_Copy 0x1008ff57 /* Copy selection */
539#define XF86XK_Cut 0x1008ff58 /* Cut selection */
540#define XF86XK_Display 0x1008ff59 /* Output switch key */
541#define XF86XK_DOS 0x1008ff5a /* Launch DOS (emulation) */
542#define XF86XK_Documents 0x1008ff5b /* Open documents window */
543#define XF86XK_Excel 0x1008ff5c /* Launch spread sheet */
544#define XF86XK_Explorer 0x1008ff5d /* Launch file explorer */
545#define XF86XK_Game 0x1008ff5e /* Launch game */
546#define XF86XK_Go 0x1008ff5f /* Go to URL */
547#define XF86XK_iTouch 0x1008ff60 /* Logitech iTouch- don't use */
548#define XF86XK_LogOff 0x1008ff61 /* Log off system */
549#define XF86XK_Market 0x1008ff62 /* ?? */
550#define XF86XK_Meeting 0x1008ff63 /* enter meeting in calendar */
551#define XF86XK_MenuKB 0x1008ff65 /* distinguish keyboard from PB */
552#define XF86XK_MenuPB 0x1008ff66 /* distinguish PB from keyboard */
553#define XF86XK_MySites 0x1008ff67 /* Favourites */
554#define XF86XK_New 0x1008ff68 /* New (folder, document... */
555#define XF86XK_News 0x1008ff69 /* News */
556#define XF86XK_OfficeHome 0x1008ff6a /* Office home (old Staroffice)*/
557#define XF86XK_Open 0x1008ff6b /* Open */
558#define XF86XK_Option 0x1008ff6c /* ?? */
559#define XF86XK_Paste 0x1008ff6d /* Paste */
560#define XF86XK_Phone 0x1008ff6e /* Launch phone; dial number */
561#define XF86XK_Q 0x1008ff70 /* Compaq's Q - don't use */
562#define XF86XK_Reply 0x1008ff72 /* Reply e.g., mail */
563#define XF86XK_Reload 0x1008ff73 /* Reload web page, file, etc. */
564#define XF86XK_RotateWindows 0x1008ff74 /* Rotate windows e.g. xrandr */
565#define XF86XK_RotationPB 0x1008ff75 /* don't use */
566#define XF86XK_RotationKB 0x1008ff76 /* don't use */
567#define XF86XK_Save 0x1008ff77 /* Save (file, document, state */
568#define XF86XK_ScrollUp 0x1008ff78 /* Scroll window/contents up */
569#define XF86XK_ScrollDown 0x1008ff79 /* Scrool window/contentd down */
570#define XF86XK_ScrollClick 0x1008ff7a /* Use XKB mousekeys instead */
571#define XF86XK_Send 0x1008ff7b /* Send mail, file, object */
572#define XF86XK_Spell 0x1008ff7c /* Spell checker */
573#define XF86XK_SplitScreen 0x1008ff7d /* Split window or screen */
574#define XF86XK_Support 0x1008ff7e /* Get support (??) */
575#define XF86XK_TaskPane 0x1008ff7f /* Show tasks */
576#define XF86XK_Terminal 0x1008ff80 /* Launch terminal emulator */
577#define XF86XK_Tools 0x1008ff81 /* toolbox of desktop/app. */
578#define XF86XK_Travel 0x1008ff82 /* ?? */
579#define XF86XK_UserPB 0x1008ff84 /* ?? */
580#define XF86XK_User1KB 0x1008ff85 /* ?? */
581#define XF86XK_User2KB 0x1008ff86 /* ?? */
582#define XF86XK_Video 0x1008ff87 /* Launch video player */
583#define XF86XK_WheelButton 0x1008ff88 /* button from a mouse wheel */
584#define XF86XK_Word 0x1008ff89 /* Launch word processor */
585#define XF86XK_Xfer 0x1008ff8a
586#define XF86XK_ZoomIn 0x1008ff8b /* zoom in view, map, etc. */
587#define XF86XK_ZoomOut 0x1008ff8c /* zoom out view, map, etc. */
588
589#define XF86XK_Away 0x1008ff8d /* mark yourself as away */
590#define XF86XK_Messenger 0x1008ff8e /* as in instant messaging */
591#define XF86XK_WebCam 0x1008ff8f /* Launch web camera app. */
592#define XF86XK_MailForward 0x1008ff90 /* Forward in mail */
593#define XF86XK_Pictures 0x1008ff91 /* Show pictures */
594#define XF86XK_Music 0x1008ff92 /* Launch music application */
595
596#define XF86XK_Battery 0x1008ff93 /* Display battery information */
597#define XF86XK_Bluetooth 0x1008ff94 /* Enable/disable Bluetooth */
598#define XF86XK_WLAN 0x1008ff95 /* Enable/disable WLAN */
599#define XF86XK_UWB 0x1008ff96 /* Enable/disable UWB */
600
601#define XF86XK_AudioForward 0x1008ff97 /* fast-forward audio track */
602#define XF86XK_AudioRepeat 0x1008ff98 /* toggle repeat mode */
603#define XF86XK_AudioRandomPlay 0x1008ff99 /* toggle shuffle mode */
604#define XF86XK_Subtitle 0x1008ff9a /* cycle through subtitle */
605#define XF86XK_AudioCycleTrack 0x1008ff9b /* cycle through audio tracks */
606#define XF86XK_CycleAngle 0x1008ff9c /* cycle through angles */
607#define XF86XK_FrameBack 0x1008ff9d /* video: go one frame back */
608#define XF86XK_FrameForward 0x1008ff9e /* video: go one frame forward */
609#define XF86XK_Time 0x1008ff9f /* display, or shows an entry for time seeking */
610#define XF86XK_Select 0x1008ffa0 /* Select button on joypads and remotes */
611#define XF86XK_View 0x1008ffa1 /* Show a view options/properties */
612#define XF86XK_TopMenu 0x1008ffa2 /* Go to a top-level menu in a video */
613
614#define XF86XK_Red 0x1008ffa3 /* Red button */
615#define XF86XK_Green 0x1008ffa4 /* Green button */
616#define XF86XK_Yellow 0x1008ffa5 /* Yellow button */
617#define XF86XK_Blue 0x1008ffa6 /* Blue button */
618
619#define XF86XK_Suspend 0x1008ffa7 /* Sleep to RAM */
620#define XF86XK_Hibernate 0x1008ffa8 /* Sleep to disk */
621#define XF86XK_TouchpadToggle 0x1008ffa9 /* Toggle between touchpad/trackstick */
622#define XF86XK_TouchpadOn 0x1008ffb0 /* The touchpad got switched on */
623#define XF86XK_TouchpadOff 0x1008ffb1 /* The touchpad got switched off */
624
625#define XF86XK_AudioMicMute 0x1008ffb2 /* Mute the Mic from the system */
626
627#define XF86XK_Keyboard 0x1008ffb3 /* User defined keyboard related action */
628
629#define XF86XK_WWAN 0x1008ffb4 /* Toggle WWAN (LTE, UMTS, etc.) radio */
630#define XF86XK_RFKill 0x1008ffb5 /* Toggle radios on/off */
631
632#define XF86XK_AudioPreset 0x1008ffb6 /* Select equalizer preset, e.g. theatre-mode */
633
634#define XF86XK_RotationLockToggle 0x1008ffb7 /* Toggle screen rotation lock on/off */
635
636#define XF86XK_FullScreen 0x1008ffb8 /* Toggle fullscreen */
637
638/* Keys for special action keys (hot keys) */
639/* Virtual terminals on some operating systems */
640#define XF86XK_Switch_VT_1 0x1008fe01
641#define XF86XK_Switch_VT_2 0x1008fe02
642#define XF86XK_Switch_VT_3 0x1008fe03
643#define XF86XK_Switch_VT_4 0x1008fe04
644#define XF86XK_Switch_VT_5 0x1008fe05
645#define XF86XK_Switch_VT_6 0x1008fe06
646#define XF86XK_Switch_VT_7 0x1008fe07
647#define XF86XK_Switch_VT_8 0x1008fe08
648#define XF86XK_Switch_VT_9 0x1008fe09
649#define XF86XK_Switch_VT_10 0x1008fe0a
650#define XF86XK_Switch_VT_11 0x1008fe0b
651#define XF86XK_Switch_VT_12 0x1008fe0c
652
653#define XF86XK_Ungrab 0x1008fe20 /* force ungrab */
654#define XF86XK_ClearGrab 0x1008fe21 /* kill application with grab */
655#define XF86XK_Next_VMode 0x1008fe22 /* next video mode available */
656#define XF86XK_Prev_VMode 0x1008fe23 /* prev. video mode available */
657#define XF86XK_LogWindowTree 0x1008fe24 /* print window tree to log */
658#define XF86XK_LogGrabInfo 0x1008fe25 /* print all active grabs to log */
659
660
661/*
662 * Reserved range for evdev symbols: 0x10081000-0x10081FFF
663 *
664 * Key syms within this range must match the Linux kernel
665 * input-event-codes.h file in the format:
666 * XF86XK_CamelCaseKernelName _EVDEVK(kernel value)
667 * For example, the kernel
668 * #define KEY_MACRO_RECORD_START 0x2b0
669 * effectively ends up as:
670 * #define XF86XK_MacroRecordStart 0x100812b0
671 *
672 * For historical reasons, some keysyms within the reserved range will be
673 * missing, most notably all "normal" keys that are mapped through default
674 * XKB layouts (e.g. KEY_Q).
675 *
676 * CamelCasing is done with a human control as last authority, e.g. see VOD
677 * instead of Vod for the Video on Demand key.
678 *
679 * The format for #defines is strict:
680 *
681 * #define XF86XK_FOO<tab...>_EVDEVK(0xABC)<tab><tab> |* kver KEY_FOO *|
682 *
683 * Where
684 * - alignment by tabs
685 * - the _EVDEVK macro must be used
686 * - the hex code must be in uppercase hex
687 * - the kernel version (kver) is in the form v5.10
688 * - kver and key name are within a slash-star comment (a pipe is used in
689 * this example for technical reasons)
690 * These #defines are parsed by scripts. Do not stray from the given format.
691 *
692 * Where the evdev keycode is mapped to a different symbol, please add a
693 * comment line starting with Use: but otherwise the same format, e.g.
694 * Use: XF86XK_RotationLockToggle _EVDEVK(0x231) v4.16 KEY_ROTATE_LOCK_TOGGLE
695 *
696 */
697#define _EVDEVK(_v) (0x10081000 + _v)
698/* Use: XF86XK_Eject _EVDEVK(0x0a2) KEY_EJECTCLOSECD */
699/* Use: XF86XK_New _EVDEVK(0x0b5) v2.6.14 KEY_NEW */
700/* Use: XK_Redo _EVDEVK(0x0b6) v2.6.14 KEY_REDO */
701/* KEY_DASHBOARD has been mapped to LaunchB in xkeyboard-config since 2011 */
702/* Use: XF86XK_LaunchB _EVDEVK(0x0cc) v2.6.28 KEY_DASHBOARD */
703/* Use: XF86XK_Display _EVDEVK(0x0e3) v2.6.12 KEY_SWITCHVIDEOMODE */
704/* Use: XF86XK_KbdLightOnOff _EVDEVK(0x0e4) v2.6.12 KEY_KBDILLUMTOGGLE */
705/* Use: XF86XK_KbdBrightnessDown _EVDEVK(0x0e5) v2.6.12 KEY_KBDILLUMDOWN */
706/* Use: XF86XK_KbdBrightnessUp _EVDEVK(0x0e6) v2.6.12 KEY_KBDILLUMUP */
707/* Use: XF86XK_Send _EVDEVK(0x0e7) v2.6.14 KEY_SEND */
708/* Use: XF86XK_Reply _EVDEVK(0x0e8) v2.6.14 KEY_REPLY */
709/* Use: XF86XK_MailForward _EVDEVK(0x0e9) v2.6.14 KEY_FORWARDMAIL */
710/* Use: XF86XK_Save _EVDEVK(0x0ea) v2.6.14 KEY_SAVE */
711/* Use: XF86XK_Documents _EVDEVK(0x0eb) v2.6.14 KEY_DOCUMENTS */
712/* Use: XF86XK_Battery _EVDEVK(0x0ec) v2.6.17 KEY_BATTERY */
713/* Use: XF86XK_Bluetooth _EVDEVK(0x0ed) v2.6.19 KEY_BLUETOOTH */
714/* Use: XF86XK_WLAN _EVDEVK(0x0ee) v2.6.19 KEY_WLAN */
715/* Use: XF86XK_UWB _EVDEVK(0x0ef) v2.6.24 KEY_UWB */
716/* Use: XF86XK_Next_VMode _EVDEVK(0x0f1) v2.6.23 KEY_VIDEO_NEXT */
717/* Use: XF86XK_Prev_VMode _EVDEVK(0x0f2) v2.6.23 KEY_VIDEO_PREV */
718/* Use: XF86XK_MonBrightnessCycle _EVDEVK(0x0f3) v2.6.23 KEY_BRIGHTNESS_CYCLE */
719#define XF86XK_BrightnessAuto _EVDEVK(0x0f4) /* v3.16 KEY_BRIGHTNESS_AUTO */
720#define XF86XK_DisplayOff _EVDEVK(0x0f5) /* v2.6.23 KEY_DISPLAY_OFF */
721/* Use: XF86XK_WWAN _EVDEVK(0x0f6) v3.13 KEY_WWAN */
722/* Use: XF86XK_RFKill _EVDEVK(0x0f7) v2.6.33 KEY_RFKILL */
723/* Use: XF86XK_AudioMicMute _EVDEVK(0x0f8) v3.1 KEY_MICMUTE */
724#define XF86XK_Info _EVDEVK(0x166) /* KEY_INFO */
725/* Use: XF86XK_CycleAngle _EVDEVK(0x173) KEY_ANGLE */
726/* Use: XF86XK_FullScreen _EVDEVK(0x174) v5.1 KEY_FULL_SCREEN */
727#define XF86XK_AspectRatio _EVDEVK(0x177) /* v5.1 KEY_ASPECT_RATIO */
728#define XF86XK_DVD _EVDEVK(0x185) /* KEY_DVD */
729#define XF86XK_Audio _EVDEVK(0x188) /* KEY_AUDIO */
730/* Use: XF86XK_Video _EVDEVK(0x189) KEY_VIDEO */
731/* Use: XF86XK_Calendar _EVDEVK(0x18d) KEY_CALENDAR */
732#define XF86XK_ChannelUp _EVDEVK(0x192) /* KEY_CHANNELUP */
733#define XF86XK_ChannelDown _EVDEVK(0x193) /* KEY_CHANNELDOWN */
734/* Use: XF86XK_AudioRandomPlay _EVDEVK(0x19a) KEY_SHUFFLE */
735#define XF86XK_Break _EVDEVK(0x19b) /* KEY_BREAK */
736#define XF86XK_VideoPhone _EVDEVK(0x1a0) /* v2.6.20 KEY_VIDEOPHONE */
737/* Use: XF86XK_Game _EVDEVK(0x1a1) v2.6.20 KEY_GAMES */
738/* Use: XF86XK_ZoomIn _EVDEVK(0x1a2) v2.6.20 KEY_ZOOMIN */
739/* Use: XF86XK_ZoomOut _EVDEVK(0x1a3) v2.6.20 KEY_ZOOMOUT */
740#define XF86XK_ZoomReset _EVDEVK(0x1a4) /* v2.6.20 KEY_ZOOMRESET */
741/* Use: XF86XK_Word _EVDEVK(0x1a5) v2.6.20 KEY_WORDPROCESSOR */
742#define XF86XK_Editor _EVDEVK(0x1a6) /* v2.6.20 KEY_EDITOR */
743/* Use: XF86XK_Excel _EVDEVK(0x1a7) v2.6.20 KEY_SPREADSHEET */
744#define XF86XK_GraphicsEditor _EVDEVK(0x1a8) /* v2.6.20 KEY_GRAPHICSEDITOR */
745#define XF86XK_Presentation _EVDEVK(0x1a9) /* v2.6.20 KEY_PRESENTATION */
746#define XF86XK_Database _EVDEVK(0x1aa) /* v2.6.20 KEY_DATABASE */
747/* Use: XF86XK_News _EVDEVK(0x1ab) v2.6.20 KEY_NEWS */
748#define XF86XK_Voicemail _EVDEVK(0x1ac) /* v2.6.20 KEY_VOICEMAIL */
749#define XF86XK_Addressbook _EVDEVK(0x1ad) /* v2.6.20 KEY_ADDRESSBOOK */
750/* Use: XF86XK_Messenger _EVDEVK(0x1ae) v2.6.20 KEY_MESSENGER */
751#define XF86XK_DisplayToggle _EVDEVK(0x1af) /* v2.6.20 KEY_DISPLAYTOGGLE */
752#define XF86XK_SpellCheck _EVDEVK(0x1b0) /* v2.6.24 KEY_SPELLCHECK */
753/* Use: XF86XK_LogOff _EVDEVK(0x1b1) v2.6.24 KEY_LOGOFF */
754/* Use: XK_dollar _EVDEVK(0x1b2) v2.6.24 KEY_DOLLAR */
755/* Use: XK_EuroSign _EVDEVK(0x1b3) v2.6.24 KEY_EURO */
756/* Use: XF86XK_FrameBack _EVDEVK(0x1b4) v2.6.24 KEY_FRAMEBACK */
757/* Use: XF86XK_FrameForward _EVDEVK(0x1b5) v2.6.24 KEY_FRAMEFORWARD */
758#define XF86XK_ContextMenu _EVDEVK(0x1b6) /* v2.6.24 KEY_CONTEXT_MENU */
759#define XF86XK_MediaRepeat _EVDEVK(0x1b7) /* v2.6.26 KEY_MEDIA_REPEAT */
760#define XF86XK_10ChannelsUp _EVDEVK(0x1b8) /* v2.6.38 KEY_10CHANNELSUP */
761#define XF86XK_10ChannelsDown _EVDEVK(0x1b9) /* v2.6.38 KEY_10CHANNELSDOWN */
762#define XF86XK_Images _EVDEVK(0x1ba) /* v2.6.39 KEY_IMAGES */
763#define XF86XK_NotificationCenter _EVDEVK(0x1bc) /* v5.10 KEY_NOTIFICATION_CENTER */
764#define XF86XK_PickupPhone _EVDEVK(0x1bd) /* v5.10 KEY_PICKUP_PHONE */
765#define XF86XK_HangupPhone _EVDEVK(0x1be) /* v5.10 KEY_HANGUP_PHONE */
766#define XF86XK_Fn _EVDEVK(0x1d0) /* KEY_FN */
767#define XF86XK_Fn_Esc _EVDEVK(0x1d1) /* KEY_FN_ESC */
768#define XF86XK_FnRightShift _EVDEVK(0x1e5) /* v5.10 KEY_FN_RIGHT_SHIFT */
769/* Use: XK_braille_dot_1 _EVDEVK(0x1f1) v2.6.17 KEY_BRL_DOT1 */
770/* Use: XK_braille_dot_2 _EVDEVK(0x1f2) v2.6.17 KEY_BRL_DOT2 */
771/* Use: XK_braille_dot_3 _EVDEVK(0x1f3) v2.6.17 KEY_BRL_DOT3 */
772/* Use: XK_braille_dot_4 _EVDEVK(0x1f4) v2.6.17 KEY_BRL_DOT4 */
773/* Use: XK_braille_dot_5 _EVDEVK(0x1f5) v2.6.17 KEY_BRL_DOT5 */
774/* Use: XK_braille_dot_6 _EVDEVK(0x1f6) v2.6.17 KEY_BRL_DOT6 */
775/* Use: XK_braille_dot_7 _EVDEVK(0x1f7) v2.6.17 KEY_BRL_DOT7 */
776/* Use: XK_braille_dot_8 _EVDEVK(0x1f8) v2.6.17 KEY_BRL_DOT8 */
777/* Use: XK_braille_dot_9 _EVDEVK(0x1f9) v2.6.23 KEY_BRL_DOT9 */
778/* Use: XK_braille_dot_1 _EVDEVK(0x1fa) v2.6.23 KEY_BRL_DOT10 */
779#define XF86XK_Numeric0 _EVDEVK(0x200) /* v2.6.28 KEY_NUMERIC_0 */
780#define XF86XK_Numeric1 _EVDEVK(0x201) /* v2.6.28 KEY_NUMERIC_1 */
781#define XF86XK_Numeric2 _EVDEVK(0x202) /* v2.6.28 KEY_NUMERIC_2 */
782#define XF86XK_Numeric3 _EVDEVK(0x203) /* v2.6.28 KEY_NUMERIC_3 */
783#define XF86XK_Numeric4 _EVDEVK(0x204) /* v2.6.28 KEY_NUMERIC_4 */
784#define XF86XK_Numeric5 _EVDEVK(0x205) /* v2.6.28 KEY_NUMERIC_5 */
785#define XF86XK_Numeric6 _EVDEVK(0x206) /* v2.6.28 KEY_NUMERIC_6 */
786#define XF86XK_Numeric7 _EVDEVK(0x207) /* v2.6.28 KEY_NUMERIC_7 */
787#define XF86XK_Numeric8 _EVDEVK(0x208) /* v2.6.28 KEY_NUMERIC_8 */
788#define XF86XK_Numeric9 _EVDEVK(0x209) /* v2.6.28 KEY_NUMERIC_9 */
789#define XF86XK_NumericStar _EVDEVK(0x20a) /* v2.6.28 KEY_NUMERIC_STAR */
790#define XF86XK_NumericPound _EVDEVK(0x20b) /* v2.6.28 KEY_NUMERIC_POUND */
791#define XF86XK_NumericA _EVDEVK(0x20c) /* v4.1 KEY_NUMERIC_A */
792#define XF86XK_NumericB _EVDEVK(0x20d) /* v4.1 KEY_NUMERIC_B */
793#define XF86XK_NumericC _EVDEVK(0x20e) /* v4.1 KEY_NUMERIC_C */
794#define XF86XK_NumericD _EVDEVK(0x20f) /* v4.1 KEY_NUMERIC_D */
795#define XF86XK_CameraFocus _EVDEVK(0x210) /* v2.6.33 KEY_CAMERA_FOCUS */
796#define XF86XK_WPSButton _EVDEVK(0x211) /* v2.6.34 KEY_WPS_BUTTON */
797/* Use: XF86XK_TouchpadToggle _EVDEVK(0x212) v2.6.37 KEY_TOUCHPAD_TOGGLE */
798/* Use: XF86XK_TouchpadOn _EVDEVK(0x213) v2.6.37 KEY_TOUCHPAD_ON */
799/* Use: XF86XK_TouchpadOff _EVDEVK(0x214) v2.6.37 KEY_TOUCHPAD_OFF */
800#define XF86XK_CameraZoomIn _EVDEVK(0x215) /* v2.6.39 KEY_CAMERA_ZOOMIN */
801#define XF86XK_CameraZoomOut _EVDEVK(0x216) /* v2.6.39 KEY_CAMERA_ZOOMOUT */
802#define XF86XK_CameraUp _EVDEVK(0x217) /* v2.6.39 KEY_CAMERA_UP */
803#define XF86XK_CameraDown _EVDEVK(0x218) /* v2.6.39 KEY_CAMERA_DOWN */
804#define XF86XK_CameraLeft _EVDEVK(0x219) /* v2.6.39 KEY_CAMERA_LEFT */
805#define XF86XK_CameraRight _EVDEVK(0x21a) /* v2.6.39 KEY_CAMERA_RIGHT */
806#define XF86XK_AttendantOn _EVDEVK(0x21b) /* v3.10 KEY_ATTENDANT_ON */
807#define XF86XK_AttendantOff _EVDEVK(0x21c) /* v3.10 KEY_ATTENDANT_OFF */
808#define XF86XK_AttendantToggle _EVDEVK(0x21d) /* v3.10 KEY_ATTENDANT_TOGGLE */
809#define XF86XK_LightsToggle _EVDEVK(0x21e) /* v3.10 KEY_LIGHTS_TOGGLE */
810#define XF86XK_ALSToggle _EVDEVK(0x230) /* v3.13 KEY_ALS_TOGGLE */
811/* Use: XF86XK_RotationLockToggle _EVDEVK(0x231) v4.16 KEY_ROTATE_LOCK_TOGGLE */
812#define XF86XK_Buttonconfig _EVDEVK(0x240) /* v3.16 KEY_BUTTONCONFIG */
813#define XF86XK_Taskmanager _EVDEVK(0x241) /* v3.16 KEY_TASKMANAGER */
814#define XF86XK_Journal _EVDEVK(0x242) /* v3.16 KEY_JOURNAL */
815#define XF86XK_ControlPanel _EVDEVK(0x243) /* v3.16 KEY_CONTROLPANEL */
816#define XF86XK_AppSelect _EVDEVK(0x244) /* v3.16 KEY_APPSELECT */
817#define XF86XK_Screensaver _EVDEVK(0x245) /* v3.16 KEY_SCREENSAVER */
818#define XF86XK_VoiceCommand _EVDEVK(0x246) /* v3.16 KEY_VOICECOMMAND */
819#define XF86XK_Assistant _EVDEVK(0x247) /* v4.13 KEY_ASSISTANT */
820/* Use: XK_ISO_Next_Group _EVDEVK(0x248) v5.2 KEY_KBD_LAYOUT_NEXT */
821#define XF86XK_EmojiPicker _EVDEVK(0x249) /* v5.13 KEY_EMOJI_PICKER */
822#define XF86XK_Dictate _EVDEVK(0x24a) /* v5.17 KEY_DICTATE */
823#define XF86XK_CameraAccessEnable _EVDEVK(0x24b) /* v6.2 KEY_CAMERA_ACCESS_ENABLE */
824#define XF86XK_CameraAccessDisable _EVDEVK(0x24c) /* v6.2 KEY_CAMERA_ACCESS_DISABLE */
825#define XF86XK_CameraAccessToggle _EVDEVK(0x24d) /* v6.2 KEY_CAMERA_ACCESS_TOGGLE */
826#define XF86XK_BrightnessMin _EVDEVK(0x250) /* v3.16 KEY_BRIGHTNESS_MIN */
827#define XF86XK_BrightnessMax _EVDEVK(0x251) /* v3.16 KEY_BRIGHTNESS_MAX */
828#define XF86XK_KbdInputAssistPrev _EVDEVK(0x260) /* v3.18 KEY_KBDINPUTASSIST_PREV */
829#define XF86XK_KbdInputAssistNext _EVDEVK(0x261) /* v3.18 KEY_KBDINPUTASSIST_NEXT */
830#define XF86XK_KbdInputAssistPrevgroup _EVDEVK(0x262) /* v3.18 KEY_KBDINPUTASSIST_PREVGROUP */
831#define XF86XK_KbdInputAssistNextgroup _EVDEVK(0x263) /* v3.18 KEY_KBDINPUTASSIST_NEXTGROUP */
832#define XF86XK_KbdInputAssistAccept _EVDEVK(0x264) /* v3.18 KEY_KBDINPUTASSIST_ACCEPT */
833#define XF86XK_KbdInputAssistCancel _EVDEVK(0x265) /* v3.18 KEY_KBDINPUTASSIST_CANCEL */
834#define XF86XK_RightUp _EVDEVK(0x266) /* v4.7 KEY_RIGHT_UP */
835#define XF86XK_RightDown _EVDEVK(0x267) /* v4.7 KEY_RIGHT_DOWN */
836#define XF86XK_LeftUp _EVDEVK(0x268) /* v4.7 KEY_LEFT_UP */
837#define XF86XK_LeftDown _EVDEVK(0x269) /* v4.7 KEY_LEFT_DOWN */
838#define XF86XK_RootMenu _EVDEVK(0x26a) /* v4.7 KEY_ROOT_MENU */
839#define XF86XK_MediaTopMenu _EVDEVK(0x26b) /* v4.7 KEY_MEDIA_TOP_MENU */
840#define XF86XK_Numeric11 _EVDEVK(0x26c) /* v4.7 KEY_NUMERIC_11 */
841#define XF86XK_Numeric12 _EVDEVK(0x26d) /* v4.7 KEY_NUMERIC_12 */
842#define XF86XK_AudioDesc _EVDEVK(0x26e) /* v4.7 KEY_AUDIO_DESC */
843#define XF86XK_3DMode _EVDEVK(0x26f) /* v4.7 KEY_3D_MODE */
844#define XF86XK_NextFavorite _EVDEVK(0x270) /* v4.7 KEY_NEXT_FAVORITE */
845#define XF86XK_StopRecord _EVDEVK(0x271) /* v4.7 KEY_STOP_RECORD */
846#define XF86XK_PauseRecord _EVDEVK(0x272) /* v4.7 KEY_PAUSE_RECORD */
847#define XF86XK_VOD _EVDEVK(0x273) /* v4.7 KEY_VOD */
848#define XF86XK_Unmute _EVDEVK(0x274) /* v4.7 KEY_UNMUTE */
849#define XF86XK_FastReverse _EVDEVK(0x275) /* v4.7 KEY_FASTREVERSE */
850#define XF86XK_SlowReverse _EVDEVK(0x276) /* v4.7 KEY_SLOWREVERSE */
851#define XF86XK_Data _EVDEVK(0x277) /* v4.7 KEY_DATA */
852#define XF86XK_OnScreenKeyboard _EVDEVK(0x278) /* v4.12 KEY_ONSCREEN_KEYBOARD */
853#define XF86XK_PrivacyScreenToggle _EVDEVK(0x279) /* v5.5 KEY_PRIVACY_SCREEN_TOGGLE */
854#define XF86XK_SelectiveScreenshot _EVDEVK(0x27a) /* v5.6 KEY_SELECTIVE_SCREENSHOT */
855#define XF86XK_NextElement _EVDEVK(0x27b) /* v5.18 KEY_NEXT_ELEMENT */
856#define XF86XK_PreviousElement _EVDEVK(0x27c) /* v5.18 KEY_PREVIOUS_ELEMENT */
857#define XF86XK_AutopilotEngageToggle _EVDEVK(0x27d) /* v5.18 KEY_AUTOPILOT_ENGAGE_TOGGLE */
858#define XF86XK_MarkWaypoint _EVDEVK(0x27e) /* v5.18 KEY_MARK_WAYPOINT */
859#define XF86XK_Sos _EVDEVK(0x27f) /* v5.18 KEY_SOS */
860#define XF86XK_NavChart _EVDEVK(0x280) /* v5.18 KEY_NAV_CHART */
861#define XF86XK_FishingChart _EVDEVK(0x281) /* v5.18 KEY_FISHING_CHART */
862#define XF86XK_SingleRangeRadar _EVDEVK(0x282) /* v5.18 KEY_SINGLE_RANGE_RADAR */
863#define XF86XK_DualRangeRadar _EVDEVK(0x283) /* v5.18 KEY_DUAL_RANGE_RADAR */
864#define XF86XK_RadarOverlay _EVDEVK(0x284) /* v5.18 KEY_RADAR_OVERLAY */
865#define XF86XK_TraditionalSonar _EVDEVK(0x285) /* v5.18 KEY_TRADITIONAL_SONAR */
866#define XF86XK_ClearvuSonar _EVDEVK(0x286) /* v5.18 KEY_CLEARVU_SONAR */
867#define XF86XK_SidevuSonar _EVDEVK(0x287) /* v5.18 KEY_SIDEVU_SONAR */
868#define XF86XK_NavInfo _EVDEVK(0x288) /* v5.18 KEY_NAV_INFO */
869/* Use: XF86XK_BrightnessAdjust _EVDEVK(0x289) v5.18 KEY_BRIGHTNESS_MENU */
870#define XF86XK_Macro1 _EVDEVK(0x290) /* v5.5 KEY_MACRO1 */
871#define XF86XK_Macro2 _EVDEVK(0x291) /* v5.5 KEY_MACRO2 */
872#define XF86XK_Macro3 _EVDEVK(0x292) /* v5.5 KEY_MACRO3 */
873#define XF86XK_Macro4 _EVDEVK(0x293) /* v5.5 KEY_MACRO4 */
874#define XF86XK_Macro5 _EVDEVK(0x294) /* v5.5 KEY_MACRO5 */
875#define XF86XK_Macro6 _EVDEVK(0x295) /* v5.5 KEY_MACRO6 */
876#define XF86XK_Macro7 _EVDEVK(0x296) /* v5.5 KEY_MACRO7 */
877#define XF86XK_Macro8 _EVDEVK(0x297) /* v5.5 KEY_MACRO8 */
878#define XF86XK_Macro9 _EVDEVK(0x298) /* v5.5 KEY_MACRO9 */
879#define XF86XK_Macro10 _EVDEVK(0x299) /* v5.5 KEY_MACRO10 */
880#define XF86XK_Macro11 _EVDEVK(0x29a) /* v5.5 KEY_MACRO11 */
881#define XF86XK_Macro12 _EVDEVK(0x29b) /* v5.5 KEY_MACRO12 */
882#define XF86XK_Macro13 _EVDEVK(0x29c) /* v5.5 KEY_MACRO13 */
883#define XF86XK_Macro14 _EVDEVK(0x29d) /* v5.5 KEY_MACRO14 */
884#define XF86XK_Macro15 _EVDEVK(0x29e) /* v5.5 KEY_MACRO15 */
885#define XF86XK_Macro16 _EVDEVK(0x29f) /* v5.5 KEY_MACRO16 */
886#define XF86XK_Macro17 _EVDEVK(0x2a0) /* v5.5 KEY_MACRO17 */
887#define XF86XK_Macro18 _EVDEVK(0x2a1) /* v5.5 KEY_MACRO18 */
888#define XF86XK_Macro19 _EVDEVK(0x2a2) /* v5.5 KEY_MACRO19 */
889#define XF86XK_Macro20 _EVDEVK(0x2a3) /* v5.5 KEY_MACRO20 */
890#define XF86XK_Macro21 _EVDEVK(0x2a4) /* v5.5 KEY_MACRO21 */
891#define XF86XK_Macro22 _EVDEVK(0x2a5) /* v5.5 KEY_MACRO22 */
892#define XF86XK_Macro23 _EVDEVK(0x2a6) /* v5.5 KEY_MACRO23 */
893#define XF86XK_Macro24 _EVDEVK(0x2a7) /* v5.5 KEY_MACRO24 */
894#define XF86XK_Macro25 _EVDEVK(0x2a8) /* v5.5 KEY_MACRO25 */
895#define XF86XK_Macro26 _EVDEVK(0x2a9) /* v5.5 KEY_MACRO26 */
896#define XF86XK_Macro27 _EVDEVK(0x2aa) /* v5.5 KEY_MACRO27 */
897#define XF86XK_Macro28 _EVDEVK(0x2ab) /* v5.5 KEY_MACRO28 */
898#define XF86XK_Macro29 _EVDEVK(0x2ac) /* v5.5 KEY_MACRO29 */
899#define XF86XK_Macro30 _EVDEVK(0x2ad) /* v5.5 KEY_MACRO30 */
900#define XF86XK_MacroRecordStart _EVDEVK(0x2b0) /* v5.5 KEY_MACRO_RECORD_START */
901#define XF86XK_MacroRecordStop _EVDEVK(0x2b1) /* v5.5 KEY_MACRO_RECORD_STOP */
902#define XF86XK_MacroPresetCycle _EVDEVK(0x2b2) /* v5.5 KEY_MACRO_PRESET_CYCLE */
903#define XF86XK_MacroPreset1 _EVDEVK(0x2b3) /* v5.5 KEY_MACRO_PRESET1 */
904#define XF86XK_MacroPreset2 _EVDEVK(0x2b4) /* v5.5 KEY_MACRO_PRESET2 */
905#define XF86XK_MacroPreset3 _EVDEVK(0x2b5) /* v5.5 KEY_MACRO_PRESET3 */
906#define XF86XK_KbdLcdMenu1 _EVDEVK(0x2b8) /* v5.5 KEY_KBD_LCD_MENU1 */
907#define XF86XK_KbdLcdMenu2 _EVDEVK(0x2b9) /* v5.5 KEY_KBD_LCD_MENU2 */
908#define XF86XK_KbdLcdMenu3 _EVDEVK(0x2ba) /* v5.5 KEY_KBD_LCD_MENU3 */
909#define XF86XK_KbdLcdMenu4 _EVDEVK(0x2bb) /* v5.5 KEY_KBD_LCD_MENU4 */
910#define XF86XK_KbdLcdMenu5 _EVDEVK(0x2bc) /* v5.5 KEY_KBD_LCD_MENU5 */
911#undef _EVDEVK
912// end of XF86keysyms.h
913
914 // All of the stuff below really has to match qxcbcommon.cpp in Qt!
915 { Qt::Key_Back, XF86XK_Back },
916 { Qt::Key_Forward, XF86XK_Forward },
917 { Qt::Key_Stop, XF86XK_Stop },
918 { Qt::Key_Refresh, XF86XK_Refresh },
919 { Qt::Key_Favorites, XF86XK_Favorites },
920 { Qt::Key_LaunchMedia, XF86XK_AudioMedia },
921 { Qt::Key_OpenUrl, XF86XK_OpenURL },
922 { Qt::Key_HomePage, XF86XK_HomePage },
923 { Qt::Key_Search, XF86XK_Search },
924 { Qt::Key_VolumeDown, XF86XK_AudioLowerVolume },
925 { Qt::Key_VolumeMute, XF86XK_AudioMute },
926 { Qt::Key_VolumeUp, XF86XK_AudioRaiseVolume },
927 { Qt::Key_MediaPlay, XF86XK_AudioPlay },
928 { Qt::Key_MediaStop, XF86XK_AudioStop },
929 { Qt::Key_MediaPrevious, XF86XK_AudioPrev },
930 { Qt::Key_MediaNext, XF86XK_AudioNext },
931 { Qt::Key_MediaRecord, XF86XK_AudioRecord },
932 { Qt::Key_MediaPause, XF86XK_AudioPause },
933 { Qt::Key_LaunchMail, XF86XK_Mail },
934 { Qt::Key_LaunchMedia, XF86XK_MyComputer },
935 { Qt::Key_Memo, XF86XK_Memo },
936 { Qt::Key_ToDoList, XF86XK_ToDoList },
937 { Qt::Key_Calendar, XF86XK_Calendar },
938 { Qt::Key_PowerDown, XF86XK_PowerDown },
939 { Qt::Key_ContrastAdjust, XF86XK_ContrastAdjust },
940 { Qt::Key_Standby, XF86XK_Standby },
941 { Qt::Key_MonBrightnessUp, XF86XK_MonBrightnessUp },
942 { Qt::Key_MonBrightnessDown, XF86XK_MonBrightnessDown },
943 { Qt::Key_KeyboardLightOnOff, XF86XK_KbdLightOnOff },
944 { Qt::Key_KeyboardBrightnessUp, XF86XK_KbdBrightnessUp },
945 { Qt::Key_KeyboardBrightnessDown,XF86XK_KbdBrightnessDown },
946 { Qt::Key_PowerOff, XF86XK_PowerOff },
947 { Qt::Key_WakeUp, XF86XK_WakeUp },
948 { Qt::Key_Eject, XF86XK_Eject },
949 { Qt::Key_ScreenSaver, XF86XK_ScreenSaver },
950 { Qt::Key_WWW, XF86XK_WWW },
951 { Qt::Key_Sleep, XF86XK_Sleep },
952 { Qt::Key_LightBulb, XF86XK_LightBulb },
953 { Qt::Key_Shop, XF86XK_Shop },
954 { Qt::Key_History, XF86XK_History },
955 { Qt::Key_AddFavorite, XF86XK_AddFavorite },
956 { Qt::Key_HotLinks, XF86XK_HotLinks },
957 { Qt::Key_BrightnessAdjust, XF86XK_BrightnessAdjust },
958 { Qt::Key_Finance, XF86XK_Finance },
959 { Qt::Key_Community, XF86XK_Community },
960 { Qt::Key_AudioRewind, XF86XK_AudioRewind },
961 { Qt::Key_BackForward, XF86XK_BackForward },
962 { Qt::Key_ApplicationLeft, XF86XK_ApplicationLeft },
963 { Qt::Key_ApplicationRight, XF86XK_ApplicationRight },
964 { Qt::Key_Book, XF86XK_Book },
965 { Qt::Key_CD, XF86XK_CD },
966 { Qt::Key_Calculator, XF86XK_Calculater },
967 { Qt::Key_Calculator, XF86XK_Calculator },
968 { Qt::Key_Clear, XF86XK_Clear },
969 { Qt::Key_ClearGrab, XF86XK_ClearGrab },
970 { Qt::Key_Close, XF86XK_Close },
971 { Qt::Key_Copy, XF86XK_Copy },
972 { Qt::Key_Cut, XF86XK_Cut },
973 { Qt::Key_Display, XF86XK_Display },
974 { Qt::Key_DOS, XF86XK_DOS },
975 { Qt::Key_Documents, XF86XK_Documents },
976 { Qt::Key_Excel, XF86XK_Excel },
977 { Qt::Key_Explorer, XF86XK_Explorer },
978 { Qt::Key_Game, XF86XK_Game },
979 { Qt::Key_Go, XF86XK_Go },
980 { Qt::Key_iTouch, XF86XK_iTouch },
981 { Qt::Key_LogOff, XF86XK_LogOff },
982 { Qt::Key_Market, XF86XK_Market },
983 { Qt::Key_Meeting, XF86XK_Meeting },
984 { Qt::Key_MenuKB, XF86XK_MenuKB },
985 { Qt::Key_MenuPB, XF86XK_MenuPB },
986 { Qt::Key_MySites, XF86XK_MySites },
987 { Qt::Key_New, XF86XK_New },
988 { Qt::Key_News, XF86XK_News },
989 { Qt::Key_OfficeHome, XF86XK_OfficeHome },
990 { Qt::Key_Open, XF86XK_Open },
991 { Qt::Key_Option, XF86XK_Option },
992 { Qt::Key_Paste, XF86XK_Paste },
993 { Qt::Key_Phone, XF86XK_Phone },
994 { Qt::Key_Reply, XF86XK_Reply },
995 { Qt::Key_Reload, XF86XK_Reload },
996 { Qt::Key_RotateWindows, XF86XK_RotateWindows },
997 { Qt::Key_RotationPB, XF86XK_RotationPB },
998 { Qt::Key_RotationKB, XF86XK_RotationKB },
999 { Qt::Key_Save, XF86XK_Save },
1000 { Qt::Key_Send, XF86XK_Send },
1001 { Qt::Key_Spell, XF86XK_Spell },
1002 { Qt::Key_SplitScreen, XF86XK_SplitScreen },
1003 { Qt::Key_Support, XF86XK_Support },
1004 { Qt::Key_TaskPane, XF86XK_TaskPane },
1005 { Qt::Key_Terminal, XF86XK_Terminal },
1006 { Qt::Key_Tools, XF86XK_Tools },
1007 { Qt::Key_Travel, XF86XK_Travel },
1008 { Qt::Key_Video, XF86XK_Video },
1009 { Qt::Key_Word, XF86XK_Word },
1010 { Qt::Key_Xfer, XF86XK_Xfer },
1011 { Qt::Key_ZoomIn, XF86XK_ZoomIn },
1012 { Qt::Key_ZoomOut, XF86XK_ZoomOut },
1013 { Qt::Key_Away, XF86XK_Away },
1014 { Qt::Key_Messenger, XF86XK_Messenger },
1015 { Qt::Key_WebCam, XF86XK_WebCam },
1016 { Qt::Key_MailForward, XF86XK_MailForward },
1017 { Qt::Key_Pictures, XF86XK_Pictures },
1018 { Qt::Key_Music, XF86XK_Music },
1019 { Qt::Key_Battery, XF86XK_Battery },
1020 { Qt::Key_Bluetooth, XF86XK_Bluetooth },
1021 { Qt::Key_WLAN, XF86XK_WLAN },
1022 { Qt::Key_UWB, XF86XK_UWB },
1023 { Qt::Key_AudioForward, XF86XK_AudioForward },
1024 { Qt::Key_AudioRepeat, XF86XK_AudioRepeat },
1025 { Qt::Key_AudioRandomPlay, XF86XK_AudioRandomPlay },
1026 { Qt::Key_Subtitle, XF86XK_Subtitle },
1027 { Qt::Key_AudioCycleTrack, XF86XK_AudioCycleTrack },
1028 { Qt::Key_Time, XF86XK_Time },
1029 { Qt::Key_Select, XF86XK_Select },
1030 { Qt::Key_View, XF86XK_View },
1031 { Qt::Key_TopMenu, XF86XK_TopMenu },
1032 { Qt::Key_Red, XF86XK_Red },
1033 { Qt::Key_Green, XF86XK_Green },
1034 { Qt::Key_Yellow, XF86XK_Yellow },
1035 { Qt::Key_Blue, XF86XK_Blue },
1036 { Qt::Key_Bluetooth, XF86XK_Bluetooth },
1037 { Qt::Key_Suspend, XF86XK_Suspend },
1038 { Qt::Key_Hibernate, XF86XK_Hibernate },
1039 { Qt::Key_TouchpadToggle, XF86XK_TouchpadToggle },
1040 { Qt::Key_TouchpadOn, XF86XK_TouchpadOn },
1041 { Qt::Key_TouchpadOff, XF86XK_TouchpadOff },
1042 { Qt::Key_MicMute, XF86XK_AudioMicMute },
1043 { Qt::Key_Launch0, XF86XK_Launch0 },
1044 { Qt::Key_Launch1, XF86XK_Launch1 },
1045 { Qt::Key_Launch2, XF86XK_Launch2 },
1046 { Qt::Key_Launch3, XF86XK_Launch3 },
1047 { Qt::Key_Launch4, XF86XK_Launch4 },
1048 { Qt::Key_Launch5, XF86XK_Launch5 },
1049 { Qt::Key_Launch6, XF86XK_Launch6 },
1050 { Qt::Key_Launch7, XF86XK_Launch7 },
1051 { Qt::Key_Launch8, XF86XK_Launch8 },
1052 { Qt::Key_Launch9, XF86XK_Launch9 },
1053 { Qt::Key_LaunchA, XF86XK_LaunchA },
1054 { Qt::Key_LaunchB, XF86XK_LaunchB },
1055 { Qt::Key_LaunchC, XF86XK_LaunchC },
1056 { Qt::Key_LaunchD, XF86XK_LaunchD },
1057 { Qt::Key_LaunchE, XF86XK_LaunchE },
1058 { Qt::Key_LaunchF, XF86XK_LaunchF },
1059};
1060// clang-format on
1061
1062//---------------------------------------------------------------------
1063// Debugging
1064//---------------------------------------------------------------------
1065#ifndef NDEBUG
1066inline void checkDisplay()
1067{
1068 // Some non-GUI apps might try to use us.
1069 if (!QX11Info::display()) {
1070 qCCritical(LOG_KKEYSERVER_X11) << "QX11Info::display() returns 0. I'm probably going to crash now.";
1071 qCCritical(LOG_KKEYSERVER_X11) << "If this is a KApplication initialized without GUI stuff, change it to be "
1072 "initialized with GUI stuff.";
1073 }
1074}
1075#else // NDEBUG
1076#define checkDisplay()
1077#endif
1078
1079//---------------------------------------------------------------------
1080// Initialization
1081//---------------------------------------------------------------------
1082
1083static bool g_bInitializedMods;
1084static uint g_modXNumLock, g_modXScrollLock, g_modXModeSwitch, g_alt_mask, g_meta_mask, g_super_mask, g_hyper_mask;
1085
1087{
1088 // Reinitialize the masks
1089 g_modXNumLock = 0;
1090 g_modXScrollLock = 0;
1091 g_modXModeSwitch = 0;
1092 g_alt_mask = 0;
1093 g_meta_mask = 0;
1094 g_super_mask = 0;
1095 g_hyper_mask = 0;
1096
1097 if (!QX11Info::isPlatformX11()) {
1098 qCWarning(LOG_KKEYSERVER_X11) << "X11 implementation of KKeyServer accessed from non-X11 platform! This is an application bug.";
1099 g_bInitializedMods = true;
1100 return false;
1101 }
1102
1103 checkDisplay();
1104 xcb_key_symbols_t *symbols = xcb_key_symbols_alloc(QX11Info::connection());
1105 XModifierKeymap *xmk = XGetModifierMapping(QX11Info::display());
1106
1107 int min_keycode;
1108 int max_keycode;
1109 int keysyms_per_keycode = 0;
1110
1111 XDisplayKeycodes(QX11Info::display(), &min_keycode, &max_keycode);
1112 XFree(XGetKeyboardMapping(QX11Info::display(), min_keycode, 1, &keysyms_per_keycode));
1113
1114 for (int i = Mod1MapIndex; i < 8; i++) {
1115 uint mask = (1 << i);
1116 uint keySymX = NoSymbol;
1117
1118 // This used to be only XKeycodeToKeysym( ... , 0 ), but that fails with XFree4.3.99
1119 // and X.org R6.7 , where for some reason only ( ... , 1 ) works. I have absolutely no
1120 // idea what the problem is, but searching all possibilities until something valid is
1121 // found fixes the problem.
1122 for (int j = 0; j < xmk->max_keypermod; ++j) {
1123 for (int k = 0; k < keysyms_per_keycode; ++k) {
1124 keySymX = xcb_key_symbols_get_keysym(symbols, xmk->modifiermap[xmk->max_keypermod * i + j], k);
1125
1126 switch (keySymX) {
1127 case XK_Alt_L:
1128 case XK_Alt_R:
1129 g_alt_mask |= mask;
1130 break;
1131
1132 case XK_Super_L:
1133 case XK_Super_R:
1134 g_super_mask |= mask;
1135 break;
1136
1137 case XK_Hyper_L:
1138 case XK_Hyper_R:
1139 g_hyper_mask |= mask;
1140 break;
1141
1142 case XK_Meta_L:
1143 case XK_Meta_R:
1144 g_meta_mask |= mask;
1145 break;
1146
1147 case XK_Num_Lock:
1148 g_modXNumLock |= mask;
1149 break;
1150 case XK_Scroll_Lock:
1151 g_modXScrollLock |= mask;
1152 break;
1153 case XK_Mode_switch:
1154 g_modXModeSwitch |= mask;
1155 break;
1156 }
1157 }
1158 }
1159 }
1160
1161#ifdef KKEYSERVER_DEBUG
1162 qCDebug(LOG_KKEYSERVER_X11) << "Alt:" << g_alt_mask;
1163 qCDebug(LOG_KKEYSERVER_X11) << "Meta:" << g_meta_mask;
1164 qCDebug(LOG_KKEYSERVER_X11) << "Super:" << g_super_mask;
1165 qCDebug(LOG_KKEYSERVER_X11) << "Hyper:" << g_hyper_mask;
1166 qCDebug(LOG_KKEYSERVER_X11) << "NumLock:" << g_modXNumLock;
1167 qCDebug(LOG_KKEYSERVER_X11) << "ScrollLock:" << g_modXScrollLock;
1168 qCDebug(LOG_KKEYSERVER_X11) << "ModeSwitch:" << g_modXModeSwitch;
1169#endif
1170
1171 // Check if hyper overlaps with super or meta or alt
1172 if (g_hyper_mask & (g_super_mask | g_meta_mask | g_alt_mask)) {
1173#ifdef KKEYSERVER_DEBUG
1174 qCDebug(LOG_KKEYSERVER_X11) << "Hyper conflicts with super, meta or alt.";
1175#endif
1176 // Remove the conflicting masks
1177 g_hyper_mask &= ~(g_super_mask | g_meta_mask | g_alt_mask);
1178 }
1179
1180 // Check if super overlaps with meta or alt
1181 if (g_super_mask & (g_meta_mask | g_alt_mask)) {
1182#ifdef KKEYSERVER_DEBUG
1183 qCDebug(LOG_KKEYSERVER_X11) << "Super conflicts with meta or alt.";
1184#endif
1185 // Remove the conflicting masks
1186 g_super_mask &= ~(g_meta_mask | g_alt_mask);
1187 }
1188
1189 // Check if meta overlaps with alt
1190 if (g_meta_mask | g_alt_mask) {
1191#ifdef KKEYSERVER_DEBUG
1192 qCDebug(LOG_KKEYSERVER_X11) << "Meta conflicts with alt.";
1193#endif
1194 // Remove the conflicting masks
1195 g_meta_mask &= ~(g_alt_mask);
1196 }
1197
1198 if (!g_meta_mask) {
1199#ifdef KKEYSERVER_DEBUG
1200 qCDebug(LOG_KKEYSERVER_X11) << "Meta is not set or conflicted with alt.";
1201#endif
1202 if (g_super_mask) {
1203#ifdef KKEYSERVER_DEBUG
1204 qCDebug(LOG_KKEYSERVER_X11) << "Using super for meta";
1205#endif
1206 // Use Super
1207 g_meta_mask = g_super_mask;
1208 } else if (g_hyper_mask) {
1209#ifdef KKEYSERVER_DEBUG
1210 qCDebug(LOG_KKEYSERVER_X11) << "Using hyper for meta";
1211#endif
1212 // User Hyper
1213 g_meta_mask = g_hyper_mask;
1214 } else {
1215 // ???? Nothing left
1216 g_meta_mask = 0;
1217 }
1218 }
1219
1220#ifdef KKEYSERVER_DEBUG
1221 qCDebug(LOG_KKEYSERVER_X11) << "Alt:" << g_alt_mask;
1222 qCDebug(LOG_KKEYSERVER_X11) << "Meta:" << g_meta_mask;
1223 qCDebug(LOG_KKEYSERVER_X11) << "Super:" << g_super_mask;
1224 qCDebug(LOG_KKEYSERVER_X11) << "Hyper:" << g_hyper_mask;
1225 qCDebug(LOG_KKEYSERVER_X11) << "NumLock:" << g_modXNumLock;
1226 qCDebug(LOG_KKEYSERVER_X11) << "ScrollLock:" << g_modXScrollLock;
1227 qCDebug(LOG_KKEYSERVER_X11) << "ModeSwitch:" << g_modXModeSwitch;
1228#endif
1229
1230 if (!g_meta_mask) {
1231 qCWarning(LOG_KKEYSERVER_X11) << "Your keyboard setup doesn't provide a key to use for meta. See 'xmodmap -pm' or 'xkbcomp $DISPLAY'";
1232 }
1233
1234 g_rgX11ModInfo[2].modX = g_alt_mask;
1235 g_rgX11ModInfo[3].modX = g_meta_mask;
1236
1237 xcb_key_symbols_free(symbols);
1238 XFreeModifiermap(xmk);
1239 g_bInitializedMods = true;
1240
1241 return true;
1242}
1243
1244//---------------------------------------------------------------------
1245// Helper functions
1246//---------------------------------------------------------------------
1247
1248static bool is_keypad_key(xcb_keysym_t keysym)
1249{
1250 return keysym >= XK_KP_Space && keysym <= XK_KP_9;
1251}
1252
1253//---------------------------------------------------------------------
1254// Public functions
1255//---------------------------------------------------------------------
1256
1258{
1259 return ShiftMask;
1260}
1262{
1263 return ControlMask;
1264}
1266{
1267 if (!g_bInitializedMods) {
1269 }
1270 return g_alt_mask;
1271}
1273{
1274 if (!g_bInitializedMods) {
1276 }
1277 return g_meta_mask;
1278}
1279
1281{
1282 if (!g_bInitializedMods) {
1284 }
1285 return g_modXNumLock;
1286}
1288{
1289 return LockMask;
1290}
1292{
1293 if (!g_bInitializedMods) {
1295 }
1296 return g_modXScrollLock;
1297}
1299{
1300 if (!g_bInitializedMods) {
1302 }
1303 return g_modXModeSwitch;
1304}
1305
1307{
1308 return modXMeta() != 0;
1309}
1310
1311uint getModsRequired(uint sym)
1312{
1313 if (!QX11Info::isPlatformX11()) {
1314 qCWarning(LOG_KKEYSERVER_X11) << "X11 implementation of KKeyServer accessed from non-X11 platform! This is an application bug.";
1315 return 0;
1316 }
1317 uint mod = 0;
1318
1319 // FIXME: This might not be true on all keyboard layouts!
1320 if (sym == XK_Sys_Req) {
1321 return Qt::ALT;
1322 }
1323 if (sym == XK_Break) {
1324 return Qt::CTRL;
1325 }
1326
1327 if (sym < 0x3000) {
1328 QChar c(sym);
1329 if (c.isLetter() && c.toLower() != c.toUpper() && sym == c.toUpper().unicode()) {
1330 return Qt::SHIFT;
1331 }
1332 }
1333
1334 uchar code = XKeysymToKeycode(QX11Info::display(), sym);
1335 if (code) {
1336 // need to check index 0 before the others, so that a null-mod
1337 // can take precedence over the others, in case the modified
1338 // key produces the same symbol.
1339 if (sym == XKeycodeToKeysym(QX11Info::display(), code, 0)) {
1340 ;
1341 } else if (sym == XKeycodeToKeysym(QX11Info::display(), code, 1)) {
1342 mod = Qt::SHIFT;
1343 } else if (sym == XKeycodeToKeysym(QX11Info::display(), code, 2)) {
1344 mod = MODE_SWITCH;
1345 } else if (sym == XKeycodeToKeysym(QX11Info::display(), code, 3)) {
1346 mod = Qt::SHIFT | MODE_SWITCH;
1347 }
1348 }
1349 return mod;
1350}
1351
1352#if KWINDOWSYSTEM_BUILD_DEPRECATED_SINCE(6, 0)
1353bool keyQtToCodeX(int keyQt, int *keyCode)
1354{
1355 if (!QX11Info::isPlatformX11()) {
1356 qCWarning(LOG_KKEYSERVER_X11) << "X11 implementation of KKeyServer accessed from non-X11 platform! This is an application bug.";
1357 return false;
1358 }
1359 int sym;
1360 uint mod;
1361 keyQtToSymX(keyQt, &sym);
1362 keyQtToModX(keyQt, &mod);
1363
1364 // Get any extra mods required by the sym.
1365 // E.g., XK_Plus requires SHIFT on the en layout.
1366 uint modExtra = getModsRequired(sym);
1367 // Get the X modifier equivalent.
1368 if (!sym || !keyQtToModX((keyQt & Qt::KeyboardModifierMask) | modExtra, &mod)) {
1369 *keyCode = 0;
1370 return false;
1371 }
1372
1373 *keyCode = XKeysymToKeycode(QX11Info::display(), sym);
1374 return true;
1375}
1376#endif
1377
1379{
1380 QList<int> keyCodes;
1381 if (!QX11Info::isPlatformX11()) {
1382 qCWarning(LOG_KKEYSERVER_X11) << "X11 implementation of KKeyServer accessed from non-X11 platform! This is an application bug.";
1383 return keyCodes;
1384 }
1385 uint mod;
1386 const QList<int> syms(keyQtToSymXs(keyQt));
1387 keyQtToModX(keyQt, &mod);
1388
1389 for (int sym : syms) {
1390 // Get any extra mods required by the sym.
1391 // E.g., XK_Plus requires SHIFT on the en layout.
1392 uint modExtra = getModsRequired(sym);
1393 // Get the X modifier equivalent.
1394 if (!sym || !keyQtToModX((keyQt & Qt::KeyboardModifierMask) | modExtra, &mod)) {
1395 continue;
1396 }
1397
1398 keyCodes.append(XKeysymToKeycode(QX11Info::display(), sym));
1399 }
1400 return keyCodes;
1401}
1402
1403#if KWINDOWSYSTEM_BUILD_DEPRECATED_SINCE(6, 0)
1404bool keyQtToSymX(int keyQt, int *keySym)
1405{
1406 int symQt = keyQt & ~Qt::KeyboardModifierMask;
1407
1408 if (keyQt & Qt::KeypadModifier) {
1409 if (symQt >= Qt::Key_0 && symQt <= Qt::Key_9) {
1410 *keySym = XK_KP_0 + (symQt - Qt::Key_0);
1411 return true;
1412 }
1413 } else {
1414 if (symQt < 0x1000) {
1415 *keySym = QChar(symQt).toUpper().unicode();
1416 return true;
1417 }
1418 }
1419
1420 for (const TransKey &tk : g_rgQtToSymX) {
1421 if (tk.keySymQt == symQt) {
1422 if ((keyQt & Qt::KeypadModifier) && !is_keypad_key(tk.keySymX)) {
1423 continue;
1424 }
1425 *keySym = tk.keySymX;
1426 return true;
1427 }
1428 }
1429
1430 *keySym = 0;
1431 if (symQt != Qt::Key_Shift && symQt != Qt::Key_Control && symQt != Qt::Key_Alt && symQt != Qt::Key_Meta && symQt != Qt::Key_Direction_L
1432 && symQt != Qt::Key_Direction_R) {
1433 // qCDebug(LOG_KKEYSERVER_X11) << "Sym::initQt( " << QString::number(keyQt,16) << " ): failed to convert key.";
1434 }
1435 return false;
1436}
1437#endif
1438
1440{
1441 int symQt = keyQt & ~Qt::KeyboardModifierMask;
1442 QList<int> syms;
1443
1444 if (keyQt & Qt::KeypadModifier) {
1445 if (symQt >= Qt::Key_0 && symQt <= Qt::Key_9) {
1446 syms.append(XK_KP_0 + (symQt - Qt::Key_0));
1447 return syms;
1448 }
1449 } else {
1450 if (symQt < 0x1000) {
1451 syms.append(QChar(symQt).toUpper().unicode());
1452 return syms;
1453 }
1454 }
1455
1456 for (const TransKey &tk : g_rgQtToSymX) {
1457 if (tk.keySymQt == symQt) {
1458 if ((keyQt & Qt::KeypadModifier) && !is_keypad_key(tk.keySymX)) {
1459 continue;
1460 }
1461 syms.append(tk.keySymX);
1462 }
1463 }
1464 return syms;
1465}
1466
1467bool symXModXToKeyQt(uint32_t keySym, uint16_t modX, int *keyQt)
1468{
1469 int keyModQt = 0;
1470 *keyQt = Qt::Key_unknown;
1471
1472 if (keySym >= XK_KP_0 && keySym <= XK_KP_9) {
1473 // numeric keypad keys
1474 *keyQt = Qt::Key_0 + ((int)keySym - XK_KP_0);
1475 } else if (keySym < 0x1000) {
1476 if (keySym >= 'a' && keySym <= 'z') {
1477 *keyQt = QChar(keySym).toUpper().unicode();
1478 } else {
1479 *keyQt = keySym;
1480 }
1481 }
1482
1483 else if (keySym < 0x3000) {
1484 *keyQt = keySym;
1485 }
1486
1487 else {
1488 for (const TransKey &tk : g_rgQtToSymX) {
1489 if (tk.keySymX == keySym) {
1490 *keyQt = tk.keySymQt;
1491 break;
1492 }
1493 }
1494 }
1495
1496 if (*keyQt == Qt::Key_unknown) {
1497 return false;
1498 }
1499
1500 if (modXToQt(modX, &keyModQt)) {
1501 *keyQt |= keyModQt;
1502 if (is_keypad_key(keySym)) {
1503 *keyQt |= Qt::KeypadModifier;
1504 }
1505 return true;
1506 }
1507 return false;
1508}
1509
1510bool keyQtToModX(int modQt, uint *modX)
1511{
1512 if (!g_bInitializedMods) {
1514 }
1515
1516 *modX = 0;
1517 for (int i = 0; i < 4; i++) {
1518 if (modQt & g_rgX11ModInfo[i].modQt) {
1519 if (g_rgX11ModInfo[i].modX) {
1520 *modX |= g_rgX11ModInfo[i].modX;
1521 } else {
1522 // The qt modifier has no x equivalent. Return false
1523 return false;
1524 }
1525 }
1526 }
1527 return true;
1528}
1529
1530bool modXToQt(uint modX, int *modQt)
1531{
1532 if (!g_bInitializedMods) {
1534 }
1535
1536 *modQt = 0;
1537 for (int i = 0; i < 4; i++) {
1538 if (modX & g_rgX11ModInfo[i].modX) {
1539 *modQt |= g_rgX11ModInfo[i].modQt;
1540 continue;
1541 }
1542 }
1543 return true;
1544}
1545
1546bool codeXToSym(uchar codeX, uint modX, uint *sym)
1547{
1548 if (!QX11Info::isPlatformX11()) {
1549 qCWarning(LOG_KKEYSERVER_X11) << "X11 implementation of KKeyServer accessed from non-X11 platform! This is an application bug.";
1550 return false;
1551 }
1552 KeySym keySym;
1553 XKeyPressedEvent event;
1554
1555 checkDisplay();
1556
1557 event.type = KeyPress;
1558 event.display = QX11Info::display();
1559 event.state = modX;
1560 event.keycode = codeX;
1561
1562 XLookupString(&event, nullptr, 0, &keySym, nullptr);
1563 *sym = (uint)keySym;
1564 return true;
1565}
1566
1568{
1569 return modXShift() | modXCtrl() | modXAlt() | modXMeta();
1570}
1571
1572bool xEventToQt(XEvent *e, int *keyQt)
1573{
1574 Q_ASSERT(e->type == KeyPress || e->type == KeyRelease);
1575
1576 uchar keyCodeX = e->xkey.keycode;
1577 uint keyModX = e->xkey.state & (accelModMaskX() | MODE_SWITCH);
1578
1579 KeySym keySym;
1580 char buffer[16];
1581 XLookupString((XKeyEvent *)e, buffer, 15, &keySym, nullptr);
1582 uint keySymX = (uint)keySym;
1583
1584 // If numlock is active and a keypad key is pressed, XOR the SHIFT state.
1585 // e.g., KP_4 => Shift+KP_Left, and Shift+KP_4 => KP_Left.
1586 if (e->xkey.state & modXNumLock()) {
1587 uint sym = XKeycodeToKeysym(QX11Info::display(), keyCodeX, 0);
1588 // TODO: what's the xor operator in c++?
1589 // If this is a keypad key,
1590 if (sym >= XK_KP_Space && sym <= XK_KP_9) {
1591 switch (sym) {
1592 // Leave the following keys unaltered
1593 // FIXME: The proper solution is to see which keysyms don't change when shifted.
1594 case XK_KP_Multiply:
1595 case XK_KP_Add:
1596 case XK_KP_Subtract:
1597 case XK_KP_Divide:
1598 break;
1599 default:
1600 if (keyModX & modXShift()) {
1601 keyModX &= ~modXShift();
1602 } else {
1603 keyModX |= modXShift();
1604 }
1605 }
1606 }
1607 }
1608
1609 return KKeyServer::symXModXToKeyQt(keySymX, keyModX, keyQt);
1610}
1611
1612bool xcbKeyPressEventToQt(xcb_generic_event_t *e, int *keyQt)
1613{
1614 if ((e->response_type & ~0x80) != XCB_KEY_PRESS && (e->response_type & ~0x80) != XCB_KEY_RELEASE) {
1615 return false;
1616 }
1617 return xcbKeyPressEventToQt(reinterpret_cast<xcb_key_press_event_t *>(e), keyQt);
1618}
1619
1620bool xcbKeyPressEventToQt(xcb_key_press_event_t *e, int *keyQt)
1621{
1622 const uint16_t keyModX = e->state & (accelModMaskX() | MODE_SWITCH);
1623
1624 xcb_key_symbols_t *symbols = xcb_key_symbols_alloc(QX11Info::connection());
1625
1626 // We might have to use 4,5 instead of 0,1 here when mode_switch is active, just not sure how to test that.
1627 const xcb_keysym_t keySym0 = xcb_key_press_lookup_keysym(symbols, e, 0);
1628 const xcb_keysym_t keySym1 = xcb_key_press_lookup_keysym(symbols, e, 1);
1629 xcb_keysym_t keySymX;
1630
1631 if ((e->state & KKeyServer::modXNumLock()) && is_keypad_key(keySym1)) {
1632 if ((e->state & XCB_MOD_MASK_SHIFT)) {
1633 keySymX = keySym0;
1634 } else {
1635 keySymX = keySym1;
1636 }
1637 } else {
1638 keySymX = keySym0;
1639 }
1640
1641 bool ok = KKeyServer::symXModXToKeyQt(keySymX, keyModX, keyQt);
1642
1643 if ((*keyQt & Qt::ShiftModifier) && !KKeyServer::isShiftAsModifierAllowed(*keyQt)) {
1644 if (*keyQt != Qt::Key_Tab) { // KKeySequenceWidget does not map shift+tab to backtab
1645 static const int FirstLevelShift = 1;
1646 keySymX = xcb_key_symbols_get_keysym(symbols, e->detail, FirstLevelShift);
1647 KKeyServer::symXModXToKeyQt(keySymX, keyModX, keyQt);
1648 }
1649 *keyQt &= ~Qt::ShiftModifier;
1650 }
1651
1652 xcb_key_symbols_free(symbols);
1653 return ok;
1654}
1655
1656} // end of namespace KKeyServer block
AKONADI_CALENDAR_EXPORT KCalendarCore::Event::Ptr event(const Akonadi::Item &item)
A collection of functions for the conversion of key presses and their modifiers from the window syste...
uint modXLock()
Returns the X11 Lock modifier mask/flag.
uint modXAlt()
Returns the X11 Alt (Mod1) modifier mask/flag.
uint modXMeta()
Returns the X11 Win (Mod3) modifier mask/flag.
bool initializeMods()
Initialises the values to return for the mod*() functions below.
uint stringUserToMod(const QString &mod)
Converts the modifier given as user-readable string (in English) to KKey::ModFlag modifier,...
bool symXModXToKeyQt(uint32_t keySym, uint16_t modX, int *keyQt)
Converts the given symbol and modifier combination to a Qt key code.
QList< int > keyQtToSymXs(int keyQt)
Extracts the symbols from the given Qt key and converts it to an X11 symbol + modifiers.
bool keyQtToSymX(int keyQt, int *keySym)
Extracts the symbol from the given Qt key and converts it to an X11 symbol + modifiers.
bool isShiftAsModifierAllowed(int keyQt)
Test if the shift modifier should be recorded for a given key.
bool keyboardHasMetaKey()
Returns true if the current keyboard layout supports the Meta key.
bool xEventToQt(XEvent *e, int *keyQt)
Converts an X keypress event into a Qt key + modifier code.
uint modXCtrl()
Returns the X11 Ctrl modifier mask/flag.
bool keyQtToCodeX(int keyQt, int *keyCode)
Extracts the code from the given Qt key.
uint modXScrollLock()
Returns the X11 ScrollLock modifier mask/flag.
uint modXShift()
Returns the X11 Shift modifier mask/flag.
QList< int > keyQtToCodeXs(int keyQt)
Extracts the codes from the given Qt key.
bool modXToQt(uint modX, int *modQt)
Converts the mask of ORed X11 modifiers to a mask of ORed Qt key code modifiers.
uint modXModeSwitch()
Returns the X11 Mode_switch modifier mask/flag.
uint accelModMaskX()
Returns bitwise OR'ed mask containing Shift, Ctrl, Alt, and Win (if available).
bool keyQtToModX(int modQt, uint *modX)
Extracts the modifiers from the given Qt key and converts them in a mask of X11 modifiers.
QString modToStringUser(uint mod)
Converts the mask of ORed KKey::ModFlag modifiers to a user-readable string.
bool xcbKeyPressEventToQt(xcb_generic_event_t *e, int *keyQt)
Converts an XCB keypress event into a Qt key + modifier code.
uint modXNumLock()
Returns the X11 NumLock modifier mask/flag.
bool isLetter() const const
char32_t toUpper(char32_t ucs4)
QString translate(const char *context, const char *sourceText, const char *disambiguation, int n)
void append(QList< T > &&value)
bool isEmpty() const const
QString toLower() const const
KeyboardModifierMask
This file is part of the KDE documentation.
Documentation copyright © 1996-2024 The KDE developers.
Generated on Fri Nov 1 2024 18:55:43 by doxygen 1.12.0 written by Dimitri van Heesch, © 1997-2006

KDE's Doxygen guidelines are available online.