KDEUI
kkeyserver_x11.cpp
Go to the documentation of this file.
00001 /* 00002 Copyright (C) 2001 Ellis Whitehead <ellis@kde.org> 00003 00004 Win32 port: 00005 Copyright (C) 2004 Jarosław Staniek <staniek@kde.org> 00006 00007 This library is free software; you can redistribute it and/or 00008 modify it under the terms of the GNU Library General Public 00009 License as published by the Free Software Foundation; either 00010 version 2 of the License, or (at your option) any later version. 00011 00012 This library is distributed in the hope that it will be useful, 00013 but WITHOUT ANY WARRANTY; without even the implied warranty of 00014 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 00015 Library General Public License for more details. 00016 00017 You should have received a copy of the GNU Library General Public License 00018 along with this library; see the file COPYING.LIB. If not, write to 00019 the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, 00020 Boston, MA 02110-1301, USA. 00021 */ 00022 00023 #include "kkeyserver_x11.h" 00024 00025 #include "kdebug.h" 00026 #include "klocale.h" 00027 00028 #include <QX11Info> 00029 # define XK_MISCELLANY 00030 # define XK_XKB_KEYS 00031 # include <X11/X.h> 00032 # include <X11/Xlib.h> 00033 # include <X11/Xutil.h> 00034 # include <X11/keysymdef.h> 00035 # define X11_ONLY(arg) arg, //allows to omit an argument 00036 00037 // #define KKEYSERVER_DEBUG 1 00038 00039 00040 00041 namespace KKeyServer 00042 { 00043 00044 //--------------------------------------------------------------------- 00045 // Data Structures 00046 //--------------------------------------------------------------------- 00047 00048 struct Mod 00049 { 00050 int m_mod; 00051 }; 00052 00053 //--------------------------------------------------------------------- 00054 // Array Structures 00055 //--------------------------------------------------------------------- 00056 00057 struct X11ModInfo 00058 { 00059 int modQt; 00060 int modX; 00061 }; 00062 00063 struct SymVariation 00064 { 00065 uint sym, symVariation; 00066 bool bActive; 00067 }; 00068 00069 struct SymName 00070 { 00071 uint sym; 00072 const char* psName; 00073 }; 00074 00075 struct TransKey { 00076 int keySymQt; 00077 uint keySymX; 00078 }; 00079 00080 //--------------------------------------------------------------------- 00081 // Arrays 00082 //--------------------------------------------------------------------- 00083 00084 static X11ModInfo g_rgX11ModInfo[4] = 00085 { 00086 { Qt::SHIFT, X11_ONLY(ShiftMask) }, 00087 { Qt::CTRL, X11_ONLY(ControlMask) }, 00088 { Qt::ALT, X11_ONLY(Mod1Mask) }, 00089 { Qt::META, X11_ONLY(Mod4Mask) } 00090 }; 00091 00092 // Special Names List 00093 static const SymName g_rgSymNames[] = { 00094 { XK_ISO_Left_Tab, "Backtab" }, 00095 { XK_BackSpace, I18N_NOOP("Backspace") }, 00096 { XK_Sys_Req, I18N_NOOP("SysReq") }, 00097 { XK_Caps_Lock, I18N_NOOP("CapsLock") }, 00098 { XK_Num_Lock, I18N_NOOP("NumLock") }, 00099 { XK_Scroll_Lock, I18N_NOOP("ScrollLock") }, 00100 { XK_Prior, I18N_NOOP("PageUp") }, 00101 { XK_Next, I18N_NOOP("PageDown") }, 00102 #ifdef sun 00103 { XK_F11, I18N_NOOP("Stop") }, 00104 { XK_F12, I18N_NOOP("Again") }, 00105 { XK_F13, I18N_NOOP("Props") }, 00106 { XK_F14, I18N_NOOP("Undo") }, 00107 { XK_F15, I18N_NOOP("Front") }, 00108 { XK_F16, I18N_NOOP("Copy") }, 00109 { XK_F17, I18N_NOOP("Open") }, 00110 { XK_F18, I18N_NOOP("Paste") }, 00111 { XK_F19, I18N_NOOP("Find") }, 00112 { XK_F20, I18N_NOOP("Cut") }, 00113 { XK_F22, I18N_NOOP("Print") }, 00114 #endif 00115 { 0, 0 } 00116 }; 00117 00118 // These are the X equivalents to the Qt keycodes 0x1000 - 0x1026 00119 static const TransKey g_rgQtToSymX[] = 00120 { 00121 { Qt::Key_Escape, XK_Escape }, 00122 { Qt::Key_Tab, XK_Tab }, 00123 { Qt::Key_Backtab, XK_ISO_Left_Tab }, 00124 { Qt::Key_Backspace, XK_BackSpace }, 00125 { Qt::Key_Return, XK_Return }, 00126 { Qt::Key_Enter, XK_KP_Enter }, 00127 { Qt::Key_Insert, XK_Insert }, 00128 { Qt::Key_Delete, XK_Delete }, 00129 { Qt::Key_Pause, XK_Pause }, 00130 #ifdef sun 00131 { Qt::Key_Print, XK_F22 }, 00132 #else 00133 { Qt::Key_Print, XK_Print }, 00134 #endif 00135 { Qt::Key_SysReq, XK_Sys_Req }, 00136 { Qt::Key_Home, XK_Home }, 00137 { Qt::Key_End, XK_End }, 00138 { Qt::Key_Left, XK_Left }, 00139 { Qt::Key_Up, XK_Up }, 00140 { Qt::Key_Right, XK_Right }, 00141 { Qt::Key_Down, XK_Down }, 00142 { Qt::Key_PageUp, XK_Prior }, 00143 { Qt::Key_PageDown, XK_Next }, 00144 //{ Qt::Key_Shift, 0 }, 00145 //{ Qt::Key_Control, 0 }, 00146 //{ Qt::Key_Meta, 0 }, 00147 //{ Qt::Key_Alt, 0 }, 00148 { Qt::Key_CapsLock, XK_Caps_Lock }, 00149 { Qt::Key_NumLock, XK_Num_Lock }, 00150 { Qt::Key_ScrollLock, XK_Scroll_Lock }, 00151 { Qt::Key_F1, XK_F1 }, 00152 { Qt::Key_F2, XK_F2 }, 00153 { Qt::Key_F3, XK_F3 }, 00154 { Qt::Key_F4, XK_F4 }, 00155 { Qt::Key_F5, XK_F5 }, 00156 { Qt::Key_F6, XK_F6 }, 00157 { Qt::Key_F7, XK_F7 }, 00158 { Qt::Key_F8, XK_F8 }, 00159 { Qt::Key_F9, XK_F9 }, 00160 { Qt::Key_F10, XK_F10 }, 00161 { Qt::Key_F11, XK_F11 }, 00162 { Qt::Key_F12, XK_F12 }, 00163 { Qt::Key_F13, XK_F13 }, 00164 { Qt::Key_F14, XK_F14 }, 00165 { Qt::Key_F15, XK_F15 }, 00166 { Qt::Key_F16, XK_F16 }, 00167 { Qt::Key_F17, XK_F17 }, 00168 { Qt::Key_F18, XK_F18 }, 00169 { Qt::Key_F19, XK_F19 }, 00170 { Qt::Key_F20, XK_F20 }, 00171 { Qt::Key_F21, XK_F21 }, 00172 { Qt::Key_F22, XK_F22 }, 00173 { Qt::Key_F23, XK_F23 }, 00174 { Qt::Key_F24, XK_F24 }, 00175 { Qt::Key_F25, XK_F25 }, 00176 { Qt::Key_F26, XK_F26 }, 00177 { Qt::Key_F27, XK_F27 }, 00178 { Qt::Key_F28, XK_F28 }, 00179 { Qt::Key_F29, XK_F29 }, 00180 { Qt::Key_F30, XK_F30 }, 00181 { Qt::Key_F31, XK_F31 }, 00182 { Qt::Key_F32, XK_F32 }, 00183 { Qt::Key_F33, XK_F33 }, 00184 { Qt::Key_F34, XK_F34 }, 00185 { Qt::Key_F35, XK_F35 }, 00186 { Qt::Key_Super_L, XK_Super_L }, 00187 { Qt::Key_Super_R, XK_Super_R }, 00188 { Qt::Key_Menu, XK_Menu }, 00189 { Qt::Key_Hyper_L, XK_Hyper_L }, 00190 { Qt::Key_Hyper_R, XK_Hyper_R }, 00191 { Qt::Key_Help, XK_Help }, 00192 //{ Qt::Key_Direction_L, XK_Direction_L }, These keys don't exist in X11 00193 //{ Qt::Key_Direction_R, XK_Direction_R }, 00194 00195 { '/', XK_KP_Divide }, 00196 { '*', XK_KP_Multiply }, 00197 { '-', XK_KP_Subtract }, 00198 { '+', XK_KP_Add }, 00199 { Qt::Key_Return, XK_KP_Enter } 00200 00201 // the next lines are taken on 10/2009 from X.org (X11/XF86keysym.h), defining some special 00202 // multimedia keys. They are included here as not every system has them. 00203 #define XF86XK_MonBrightnessUp 0x1008FF02 00204 #define XF86XK_MonBrightnessDown 0x1008FF03 00205 #define XF86XK_KbdLightOnOff 0x1008FF04 00206 #define XF86XK_KbdBrightnessUp 0x1008FF05 00207 #define XF86XK_KbdBrightnessDown 0x1008FF06 00208 #define XF86XK_Standby 0x1008FF10 00209 #define XF86XK_AudioLowerVolume 0x1008FF11 00210 #define XF86XK_AudioMute 0x1008FF12 00211 #define XF86XK_AudioRaiseVolume 0x1008FF13 00212 #define XF86XK_AudioPlay 0x1008FF14 00213 #define XF86XK_AudioStop 0x1008FF15 00214 #define XF86XK_AudioPrev 0x1008FF16 00215 #define XF86XK_AudioNext 0x1008FF17 00216 #define XF86XK_HomePage 0x1008FF18 00217 #define XF86XK_Mail 0x1008FF19 00218 #define XF86XK_Start 0x1008FF1A 00219 #define XF86XK_Search 0x1008FF1B 00220 #define XF86XK_AudioRecord 0x1008FF1C 00221 #define XF86XK_Calculator 0x1008FF1D 00222 #define XF86XK_Memo 0x1008FF1E 00223 #define XF86XK_ToDoList 0x1008FF1F 00224 #define XF86XK_Calendar 0x1008FF20 00225 #define XF86XK_PowerDown 0x1008FF21 00226 #define XF86XK_ContrastAdjust 0x1008FF22 00227 #define XF86XK_Back 0x1008FF26 00228 #define XF86XK_Forward 0x1008FF27 00229 #define XF86XK_Stop 0x1008FF28 00230 #define XF86XK_Refresh 0x1008FF29 00231 #define XF86XK_PowerOff 0x1008FF2A 00232 #define XF86XK_WakeUp 0x1008FF2B 00233 #define XF86XK_Eject 0x1008FF2C 00234 #define XF86XK_ScreenSaver 0x1008FF2D 00235 #define XF86XK_WWW 0x1008FF2E 00236 #define XF86XK_Sleep 0x1008FF2F 00237 #define XF86XK_Favorites 0x1008FF30 00238 #define XF86XK_AudioPause 0x1008FF31 00239 #define XF86XK_AudioMedia 0x1008FF32 00240 #define XF86XK_MyComputer 0x1008FF33 00241 #define XF86XK_LightBulb 0x1008FF35 00242 #define XF86XK_Shop 0x1008FF36 00243 #define XF86XK_History 0x1008FF37 00244 #define XF86XK_OpenURL 0x1008FF38 00245 #define XF86XK_AddFavorite 0x1008FF39 00246 #define XF86XK_HotLinks 0x1008FF3A 00247 #define XF86XK_BrightnessAdjust 0x1008FF3B 00248 #define XF86XK_Finance 0x1008FF3C 00249 #define XF86XK_Community 0x1008FF3D 00250 #define XF86XK_AudioRewind 0x1008FF3E 00251 #define XF86XK_BackForward 0x1008FF3F 00252 #define XF86XK_Launch0 0x1008FF40 00253 #define XF86XK_Launch1 0x1008FF41 00254 #define XF86XK_Launch2 0x1008FF42 00255 #define XF86XK_Launch3 0x1008FF43 00256 #define XF86XK_Launch4 0x1008FF44 00257 #define XF86XK_Launch5 0x1008FF45 00258 #define XF86XK_Launch6 0x1008FF46 00259 #define XF86XK_Launch7 0x1008FF47 00260 #define XF86XK_Launch8 0x1008FF48 00261 #define XF86XK_Launch9 0x1008FF49 00262 #define XF86XK_LaunchA 0x1008FF4A 00263 #define XF86XK_LaunchB 0x1008FF4B 00264 #define XF86XK_LaunchC 0x1008FF4C 00265 #define XF86XK_LaunchD 0x1008FF4D 00266 #define XF86XK_LaunchE 0x1008FF4E 00267 #define XF86XK_LaunchF 0x1008FF4F 00268 #define XF86XK_ApplicationLeft 0x1008FF50 00269 #define XF86XK_ApplicationRight 0x1008FF51 00270 #define XF86XK_Book 0x1008FF52 00271 #define XF86XK_CD 0x1008FF53 00272 #define XF86XK_Calculater 0x1008FF54 00273 #define XF86XK_Clear 0x1008FF55 00274 #define XF86XK_ClearGrab 0x1008FE21 00275 #define XF86XK_Close 0x1008FF56 00276 #define XF86XK_Copy 0x1008FF57 00277 #define XF86XK_Cut 0x1008FF58 00278 #define XF86XK_Display 0x1008FF59 00279 #define XF86XK_DOS 0x1008FF5A 00280 #define XF86XK_Documents 0x1008FF5B 00281 #define XF86XK_Excel 0x1008FF5C 00282 #define XF86XK_Explorer 0x1008FF5D 00283 #define XF86XK_Game 0x1008FF5E 00284 #define XF86XK_Go 0x1008FF5F 00285 #define XF86XK_iTouch 0x1008FF60 00286 #define XF86XK_LogOff 0x1008FF61 00287 #define XF86XK_Market 0x1008FF62 00288 #define XF86XK_Meeting 0x1008FF63 00289 #define XF86XK_MenuKB 0x1008FF65 00290 #define XF86XK_MenuPB 0x1008FF66 00291 #define XF86XK_MySites 0x1008FF67 00292 #define XF86XK_News 0x1008FF69 00293 #define XF86XK_OfficeHome 0x1008FF6A 00294 #define XF86XK_Option 0x1008FF6C 00295 #define XF86XK_Paste 0x1008FF6D 00296 #define XF86XK_Phone 0x1008FF6E 00297 #define XF86XK_Reply 0x1008FF72 00298 #define XF86XK_Reload 0x1008FF73 00299 #define XF86XK_RotateWindows 0x1008FF74 00300 #define XF86XK_RotationPB 0x1008FF75 00301 #define XF86XK_RotationKB 0x1008FF76 00302 #define XF86XK_Save 0x1008FF77 00303 #define XF86XK_Send 0x1008FF7B 00304 #define XF86XK_Spell 0x1008FF7C 00305 #define XF86XK_SplitScreen 0x1008FF7D 00306 #define XF86XK_Support 0x1008FF7E 00307 #define XF86XK_TaskPane 0x1008FF7F 00308 #define XF86XK_Terminal 0x1008FF80 00309 #define XF86XK_Tools 0x1008FF81 00310 #define XF86XK_Travel 0x1008FF82 00311 #define XF86XK_Video 0x1008FF87 00312 #define XF86XK_Word 0x1008FF89 00313 #define XF86XK_Xfer 0x1008FF8A 00314 #define XF86XK_ZoomIn 0x1008FF8B 00315 #define XF86XK_ZoomOut 0x1008FF8C 00316 #define XF86XK_Away 0x1008FF8D 00317 #define XF86XK_Messenger 0x1008FF8E 00318 #define XF86XK_WebCam 0x1008FF8F 00319 #define XF86XK_MailForward 0x1008FF90 00320 #define XF86XK_Pictures 0x1008FF91 00321 #define XF86XK_Music 0x1008FF92 00322 #define XF86XK_Battery 0x1008FF93 00323 #define XF86XK_Bluetooth 0x1008FF94 00324 #define XF86XK_WLAN 0x1008FF95 00325 #define XF86XK_UWB 0x1008FF96 00326 #define XF86XK_AudioForward 0x1008FF97 00327 #define XF86XK_AudioRepeat 0x1008FF98 00328 #define XF86XK_AudioRandomPlay 0x1008FF99 00329 #define XF86XK_Subtitle 0x1008FF9A 00330 #define XF86XK_AudioCycleTrack 0x1008FF9B 00331 #define XF86XK_Time 0x1008FF9F 00332 #define XF86XK_Select 0x1008FFA0 00333 #define XF86XK_View 0x1008FFA1 00334 #define XF86XK_TopMenu 0x1008FFA2 00335 #define XF86XK_Suspend 0x1008FFA7 00336 #define XF86XK_Hibernate 0x1008FFA8 00337 // end of XF86keysyms.h 00338 , 00339 { Qt::Key_Back, XF86XK_Back }, 00340 { Qt::Key_Forward, XF86XK_Forward }, 00341 { Qt::Key_Stop, XF86XK_Stop }, 00342 { Qt::Key_Refresh, XF86XK_Refresh }, 00343 { Qt::Key_Favorites, XF86XK_Favorites }, 00344 { Qt::Key_LaunchMedia, XF86XK_AudioMedia }, 00345 { Qt::Key_OpenUrl, XF86XK_OpenURL }, 00346 { Qt::Key_HomePage, XF86XK_HomePage }, 00347 { Qt::Key_Search, XF86XK_Search }, 00348 { Qt::Key_VolumeDown, XF86XK_AudioLowerVolume }, 00349 { Qt::Key_VolumeMute, XF86XK_AudioMute }, 00350 { Qt::Key_VolumeUp, XF86XK_AudioRaiseVolume }, 00351 { Qt::Key_MediaPlay, XF86XK_AudioPlay }, 00352 { Qt::Key_MediaStop, XF86XK_AudioStop }, 00353 { Qt::Key_MediaPrevious, XF86XK_AudioPrev }, 00354 { Qt::Key_MediaNext, XF86XK_AudioNext }, 00355 { Qt::Key_MediaRecord, XF86XK_AudioRecord }, 00356 { Qt::Key_LaunchMail, XF86XK_Mail }, 00357 { Qt::Key_Launch0, XF86XK_MyComputer }, 00358 { Qt::Key_Calculator, XF86XK_Calculator }, 00359 { Qt::Key_Memo, XF86XK_Memo }, 00360 { Qt::Key_ToDoList, XF86XK_ToDoList }, 00361 { Qt::Key_Calendar, XF86XK_Calendar }, 00362 { Qt::Key_PowerDown, XF86XK_PowerDown }, 00363 { Qt::Key_ContrastAdjust, XF86XK_ContrastAdjust }, 00364 { Qt::Key_Standby, XF86XK_Standby }, 00365 { Qt::Key_MonBrightnessUp, XF86XK_MonBrightnessUp }, 00366 { Qt::Key_MonBrightnessDown, XF86XK_MonBrightnessDown }, 00367 { Qt::Key_KeyboardLightOnOff, XF86XK_KbdLightOnOff }, 00368 { Qt::Key_KeyboardBrightnessUp, XF86XK_KbdBrightnessUp }, 00369 { Qt::Key_KeyboardBrightnessDown, XF86XK_KbdBrightnessDown }, 00370 { Qt::Key_PowerOff, XF86XK_PowerOff }, 00371 { Qt::Key_WakeUp, XF86XK_WakeUp }, 00372 { Qt::Key_Eject, XF86XK_Eject }, 00373 { Qt::Key_ScreenSaver, XF86XK_ScreenSaver }, 00374 { Qt::Key_WWW, XF86XK_WWW }, 00375 { Qt::Key_Sleep, XF86XK_Sleep }, 00376 { Qt::Key_LightBulb, XF86XK_LightBulb }, 00377 { Qt::Key_Shop, XF86XK_Shop }, 00378 { Qt::Key_History, XF86XK_History }, 00379 { Qt::Key_AddFavorite, XF86XK_AddFavorite }, 00380 { Qt::Key_HotLinks, XF86XK_HotLinks }, 00381 { Qt::Key_BrightnessAdjust, XF86XK_BrightnessAdjust }, 00382 { Qt::Key_Finance, XF86XK_Finance }, 00383 { Qt::Key_Community, XF86XK_Community }, 00384 { Qt::Key_AudioRewind, XF86XK_AudioRewind }, 00385 { Qt::Key_BackForward, XF86XK_BackForward }, 00386 { Qt::Key_ApplicationLeft, XF86XK_ApplicationLeft }, 00387 { Qt::Key_ApplicationRight, XF86XK_ApplicationRight }, 00388 { Qt::Key_Book, XF86XK_Book }, 00389 { Qt::Key_CD, XF86XK_CD }, 00390 { Qt::Key_Calculator, XF86XK_Calculater }, 00391 { Qt::Key_Clear, XF86XK_Clear }, 00392 { Qt::Key_ClearGrab, XF86XK_ClearGrab }, 00393 { Qt::Key_Close, XF86XK_Close }, 00394 { Qt::Key_Copy, XF86XK_Copy }, 00395 { Qt::Key_Cut, XF86XK_Cut }, 00396 { Qt::Key_Display, XF86XK_Display }, 00397 { Qt::Key_DOS, XF86XK_DOS }, 00398 { Qt::Key_Documents, XF86XK_Documents }, 00399 { Qt::Key_Excel, XF86XK_Excel }, 00400 { Qt::Key_Explorer, XF86XK_Explorer }, 00401 { Qt::Key_Game, XF86XK_Game }, 00402 { Qt::Key_Go, XF86XK_Go }, 00403 { Qt::Key_iTouch, XF86XK_iTouch }, 00404 { Qt::Key_LogOff, XF86XK_LogOff }, 00405 { Qt::Key_Market, XF86XK_Market }, 00406 { Qt::Key_Meeting, XF86XK_Meeting }, 00407 { Qt::Key_MenuKB, XF86XK_MenuKB }, 00408 { Qt::Key_MenuPB, XF86XK_MenuPB }, 00409 { Qt::Key_MySites, XF86XK_MySites }, 00410 { Qt::Key_News, XF86XK_News }, 00411 { Qt::Key_OfficeHome, XF86XK_OfficeHome }, 00412 { Qt::Key_Option, XF86XK_Option }, 00413 { Qt::Key_Paste, XF86XK_Paste }, 00414 { Qt::Key_Phone, XF86XK_Phone }, 00415 { Qt::Key_Reply, XF86XK_Reply }, 00416 { Qt::Key_Reload, XF86XK_Reload }, 00417 { Qt::Key_RotateWindows, XF86XK_RotateWindows }, 00418 { Qt::Key_RotationPB, XF86XK_RotationPB }, 00419 { Qt::Key_RotationKB, XF86XK_RotationKB }, 00420 { Qt::Key_Save, XF86XK_Save }, 00421 { Qt::Key_Send, XF86XK_Send }, 00422 { Qt::Key_Spell, XF86XK_Spell }, 00423 { Qt::Key_SplitScreen, XF86XK_SplitScreen }, 00424 { Qt::Key_Support, XF86XK_Support }, 00425 { Qt::Key_TaskPane, XF86XK_TaskPane }, 00426 { Qt::Key_Terminal, XF86XK_Terminal }, 00427 { Qt::Key_Tools, XF86XK_Tools }, 00428 { Qt::Key_Travel, XF86XK_Travel }, 00429 { Qt::Key_Video, XF86XK_Video }, 00430 { Qt::Key_Word, XF86XK_Word }, 00431 { Qt::Key_Xfer, XF86XK_Xfer }, 00432 { Qt::Key_ZoomIn, XF86XK_ZoomIn }, 00433 { Qt::Key_ZoomOut, XF86XK_ZoomOut }, 00434 { Qt::Key_Away, XF86XK_Away }, 00435 { Qt::Key_Messenger, XF86XK_Messenger }, 00436 { Qt::Key_WebCam, XF86XK_WebCam }, 00437 { Qt::Key_MailForward, XF86XK_MailForward }, 00438 { Qt::Key_Pictures, XF86XK_Pictures }, 00439 { Qt::Key_Music, XF86XK_Music }, 00440 { Qt::Key_Battery, XF86XK_Battery }, 00441 { Qt::Key_Bluetooth, XF86XK_Bluetooth }, 00442 { Qt::Key_WLAN, XF86XK_WLAN }, 00443 { Qt::Key_UWB, XF86XK_UWB }, 00444 { Qt::Key_AudioForward, XF86XK_AudioForward }, 00445 { Qt::Key_AudioRepeat, XF86XK_AudioRepeat }, 00446 { Qt::Key_AudioRandomPlay, XF86XK_AudioRandomPlay }, 00447 { Qt::Key_Subtitle, XF86XK_Subtitle }, 00448 { Qt::Key_AudioCycleTrack, XF86XK_AudioCycleTrack }, 00449 { Qt::Key_Time, XF86XK_Time }, 00450 { Qt::Key_Select, XF86XK_Select }, 00451 { Qt::Key_View, XF86XK_View }, 00452 { Qt::Key_TopMenu, XF86XK_TopMenu }, 00453 { Qt::Key_Bluetooth, XF86XK_Bluetooth }, 00454 { Qt::Key_Suspend, XF86XK_Suspend }, 00455 { Qt::Key_Hibernate, XF86XK_Hibernate }, 00456 { Qt::Key_Launch2, XF86XK_Launch0 }, 00457 { Qt::Key_Launch3, XF86XK_Launch1 }, 00458 { Qt::Key_Launch4, XF86XK_Launch2 }, 00459 { Qt::Key_Launch5, XF86XK_Launch3 }, 00460 { Qt::Key_Launch6, XF86XK_Launch4 }, 00461 { Qt::Key_Launch7, XF86XK_Launch5 }, 00462 { Qt::Key_Launch8, XF86XK_Launch6 }, 00463 { Qt::Key_Launch9, XF86XK_Launch7 }, 00464 { Qt::Key_LaunchA, XF86XK_Launch8 }, 00465 { Qt::Key_LaunchB, XF86XK_Launch9 }, 00466 { Qt::Key_LaunchC, XF86XK_LaunchA }, 00467 { Qt::Key_LaunchD, XF86XK_LaunchB }, 00468 { Qt::Key_LaunchE, XF86XK_LaunchC }, 00469 { Qt::Key_LaunchF, XF86XK_LaunchD }, 00470 }; 00471 00472 //--------------------------------------------------------------------- 00473 // Debugging 00474 //--------------------------------------------------------------------- 00475 #ifndef NDEBUG 00476 inline void checkDisplay() 00477 { 00478 // Some non-GUI apps might try to use us. 00479 if ( !QX11Info::display() ) { 00480 kError() << "QX11Info::display() returns 0. I'm probably going to crash now." << endl; 00481 kError() << "If this is a KApplication initialized without GUI stuff, change it to be " 00482 "initialized with GUI stuff." << endl; 00483 } 00484 } 00485 #else // NDEBUG 00486 # define checkDisplay() 00487 #endif 00488 00489 //--------------------------------------------------------------------- 00490 // Initialization 00491 //--------------------------------------------------------------------- 00492 00493 static bool g_bInitializedMods; 00494 static uint g_modXNumLock, g_modXScrollLock, g_modXModeSwitch, g_alt_mask, g_meta_mask, g_super_mask, g_hyper_mask; 00495 00496 bool initializeMods() 00497 { 00498 // Reinitialize the masks 00499 g_modXNumLock = 0; 00500 g_modXScrollLock = 0; 00501 g_modXModeSwitch = 0; 00502 g_alt_mask = 0; 00503 g_meta_mask = 0; 00504 g_super_mask = 0; 00505 g_hyper_mask = 0; 00506 00507 checkDisplay(); 00508 XModifierKeymap* xmk = XGetModifierMapping( QX11Info::display() ); 00509 00510 int min_keycode, max_keycode; 00511 int keysyms_per_keycode = 0; 00512 00513 XDisplayKeycodes( QX11Info::display(), &min_keycode, &max_keycode ); 00514 XFree( XGetKeyboardMapping( QX11Info::display(), min_keycode, 1, &keysyms_per_keycode )); 00515 00516 for( int i = Mod1MapIndex; i < 8; i++ ) { 00517 uint mask = (1 << i); 00518 uint keySymX = NoSymbol; 00519 00520 // This used to be only XKeycodeToKeysym( ... , 0 ), but that fails with XFree4.3.99 00521 // and X.org R6.7 , where for some reason only ( ... , 1 ) works. I have absolutely no 00522 // idea what the problem is, but searching all possibilities until something valid is 00523 // found fixes the problem. 00524 for( int j = 0; j < xmk->max_keypermod; ++j ) { 00525 00526 for( int k = 0; k < keysyms_per_keycode; ++k ) { 00527 00528 keySymX = XKeycodeToKeysym( QX11Info::display(), xmk->modifiermap[xmk->max_keypermod * i + j], k ); 00529 00530 switch( keySymX ) { 00531 case XK_Alt_L: 00532 case XK_Alt_R: g_alt_mask |= mask; break; 00533 00534 case XK_Super_L: 00535 case XK_Super_R: g_super_mask |= mask; break; 00536 00537 case XK_Hyper_L: 00538 case XK_Hyper_R: g_hyper_mask |= mask; break; 00539 00540 case XK_Meta_L: 00541 case XK_Meta_R: g_meta_mask |= mask; break; 00542 00543 case XK_Num_Lock: g_modXNumLock |= mask; break; 00544 case XK_Scroll_Lock: g_modXScrollLock |= mask; break; 00545 case XK_Mode_switch: g_modXModeSwitch |= mask; break; 00546 } 00547 } 00548 } 00549 } 00550 00551 #ifdef KKEYSERVER_DEBUG 00552 kDebug() << "Alt:" << g_alt_mask; 00553 kDebug() << "Meta:" << g_meta_mask; 00554 kDebug() << "Super:" << g_super_mask; 00555 kDebug() << "Hyper:" << g_hyper_mask; 00556 kDebug() << "NumLock:" << g_modXNumLock; 00557 kDebug() << "ScrollLock:" << g_modXScrollLock; 00558 kDebug() << "ModeSwitch:" << g_modXModeSwitch; 00559 #endif 00560 00561 // Check if hyper overlaps with super or meta or alt 00562 if (g_hyper_mask&(g_super_mask|g_meta_mask|g_alt_mask)) { 00563 #ifdef KKEYSERVER_DEBUG 00564 kDebug() << "Hyper conflicts with super, meta or alt."; 00565 #endif 00566 // Remove the conflicting masks 00567 g_hyper_mask &= ~(g_super_mask|g_meta_mask|g_alt_mask); 00568 } 00569 00570 // Check if super overlaps with meta or alt 00571 if (g_super_mask&(g_meta_mask|g_alt_mask)) { 00572 #ifdef KKEYSERVER_DEBUG 00573 kDebug() << "Super conflicts with meta or alt."; 00574 #endif 00575 // Remove the conflicting masks 00576 g_super_mask &= ~(g_meta_mask|g_alt_mask); 00577 } 00578 00579 00580 // Check if meta overlaps with alt 00581 if (g_meta_mask|g_alt_mask) { 00582 #ifdef KKEYSERVER_DEBUG 00583 kDebug() << "Meta conflicts with alt."; 00584 #endif 00585 // Remove the conflicting masks 00586 g_meta_mask &= ~(g_alt_mask); 00587 } 00588 00589 if (!g_meta_mask) { 00590 #ifdef KKEYSERVER_DEBUG 00591 kDebug() << "Meta is not set or conflicted with alt."; 00592 #endif 00593 if (g_super_mask) { 00594 #ifdef KKEYSERVER_DEBUG 00595 kDebug() << "Using super for meta"; 00596 #endif 00597 // Use Super 00598 g_meta_mask = g_super_mask; 00599 } else if (g_hyper_mask) { 00600 #ifdef KKEYSERVER_DEBUG 00601 kDebug() << "Using hyper for meta"; 00602 #endif 00603 // User Hyper 00604 g_meta_mask = g_hyper_mask; 00605 } else { 00606 // ???? Nothing left 00607 g_meta_mask = 0; 00608 } 00609 } 00610 00611 #ifdef KKEYSERVER_DEBUG 00612 kDebug() << "Alt:" << g_alt_mask; 00613 kDebug() << "Meta:" << g_meta_mask; 00614 kDebug() << "Super:" << g_super_mask; 00615 kDebug() << "Hyper:" << g_hyper_mask; 00616 kDebug() << "NumLock:" << g_modXNumLock; 00617 kDebug() << "ScrollLock:" << g_modXScrollLock; 00618 kDebug() << "ModeSwitch:" << g_modXModeSwitch; 00619 #endif 00620 00621 if (!g_meta_mask) { 00622 kWarning() << "Your keyboard setup doesn't provide a key to use for meta. See 'xmodmap -pm' or 'xkbcomp $DISPLAY'"; 00623 } 00624 00625 g_rgX11ModInfo[2].modX = g_alt_mask; 00626 g_rgX11ModInfo[3].modX = g_meta_mask; 00627 00628 XFreeModifiermap( xmk ); 00629 g_bInitializedMods = true; 00630 00631 return true; 00632 } 00633 00634 00635 //--------------------------------------------------------------------- 00636 // Public functions 00637 //--------------------------------------------------------------------- 00638 00639 00640 uint modXShift() { return ShiftMask; } 00641 uint modXCtrl() { return ControlMask; } 00642 uint modXAlt() { if( !g_bInitializedMods ) { initializeMods(); } return g_alt_mask; } 00643 uint modXMeta() { if( !g_bInitializedMods ) { initializeMods(); } return g_meta_mask; } 00644 00645 uint modXNumLock() { if( !g_bInitializedMods ) { initializeMods(); } return g_modXNumLock; } 00646 uint modXLock() { return LockMask; } 00647 uint modXScrollLock() { if( !g_bInitializedMods ) { initializeMods(); } return g_modXScrollLock; } 00648 uint modXModeSwitch() { if( !g_bInitializedMods ) { initializeMods(); } return g_modXModeSwitch; } 00649 00650 bool keyboardHasMetaKey() { return modXMeta() != 0; } 00651 00652 00653 uint getModsRequired(uint sym) 00654 { 00655 uint mod = 0; 00656 00657 // FIXME: This might not be true on all keyboard layouts! 00658 if( sym == XK_Sys_Req ) return Qt::ALT; 00659 if( sym == XK_Break ) return Qt::CTRL; 00660 00661 if( sym < 0x3000 ) { 00662 QChar c(sym); 00663 if( c.isLetter() && c.toLower() != c.toUpper() && sym == c.toUpper().unicode() ) 00664 return Qt::SHIFT; 00665 } 00666 00667 uchar code = XKeysymToKeycode( QX11Info::display(), sym ); 00668 if( code ) { 00669 // need to check index 0 before the others, so that a null-mod 00670 // can take precedence over the others, in case the modified 00671 // key produces the same symbol. 00672 if( sym == XKeycodeToKeysym( QX11Info::display(), code, 0 ) ) 00673 ; 00674 else if( sym == XKeycodeToKeysym( QX11Info::display(), code, 1 ) ) 00675 mod = Qt::SHIFT; 00676 else if( sym == XKeycodeToKeysym( QX11Info::display(), code, 2 ) ) 00677 mod = MODE_SWITCH; 00678 else if( sym == XKeycodeToKeysym( QX11Info::display(), code, 3 ) ) 00679 mod = Qt::SHIFT | MODE_SWITCH; 00680 } 00681 return mod; 00682 } 00683 00684 bool keyQtToCodeX( int keyQt, int* keyCode ) 00685 { 00686 int sym; 00687 uint mod; 00688 keyQtToSymX(keyQt, &sym); 00689 keyQtToModX(keyQt, &mod); 00690 00691 // Get any extra mods required by the sym. 00692 // E.g., XK_Plus requires SHIFT on the en layout. 00693 uint modExtra = getModsRequired(sym); 00694 // Get the X modifier equivalent. 00695 if( !sym || !keyQtToModX( (keyQt & Qt::KeyboardModifierMask) | modExtra, &mod ) ) { 00696 *keyCode = 0; 00697 return false; 00698 } 00699 00700 *keyCode = XKeysymToKeycode( QX11Info::display(), sym ); 00701 return true; 00702 } 00703 00704 bool keyQtToSymX( int keyQt, int* keySym ) 00705 { 00706 int symQt = keyQt & ~Qt::KeyboardModifierMask; 00707 00708 if( symQt < 0x1000 ) { 00709 *keySym = QChar(symQt).toUpper().unicode(); 00710 return true; 00711 } 00712 00713 00714 for( uint i = 0; i < sizeof(g_rgQtToSymX)/sizeof(TransKey); i++ ) { 00715 if( g_rgQtToSymX[i].keySymQt == symQt ) { 00716 *keySym = g_rgQtToSymX[i].keySymX; 00717 return true; 00718 } 00719 } 00720 00721 *keySym = 0; 00722 if( symQt != Qt::Key_Shift && symQt != Qt::Key_Control && symQt != Qt::Key_Alt && 00723 symQt != Qt::Key_Meta && symQt != Qt::Key_Direction_L && symQt != Qt::Key_Direction_R ) 00724 kDebug(125) << "Sym::initQt( " << QString::number(keyQt,16) << " ): failed to convert key."; 00725 return false; 00726 } 00727 00728 bool symXToKeyQt( uint keySym, int* keyQt ) 00729 { 00730 *keyQt = Qt::Key_unknown; 00731 if( keySym < 0x1000 ) { 00732 if( keySym >= 'a' && keySym <= 'z' ) 00733 *keyQt = QChar(keySym).toUpper().unicode(); 00734 else 00735 *keyQt = keySym; 00736 } 00737 00738 else if( keySym < 0x3000 ) 00739 *keyQt = keySym; 00740 00741 else { 00742 for( uint i = 0; i < sizeof(g_rgQtToSymX)/sizeof(TransKey); i++ ) 00743 if( g_rgQtToSymX[i].keySymX == keySym ) { 00744 *keyQt = g_rgQtToSymX[i].keySymQt; 00745 break; 00746 } 00747 } 00748 00749 return (*keyQt != Qt::Key_unknown); 00750 } 00751 00752 /* are these things actually used anywhere? there's no way 00753 they can do anything on non-X11 */ 00754 00755 bool keyQtToModX( int modQt, uint* modX ) 00756 { 00757 if( !g_bInitializedMods ) 00758 initializeMods(); 00759 00760 *modX = 0; 00761 for( int i = 0; i < 4; i++ ) { 00762 00763 if( modQt & g_rgX11ModInfo[i].modQt ) { 00764 if( g_rgX11ModInfo[i].modX ) { 00765 *modX |= g_rgX11ModInfo[i].modX; 00766 } else { 00767 // The qt modifier has no x equivalent. Return false 00768 return false; 00769 } 00770 } 00771 } 00772 return true; 00773 } 00774 00775 bool modXToQt( uint modX, int* modQt ) 00776 { 00777 if( !g_bInitializedMods ) 00778 initializeMods(); 00779 00780 *modQt = 0; 00781 for( int i = 0; i < 4; i++ ) { 00782 if( modX & g_rgX11ModInfo[i].modX ) { 00783 *modQt |= g_rgX11ModInfo[i].modQt; 00784 continue; 00785 } 00786 } 00787 return true; 00788 } 00789 00790 00791 bool codeXToSym( uchar codeX, uint modX, uint* sym ) 00792 { 00793 KeySym keySym; 00794 XKeyPressedEvent event; 00795 00796 checkDisplay(); 00797 00798 event.type = KeyPress; 00799 event.display = QX11Info::display(); 00800 event.state = modX; 00801 event.keycode = codeX; 00802 00803 XLookupString( &event, 0, 0, &keySym, 0 ); 00804 *sym = (uint) keySym; 00805 return true; 00806 } 00807 00808 00809 uint accelModMaskX() 00810 { 00811 return modXShift() | modXCtrl() | modXAlt() | modXMeta(); 00812 } 00813 00814 00815 bool xEventToQt( XEvent* e, int* keyQt ) 00816 { 00817 Q_ASSERT(e->type == KeyPress || e->type == KeyRelease); 00818 00819 uchar keyCodeX = e->xkey.keycode; 00820 uint keyModX = e->xkey.state & (accelModMaskX() | MODE_SWITCH); 00821 00822 KeySym keySym; 00823 char buffer[16]; 00824 XLookupString( (XKeyEvent*) e, buffer, 15, &keySym, 0 ); 00825 uint keySymX = (uint)keySym; 00826 00827 // If numlock is active and a keypad key is pressed, XOR the SHIFT state. 00828 // e.g., KP_4 => Shift+KP_Left, and Shift+KP_4 => KP_Left. 00829 if( e->xkey.state & modXNumLock() ) { 00830 uint sym = XKeycodeToKeysym( QX11Info::display(), keyCodeX, 0 ); 00831 // TODO: what's the xor operator in c++? 00832 // If this is a keypad key, 00833 if( sym >= XK_KP_Space && sym <= XK_KP_9 ) { 00834 switch( sym ) { 00835 // Leave the following keys unaltered 00836 // FIXME: The proper solution is to see which keysyms don't change when shifted. 00837 case XK_KP_Multiply: 00838 case XK_KP_Add: 00839 case XK_KP_Subtract: 00840 case XK_KP_Divide: 00841 break; 00842 default: 00843 if( keyModX & modXShift() ) 00844 keyModX &= ~modXShift(); 00845 else 00846 keyModX |= modXShift(); 00847 } 00848 } 00849 } 00850 00851 int keyCodeQt; 00852 int keyModQt; 00853 symXToKeyQt(keySymX, &keyCodeQt); 00854 modXToQt(keyModX, &keyModQt); 00855 00856 *keyQt = keyCodeQt | keyModQt; 00857 return true; 00858 } 00859 00860 00861 } // end of namespace KKeyServer block
KDE 4.6 API Reference