kkeyserver_x11.cpp
00001 /* 00002 Copyright (C) 2001 Ellis Whitehead <ellis@kde.org> 00003 00004 Win32 port: 00005 Copyright (C) 2004 Jaroslaw Staniek <js@iidea.pl> 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 <config.h> 00024 00025 #include <tqnamespace.h> 00026 #include <tqwindowdefs.h> 00027 00028 #if defined(Q_WS_X11) || defined(Q_WS_WIN) || defined(Q_WS_MACX) // Only compile this module if we're compiling for X11, mac or win32 00029 00030 #include "kkeyserver_x11.h" 00031 #include "kkeynative.h" 00032 #include "tdeshortcut.h" 00033 00034 #include <tdeconfig.h> 00035 #include <kdebug.h> 00036 #include <tdeglobal.h> 00037 #include <tdelocale.h> 00038 00039 #ifdef Q_WS_X11 00040 # define XK_MISCELLANY 00041 # define XK_XKB_KEYS 00042 # include <X11/X.h> 00043 # include <X11/Xlib.h> 00044 # include <X11/Xutil.h> 00045 # include <X11/XKBlib.h> 00046 # include <X11/keysymdef.h> 00047 # define X11_ONLY(arg) arg, //allows to omit an argument 00048 #else 00049 # include <kckey.h> 00050 # define X11_ONLY(arg) 00051 # define XK_ISO_Left_Tab Qt::Key_Backtab 00052 # define XK_BackSpace Qt::Key_Backspace 00053 # define XK_Sys_Req Qt::Key_SysReq 00054 # define XK_Caps_Lock Qt::Key_CapsLock 00055 # define XK_Num_Lock Qt::Key_NumLock 00056 # define XK_Scroll_Lock Qt::Key_ScrollLock 00057 # define XK_Prior Qt::Key_Prior 00058 # define XK_Next Qt::Key_Next 00059 #endif 00060 00061 namespace KKeyServer 00062 { 00063 00064 //--------------------------------------------------------------------- 00065 // Data Structures 00066 //--------------------------------------------------------------------- 00067 00068 struct Mod 00069 { 00070 int m_mod; 00071 }; 00072 00073 //--------------------------------------------------------------------- 00074 // Array Structures 00075 //--------------------------------------------------------------------- 00076 00077 struct ModInfo 00078 { 00079 KKey::ModFlag mod; 00080 int modQt; 00081 #ifdef Q_WS_X11 00082 uint modX; 00083 #endif 00084 const char* psName; 00085 TQString sLabel; 00086 }; 00087 00088 struct SymVariation 00089 { 00090 uint sym, symVariation; 00091 bool bActive; 00092 }; 00093 00094 struct SymName 00095 { 00096 uint sym; 00097 const char* psName; 00098 }; 00099 00100 struct TransKey { 00101 int keySymQt; 00102 uint keySymX; 00103 }; 00104 00105 //--------------------------------------------------------------------- 00106 // Arrays 00107 //--------------------------------------------------------------------- 00108 00109 static ModInfo g_rgModInfo[KKey::MOD_FLAG_COUNT] = 00110 { 00111 { KKey::SHIFT, Qt::SHIFT, X11_ONLY(ShiftMask) I18N_NOOP("Shift"), TQString() }, 00112 { KKey::CTRL, Qt::CTRL, X11_ONLY(ControlMask) I18N_NOOP("Ctrl"), TQString() }, 00113 { KKey::ALT, Qt::ALT, X11_ONLY(Mod1Mask) I18N_NOOP("Alt"), TQString() }, 00114 { KKey::WIN, KKey::QtWIN, X11_ONLY(Mod4Mask) I18N_NOOP("Win"), TQString() } 00115 }; 00116 00117 // Special Names List 00118 static const SymName g_rgSymNames[] = { 00119 { XK_ISO_Left_Tab, "Backtab" }, 00120 { XK_BackSpace, I18N_NOOP("Backspace") }, 00121 { XK_Sys_Req, I18N_NOOP("SysReq") }, 00122 { XK_Caps_Lock, I18N_NOOP("CapsLock") }, 00123 { XK_Num_Lock, I18N_NOOP("NumLock") }, 00124 { XK_Scroll_Lock, I18N_NOOP("ScrollLock") }, 00125 { XK_Prior, I18N_NOOP("PageUp") }, 00126 { XK_Next, I18N_NOOP("PageDown") }, 00127 #ifdef sun 00128 { XK_F11, I18N_NOOP("Stop") }, 00129 { XK_F12, I18N_NOOP("Again") }, 00130 { XK_F13, I18N_NOOP("Props") }, 00131 { XK_F14, I18N_NOOP("Undo") }, 00132 { XK_F15, I18N_NOOP("Front") }, 00133 { XK_F16, I18N_NOOP("Copy") }, 00134 { XK_F17, I18N_NOOP("Open") }, 00135 { XK_F18, I18N_NOOP("Paste") }, 00136 { XK_F19, I18N_NOOP("Find") }, 00137 { XK_F20, I18N_NOOP("Cut") }, 00138 { XK_F22, I18N_NOOP("Print") }, 00139 #endif 00140 { 0, 0 } 00141 }; 00142 00143 #ifdef Q_WS_X11 00144 static SymVariation g_rgSymVariation[] = 00145 { 00146 { '/', XK_KP_Divide, false }, 00147 { '*', XK_KP_Multiply, false }, 00148 { '-', XK_KP_Subtract, false }, 00149 { '+', XK_KP_Add, false }, 00150 { XK_Return, XK_KP_Enter, false }, 00151 { 0, 0, false } 00152 }; 00153 00154 // TODO: Add Mac key names list: Key_Backspace => "Delete", Key_Delete => "Del" 00155 00156 // These are the X equivalents to the Qt keycodes 0x1000 - 0x1026 00157 static const TransKey g_rgQtToSymX[] = 00158 { 00159 { Qt::Key_Escape, XK_Escape }, 00160 { Qt::Key_Tab, XK_Tab }, 00161 { Qt::Key_Backtab, XK_ISO_Left_Tab }, 00162 { Qt::Key_Backspace, XK_BackSpace }, 00163 { Qt::Key_Return, XK_Return }, 00164 { Qt::Key_Enter, XK_KP_Enter }, 00165 { Qt::Key_Insert, XK_Insert }, 00166 { Qt::Key_Delete, XK_Delete }, 00167 { Qt::Key_Pause, XK_Pause }, 00168 #ifdef sun 00169 { Qt::Key_Print, XK_F22 }, 00170 #else 00171 { Qt::Key_Print, XK_Print }, 00172 #endif 00173 { Qt::Key_SysReq, XK_Sys_Req }, 00174 { Qt::Key_Home, XK_Home }, 00175 { Qt::Key_End, XK_End }, 00176 { Qt::Key_Left, XK_Left }, 00177 { Qt::Key_Up, XK_Up }, 00178 { Qt::Key_Right, XK_Right }, 00179 { Qt::Key_Down, XK_Down }, 00180 { TQt::Key_Prior, XK_Prior }, 00181 { TQt::Key_Next, XK_Next }, 00182 //{ Qt::Key_Shift, 0 }, 00183 //{ Qt::Key_Control, 0 }, 00184 //{ Qt::Key_Meta, 0 }, 00185 //{ Qt::Key_Alt, 0 }, 00186 { Qt::Key_CapsLock, XK_Caps_Lock }, 00187 { Qt::Key_NumLock, XK_Num_Lock }, 00188 { Qt::Key_ScrollLock, XK_Scroll_Lock }, 00189 { Qt::Key_F1, XK_F1 }, 00190 { Qt::Key_F2, XK_F2 }, 00191 { Qt::Key_F3, XK_F3 }, 00192 { Qt::Key_F4, XK_F4 }, 00193 { Qt::Key_F5, XK_F5 }, 00194 { Qt::Key_F6, XK_F6 }, 00195 { Qt::Key_F7, XK_F7 }, 00196 { Qt::Key_F8, XK_F8 }, 00197 { Qt::Key_F9, XK_F9 }, 00198 { Qt::Key_F10, XK_F10 }, 00199 { Qt::Key_F11, XK_F11 }, 00200 { Qt::Key_F12, XK_F12 }, 00201 { Qt::Key_F13, XK_F13 }, 00202 { Qt::Key_F14, XK_F14 }, 00203 { Qt::Key_F15, XK_F15 }, 00204 { Qt::Key_F16, XK_F16 }, 00205 { Qt::Key_F17, XK_F17 }, 00206 { Qt::Key_F18, XK_F18 }, 00207 { Qt::Key_F19, XK_F19 }, 00208 { Qt::Key_F20, XK_F20 }, 00209 { Qt::Key_F21, XK_F21 }, 00210 { Qt::Key_F22, XK_F22 }, 00211 { Qt::Key_F23, XK_F23 }, 00212 { Qt::Key_F24, XK_F24 }, 00213 { Qt::Key_F25, XK_F25 }, 00214 { Qt::Key_F26, XK_F26 }, 00215 { Qt::Key_F27, XK_F27 }, 00216 { Qt::Key_F28, XK_F28 }, 00217 { Qt::Key_F29, XK_F29 }, 00218 { Qt::Key_F30, XK_F30 }, 00219 { Qt::Key_F31, XK_F31 }, 00220 { Qt::Key_F32, XK_F32 }, 00221 { Qt::Key_F33, XK_F33 }, 00222 { Qt::Key_F34, XK_F34 }, 00223 { Qt::Key_F35, XK_F35 }, 00224 { Qt::Key_Super_L, XK_Super_L }, 00225 { Qt::Key_Super_R, XK_Super_R }, 00226 { Qt::Key_Menu, XK_Menu }, 00227 { Qt::Key_Hyper_L, XK_Hyper_L }, 00228 { Qt::Key_Hyper_R, XK_Hyper_R }, 00229 { Qt::Key_Help, XK_Help }, 00230 //{ Qt::Key_Direction_L, XK_Direction_L }, These keys don't exist in X11 00231 //{ Qt::Key_Direction_R, XK_Direction_R }, 00232 00233 { '/', XK_KP_Divide }, 00234 { '*', XK_KP_Multiply }, 00235 { '-', XK_KP_Subtract }, 00236 { '+', XK_KP_Add }, 00237 { Qt::Key_Return, XK_KP_Enter } 00238 #if TQT_VERSION >= 0x030100 00239 00240 // the next lines are taken from XFree > 4.0 (X11/XF86keysyms.h), defining some special 00241 // multimedia keys. They are included here as not every system has them. 00242 #define XF86XK_Standby 0x1008FF10 00243 #define XF86XK_AudioLowerVolume 0x1008FF11 00244 #define XF86XK_AudioMute 0x1008FF12 00245 #define XF86XK_AudioRaiseVolume 0x1008FF13 00246 #define XF86XK_AudioPlay 0x1008FF14 00247 #define XF86XK_AudioStop 0x1008FF15 00248 #define XF86XK_AudioPrev 0x1008FF16 00249 #define XF86XK_AudioNext 0x1008FF17 00250 #define XF86XK_HomePage 0x1008FF18 00251 #define XF86XK_Calculator 0x1008FF1D 00252 #define XF86XK_Mail 0x1008FF19 00253 #define XF86XK_Start 0x1008FF1A 00254 #define XF86XK_Search 0x1008FF1B 00255 #define XF86XK_AudioRecord 0x1008FF1C 00256 #define XF86XK_Back 0x1008FF26 00257 #define XF86XK_Forward 0x1008FF27 00258 #define XF86XK_Stop 0x1008FF28 00259 #define XF86XK_Refresh 0x1008FF29 00260 #define XF86XK_Favorites 0x1008FF30 00261 #define XF86XK_AudioPause 0x1008FF31 00262 #define XF86XK_AudioMedia 0x1008FF32 00263 #define XF86XK_MyComputer 0x1008FF33 00264 #define XF86XK_OpenURL 0x1008FF38 00265 #define XF86XK_Launch0 0x1008FF40 00266 #define XF86XK_Launch1 0x1008FF41 00267 #define XF86XK_Launch2 0x1008FF42 00268 #define XF86XK_Launch3 0x1008FF43 00269 #define XF86XK_Launch4 0x1008FF44 00270 #define XF86XK_Launch5 0x1008FF45 00271 #define XF86XK_Launch6 0x1008FF46 00272 #define XF86XK_Launch7 0x1008FF47 00273 #define XF86XK_Launch8 0x1008FF48 00274 #define XF86XK_Launch9 0x1008FF49 00275 #define XF86XK_LaunchA 0x1008FF4A 00276 #define XF86XK_LaunchB 0x1008FF4B 00277 #define XF86XK_LaunchC 0x1008FF4C 00278 #define XF86XK_LaunchD 0x1008FF4D 00279 #define XF86XK_LaunchE 0x1008FF4E 00280 #define XF86XK_LaunchF 0x1008FF4F 00281 #define XF86XK_MonBrightnessUp 0x1008FF02 /* Monitor/panel brightness */ 00282 #define XF86XK_MonBrightnessDown 0x1008FF03 /* Monitor/panel brightness */ 00283 #define XF86XK_KbdLightOnOff 0x1008FF04 /* Keyboards may be lit */ 00284 #define XF86XK_KbdBrightnessUp 0x1008FF05 /* Keyboards may be lit */ 00285 #define XF86XK_KbdBrightnessDown 0x1008FF06 /* Keyboards may be lit */ 00286 // end of XF86keysyms.h 00287 , 00288 { Qt::Key_Standby, XF86XK_Standby }, 00289 { Qt::Key_VolumeDown, XF86XK_AudioLowerVolume }, 00290 { Qt::Key_VolumeMute, XF86XK_AudioMute }, 00291 { Qt::Key_VolumeUp, XF86XK_AudioRaiseVolume }, 00292 { Qt::Key_MediaPlay, XF86XK_AudioPlay }, 00293 { Qt::Key_MediaStop, XF86XK_AudioStop }, 00294 { TQt::Key_MediaPrev, XF86XK_AudioPrev }, 00295 { Qt::Key_MediaNext, XF86XK_AudioNext }, 00296 { Qt::Key_HomePage, XF86XK_HomePage }, 00297 { Qt::Key_LaunchMail, XF86XK_Mail }, 00298 { Qt::Key_Search, XF86XK_Search }, 00299 { Qt::Key_MediaRecord, XF86XK_AudioRecord }, 00300 { Qt::Key_LaunchMedia, XF86XK_AudioMedia }, 00301 { Qt::Key_Launch1, XF86XK_Calculator }, 00302 { Qt::Key_Back, XF86XK_Back }, 00303 { Qt::Key_Forward, XF86XK_Forward }, 00304 { Qt::Key_Stop, XF86XK_Stop }, 00305 { Qt::Key_Refresh, XF86XK_Refresh }, 00306 { Qt::Key_Favorites, XF86XK_Favorites }, 00307 { Qt::Key_Launch0, XF86XK_MyComputer }, 00308 { Qt::Key_OpenUrl, XF86XK_OpenURL }, 00309 { Qt::Key_Launch2, XF86XK_Launch0 }, 00310 { Qt::Key_Launch3, XF86XK_Launch1 }, 00311 { Qt::Key_Launch4, XF86XK_Launch2 }, 00312 { Qt::Key_Launch5, XF86XK_Launch3 }, 00313 { Qt::Key_Launch6, XF86XK_Launch4 }, 00314 { Qt::Key_Launch7, XF86XK_Launch5 }, 00315 { Qt::Key_Launch8, XF86XK_Launch6 }, 00316 { Qt::Key_Launch9, XF86XK_Launch7 }, 00317 { Qt::Key_LaunchA, XF86XK_Launch8 }, 00318 { Qt::Key_LaunchB, XF86XK_Launch9 }, 00319 { Qt::Key_LaunchC, XF86XK_LaunchA }, 00320 { Qt::Key_LaunchD, XF86XK_LaunchB }, 00321 { Qt::Key_LaunchE, XF86XK_LaunchC }, 00322 { Qt::Key_LaunchF, XF86XK_LaunchD }, 00323 { Qt::Key_MonBrightnessUp, XF86XK_MonBrightnessUp }, 00324 { Qt::Key_MonBrightnessDown, XF86XK_MonBrightnessDown }, 00325 { Qt::Key_KeyboardLightOnOff, XF86XK_KbdLightOnOff }, 00326 { Qt::Key_KeyboardBrightnessUp, XF86XK_KbdBrightnessUp }, 00327 { Qt::Key_KeyboardBrightnessDown, XF86XK_KbdBrightnessDown }, 00328 #endif 00329 }; 00330 #endif //Q_WS_X11 00331 00332 //--------------------------------------------------------------------- 00333 // Initialization 00334 //--------------------------------------------------------------------- 00335 static bool g_bInitializedMods, g_bInitializedVariations, g_bInitializedKKeyLabels; 00336 static bool g_bMacLabels; 00337 #ifdef Q_WS_X11 00338 static uint g_modXNumLock, g_modXScrollLock, g_modXModeSwitch; 00339 00340 bool initializeMods() 00341 { 00342 XModifierKeymap* xmk = XGetModifierMapping( tqt_xdisplay() ); 00343 00344 g_rgModInfo[3].modX = g_modXNumLock = g_modXScrollLock = g_modXModeSwitch = 0; 00345 00346 int min_keycode, max_keycode; 00347 int keysyms_per_keycode = 0; 00348 XDisplayKeycodes( tqt_xdisplay(), &min_keycode, &max_keycode ); 00349 XFree( XGetKeyboardMapping( tqt_xdisplay(), min_keycode, 1, &keysyms_per_keycode )); 00350 // Qt assumes that Alt is always Mod1Mask, so start at Mod2Mask. 00351 for( int i = Mod2MapIndex; i < 8; i++ ) { 00352 uint mask = (1 << i); 00353 uint keySymX = NoSymbol; 00354 // This used to be only XkbKeycodeToKeysym( ... , 0, 0 ), but that fails with XFree4.3.99 00355 // and X.org R6.7 , where for some reason only ( ... , 0, 1 ) works. I have absolutely no 00356 // idea what the problem is, but searching all posibilities until something valid is 00357 // found fixes the problem. 00358 for( int j = 0; j < xmk->max_keypermod && keySymX == NoSymbol; ++j ) 00359 for( int k = 0; k < keysyms_per_keycode && keySymX == NoSymbol; ++k ) 00360 keySymX = XkbKeycodeToKeysym( tqt_xdisplay(), xmk->modifiermap[xmk->max_keypermod * i + j], 0, k ); 00361 switch( keySymX ) { 00362 case XK_Num_Lock: g_modXNumLock = mask; break; // Normally Mod2Mask 00363 case XK_Super_L: 00364 case XK_Super_R: g_rgModInfo[3].modX = mask; break; // Win key, Normally Mod4Mask 00365 case XK_Meta_L: 00366 case XK_Meta_R: if( !g_rgModInfo[3].modX ) g_rgModInfo[3].modX = mask; break; // Win alternate 00367 case XK_Scroll_Lock: g_modXScrollLock = mask; break; // Normally Mod5Mask 00368 case XK_Mode_switch: g_modXModeSwitch = mask; break; 00369 } 00370 } 00371 00372 XFreeModifiermap( xmk ); 00373 00374 //TDEConfigGroupSaver cgs( TDEGlobal::config(), "Keyboard" ); 00375 // read in mod that win should be attached to 00376 00377 g_bInitializedMods = true; 00378 00379 kdDebug(125) << "KKeyServer::initializeMods(): Win Mod = 0x" << TQString::number(g_rgModInfo[3].modX, 16) << endl; 00380 return true; 00381 } 00382 00383 static void initializeVariations() 00384 { 00385 for( int i = 0; g_rgSymVariation[i].sym != 0; i++ ) 00386 g_rgSymVariation[i].bActive = (XKeysymToKeycode( tqt_xdisplay(), g_rgSymVariation[i].symVariation ) != 0); 00387 g_bInitializedVariations = true; 00388 } 00389 #endif //Q_WS_X11 00390 00391 static void intializeKKeyLabels() 00392 { 00393 TDEConfigGroupSaver cgs( TDEGlobal::config(), "Keyboard" ); 00394 g_rgModInfo[0].sLabel = TDEGlobal::config()->readEntry( "Label Shift", i18n(g_rgModInfo[0].psName) ); 00395 g_rgModInfo[1].sLabel = TDEGlobal::config()->readEntry( "Label Ctrl", i18n(g_rgModInfo[1].psName) ); 00396 g_rgModInfo[2].sLabel = TDEGlobal::config()->readEntry( "Label Alt", i18n(g_rgModInfo[2].psName) ); 00397 g_rgModInfo[3].sLabel = TDEGlobal::config()->readEntry( "Label Win", i18n(g_rgModInfo[3].psName) ); 00398 g_bMacLabels = (g_rgModInfo[2].sLabel == "Command"); 00399 g_bInitializedKKeyLabels = true; 00400 } 00401 00402 //--------------------------------------------------------------------- 00403 // class Mod 00404 //--------------------------------------------------------------------- 00405 00406 /*void Mod::init( const TQString& s ) 00407 { 00408 00409 }*/ 00410 00411 //--------------------------------------------------------------------- 00412 // class Sym 00413 //--------------------------------------------------------------------- 00414 00415 bool Sym::initQt( int keyQt ) 00416 { 00417 int symQt = keyQt & 0xffff; 00418 00419 if( (keyQt & Qt::UNICODE_ACCEL) || symQt < 0x1000 ) { 00420 m_sym = TQChar(symQt).lower().unicode(); 00421 return true; 00422 } 00423 00424 #ifdef Q_WS_WIN 00425 m_sym = symQt; 00426 return true; 00427 #elif defined(Q_WS_X11) 00428 for( uint i = 0; i < sizeof(g_rgQtToSymX)/sizeof(TransKey); i++ ) { 00429 if( g_rgQtToSymX[i].keySymQt == symQt ) { 00430 m_sym = g_rgQtToSymX[i].keySymX; 00431 return true; 00432 } 00433 } 00434 00435 m_sym = 0; 00436 if( symQt != Qt::Key_Shift && symQt != Qt::Key_Control && symQt != Qt::Key_Alt && 00437 symQt != Qt::Key_Meta && symQt != Qt::Key_Direction_L && symQt != Qt::Key_Direction_R ) 00438 kdDebug(125) << "Sym::initQt( " << TQString::number(keyQt,16) << " ): failed to convert key." << endl; 00439 return false; 00440 #elif defined(Q_WS_MACX) 00441 m_sym = symQt; 00442 return true; 00443 #endif 00444 } 00445 00446 bool Sym::init( const TQString& s ) 00447 { 00448 // If it's a single character, get unicode value. 00449 if( s.length() == 1 ) { 00450 m_sym = s[0].lower().unicode(); 00451 return true; 00452 } 00453 00454 // Look up in special names list 00455 for( int i = 0; g_rgSymNames[i].sym != 0; i++ ) { 00456 if( tqstricmp( s.latin1(), g_rgSymNames[i].psName ) == 0 ) { 00457 m_sym = g_rgSymNames[i].sym; 00458 return true; 00459 } 00460 } 00461 00462 #ifdef Q_WS_WIN 00463 // search for name in KKeys array 00464 for ( KKeys const *pKey = kde_KKEYS; pKey->code != 0xffff; pKey++) { 00465 if( tqstricmp( s.latin1(), pKey->name ) == 0 ) { 00466 m_sym = pKey->code; 00467 return true; 00468 } 00469 } 00470 m_sym = 0; 00471 #elif defined(Q_WS_X11) 00472 // search X list: 's' as is, all lower, first letter in caps 00473 m_sym = XStringToKeysym( s.latin1() ); 00474 if( !m_sym ) { 00475 m_sym = XStringToKeysym( s.lower().latin1() ); 00476 if( !m_sym ) { 00477 TQString s2 = s; 00478 s2[0] = s2[0].upper(); 00479 m_sym = XStringToKeysym( s2.latin1() ); 00480 } 00481 } 00482 #endif 00483 return m_sym != 0; 00484 } 00485 00486 int Sym::qt() const 00487 { 00488 if( m_sym < 0x1000 ) { 00489 if( m_sym >= 'a' && m_sym <= 'z' ) 00490 return TQChar(m_sym).upper(); 00491 return m_sym; 00492 } 00493 #ifdef Q_WS_WIN 00494 if( m_sym < 0x3000 ) 00495 return m_sym; 00496 #elif defined(Q_WS_X11) 00497 if( m_sym < 0x3000 ) 00498 return m_sym | Qt::UNICODE_ACCEL; 00499 00500 for( uint i = 0; i < sizeof(g_rgQtToSymX)/sizeof(TransKey); i++ ) 00501 if( g_rgQtToSymX[i].keySymX == m_sym ) 00502 return g_rgQtToSymX[i].keySymQt; 00503 #endif 00504 return TQt::Key_unknown; 00505 } 00506 00507 TQString Sym::toString( bool bUserSpace ) const 00508 { 00509 if( m_sym == 0 ) { 00510 return TQString::null; 00511 } 00512 00513 // If it's a unicode character, 00514 #ifdef Q_WS_WIN 00515 else if( m_sym < 0x1000 ) { 00516 #else 00517 else if( m_sym < 0x3000 ) { 00518 #endif 00519 TQChar c = TQChar(m_sym).upper(); 00520 // Print all non-space characters directly when output is user-visible. 00521 // Otherwise only print alphanumeric latin1 characters directly (A,B,C,1,2,3). 00522 if( (c.latin1() && c.isLetterOrNumber()) 00523 || (bUserSpace && !c.isSpace()) ) { 00524 return c; 00525 } 00526 } 00527 00528 // Look up in special names list 00529 for( int i = 0; g_rgSymNames[i].sym != 0; i++ ) { 00530 if( m_sym == g_rgSymNames[i].sym ) { 00531 return bUserSpace ? i18n(g_rgSymNames[i].psName) : TQString(g_rgSymNames[i].psName); 00532 } 00533 } 00534 00535 TQString s; 00536 #ifdef Q_WS_WIN 00537 s = TQKeySequence( m_sym ); 00538 #elif defined(Q_WS_X11) 00539 // Get X-name 00540 s = XKeysymToString( m_sym ); 00541 #endif 00542 capitalizeKeyname( s ); 00543 return bUserSpace ? i18n("TQAccel", s.latin1()) : s; 00544 } 00545 00546 TQString Sym::toStringInternal() const { return toString( false ); } 00547 TQString Sym::toString() const { return toString( true ); } 00548 00549 uint Sym::getModsRequired() const 00550 { 00551 uint mod = 0; 00552 #ifdef Q_WS_X11 00553 // FIXME: This might not be true on all keyboard layouts! 00554 if( m_sym == XK_Sys_Req ) return KKey::ALT; 00555 if( m_sym == XK_Break ) return KKey::CTRL; 00556 00557 if( m_sym < 0x3000 ) { 00558 TQChar c(m_sym); 00559 if( c.isLetter() && c.lower() != c.upper() && m_sym == c.upper().unicode() ) 00560 return KKey::SHIFT; 00561 } 00562 00563 uchar code = XKeysymToKeycode( tqt_xdisplay(), m_sym ); 00564 if( code ) { 00565 // need to check index 0 before the others, so that a null-mod 00566 // can take precedence over the others, in case the modified 00567 // key produces the same symbol. 00568 if( m_sym == XkbKeycodeToKeysym( tqt_xdisplay(), code, 0, 0 ) ) 00569 ; 00570 else if( m_sym == XkbKeycodeToKeysym( tqt_xdisplay(), code, 0, 1 ) ) 00571 mod = KKey::SHIFT; 00572 else if( m_sym == XkbKeycodeToKeysym( tqt_xdisplay(), code, 0, 2 ) ) 00573 mod = KKeyServer::MODE_SWITCH; 00574 else if( m_sym == XkbKeycodeToKeysym( tqt_xdisplay(), code, 0, 3 ) ) 00575 mod = KKey::SHIFT | KKeyServer::MODE_SWITCH; 00576 } 00577 #endif 00578 return mod; 00579 } 00580 00581 uint Sym::getSymVariation() const 00582 { 00583 #ifdef Q_WS_X11 00584 if( !g_bInitializedVariations ) 00585 initializeVariations(); 00586 for( int i = 0; g_rgSymVariation[i].sym != 0; i++ ) 00587 if( g_rgSymVariation[i].sym == m_sym && g_rgSymVariation[i].bActive ) 00588 return g_rgSymVariation[i].symVariation; 00589 #endif 00590 return 0; 00591 } 00592 00593 void Sym::capitalizeKeyname( TQString& s ) 00594 { 00595 s[0] = s[0].upper(); 00596 int len = s.length(); 00597 if( s.endsWith( "left" ) ) s[len-4] = 'L'; 00598 else if( s.endsWith( "right" ) ) s[len-5] = 'R'; 00599 else if( s == "Sysreq" ) s[len-3] = 'R'; 00600 } 00601 00602 //--------------------------------------------------------------------- 00603 // Public functions 00604 //--------------------------------------------------------------------- 00605 00606 #ifdef Q_WS_X11 00607 uint modX( KKey::ModFlag mod ) 00608 { 00609 if( mod == KKey::WIN && !g_bInitializedMods ) 00610 initializeMods(); 00611 00612 for( uint i = 0; i < KKey::MOD_FLAG_COUNT; i++ ) { 00613 if( g_rgModInfo[i].mod == mod ) 00614 return g_rgModInfo[i].modX; 00615 } 00616 return 0; 00617 } 00618 00619 bool keyboardHasWinKey() { if( !g_bInitializedMods ) { initializeMods(); } return g_rgModInfo[3].modX != 0; } 00620 uint modXShift() { return ShiftMask; } 00621 uint modXLock() { return LockMask; } 00622 uint modXCtrl() { return ControlMask; } 00623 uint modXAlt() { return Mod1Mask; } 00624 uint modXNumLock() { if( !g_bInitializedMods ) { initializeMods(); } return g_modXNumLock; } 00625 uint modXWin() { if( !g_bInitializedMods ) { initializeMods(); } return g_rgModInfo[3].modX; } 00626 uint modXScrollLock() { if( !g_bInitializedMods ) { initializeMods(); } return g_modXScrollLock; } 00627 uint modXModeSwitch() { if( !g_bInitializedMods ) { initializeMods(); } return g_modXModeSwitch; } 00628 00629 uint accelModMaskX() 00630 { 00631 if( !g_bInitializedMods ) 00632 initializeMods(); 00633 return ShiftMask | ControlMask | Mod1Mask | g_rgModInfo[3].modX; 00634 } 00635 #endif //Q_WS_X11 00636 00637 bool keyQtToSym( int keyQt, uint& keySym ) 00638 { 00639 Sym sym; 00640 if( sym.initQt( keyQt ) ) { 00641 keySym = sym.m_sym; 00642 return true; 00643 } else 00644 return false; 00645 } 00646 00647 bool keyQtToMod( int keyQt, uint& mod ) 00648 { 00649 mod = 0; 00650 00651 if( keyQt & Qt::SHIFT ) mod |= KKey::SHIFT; 00652 if( keyQt & Qt::CTRL ) mod |= KKey::CTRL; 00653 if( keyQt & Qt::ALT ) mod |= KKey::ALT; 00654 if( keyQt & Qt::META ) mod |= KKey::WIN; 00655 00656 return true; 00657 } 00658 00659 bool symToKeyQt( uint keySym, int& keyQt ) 00660 { 00661 Sym sym( keySym ); 00662 keyQt = sym.qt(); 00663 return (keyQt != TQt::Key_unknown); 00664 } 00665 00666 bool modToModQt( uint mod, int& modQt ) 00667 { 00668 modQt = 0; 00669 for( int i = 0; i < KKey::MOD_FLAG_COUNT; i++ ) { 00670 if( mod & g_rgModInfo[i].mod ) { 00671 if( !g_rgModInfo[i].modQt ) { 00672 modQt = 0; 00673 return false; 00674 } 00675 modQt |= g_rgModInfo[i].modQt; 00676 } 00677 } 00678 return true; 00679 } 00680 00681 #ifdef Q_WS_WIN 00682 //wrapped 00683 bool modXToModQt( uint modX, int& modQt ) 00684 { 00685 return modToModQt( modX, modQt ); 00686 } 00687 00688 TDECORE_EXPORT int qtButtonStateToMod( TQt::ButtonState s ) 00689 { 00690 int modQt = 0; 00691 if (s & Qt::ShiftButton) modQt |= KKey::SHIFT; 00692 if (s & Qt::ControlButton) modQt |= KKey::CTRL; 00693 if (s & Qt::AltButton) modQt |= KKey::ALT; 00694 return modQt; 00695 } 00696 00697 bool keyboardHasWinKey() { 00699 return true; 00700 } 00701 00702 #elif defined(Q_WS_MACX) 00703 00704 bool modXToModQt(uint modX, int& modQt) 00705 { 00706 return modToModQt( modX, modQt ); 00707 } 00708 00709 bool keyboardHasWinKey() { 00711 return false; 00712 } 00713 00714 bool modXToMod( uint , uint& ) 00715 { 00716 return false; 00717 } 00718 #elif defined(Q_WS_X11) 00719 00720 bool modToModX( uint mod, uint& modX ) 00721 { 00722 if( !g_bInitializedMods ) 00723 initializeMods(); 00724 00725 modX = 0; 00726 for( int i = 0; i < KKey::MOD_FLAG_COUNT; i++ ) { 00727 if( mod & g_rgModInfo[i].mod ) { 00728 if( !g_rgModInfo[i].modX ) { 00729 kdDebug(125) << "Invalid modifier flag." << endl; 00730 modX = 0; 00731 return false; 00732 } 00733 modX |= g_rgModInfo[i].modX; 00734 } 00735 } 00736 // TODO: document 0x2000 flag 00737 if( mod & 0x2000 ) 00738 modX |= 0x2000; 00739 return true; 00740 } 00741 00742 bool modXToModQt( uint modX, int& modQt ) 00743 { 00744 if( !g_bInitializedMods ) 00745 initializeMods(); 00746 00747 modQt = 0; 00748 for( int i = 0; i < KKey::MOD_FLAG_COUNT; i++ ) { 00749 if( modX & g_rgModInfo[i].modX ) { 00750 if( !g_rgModInfo[i].modQt ) { 00751 modQt = 0; 00752 return false; 00753 } 00754 modQt |= g_rgModInfo[i].modQt; 00755 } 00756 } 00757 return true; 00758 } 00759 00760 bool modXToMod( uint modX, uint& mod ) 00761 { 00762 if( !g_bInitializedMods ) 00763 initializeMods(); 00764 00765 mod = 0; 00766 for( int i = 0; i < KKey::MOD_FLAG_COUNT; i++ ) { 00767 if( modX & g_rgModInfo[i].modX ) 00768 mod |= g_rgModInfo[i].mod; 00769 } 00770 return true; 00771 } 00772 00773 bool codeXToSym( uchar codeX, uint modX, uint& sym ) 00774 { 00775 KeySym keySym; 00776 XKeyPressedEvent event; 00777 00778 event.type = KeyPress; 00779 event.display = tqt_xdisplay(); 00780 event.state = modX; 00781 event.keycode = codeX; 00782 00783 char buffer[64]; 00784 XLookupString( &event, buffer, 63, &keySym, NULL ); 00785 sym = (uint) keySym; 00786 return true; 00787 } 00788 #endif //!Q_WS_WIN 00789 00790 static TQString modToString( uint mod, bool bUserSpace ) 00791 { 00792 if( bUserSpace && !g_bInitializedKKeyLabels ) 00793 intializeKKeyLabels(); 00794 00795 TQString s; 00796 for( int i = KKey::MOD_FLAG_COUNT-1; i >= 0; i-- ) { 00797 if( mod & g_rgModInfo[i].mod ) { 00798 if( !s.isEmpty() ) 00799 s += '+'; 00800 s += (bUserSpace) 00801 ? g_rgModInfo[i].sLabel 00802 : TQString(g_rgModInfo[i].psName); 00803 } 00804 } 00805 return s; 00806 } 00807 00808 TQString modToStringInternal( uint mod ) { return modToString( mod, false ); } 00809 TQString modToStringUser( uint mod ) { return modToString( mod, true ); } 00810 00811 uint stringUserToMod( const TQString& mod ) 00812 { 00813 if( !g_bInitializedKKeyLabels ) 00814 intializeKKeyLabels(); 00815 00816 TQString s; 00817 for( int i = KKey::MOD_FLAG_COUNT-1; i >= 0; i-- ) { 00818 if( mod.lower() == g_rgModInfo[i].sLabel.lower()) 00819 return g_rgModInfo[i].mod; 00820 } 00821 return 0; 00822 } 00823 00824 /*void keySymModToKeyX( uint sym, uint mod, unsigned char *pKeyCodeX, uint *pKeySymX, uint *pKeyModX ) 00825 { 00826 ... 00827 uint keySymQt; 00828 uint keySymX = 0; 00829 unsigned char keyCodeX = 0; 00830 uint keyModX = 0; 00831 00832 const char *psKeySym = 0; 00833 00834 if( !g_bInitialized ) 00835 Initialize(); 00836 00837 // Get code of just the primary key 00838 keySymQt = keyCombQt & 0xffff; 00839 00840 // If unicode value beneath 0x1000 (special Qt codes begin thereafter), 00841 if( keySymQt < 0x1000 ) { 00842 // For reasons unbeknownst to me, Qt converts 'a-z' to 'A-Z'. 00843 // So convert it back to lowercase if SHIFT isn't held down. 00844 if( keySymQt >= Qt::Key_A && keySymQt <= Qt::Key_Z && !(keyCombQt & Qt::SHIFT) ) 00845 keySymQt = tolower( keySymQt ); 00846 keySymX = keySymQt; 00847 } 00848 // Else, special key (e.g. Delete, F1, etc.) 00849 else { 00850 for( int i = 0; i < NB_KEYS; i++ ) { 00851 if( keySymQt == (uint) KKEYS[i].code ) { 00852 psKeySym = KKEYS[i].name; 00853 //kdDebug(125) << " symbol found: \"" << psKeySym << "\"" << endl; 00854 break; 00855 } 00856 } 00857 00858 // Get X key symbol. Only works if Qt name is same as X name. 00859 if( psKeySym ) { 00860 TQString sKeySym = psKeySym; 00861 00862 // Check for lower-case equalent first because most 00863 // X11 names are all lower-case. 00864 keySymX = XStringToKeysym( sKeySym.lower().ascii() ); 00865 if( keySymX == 0 ) 00866 keySymX = XStringToKeysym( psKeySym ); 00867 } 00868 00869 if( keySymX == 0 ) 00870 keySymX = getSymXEquiv( keySymQt ); 00871 } 00872 00873 if( keySymX != 0 ) { 00874 // Get X keyboard code 00875 keyCodeX = XKeysymToKeycode( tqt_xdisplay(), keySymX ); 00876 // Add ModeSwitch modifier bit, if necessary 00877 keySymXMods( keySymX, 0, &keyModX ); 00878 00879 // Get X modifier flags 00880 for( int i = 0; i < MOD_KEYS; i++ ) { 00881 if( keyCombQt & g_aModKeys[i].keyModMaskQt ) { 00882 if( g_aModKeys[i].keyModMaskX ) 00883 keyModX |= g_aModKeys[i].keyModMaskX; 00884 // Qt key calls for a modifier which the current 00885 // X modifier map doesn't support. 00886 else { 00887 keySymX = 0; 00888 keyCodeX = 0; 00889 keyModX = 0; 00890 break; 00891 } 00892 } 00893 } 00894 } 00895 00896 // Take care of complications: 00897 // The following keys will not have been correctly interpreted, 00898 // because their shifted values are not activated with the 00899 // Shift key, but rather something else. They are also 00900 // defined twice under different keycodes. 00901 // keycode 111 & 92: Print Sys_Req -> Sys_Req = Alt+Print 00902 // keycode 110 & 114: Pause Break -> Break = Ctrl+Pause 00903 if( (keyCodeX == 92 || keyCodeX == 111) && 00904 XkbKeycodeToKeysym( tqt_xdisplay(), 92, 0, 0 ) == XK_Print && 00905 XkbKeycodeToKeysym( tqt_xdisplay(), 111, 0, 0 ) == XK_Print ) 00906 { 00907 // If Alt is pressed, then we need keycode 92, keysym XK_Sys_Req 00908 if( keyModX & keyModXAlt() ) { 00909 keyCodeX = 92; 00910 keySymX = XK_Sys_Req; 00911 } 00912 // Otherwise, keycode 111, keysym XK_Print 00913 else { 00914 keyCodeX = 111; 00915 keySymX = XK_Print; 00916 } 00917 } 00918 else if( (keyCodeX == 110 || keyCodeX == 114) && 00919 XkbKeycodeToKeysym( tqt_xdisplay(), 110, 0, 0 ) == XK_Pause && 00920 XkbKeycodeToKeysym( tqt_xdisplay(), 114, 0, 0 ) == XK_Pause ) 00921 { 00922 if( keyModX & keyModXCtrl() ) { 00923 keyCodeX = 114; 00924 keySymX = XK_Break; 00925 } else { 00926 keyCodeX = 110; 00927 keySymX = XK_Pause; 00928 } 00929 } 00930 00931 if( pKeySymX ) *pKeySymX = keySymX; 00932 if( pKeyCodeX ) *pKeyCodeX = keyCodeX; 00933 if( pKeyModX ) *pKeyModX = keyModX; 00934 }*/ 00935 00936 //--------------------------------------------------------------------- 00937 // Key 00938 //--------------------------------------------------------------------- 00939 00940 bool Key::init( const KKey& key, bool bQt ) 00941 { 00942 if( bQt ) { 00943 m_code = CODE_FOR_QT; 00944 m_sym = key.keyCodeQt(); 00945 } else { 00946 KKeyNative keyNative( key ); 00947 *this = keyNative; 00948 } 00949 return true; 00950 } 00951 00952 KKey Key::key() const 00953 { 00954 if( m_code == CODE_FOR_QT ) 00955 return KKey( keyCodeQt() ); 00956 else { 00957 #if defined(Q_WS_WIN) || defined(Q_WS_MACX) 00958 return KKey(); 00959 #else 00960 uint mod; 00961 modXToMod( m_mod, mod ); 00962 return KKey( m_sym, mod ); 00963 #endif 00964 } 00965 } 00966 00967 Key& Key::operator =( const KKeyNative& key ) 00968 { 00969 m_code = key.code(); m_mod = key.mod(); m_sym = key.sym(); 00970 return *this; 00971 } 00972 00973 int Key::compare( const Key& b ) const 00974 { 00975 if( m_code == CODE_FOR_QT ) 00976 return m_sym - b.m_sym; 00977 if( m_sym != b.m_sym ) return m_sym - b.m_sym; 00978 if( m_mod != b.m_mod ) return m_mod - b.m_mod; 00979 return m_code - b.m_code; 00980 } 00981 00982 //--------------------------------------------------------------------- 00983 // Variations 00984 //--------------------------------------------------------------------- 00985 00986 // TODO: allow for sym to have variations, such as Plus => { Plus, KP_Add } 00987 void Variations::init( const KKey& key, bool bQt ) 00988 { 00989 if( key.isNull() ) { 00990 m_nVariations = 0; 00991 return; 00992 } 00993 00994 m_nVariations = 1; 00995 m_rgkey[0] = KKeyNative(key); 00996 uint symVar = Sym(key.sym()).getSymVariation(); 00997 if( symVar ) { 00998 uint modReq = Sym(m_rgkey[0].sym()).getModsRequired(); 00999 uint modReqVar = Sym(symVar).getModsRequired(); 01000 // If 'key' doesn't require any mods that are inherent in 01001 // the primary key but not required for the alternate, 01002 if( (key.modFlags() & modReq) == (key.modFlags() & modReqVar) ) { 01003 m_rgkey[1] = KKeyNative(KKey(symVar, key.modFlags())); 01004 m_nVariations = 2; 01005 } 01006 } 01007 01008 if( bQt ) { 01009 uint nVariations = 0; 01010 for( uint i = 0; i < m_nVariations; i++ ) { 01011 int keyQt = KKeyNative( m_rgkey[i].code(), m_rgkey[i].mod(), m_rgkey[i].sym() ).keyCodeQt(); 01012 if( keyQt ) { 01013 m_rgkey[nVariations++].setKeycodeQt( keyQt ); 01014 } 01015 } 01016 m_nVariations = nVariations; 01017 01018 // Two different native codes may produce a single 01019 // Qt code. Search for duplicates. 01020 for( uint i = 1; i < m_nVariations; i++ ) { 01021 for( uint j = 0; j < i; j++ ) { 01022 // If key is already present in list, then remove it. 01023 if( m_rgkey[i].keyCodeQt() == m_rgkey[j].keyCodeQt() ) { 01024 for( uint k = i; k < m_nVariations - 1; k++ ) { 01025 m_rgkey[k].setKeycodeQt( m_rgkey[k+1].keyCodeQt() ); 01026 } 01027 m_nVariations--; 01028 i--; 01029 break; 01030 } 01031 } 01032 } 01033 } 01034 } 01035 01036 } // end of namespace KKeyServer block 01037 01038 // FIXME: This needs to be moved to tdeshortcut.cpp, and create a 01039 // KKeyServer::method which it will call. 01040 // Alt+SysReq => Alt+Print 01041 // Ctrl+Shift+Plus => Ctrl+Plus (en) 01042 // Ctrl+Shift+Equal => Ctrl+Plus 01043 // Ctrl+Pause => Ctrl+Break 01044 void KKey::simplify() 01045 { 01046 #ifdef Q_WS_X11 01047 if( m_sym == XK_Sys_Req ) { 01048 m_sym = XK_Print; 01049 m_mod |= ALT; 01050 } else if( m_sym == XK_ISO_Left_Tab ) { 01051 m_sym = XK_Tab; 01052 m_mod |= SHIFT; 01053 } else { 01054 // Shift+Equal => Shift+Plus (en) 01055 m_sym = KKeyNative(*this).sym(); 01056 } 01057 01058 // If this is a letter, don't remove any modifiers. 01059 if( m_sym < 0x3000 && TQChar(m_sym).isLetter() ) { 01060 m_sym = TQChar(m_sym).lower().unicode(); 01061 } 01062 01063 // Remove modifers from modifier list which are implicit in the symbol. 01064 // Ex. Shift+Plus => Plus (en) 01065 m_mod &= ~KKeyServer::Sym(m_sym).getModsRequired(); 01066 #endif 01067 } 01068 01069 #endif //Q_WS_X11 || Q_WS_WIN 01070