00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
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
00038
00039
00040
00041 namespace KKeyServer
00042 {
00043
00044
00045
00046
00047
00048 struct Mod
00049 {
00050 int m_mod;
00051 };
00052
00053
00054
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
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
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
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
00145
00146
00147
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
00193
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
00202
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
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
00474
00475 #ifndef NDEBUG
00476 inline void checkDisplay()
00477 {
00478
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
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
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
00521
00522
00523
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
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
00567 g_hyper_mask &= ~(g_super_mask|g_meta_mask|g_alt_mask);
00568 }
00569
00570
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
00576 g_super_mask &= ~(g_meta_mask|g_alt_mask);
00577 }
00578
00579
00580
00581 if (g_meta_mask|g_alt_mask) {
00582 #ifdef KKEYSERVER_DEBUG
00583 kDebug() << "Meta conflicts with alt.";
00584 #endif
00585
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
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
00604 g_meta_mask = g_hyper_mask;
00605 } else {
00606
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
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
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
00670
00671
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
00692
00693 uint modExtra = getModsRequired(sym);
00694
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
00753
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
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 uchar keyCodeX = e->xkey.keycode;
00818 uint keyModX = e->xkey.state & (accelModMaskX() | MODE_SWITCH);
00819
00820 KeySym keySym;
00821 XLookupString( (XKeyEvent*) e, 0, 0, &keySym, 0 );
00822 uint keySymX = (uint)keySym;
00823
00824
00825
00826 if( e->xkey.state & modXNumLock() ) {
00827 uint sym = XKeycodeToKeysym( QX11Info::display(), keyCodeX, 0 );
00828
00829
00830 if( sym >= XK_KP_Space && sym <= XK_KP_9 ) {
00831 switch( sym ) {
00832
00833
00834 case XK_KP_Multiply:
00835 case XK_KP_Add:
00836 case XK_KP_Subtract:
00837 case XK_KP_Divide:
00838 break;
00839 default:
00840 if( keyModX & modXShift() )
00841 keyModX &= ~modXShift();
00842 else
00843 keyModX |= modXShift();
00844 }
00845 }
00846 }
00847
00848 int keyCodeQt;
00849 int keyModQt;
00850 symXToKeyQt(keySymX, &keyCodeQt);
00851 modXToQt(keyModX, &keyModQt);
00852
00853 *keyQt = keyCodeQt | keyModQt;
00854 return true;
00855 }
00856
00857
00858 }