diff --git a/autotests/test_xkb.cpp b/autotests/test_xkb.cpp index d71f05f8e..eeb548f32 100644 --- a/autotests/test_xkb.cpp +++ b/autotests/test_xkb.cpp @@ -1,521 +1,491 @@ /******************************************************************** KWin - the KDE window manager This file is part of the KDE project. Copyright (C) 2017 Martin Flöser This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . *********************************************************************/ #include "../xkb.h" #include #include using namespace KWin; class XkbTest : public QObject { Q_OBJECT private Q_SLOTS: void testToQtKey_data(); void testToQtKey(); }; // from kwindowsystem/src/platforms/xcb/kkeyserver.cpp // adjusted to xkb struct TransKey { Qt::Key keySymQt; xkb_keysym_t keySymX; }; static const TransKey g_rgQtToSymX[] = { { Qt::Key_Escape, XKB_KEY_Escape }, { Qt::Key_Tab, XKB_KEY_Tab }, { Qt::Key_Backtab, XKB_KEY_ISO_Left_Tab }, { Qt::Key_Backspace, XKB_KEY_BackSpace }, { Qt::Key_Return, XKB_KEY_Return }, { Qt::Key_Insert, XKB_KEY_Insert }, { Qt::Key_Delete, XKB_KEY_Delete }, { Qt::Key_Pause, XKB_KEY_Pause }, { Qt::Key_Print, XKB_KEY_Print }, { Qt::Key_SysReq, XKB_KEY_Sys_Req }, { Qt::Key_Home, XKB_KEY_Home }, { Qt::Key_End, XKB_KEY_End }, { Qt::Key_Left, XKB_KEY_Left }, { Qt::Key_Up, XKB_KEY_Up }, { Qt::Key_Right, XKB_KEY_Right }, { Qt::Key_Down, XKB_KEY_Down }, { Qt::Key_PageUp, XKB_KEY_Prior }, { Qt::Key_PageDown, XKB_KEY_Next }, { Qt::Key_CapsLock, XKB_KEY_Caps_Lock }, { Qt::Key_NumLock, XKB_KEY_Num_Lock }, { Qt::Key_ScrollLock, XKB_KEY_Scroll_Lock }, { Qt::Key_F1, XKB_KEY_F1 }, { Qt::Key_F2, XKB_KEY_F2 }, { Qt::Key_F3, XKB_KEY_F3 }, { Qt::Key_F4, XKB_KEY_F4 }, { Qt::Key_F5, XKB_KEY_F5 }, { Qt::Key_F6, XKB_KEY_F6 }, { Qt::Key_F7, XKB_KEY_F7 }, { Qt::Key_F8, XKB_KEY_F8 }, { Qt::Key_F9, XKB_KEY_F9 }, { Qt::Key_F10, XKB_KEY_F10 }, { Qt::Key_F11, XKB_KEY_F11 }, { Qt::Key_F12, XKB_KEY_F12 }, { Qt::Key_F13, XKB_KEY_F13 }, { Qt::Key_F14, XKB_KEY_F14 }, { Qt::Key_F15, XKB_KEY_F15 }, { Qt::Key_F16, XKB_KEY_F16 }, { Qt::Key_F17, XKB_KEY_F17 }, { Qt::Key_F18, XKB_KEY_F18 }, { Qt::Key_F19, XKB_KEY_F19 }, { Qt::Key_F20, XKB_KEY_F20 }, { Qt::Key_F21, XKB_KEY_F21 }, { Qt::Key_F22, XKB_KEY_F22 }, { Qt::Key_F23, XKB_KEY_F23 }, { Qt::Key_F24, XKB_KEY_F24 }, { Qt::Key_F25, XKB_KEY_F25 }, { Qt::Key_F26, XKB_KEY_F26 }, { Qt::Key_F27, XKB_KEY_F27 }, { Qt::Key_F28, XKB_KEY_F28 }, { Qt::Key_F29, XKB_KEY_F29 }, { Qt::Key_F30, XKB_KEY_F30 }, { Qt::Key_F31, XKB_KEY_F31 }, { Qt::Key_F32, XKB_KEY_F32 }, { Qt::Key_F33, XKB_KEY_F33 }, { Qt::Key_F34, XKB_KEY_F34 }, { Qt::Key_F35, XKB_KEY_F35 }, { Qt::Key_Super_L, XKB_KEY_Super_L }, { Qt::Key_Super_R, XKB_KEY_Super_R }, { Qt::Key_Menu, XKB_KEY_Menu }, { Qt::Key_Hyper_L, XKB_KEY_Hyper_L }, { Qt::Key_Hyper_R, XKB_KEY_Hyper_R }, { Qt::Key_Help, XKB_KEY_Help }, { Qt::Key_Space, XKB_KEY_KP_Space }, { Qt::Key_Tab, XKB_KEY_KP_Tab }, { Qt::Key_Enter, XKB_KEY_KP_Enter }, { Qt::Key_Home, XKB_KEY_KP_Home }, { Qt::Key_Left, XKB_KEY_KP_Left }, { Qt::Key_Up, XKB_KEY_KP_Up }, { Qt::Key_Right, XKB_KEY_KP_Right }, { Qt::Key_Down, XKB_KEY_KP_Down }, { Qt::Key_PageUp, XKB_KEY_KP_Prior }, { Qt::Key_PageDown, XKB_KEY_KP_Next }, { Qt::Key_End, XKB_KEY_KP_End }, { Qt::Key_Clear, XKB_KEY_KP_Begin }, { Qt::Key_Insert, XKB_KEY_KP_Insert }, { Qt::Key_Delete, XKB_KEY_KP_Delete }, { Qt::Key_Equal, XKB_KEY_KP_Equal }, { Qt::Key_Asterisk, XKB_KEY_KP_Multiply }, { Qt::Key_Plus, XKB_KEY_KP_Add }, { Qt::Key_Comma, XKB_KEY_KP_Separator }, { Qt::Key_Minus, XKB_KEY_KP_Subtract }, { Qt::Key_Period, XKB_KEY_KP_Decimal }, { Qt::Key_Slash, XKB_KEY_KP_Divide }, { Qt::Key_Back, XKB_KEY_XF86Back }, { Qt::Key_Forward, XKB_KEY_XF86Forward }, { Qt::Key_Stop, XKB_KEY_XF86Stop }, { Qt::Key_Refresh, XKB_KEY_XF86Refresh }, { Qt::Key_Favorites, XKB_KEY_XF86Favorites }, { Qt::Key_LaunchMedia, XKB_KEY_XF86AudioMedia }, { Qt::Key_OpenUrl, XKB_KEY_XF86OpenURL }, { Qt::Key_HomePage, XKB_KEY_XF86HomePage }, { Qt::Key_Search, XKB_KEY_XF86Search }, { Qt::Key_VolumeDown, XKB_KEY_XF86AudioLowerVolume }, { Qt::Key_VolumeMute, XKB_KEY_XF86AudioMute }, { Qt::Key_VolumeUp, XKB_KEY_XF86AudioRaiseVolume }, { Qt::Key_MediaPlay, XKB_KEY_XF86AudioPlay }, { Qt::Key_MediaStop, XKB_KEY_XF86AudioStop }, { Qt::Key_MediaPrevious, XKB_KEY_XF86AudioPrev }, { Qt::Key_MediaNext, XKB_KEY_XF86AudioNext }, { Qt::Key_MediaRecord, XKB_KEY_XF86AudioRecord }, { Qt::Key_LaunchMail, XKB_KEY_XF86Mail }, { Qt::Key_Launch0, XKB_KEY_XF86MyComputer }, { Qt::Key_Launch1, XKB_KEY_XF86Calculator }, { Qt::Key_Memo, XKB_KEY_XF86Memo }, { Qt::Key_ToDoList, XKB_KEY_XF86ToDoList }, { Qt::Key_Calendar, XKB_KEY_XF86Calendar }, { Qt::Key_PowerDown, XKB_KEY_XF86PowerDown }, { Qt::Key_ContrastAdjust, XKB_KEY_XF86ContrastAdjust }, { Qt::Key_Standby, XKB_KEY_XF86Standby }, { Qt::Key_MonBrightnessUp, XKB_KEY_XF86MonBrightnessUp }, { Qt::Key_MonBrightnessDown, XKB_KEY_XF86MonBrightnessDown }, { Qt::Key_KeyboardLightOnOff, XKB_KEY_XF86KbdLightOnOff }, { Qt::Key_KeyboardBrightnessUp, XKB_KEY_XF86KbdBrightnessUp }, { Qt::Key_KeyboardBrightnessDown, XKB_KEY_XF86KbdBrightnessDown }, { Qt::Key_PowerOff, XKB_KEY_XF86PowerOff }, { Qt::Key_WakeUp, XKB_KEY_XF86WakeUp }, { Qt::Key_Eject, XKB_KEY_XF86Eject }, { Qt::Key_ScreenSaver, XKB_KEY_XF86ScreenSaver }, { Qt::Key_WWW, XKB_KEY_XF86WWW }, { Qt::Key_Sleep, XKB_KEY_XF86Sleep }, { Qt::Key_LightBulb, XKB_KEY_XF86LightBulb }, { Qt::Key_Shop, XKB_KEY_XF86Shop }, { Qt::Key_History, XKB_KEY_XF86History }, { Qt::Key_AddFavorite, XKB_KEY_XF86AddFavorite }, { Qt::Key_HotLinks, XKB_KEY_XF86HotLinks }, { Qt::Key_BrightnessAdjust, XKB_KEY_XF86BrightnessAdjust }, { Qt::Key_Finance, XKB_KEY_XF86Finance }, { Qt::Key_Community, XKB_KEY_XF86Community }, { Qt::Key_AudioRewind, XKB_KEY_XF86AudioRewind }, { Qt::Key_BackForward, XKB_KEY_XF86BackForward }, { Qt::Key_ApplicationLeft, XKB_KEY_XF86ApplicationLeft }, { Qt::Key_ApplicationRight, XKB_KEY_XF86ApplicationRight }, { Qt::Key_Book, XKB_KEY_XF86Book }, { Qt::Key_CD, XKB_KEY_XF86CD }, { Qt::Key_Calculator, XKB_KEY_XF86Calculater }, { Qt::Key_Clear, XKB_KEY_XF86Clear }, { Qt::Key_ClearGrab, XKB_KEY_XF86ClearGrab }, { Qt::Key_Close, XKB_KEY_XF86Close }, { Qt::Key_Copy, XKB_KEY_XF86Copy }, { Qt::Key_Cut, XKB_KEY_XF86Cut }, { Qt::Key_Display, XKB_KEY_XF86Display }, { Qt::Key_DOS, XKB_KEY_XF86DOS }, { Qt::Key_Documents, XKB_KEY_XF86Documents }, { Qt::Key_Excel, XKB_KEY_XF86Excel }, { Qt::Key_Explorer, XKB_KEY_XF86Explorer }, { Qt::Key_Game, XKB_KEY_XF86Game }, { Qt::Key_Go, XKB_KEY_XF86Go }, { Qt::Key_iTouch, XKB_KEY_XF86iTouch }, { Qt::Key_LogOff, XKB_KEY_XF86LogOff }, { Qt::Key_Market, XKB_KEY_XF86Market }, { Qt::Key_Meeting, XKB_KEY_XF86Meeting }, { Qt::Key_MenuKB, XKB_KEY_XF86MenuKB }, { Qt::Key_MenuPB, XKB_KEY_XF86MenuPB }, { Qt::Key_MySites, XKB_KEY_XF86MySites }, { Qt::Key_News, XKB_KEY_XF86News }, { Qt::Key_OfficeHome, XKB_KEY_XF86OfficeHome }, { Qt::Key_Option, XKB_KEY_XF86Option }, { Qt::Key_Paste, XKB_KEY_XF86Paste }, { Qt::Key_Phone, XKB_KEY_XF86Phone }, { Qt::Key_Reply, XKB_KEY_XF86Reply }, { Qt::Key_Reload, XKB_KEY_XF86Reload }, { Qt::Key_RotateWindows, XKB_KEY_XF86RotateWindows }, { Qt::Key_RotationPB, XKB_KEY_XF86RotationPB }, { Qt::Key_RotationKB, XKB_KEY_XF86RotationKB }, { Qt::Key_Save, XKB_KEY_XF86Save }, { Qt::Key_Send, XKB_KEY_XF86Send }, { Qt::Key_Spell, XKB_KEY_XF86Spell }, { Qt::Key_SplitScreen, XKB_KEY_XF86SplitScreen }, { Qt::Key_Support, XKB_KEY_XF86Support }, { Qt::Key_TaskPane, XKB_KEY_XF86TaskPane }, { Qt::Key_Terminal, XKB_KEY_XF86Terminal }, { Qt::Key_Tools, XKB_KEY_XF86Tools }, { Qt::Key_Travel, XKB_KEY_XF86Travel }, { Qt::Key_Video, XKB_KEY_XF86Video }, { Qt::Key_Word, XKB_KEY_XF86Word }, { Qt::Key_Xfer, XKB_KEY_XF86Xfer }, { Qt::Key_ZoomIn, XKB_KEY_XF86ZoomIn }, { Qt::Key_ZoomOut, XKB_KEY_XF86ZoomOut }, { Qt::Key_Away, XKB_KEY_XF86Away }, { Qt::Key_Messenger, XKB_KEY_XF86Messenger }, { Qt::Key_WebCam, XKB_KEY_XF86WebCam }, { Qt::Key_MailForward, XKB_KEY_XF86MailForward }, { Qt::Key_Pictures, XKB_KEY_XF86Pictures }, { Qt::Key_Music, XKB_KEY_XF86Music }, { Qt::Key_Battery, XKB_KEY_XF86Battery }, { Qt::Key_Bluetooth, XKB_KEY_XF86Bluetooth }, { Qt::Key_WLAN, XKB_KEY_XF86WLAN }, { Qt::Key_UWB, XKB_KEY_XF86UWB }, { Qt::Key_AudioForward, XKB_KEY_XF86AudioForward }, { Qt::Key_AudioRepeat, XKB_KEY_XF86AudioRepeat }, { Qt::Key_AudioRandomPlay, XKB_KEY_XF86AudioRandomPlay }, { Qt::Key_Subtitle, XKB_KEY_XF86Subtitle }, { Qt::Key_AudioCycleTrack, XKB_KEY_XF86AudioCycleTrack }, { Qt::Key_Time, XKB_KEY_XF86Time }, { Qt::Key_Select, XKB_KEY_XF86Select }, { Qt::Key_View, XKB_KEY_XF86View }, { Qt::Key_TopMenu, XKB_KEY_XF86TopMenu }, { Qt::Key_Bluetooth, XKB_KEY_XF86Bluetooth }, { Qt::Key_Suspend, XKB_KEY_XF86Suspend }, { Qt::Key_Hibernate, XKB_KEY_XF86Hibernate }, { Qt::Key_TouchpadToggle, XKB_KEY_XF86TouchpadToggle }, { Qt::Key_TouchpadOn, XKB_KEY_XF86TouchpadOn }, { Qt::Key_TouchpadOff, XKB_KEY_XF86TouchpadOff }, { Qt::Key_MicMute, XKB_KEY_XF86AudioMicMute }, { Qt::Key_Launch2, XKB_KEY_XF86Launch0 }, { Qt::Key_Launch3, XKB_KEY_XF86Launch1 }, { Qt::Key_Launch4, XKB_KEY_XF86Launch2 }, { Qt::Key_Launch5, XKB_KEY_XF86Launch3 }, { Qt::Key_Launch6, XKB_KEY_XF86Launch4 }, { Qt::Key_Launch7, XKB_KEY_XF86Launch5 }, { Qt::Key_Launch8, XKB_KEY_XF86Launch6 }, { Qt::Key_Launch9, XKB_KEY_XF86Launch7 }, { Qt::Key_LaunchA, XKB_KEY_XF86Launch8 }, { Qt::Key_LaunchB, XKB_KEY_XF86Launch9 }, { Qt::Key_LaunchC, XKB_KEY_XF86LaunchA }, { Qt::Key_LaunchD, XKB_KEY_XF86LaunchB }, { Qt::Key_LaunchE, XKB_KEY_XF86LaunchC }, { Qt::Key_LaunchF, XKB_KEY_XF86LaunchD }, /* * Latin 1 * (ISO/IEC 8859-1 = Unicode U+0020..U+00FF) * Byte 3 = 0 */ { Qt::Key_Exclam, XKB_KEY_exclam }, { Qt::Key_QuoteDbl, XKB_KEY_quotedbl }, { Qt::Key_NumberSign, XKB_KEY_numbersign }, { Qt::Key_Dollar, XKB_KEY_dollar }, { Qt::Key_Percent, XKB_KEY_percent }, { Qt::Key_Ampersand, XKB_KEY_ampersand }, { Qt::Key_Apostrophe, XKB_KEY_apostrophe }, { Qt::Key_ParenLeft, XKB_KEY_parenleft }, { Qt::Key_ParenRight, XKB_KEY_parenright }, { Qt::Key_Asterisk, XKB_KEY_asterisk }, { Qt::Key_Plus, XKB_KEY_plus }, { Qt::Key_Comma, XKB_KEY_comma }, { Qt::Key_Minus, XKB_KEY_minus }, { Qt::Key_Period, XKB_KEY_period }, { Qt::Key_Slash, XKB_KEY_slash }, { Qt::Key_0, XKB_KEY_0 }, { Qt::Key_1, XKB_KEY_1 }, { Qt::Key_2, XKB_KEY_2 }, { Qt::Key_3, XKB_KEY_3 }, { Qt::Key_4, XKB_KEY_4 }, { Qt::Key_5, XKB_KEY_5 }, { Qt::Key_6, XKB_KEY_6 }, { Qt::Key_7, XKB_KEY_7 }, { Qt::Key_8, XKB_KEY_8 }, { Qt::Key_9, XKB_KEY_9 }, { Qt::Key_Colon, XKB_KEY_colon }, { Qt::Key_Semicolon, XKB_KEY_semicolon }, { Qt::Key_Less, XKB_KEY_less }, { Qt::Key_Equal, XKB_KEY_equal }, { Qt::Key_Greater, XKB_KEY_greater }, { Qt::Key_Question, XKB_KEY_question }, { Qt::Key_At, XKB_KEY_at }, { Qt::Key_A, XKB_KEY_A }, { Qt::Key_B, XKB_KEY_B }, { Qt::Key_C, XKB_KEY_C }, { Qt::Key_D, XKB_KEY_D }, { Qt::Key_E, XKB_KEY_E }, { Qt::Key_F, XKB_KEY_F }, { Qt::Key_G, XKB_KEY_G }, { Qt::Key_H, XKB_KEY_H }, { Qt::Key_I, XKB_KEY_I }, { Qt::Key_J, XKB_KEY_J }, { Qt::Key_K, XKB_KEY_K }, { Qt::Key_L, XKB_KEY_L }, { Qt::Key_M, XKB_KEY_M }, { Qt::Key_N, XKB_KEY_N }, { Qt::Key_O, XKB_KEY_O }, { Qt::Key_P, XKB_KEY_P }, { Qt::Key_Q, XKB_KEY_Q }, { Qt::Key_R, XKB_KEY_R }, { Qt::Key_S, XKB_KEY_S }, { Qt::Key_T, XKB_KEY_T }, { Qt::Key_U, XKB_KEY_U }, { Qt::Key_V, XKB_KEY_V }, { Qt::Key_W, XKB_KEY_W }, { Qt::Key_X, XKB_KEY_X }, { Qt::Key_Y, XKB_KEY_Y }, { Qt::Key_Z, XKB_KEY_Z }, { Qt::Key_BracketLeft, XKB_KEY_bracketleft }, { Qt::Key_Backslash, XKB_KEY_backslash }, { Qt::Key_BracketRight, XKB_KEY_bracketright}, { Qt::Key_AsciiCircum, XKB_KEY_asciicircum }, { Qt::Key_Underscore, XKB_KEY_underscore }, { Qt::Key_QuoteLeft, XKB_KEY_quoteleft }, { Qt::Key_A, XKB_KEY_a }, { Qt::Key_B, XKB_KEY_b }, { Qt::Key_C, XKB_KEY_c }, { Qt::Key_D, XKB_KEY_d }, { Qt::Key_E, XKB_KEY_e }, { Qt::Key_F, XKB_KEY_f }, { Qt::Key_G, XKB_KEY_g }, { Qt::Key_H, XKB_KEY_h }, { Qt::Key_I, XKB_KEY_i }, { Qt::Key_J, XKB_KEY_j }, { Qt::Key_K, XKB_KEY_k }, { Qt::Key_L, XKB_KEY_l }, { Qt::Key_M, XKB_KEY_m }, { Qt::Key_N, XKB_KEY_n }, { Qt::Key_O, XKB_KEY_o }, { Qt::Key_P, XKB_KEY_p }, { Qt::Key_Q, XKB_KEY_q }, { Qt::Key_R, XKB_KEY_r }, { Qt::Key_S, XKB_KEY_s }, { Qt::Key_T, XKB_KEY_t }, { Qt::Key_U, XKB_KEY_u }, { Qt::Key_V, XKB_KEY_v }, { Qt::Key_W, XKB_KEY_w }, { Qt::Key_X, XKB_KEY_x }, { Qt::Key_Y, XKB_KEY_y }, { Qt::Key_Z, XKB_KEY_z }, { Qt::Key_BraceLeft, XKB_KEY_braceleft }, { Qt::Key_Bar, XKB_KEY_bar }, { Qt::Key_BraceRight, XKB_KEY_braceright }, { Qt::Key_AsciiTilde, XKB_KEY_asciitilde }, { Qt::Key_nobreakspace, XKB_KEY_nobreakspace }, { Qt::Key_exclamdown, XKB_KEY_exclamdown }, { Qt::Key_cent, XKB_KEY_cent }, { Qt::Key_sterling, XKB_KEY_sterling }, { Qt::Key_currency, XKB_KEY_currency }, { Qt::Key_yen, XKB_KEY_yen }, { Qt::Key_brokenbar, XKB_KEY_brokenbar }, { Qt::Key_section, XKB_KEY_section }, { Qt::Key_diaeresis, XKB_KEY_diaeresis }, { Qt::Key_copyright, XKB_KEY_copyright }, { Qt::Key_ordfeminine, XKB_KEY_ordfeminine }, { Qt::Key_guillemotleft, XKB_KEY_guillemotleft }, { Qt::Key_notsign, XKB_KEY_notsign }, { Qt::Key_hyphen, XKB_KEY_hyphen }, { Qt::Key_registered, XKB_KEY_registered }, { Qt::Key_macron, XKB_KEY_macron }, { Qt::Key_degree, XKB_KEY_degree }, { Qt::Key_plusminus, XKB_KEY_plusminus }, { Qt::Key_twosuperior, XKB_KEY_twosuperior }, { Qt::Key_threesuperior, XKB_KEY_threesuperior }, { Qt::Key_acute, XKB_KEY_acute }, { Qt::Key_mu, XKB_KEY_mu }, { Qt::Key_paragraph, XKB_KEY_paragraph }, { Qt::Key_periodcentered, XKB_KEY_periodcentered }, { Qt::Key_cedilla, XKB_KEY_cedilla }, { Qt::Key_onesuperior, XKB_KEY_onesuperior }, { Qt::Key_masculine, XKB_KEY_masculine }, { Qt::Key_guillemotright, XKB_KEY_guillemotright }, { Qt::Key_onequarter, XKB_KEY_onequarter }, { Qt::Key_onehalf, XKB_KEY_onehalf }, { Qt::Key_threequarters, XKB_KEY_threequarters }, { Qt::Key_questiondown, XKB_KEY_questiondown }, { Qt::Key_Agrave, XKB_KEY_Agrave }, { Qt::Key_Aacute, XKB_KEY_Aacute }, { Qt::Key_Acircumflex, XKB_KEY_Acircumflex }, { Qt::Key_Atilde, XKB_KEY_Atilde }, { Qt::Key_Adiaeresis, XKB_KEY_Adiaeresis }, { Qt::Key_Aring, XKB_KEY_Aring }, { Qt::Key_AE, XKB_KEY_AE }, { Qt::Key_Ccedilla, XKB_KEY_Ccedilla }, { Qt::Key_Egrave, XKB_KEY_Egrave }, { Qt::Key_Eacute, XKB_KEY_Eacute }, { Qt::Key_Ecircumflex, XKB_KEY_Ecircumflex }, { Qt::Key_Ediaeresis, XKB_KEY_Ediaeresis }, { Qt::Key_Igrave, XKB_KEY_Igrave }, { Qt::Key_Iacute, XKB_KEY_Iacute }, { Qt::Key_Icircumflex, XKB_KEY_Icircumflex }, { Qt::Key_Idiaeresis, XKB_KEY_Idiaeresis }, { Qt::Key_ETH, XKB_KEY_ETH }, { Qt::Key_Ntilde, XKB_KEY_Ntilde }, { Qt::Key_Ograve, XKB_KEY_Ograve }, { Qt::Key_Oacute, XKB_KEY_Oacute }, { Qt::Key_Ocircumflex, XKB_KEY_Ocircumflex }, { Qt::Key_Otilde, XKB_KEY_Otilde }, { Qt::Key_Odiaeresis, XKB_KEY_Odiaeresis }, { Qt::Key_multiply, XKB_KEY_multiply }, { Qt::Key_Ooblique, XKB_KEY_Ooblique }, { Qt::Key_Ugrave, XKB_KEY_Ugrave }, { Qt::Key_Uacute, XKB_KEY_Uacute }, { Qt::Key_Ucircumflex, XKB_KEY_Ucircumflex }, { Qt::Key_Udiaeresis, XKB_KEY_Udiaeresis }, { Qt::Key_Yacute, XKB_KEY_Yacute }, { Qt::Key_THORN, XKB_KEY_THORN }, { Qt::Key_ssharp, XKB_KEY_ssharp }, { Qt::Key_Agrave, XKB_KEY_agrave }, { Qt::Key_Aacute, XKB_KEY_aacute }, { Qt::Key_Acircumflex, XKB_KEY_acircumflex }, { Qt::Key_Atilde, XKB_KEY_atilde }, { Qt::Key_Adiaeresis, XKB_KEY_adiaeresis }, { Qt::Key_Aring, XKB_KEY_aring }, { Qt::Key_AE, XKB_KEY_ae }, { Qt::Key_Ccedilla, XKB_KEY_ccedilla }, { Qt::Key_Egrave, XKB_KEY_egrave }, { Qt::Key_Eacute, XKB_KEY_eacute }, { Qt::Key_Ecircumflex, XKB_KEY_ecircumflex }, { Qt::Key_Ediaeresis, XKB_KEY_ediaeresis }, { Qt::Key_Igrave, XKB_KEY_igrave }, { Qt::Key_Iacute, XKB_KEY_iacute }, { Qt::Key_Icircumflex, XKB_KEY_icircumflex }, { Qt::Key_Idiaeresis, XKB_KEY_idiaeresis }, { Qt::Key_ETH, XKB_KEY_eth }, { Qt::Key_Ntilde, XKB_KEY_ntilde }, { Qt::Key_Ograve, XKB_KEY_ograve }, { Qt::Key_Oacute, XKB_KEY_oacute }, { Qt::Key_Ocircumflex, XKB_KEY_ocircumflex }, { Qt::Key_Otilde, XKB_KEY_otilde }, { Qt::Key_Odiaeresis, XKB_KEY_odiaeresis }, { Qt::Key_division, XKB_KEY_division }, { Qt::Key_Ooblique, XKB_KEY_ooblique }, { Qt::Key_Ugrave, XKB_KEY_ugrave }, { Qt::Key_Uacute, XKB_KEY_uacute }, { Qt::Key_Ucircumflex, XKB_KEY_ucircumflex }, { Qt::Key_Udiaeresis, XKB_KEY_udiaeresis }, { Qt::Key_Yacute, XKB_KEY_yacute }, { Qt::Key_THORN, XKB_KEY_thorn }, { Qt::Key_ydiaeresis, XKB_KEY_ydiaeresis }, /* * Numpad **/ { Qt::Key_0, XKB_KEY_KP_0}, { Qt::Key_1, XKB_KEY_KP_1}, { Qt::Key_2, XKB_KEY_KP_2}, { Qt::Key_3, XKB_KEY_KP_3}, { Qt::Key_4, XKB_KEY_KP_4}, { Qt::Key_5, XKB_KEY_KP_5}, { Qt::Key_6, XKB_KEY_KP_6}, { Qt::Key_7, XKB_KEY_KP_7}, { Qt::Key_8, XKB_KEY_KP_8}, { Qt::Key_9, XKB_KEY_KP_9} }; void XkbTest::testToQtKey_data() { QTest::addColumn("qt"); QTest::addColumn("keySym"); for (std::size_t i = 0; i < sizeof(g_rgQtToSymX) / sizeof(TransKey); i++) { const QByteArray row = QByteArray::number(g_rgQtToSymX[i].keySymX, 16); QTest::newRow(row.constData()) << g_rgQtToSymX[i].keySymQt << g_rgQtToSymX[i].keySymX; } } void XkbTest::testToQtKey() { Xkb xkb; QFETCH(xkb_keysym_t, keySym); - QEXPECT_FAIL("e0", "Incorrectly mapped by KKeyServer", Continue); - QEXPECT_FAIL("e1", "Incorrectly mapped by KKeyServer", Continue); - QEXPECT_FAIL("e2", "Incorrectly mapped by KKeyServer", Continue); - QEXPECT_FAIL("e3", "Incorrectly mapped by KKeyServer", Continue); - QEXPECT_FAIL("e4", "Incorrectly mapped by KKeyServer", Continue); - QEXPECT_FAIL("e5", "Incorrectly mapped by KKeyServer", Continue); - QEXPECT_FAIL("e6", "Incorrectly mapped by KKeyServer", Continue); - QEXPECT_FAIL("e7", "Incorrectly mapped by KKeyServer", Continue); - QEXPECT_FAIL("e8", "Incorrectly mapped by KKeyServer", Continue); - QEXPECT_FAIL("e9", "Incorrectly mapped by KKeyServer", Continue); - QEXPECT_FAIL("ea", "Incorrectly mapped by KKeyServer", Continue); - QEXPECT_FAIL("eb", "Incorrectly mapped by KKeyServer", Continue); - QEXPECT_FAIL("ec", "Incorrectly mapped by KKeyServer", Continue); - QEXPECT_FAIL("ed", "Incorrectly mapped by KKeyServer", Continue); - QEXPECT_FAIL("ee", "Incorrectly mapped by KKeyServer", Continue); - QEXPECT_FAIL("ef", "Incorrectly mapped by KKeyServer", Continue); - QEXPECT_FAIL("f0", "Incorrectly mapped by KKeyServer", Continue); - QEXPECT_FAIL("f1", "Incorrectly mapped by KKeyServer", Continue); - QEXPECT_FAIL("f2", "Incorrectly mapped by KKeyServer", Continue); - QEXPECT_FAIL("f3", "Incorrectly mapped by KKeyServer", Continue); - QEXPECT_FAIL("f4", "Incorrectly mapped by KKeyServer", Continue); - QEXPECT_FAIL("f5", "Incorrectly mapped by KKeyServer", Continue); - QEXPECT_FAIL("f6", "Incorrectly mapped by KKeyServer", Continue); - QEXPECT_FAIL("f8", "Incorrectly mapped by KKeyServer", Continue); - QEXPECT_FAIL("f9", "Incorrectly mapped by KKeyServer", Continue); - QEXPECT_FAIL("fa", "Incorrectly mapped by KKeyServer", Continue); - QEXPECT_FAIL("fb", "Incorrectly mapped by KKeyServer", Continue); - QEXPECT_FAIL("fc", "Incorrectly mapped by KKeyServer", Continue); - QEXPECT_FAIL("fd", "Incorrectly mapped by KKeyServer", Continue); - QEXPECT_FAIL("fe", "Incorrectly mapped by KKeyServer", Continue); QTEST(xkb.toQtKey(keySym), "qt"); } QTEST_MAIN(XkbTest) #include "test_xkb.moc" diff --git a/xkb.cpp b/xkb.cpp index c8b2fe0b0..9612930c5 100644 --- a/xkb.cpp +++ b/xkb.cpp @@ -1,509 +1,504 @@ /******************************************************************** KWin - the KDE window manager This file is part of the KDE project. Copyright (C) 2013, 2016, 2017 Martin Gräßlin This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . *********************************************************************/ #include "xkb.h" +#include "xkb_qt_mapping.h" #include "utils.h" // frameworks #include -#include // KWayland #include // Qt #include // xkbcommon #include #include #include // system #include #include Q_LOGGING_CATEGORY(KWIN_XKB, "kwin_xkbcommon", QtCriticalMsg) namespace KWin { static void xkbLogHandler(xkb_context *context, xkb_log_level priority, const char *format, va_list args) { Q_UNUSED(context) char buf[1024]; if (std::vsnprintf(buf, 1023, format, args) <= 0) { return; } switch (priority) { case XKB_LOG_LEVEL_DEBUG: qCDebug(KWIN_XKB) << "XKB:" << buf; break; case XKB_LOG_LEVEL_INFO: qCInfo(KWIN_XKB) << "XKB:" << buf; break; case XKB_LOG_LEVEL_WARNING: qCWarning(KWIN_XKB) << "XKB:" << buf; break; case XKB_LOG_LEVEL_ERROR: case XKB_LOG_LEVEL_CRITICAL: default: qCCritical(KWIN_XKB) << "XKB:" << buf; break; } } Xkb::Xkb(QObject *parent) : QObject(parent) , m_context(xkb_context_new(static_cast(0))) , m_keymap(NULL) , m_state(NULL) , m_shiftModifier(0) , m_capsModifier(0) , m_controlModifier(0) , m_altModifier(0) , m_metaModifier(0) , m_numLock(0) , m_capsLock(0) , m_scrollLock(0) , m_modifiers(Qt::NoModifier) , m_consumedModifiers(Qt::NoModifier) , m_keysym(XKB_KEY_NoSymbol) , m_leds() { qRegisterMetaType(); if (!m_context) { qCDebug(KWIN_XKB) << "Could not create xkb context"; } else { xkb_context_set_log_level(m_context, XKB_LOG_LEVEL_DEBUG); xkb_context_set_log_fn(m_context, &xkbLogHandler); // get locale as described in xkbcommon doc // cannot use QLocale as it drops the modifier part QByteArray locale = qgetenv("LC_ALL"); if (locale.isEmpty()) { locale = qgetenv("LC_CTYPE"); } if (locale.isEmpty()) { locale = qgetenv("LANG"); } if (locale.isEmpty()) { locale = QByteArrayLiteral("C"); } m_compose.table = xkb_compose_table_new_from_locale(m_context, locale.constData(), XKB_COMPOSE_COMPILE_NO_FLAGS); if (m_compose.table) { m_compose.state = xkb_compose_state_new(m_compose.table, XKB_COMPOSE_STATE_NO_FLAGS); } } } Xkb::~Xkb() { xkb_compose_state_unref(m_compose.state); xkb_compose_table_unref(m_compose.table); xkb_state_unref(m_state); xkb_keymap_unref(m_keymap); xkb_context_unref(m_context); } void Xkb::reconfigure() { if (!m_context) { return; } xkb_keymap *keymap = nullptr; if (!qEnvironmentVariableIsSet("KWIN_XKB_DEFAULT_KEYMAP")) { keymap = loadKeymapFromConfig(); } if (!keymap) { qCDebug(KWIN_XKB) << "Could not create xkb keymap from configuration"; keymap = loadDefaultKeymap(); } if (keymap) { updateKeymap(keymap); } else { qCDebug(KWIN_XKB) << "Could not create default xkb keymap"; } } xkb_keymap *Xkb::loadKeymapFromConfig() { // load config if (!m_config) { return nullptr; } const KConfigGroup config = m_config->group("Layout"); const QByteArray model = config.readEntry("Model", "pc104").toLocal8Bit(); const QByteArray layout = config.readEntry("LayoutList", "").toLocal8Bit(); const QByteArray options = config.readEntry("Options", "").toLocal8Bit(); xkb_rule_names ruleNames = { .rules = nullptr, .model = model.constData(), .layout = layout.constData(), .variant = nullptr, .options = options.constData() }; return xkb_keymap_new_from_names(m_context, &ruleNames, XKB_KEYMAP_COMPILE_NO_FLAGS); } xkb_keymap *Xkb::loadDefaultKeymap() { return xkb_keymap_new_from_names(m_context, nullptr, XKB_KEYMAP_COMPILE_NO_FLAGS); } void Xkb::installKeymap(int fd, uint32_t size) { if (!m_context) { return; } char *map = reinterpret_cast(mmap(NULL, size, PROT_READ, MAP_SHARED, fd, 0)); if (map == MAP_FAILED) { return; } xkb_keymap *keymap = xkb_keymap_new_from_string(m_context, map, XKB_KEYMAP_FORMAT_TEXT_V1, XKB_MAP_COMPILE_PLACEHOLDER); munmap(map, size); if (!keymap) { qCDebug(KWIN_XKB) << "Could not map keymap from file"; return; } updateKeymap(keymap); } void Xkb::updateKeymap(xkb_keymap *keymap) { Q_ASSERT(keymap); xkb_state *state = xkb_state_new(keymap); if (!state) { qCDebug(KWIN_XKB) << "Could not create XKB state"; xkb_keymap_unref(keymap); return; } // now release the old ones xkb_state_unref(m_state); xkb_keymap_unref(m_keymap); m_keymap = keymap; m_state = state; m_shiftModifier = xkb_keymap_mod_get_index(m_keymap, XKB_MOD_NAME_SHIFT); m_capsModifier = xkb_keymap_mod_get_index(m_keymap, XKB_MOD_NAME_CAPS); m_controlModifier = xkb_keymap_mod_get_index(m_keymap, XKB_MOD_NAME_CTRL); m_altModifier = xkb_keymap_mod_get_index(m_keymap, XKB_MOD_NAME_ALT); m_metaModifier = xkb_keymap_mod_get_index(m_keymap, XKB_MOD_NAME_LOGO); m_numLock = xkb_keymap_led_get_index(m_keymap, XKB_LED_NAME_NUM); m_capsLock = xkb_keymap_led_get_index(m_keymap, XKB_LED_NAME_CAPS); m_scrollLock = xkb_keymap_led_get_index(m_keymap, XKB_LED_NAME_SCROLL); m_currentLayout = xkb_state_serialize_layout(m_state, XKB_STATE_LAYOUT_EFFECTIVE); m_modifierState.depressed = xkb_state_serialize_mods(m_state, xkb_state_component(XKB_STATE_MODS_DEPRESSED)); m_modifierState.latched = xkb_state_serialize_mods(m_state, xkb_state_component(XKB_STATE_MODS_LATCHED)); m_modifierState.locked = xkb_state_serialize_mods(m_state, xkb_state_component(XKB_STATE_MODS_LOCKED)); createKeymapFile(); forwardModifiers(); } void Xkb::createKeymapFile() { if (!m_seat) { return; } // TODO: uninstall keymap on server? if (!m_keymap) { return; } ScopedCPointer keymapString(xkb_keymap_get_as_string(m_keymap, XKB_KEYMAP_FORMAT_TEXT_V1)); if (keymapString.isNull()) { return; } const uint size = qstrlen(keymapString.data()) + 1; QTemporaryFile *tmp = new QTemporaryFile(this); if (!tmp->open()) { delete tmp; return; } unlink(tmp->fileName().toUtf8().constData()); if (!tmp->resize(size)) { delete tmp; return; } uchar *address = tmp->map(0, size); if (!address) { return; } if (qstrncpy(reinterpret_cast(address), keymapString.data(), size) == nullptr) { delete tmp; return; } m_seat->setKeymap(tmp->handle(), size); } void Xkb::updateModifiers(uint32_t modsDepressed, uint32_t modsLatched, uint32_t modsLocked, uint32_t group) { if (!m_keymap || !m_state) { return; } xkb_state_update_mask(m_state, modsDepressed, modsLatched, modsLocked, 0, 0, group); updateModifiers(); forwardModifiers(); } void Xkb::updateKey(uint32_t key, InputRedirection::KeyboardKeyState state) { if (!m_keymap || !m_state) { return; } xkb_state_update_key(m_state, key + 8, static_cast(state)); if (state == InputRedirection::KeyboardKeyPressed) { const auto sym = toKeysym(key); if (m_compose.state && xkb_compose_state_feed(m_compose.state, sym) == XKB_COMPOSE_FEED_ACCEPTED) { switch (xkb_compose_state_get_status(m_compose.state)) { case XKB_COMPOSE_NOTHING: m_keysym = sym; break; case XKB_COMPOSE_COMPOSED: m_keysym = xkb_compose_state_get_one_sym(m_compose.state); break; default: m_keysym = XKB_KEY_NoSymbol; break; } } else { m_keysym = sym; } } updateModifiers(); updateConsumedModifiers(key); } void Xkb::updateModifiers() { Qt::KeyboardModifiers mods = Qt::NoModifier; if (xkb_state_mod_index_is_active(m_state, m_shiftModifier, XKB_STATE_MODS_EFFECTIVE) == 1 || xkb_state_mod_index_is_active(m_state, m_capsModifier, XKB_STATE_MODS_EFFECTIVE) == 1) { mods |= Qt::ShiftModifier; } if (xkb_state_mod_index_is_active(m_state, m_altModifier, XKB_STATE_MODS_EFFECTIVE) == 1) { mods |= Qt::AltModifier; } if (xkb_state_mod_index_is_active(m_state, m_controlModifier, XKB_STATE_MODS_EFFECTIVE) == 1) { mods |= Qt::ControlModifier; } if (xkb_state_mod_index_is_active(m_state, m_metaModifier, XKB_STATE_MODS_EFFECTIVE) == 1) { mods |= Qt::MetaModifier; } m_modifiers = mods; // update LEDs LEDs leds; if (xkb_state_led_index_is_active(m_state, m_numLock) == 1) { leds = leds | LED::NumLock; } if (xkb_state_led_index_is_active(m_state, m_capsLock) == 1) { leds = leds | LED::CapsLock; } if (xkb_state_led_index_is_active(m_state, m_scrollLock) == 1) { leds = leds | LED::ScrollLock; } if (m_leds != leds) { m_leds = leds; emit ledsChanged(m_leds); } m_currentLayout = xkb_state_serialize_layout(m_state, XKB_STATE_LAYOUT_EFFECTIVE); m_modifierState.depressed = xkb_state_serialize_mods(m_state, xkb_state_component(XKB_STATE_MODS_DEPRESSED)); m_modifierState.latched = xkb_state_serialize_mods(m_state, xkb_state_component(XKB_STATE_MODS_LATCHED)); m_modifierState.locked = xkb_state_serialize_mods(m_state, xkb_state_component(XKB_STATE_MODS_LOCKED)); } void Xkb::forwardModifiers() { if (!m_seat) { return; } m_seat->updateKeyboardModifiers(m_modifierState.depressed, m_modifierState.latched, m_modifierState.locked, m_currentLayout); } QString Xkb::layoutName() const { return layoutName(m_currentLayout); } QString Xkb::layoutName(xkb_layout_index_t layout) const { if (!m_keymap) { return QString{}; } return QString::fromLocal8Bit(xkb_keymap_layout_get_name(m_keymap, layout)); } QMap Xkb::layoutNames() const { QMap layouts; const auto size = m_keymap ? xkb_keymap_num_layouts(m_keymap) : 0u; for (xkb_layout_index_t i = 0; i < size; i++) { layouts.insert(i, layoutName(i)); } return layouts; } void Xkb::updateConsumedModifiers(uint32_t key) { Qt::KeyboardModifiers mods = Qt::NoModifier; if (xkb_state_mod_index_is_consumed2(m_state, key + 8, m_shiftModifier, XKB_CONSUMED_MODE_GTK) == 1) { mods |= Qt::ShiftModifier; } if (xkb_state_mod_index_is_consumed2(m_state, key + 8, m_altModifier, XKB_CONSUMED_MODE_GTK) == 1) { mods |= Qt::AltModifier; } if (xkb_state_mod_index_is_consumed2(m_state, key + 8, m_controlModifier, XKB_CONSUMED_MODE_GTK) == 1) { mods |= Qt::ControlModifier; } if (xkb_state_mod_index_is_consumed2(m_state, key + 8, m_metaModifier, XKB_CONSUMED_MODE_GTK) == 1) { mods |= Qt::MetaModifier; } m_consumedModifiers = mods; } Qt::KeyboardModifiers Xkb::modifiersRelevantForGlobalShortcuts() const { if (!m_state) { return Qt::NoModifier; } Qt::KeyboardModifiers mods = Qt::NoModifier; if (xkb_state_mod_index_is_active(m_state, m_shiftModifier, XKB_STATE_MODS_EFFECTIVE) == 1) { mods |= Qt::ShiftModifier; } if (xkb_state_mod_index_is_active(m_state, m_altModifier, XKB_STATE_MODS_EFFECTIVE) == 1) { mods |= Qt::AltModifier; } if (xkb_state_mod_index_is_active(m_state, m_controlModifier, XKB_STATE_MODS_EFFECTIVE) == 1) { mods |= Qt::ControlModifier; } if (xkb_state_mod_index_is_active(m_state, m_metaModifier, XKB_STATE_MODS_EFFECTIVE) == 1) { mods |= Qt::MetaModifier; } Qt::KeyboardModifiers consumedMods = m_consumedModifiers; if ((mods & Qt::ShiftModifier) && (consumedMods == Qt::ShiftModifier)) { // test whether current keysym is a letter // in that case the shift should be removed from the consumed modifiers again // otherwise it would not be possible to trigger e.g. Shift+W as a shortcut // see BUG: 370341 if (QChar(toQtKey(m_keysym)).isLetter()) { consumedMods = Qt::KeyboardModifiers(); } } return mods & ~consumedMods; } xkb_keysym_t Xkb::toKeysym(uint32_t key) { if (!m_state) { return XKB_KEY_NoSymbol; } return xkb_state_key_get_one_sym(m_state, key + 8); } QString Xkb::toString(xkb_keysym_t keysym) { if (!m_state || keysym == XKB_KEY_NoSymbol) { return QString(); } QByteArray byteArray(7, 0); int ok = xkb_keysym_to_utf8(keysym, byteArray.data(), byteArray.size()); if (ok == -1 || ok == 0) { return QString(); } return QString::fromUtf8(byteArray.constData()); } Qt::Key Xkb::toQtKey(xkb_keysym_t keysym) const { - int key = Qt::Key_unknown; - KKeyServer::symXToKeyQt(keysym, &key); - if (key & Qt::KeyboardModifierMask) { - key &= ~Qt::KeyboardModifierMask; - } - return static_cast(key); + return xkbToQtKey(keysym); } bool Xkb::shouldKeyRepeat(quint32 key) const { if (!m_keymap) { return false; } return xkb_keymap_key_repeats(m_keymap, key + 8) != 0; } void Xkb::switchToNextLayout() { if (!m_keymap || !m_state) { return; } const xkb_layout_index_t numLayouts = xkb_keymap_num_layouts(m_keymap); const xkb_layout_index_t nextLayout = (xkb_state_serialize_layout(m_state, XKB_STATE_LAYOUT_EFFECTIVE) + 1) % numLayouts; switchToLayout(nextLayout); } void Xkb::switchToPreviousLayout() { if (!m_keymap || !m_state) { return; } const xkb_layout_index_t previousLayout = m_currentLayout == 0 ? numberOfLayouts() - 1 : m_currentLayout -1; switchToLayout(previousLayout); } void Xkb::switchToLayout(xkb_layout_index_t layout) { if (!m_keymap || !m_state) { return; } if (layout >= numberOfLayouts()) { return; } const xkb_mod_mask_t depressed = xkb_state_serialize_mods(m_state, xkb_state_component(XKB_STATE_MODS_DEPRESSED)); const xkb_mod_mask_t latched = xkb_state_serialize_mods(m_state, xkb_state_component(XKB_STATE_MODS_LATCHED)); const xkb_mod_mask_t locked = xkb_state_serialize_mods(m_state, xkb_state_component(XKB_STATE_MODS_LOCKED)); xkb_state_update_mask(m_state, depressed, latched, locked, 0, 0, layout); updateModifiers(); forwardModifiers(); } quint32 Xkb::numberOfLayouts() const { if (!m_keymap) { return 0; } return xkb_keymap_num_layouts(m_keymap); } void Xkb::setSeat(KWayland::Server::SeatInterface *seat) { m_seat = QPointer(seat); } } diff --git a/xkb_qt_mapping.h b/xkb_qt_mapping.h new file mode 100644 index 000000000..17f019793 --- /dev/null +++ b/xkb_qt_mapping.h @@ -0,0 +1,278 @@ +/******************************************************************** + KWin - the KDE window manager + This file is part of the KDE project. + +Copyright (C) 2017 Martin Flöser + +This program is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2 of the License, or +(at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program. If not, see . +*********************************************************************/ +#ifndef KWIN_XKB_QT_MAPPING_H +#define KWIN_XKB_QT_MAPPING_H + +#include + +#include +#include + +namespace KWin +{ + +// based on mapping in kwindowsystem/src/platforms/xcb/kkeyserver.cpp +// adjusted to XKB +static const std::map s_mapping{ + { XKB_KEY_Escape, Qt::Key_Escape }, + { XKB_KEY_Tab, Qt::Key_Tab }, + { XKB_KEY_ISO_Left_Tab, Qt::Key_Backtab }, + { XKB_KEY_BackSpace, Qt::Key_Backspace }, + { XKB_KEY_Return, Qt::Key_Return }, + { XKB_KEY_Insert, Qt::Key_Insert }, + { XKB_KEY_Delete, Qt::Key_Delete }, + { XKB_KEY_Pause, Qt::Key_Pause }, + { XKB_KEY_Print, Qt::Key_Print }, + { XKB_KEY_Sys_Req, Qt::Key_SysReq }, + { XKB_KEY_Home, Qt::Key_Home }, + { XKB_KEY_End, Qt::Key_End }, + { XKB_KEY_Left, Qt::Key_Left }, + { XKB_KEY_Up, Qt::Key_Up }, + { XKB_KEY_Right, Qt::Key_Right }, + { XKB_KEY_Down, Qt::Key_Down }, + { XKB_KEY_Prior, Qt::Key_PageUp }, + { XKB_KEY_Next, Qt::Key_PageDown }, + { XKB_KEY_Caps_Lock, Qt::Key_CapsLock }, + { XKB_KEY_Num_Lock, Qt::Key_NumLock }, + { XKB_KEY_Scroll_Lock, Qt::Key_ScrollLock }, + { XKB_KEY_F1, Qt::Key_F1 }, + { XKB_KEY_F2, Qt::Key_F2 }, + { XKB_KEY_F3, Qt::Key_F3 }, + { XKB_KEY_F4, Qt::Key_F4 }, + { XKB_KEY_F5, Qt::Key_F5 }, + { XKB_KEY_F6, Qt::Key_F6 }, + { XKB_KEY_F7, Qt::Key_F7 }, + { XKB_KEY_F8, Qt::Key_F8 }, + { XKB_KEY_F9, Qt::Key_F9 }, + { XKB_KEY_F10, Qt::Key_F10 }, + { XKB_KEY_F11, Qt::Key_F11 }, + { XKB_KEY_F12, Qt::Key_F12 }, + { XKB_KEY_F13, Qt::Key_F13 }, + { XKB_KEY_F14, Qt::Key_F14 }, + { XKB_KEY_F15, Qt::Key_F15 }, + { XKB_KEY_F16, Qt::Key_F16 }, + { XKB_KEY_F17, Qt::Key_F17 }, + { XKB_KEY_F18, Qt::Key_F18 }, + { XKB_KEY_F19, Qt::Key_F19 }, + { XKB_KEY_F20, Qt::Key_F20 }, + { XKB_KEY_F21, Qt::Key_F21 }, + { XKB_KEY_F22, Qt::Key_F22 }, + { XKB_KEY_F23, Qt::Key_F23 }, + { XKB_KEY_F24, Qt::Key_F24 }, + { XKB_KEY_F25, Qt::Key_F25 }, + { XKB_KEY_F26, Qt::Key_F26 }, + { XKB_KEY_F27, Qt::Key_F27 }, + { XKB_KEY_F28, Qt::Key_F28 }, + { XKB_KEY_F29, Qt::Key_F29 }, + { XKB_KEY_F30, Qt::Key_F30 }, + { XKB_KEY_F31, Qt::Key_F31 }, + { XKB_KEY_F32, Qt::Key_F32 }, + { XKB_KEY_F33, Qt::Key_F33 }, + { XKB_KEY_F34, Qt::Key_F34 }, + { XKB_KEY_F35, Qt::Key_F35 }, + { XKB_KEY_Super_L, Qt::Key_Super_L }, + { XKB_KEY_Super_R, Qt::Key_Super_R }, + { XKB_KEY_Menu, Qt::Key_Menu }, + { XKB_KEY_Hyper_L, Qt::Key_Hyper_L }, + { XKB_KEY_Hyper_R, Qt::Key_Hyper_R }, + { XKB_KEY_Help, Qt::Key_Help }, + { XKB_KEY_KP_Space, Qt::Key_Space }, + { XKB_KEY_KP_Tab, Qt::Key_Tab }, + { XKB_KEY_KP_Enter, Qt::Key_Enter }, + { XKB_KEY_KP_Home, Qt::Key_Home }, + { XKB_KEY_KP_Left, Qt::Key_Left }, + { XKB_KEY_KP_Up, Qt::Key_Up }, + { XKB_KEY_KP_Right, Qt::Key_Right }, + { XKB_KEY_KP_Down, Qt::Key_Down }, + { XKB_KEY_KP_Prior, Qt::Key_PageUp }, + { XKB_KEY_KP_Next, Qt::Key_PageDown }, + { XKB_KEY_KP_End, Qt::Key_End }, + { XKB_KEY_KP_Begin, Qt::Key_Clear }, + { XKB_KEY_KP_Insert, Qt::Key_Insert }, + { XKB_KEY_KP_Delete, Qt::Key_Delete }, + { XKB_KEY_KP_Equal, Qt::Key_Equal }, + { XKB_KEY_KP_Multiply, Qt::Key_Asterisk }, + { XKB_KEY_KP_Add, Qt::Key_Plus }, + { XKB_KEY_KP_Separator, Qt::Key_Comma }, + { XKB_KEY_KP_Subtract, Qt::Key_Minus }, + { XKB_KEY_KP_Decimal, Qt::Key_Period }, + { XKB_KEY_KP_Divide, Qt::Key_Slash }, + { XKB_KEY_XF86Back, Qt::Key_Back }, + { XKB_KEY_XF86Forward, Qt::Key_Forward }, + { XKB_KEY_XF86Stop, Qt::Key_Stop }, + { XKB_KEY_XF86Refresh, Qt::Key_Refresh }, + { XKB_KEY_XF86Favorites, Qt::Key_Favorites }, + { XKB_KEY_XF86AudioMedia, Qt::Key_LaunchMedia }, + { XKB_KEY_XF86OpenURL, Qt::Key_OpenUrl }, + { XKB_KEY_XF86HomePage, Qt::Key_HomePage }, + { XKB_KEY_XF86Search, Qt::Key_Search }, + { XKB_KEY_XF86AudioLowerVolume, Qt::Key_VolumeDown }, + { XKB_KEY_XF86AudioMute, Qt::Key_VolumeMute }, + { XKB_KEY_XF86AudioRaiseVolume, Qt::Key_VolumeUp }, + { XKB_KEY_XF86AudioPlay, Qt::Key_MediaPlay }, + { XKB_KEY_XF86AudioStop, Qt::Key_MediaStop }, + { XKB_KEY_XF86AudioPrev, Qt::Key_MediaPrevious }, + { XKB_KEY_XF86AudioNext, Qt::Key_MediaNext }, + { XKB_KEY_XF86AudioRecord, Qt::Key_MediaRecord }, + { XKB_KEY_XF86Mail, Qt::Key_LaunchMail }, + { XKB_KEY_XF86MyComputer, Qt::Key_Launch0 }, + { XKB_KEY_XF86Calculator, Qt::Key_Launch1 }, + { XKB_KEY_XF86Memo, Qt::Key_Memo }, + { XKB_KEY_XF86ToDoList, Qt::Key_ToDoList }, + { XKB_KEY_XF86Calendar, Qt::Key_Calendar }, + { XKB_KEY_XF86PowerDown, Qt::Key_PowerDown }, + { XKB_KEY_XF86ContrastAdjust, Qt::Key_ContrastAdjust }, + { XKB_KEY_XF86Standby, Qt::Key_Standby }, + { XKB_KEY_XF86MonBrightnessUp, Qt::Key_MonBrightnessUp }, + { XKB_KEY_XF86MonBrightnessDown, Qt::Key_MonBrightnessDown }, + { XKB_KEY_XF86KbdLightOnOff, Qt::Key_KeyboardLightOnOff }, + { XKB_KEY_XF86KbdBrightnessUp, Qt::Key_KeyboardBrightnessUp }, + { XKB_KEY_XF86KbdBrightnessDown, Qt::Key_KeyboardBrightnessDown }, + { XKB_KEY_XF86PowerOff, Qt::Key_PowerOff }, + { XKB_KEY_XF86WakeUp, Qt::Key_WakeUp }, + { XKB_KEY_XF86Eject, Qt::Key_Eject }, + { XKB_KEY_XF86ScreenSaver, Qt::Key_ScreenSaver }, + { XKB_KEY_XF86WWW, Qt::Key_WWW }, + { XKB_KEY_XF86Sleep, Qt::Key_Sleep }, + { XKB_KEY_XF86LightBulb, Qt::Key_LightBulb }, + { XKB_KEY_XF86Shop, Qt::Key_Shop }, + { XKB_KEY_XF86History, Qt::Key_History }, + { XKB_KEY_XF86AddFavorite, Qt::Key_AddFavorite }, + { XKB_KEY_XF86HotLinks, Qt::Key_HotLinks }, + { XKB_KEY_XF86BrightnessAdjust, Qt::Key_BrightnessAdjust }, + { XKB_KEY_XF86Finance, Qt::Key_Finance }, + { XKB_KEY_XF86Community, Qt::Key_Community }, + { XKB_KEY_XF86AudioRewind, Qt::Key_AudioRewind }, + { XKB_KEY_XF86BackForward, Qt::Key_BackForward }, + { XKB_KEY_XF86ApplicationLeft, Qt::Key_ApplicationLeft }, + { XKB_KEY_XF86ApplicationRight, Qt::Key_ApplicationRight }, + { XKB_KEY_XF86Book, Qt::Key_Book }, + { XKB_KEY_XF86CD, Qt::Key_CD }, + { XKB_KEY_XF86Calculater, Qt::Key_Calculator }, + { XKB_KEY_XF86Clear, Qt::Key_Clear }, + { XKB_KEY_XF86ClearGrab, Qt::Key_ClearGrab }, + { XKB_KEY_XF86Close, Qt::Key_Close }, + { XKB_KEY_XF86Copy, Qt::Key_Copy }, + { XKB_KEY_XF86Cut, Qt::Key_Cut }, + { XKB_KEY_XF86Display, Qt::Key_Display }, + { XKB_KEY_XF86DOS, Qt::Key_DOS }, + { XKB_KEY_XF86Documents, Qt::Key_Documents }, + { XKB_KEY_XF86Excel, Qt::Key_Excel }, + { XKB_KEY_XF86Explorer, Qt::Key_Explorer }, + { XKB_KEY_XF86Game, Qt::Key_Game }, + { XKB_KEY_XF86Go, Qt::Key_Go }, + { XKB_KEY_XF86iTouch, Qt::Key_iTouch }, + { XKB_KEY_XF86LogOff, Qt::Key_LogOff }, + { XKB_KEY_XF86Market, Qt::Key_Market }, + { XKB_KEY_XF86Meeting, Qt::Key_Meeting }, + { XKB_KEY_XF86MenuKB, Qt::Key_MenuKB }, + { XKB_KEY_XF86MenuPB, Qt::Key_MenuPB }, + { XKB_KEY_XF86MySites, Qt::Key_MySites }, + { XKB_KEY_XF86News, Qt::Key_News }, + { XKB_KEY_XF86OfficeHome, Qt::Key_OfficeHome }, + { XKB_KEY_XF86Option, Qt::Key_Option }, + { XKB_KEY_XF86Paste, Qt::Key_Paste }, + { XKB_KEY_XF86Phone, Qt::Key_Phone }, + { XKB_KEY_XF86Reply, Qt::Key_Reply }, + { XKB_KEY_XF86Reload, Qt::Key_Reload }, + { XKB_KEY_XF86RotateWindows, Qt::Key_RotateWindows }, + { XKB_KEY_XF86RotationPB, Qt::Key_RotationPB }, + { XKB_KEY_XF86RotationKB, Qt::Key_RotationKB }, + { XKB_KEY_XF86Save, Qt::Key_Save }, + { XKB_KEY_XF86Send, Qt::Key_Send }, + { XKB_KEY_XF86Spell, Qt::Key_Spell }, + { XKB_KEY_XF86SplitScreen, Qt::Key_SplitScreen }, + { XKB_KEY_XF86Support, Qt::Key_Support }, + { XKB_KEY_XF86TaskPane, Qt::Key_TaskPane }, + { XKB_KEY_XF86Terminal, Qt::Key_Terminal }, + { XKB_KEY_XF86Tools, Qt::Key_Tools }, + { XKB_KEY_XF86Travel, Qt::Key_Travel }, + { XKB_KEY_XF86Video, Qt::Key_Video }, + { XKB_KEY_XF86Word, Qt::Key_Word }, + { XKB_KEY_XF86Xfer, Qt::Key_Xfer }, + { XKB_KEY_XF86ZoomIn, Qt::Key_ZoomIn }, + { XKB_KEY_XF86ZoomOut, Qt::Key_ZoomOut }, + { XKB_KEY_XF86Away, Qt::Key_Away }, + { XKB_KEY_XF86Messenger, Qt::Key_Messenger }, + { XKB_KEY_XF86WebCam, Qt::Key_WebCam }, + { XKB_KEY_XF86MailForward, Qt::Key_MailForward }, + { XKB_KEY_XF86Pictures, Qt::Key_Pictures }, + { XKB_KEY_XF86Music, Qt::Key_Music }, + { XKB_KEY_XF86Battery, Qt::Key_Battery }, + { XKB_KEY_XF86Bluetooth, Qt::Key_Bluetooth }, + { XKB_KEY_XF86WLAN, Qt::Key_WLAN }, + { XKB_KEY_XF86UWB, Qt::Key_UWB }, + { XKB_KEY_XF86AudioForward, Qt::Key_AudioForward }, + { XKB_KEY_XF86AudioRepeat, Qt::Key_AudioRepeat }, + { XKB_KEY_XF86AudioRandomPlay, Qt::Key_AudioRandomPlay }, + { XKB_KEY_XF86Subtitle, Qt::Key_Subtitle }, + { XKB_KEY_XF86AudioCycleTrack, Qt::Key_AudioCycleTrack }, + { XKB_KEY_XF86Time, Qt::Key_Time }, + { XKB_KEY_XF86Select, Qt::Key_Select }, + { XKB_KEY_XF86View, Qt::Key_View }, + { XKB_KEY_XF86TopMenu, Qt::Key_TopMenu }, + { XKB_KEY_XF86Bluetooth, Qt::Key_Bluetooth }, + { XKB_KEY_XF86Suspend, Qt::Key_Suspend }, + { XKB_KEY_XF86Hibernate, Qt::Key_Hibernate }, + { XKB_KEY_XF86TouchpadToggle, Qt::Key_TouchpadToggle }, + { XKB_KEY_XF86TouchpadOn, Qt::Key_TouchpadOn }, + { XKB_KEY_XF86TouchpadOff, Qt::Key_TouchpadOff }, + { XKB_KEY_XF86AudioMicMute, Qt::Key_MicMute }, + { XKB_KEY_XF86Launch0, Qt::Key_Launch2 }, + { XKB_KEY_XF86Launch1, Qt::Key_Launch3 }, + { XKB_KEY_XF86Launch2, Qt::Key_Launch4 }, + { XKB_KEY_XF86Launch3, Qt::Key_Launch5 }, + { XKB_KEY_XF86Launch4, Qt::Key_Launch6 }, + { XKB_KEY_XF86Launch5, Qt::Key_Launch7 }, + { XKB_KEY_XF86Launch6, Qt::Key_Launch8 }, + { XKB_KEY_XF86Launch7, Qt::Key_Launch9 }, + { XKB_KEY_XF86Launch8, Qt::Key_LaunchA }, + { XKB_KEY_XF86Launch9, Qt::Key_LaunchB }, + { XKB_KEY_XF86LaunchA, Qt::Key_LaunchC }, + { XKB_KEY_XF86LaunchB, Qt::Key_LaunchD }, + { XKB_KEY_XF86LaunchC, Qt::Key_LaunchE }, + { XKB_KEY_XF86LaunchD, Qt::Key_LaunchF } +}; + +static inline Qt::Key xkbToQtKey(xkb_keysym_t keySym) +{ + Qt::Key key = Qt::Key_unknown; + if (keySym >= XKB_KEY_KP_0 && keySym <= XKB_KEY_KP_9) { + // numeric keypad keys + key = Qt::Key(int(Qt::Key_0) + int(keySym) - XKB_KEY_KP_0); + } else if ((keySym >= XKB_KEY_a && keySym <= XKB_KEY_z) || + (keySym >= XKB_KEY_agrave && keySym < XKB_KEY_division) || + (keySym > XKB_KEY_division && keySym <= XKB_KEY_thorn)) { + key = Qt::Key(QChar(keySym).toUpper().unicode()); + } else if (keySym < 0x3000) { + key = Qt::Key(keySym); + } + if (key == Qt::Key_unknown) { + const auto it = s_mapping.find(keySym); + if (it != s_mapping.end()) { + key = it->second; + } + } + return key; +} + +} + +#endif