00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023 #include <config.h>
00024
00025 #include <qnamespace.h>
00026 #include <qwindowdefs.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 "kshortcut.h"
00033
00034 #include <kconfig.h>
00035 #include <kdebug.h>
00036 #include <kglobal.h>
00037 #include <klocale.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/keysymdef.h>
00046 # define X11_ONLY(arg) arg, //allows to omit an argument
00047 #else
00048 # include <kckey.h>
00049 # define X11_ONLY(arg)
00050 # define XK_ISO_Left_Tab Qt::Key_Backtab
00051 # define XK_BackSpace Qt::Key_Backspace
00052 # define XK_Sys_Req Qt::Key_SysReq
00053 # define XK_Caps_Lock Qt::Key_CapsLock
00054 # define XK_Num_Lock Qt::Key_NumLock
00055 # define XK_Scroll_Lock Qt::Key_ScrollLock
00056 # define XK_Prior Qt::Key_Prior
00057 # define XK_Next Qt::Key_Next
00058 #endif
00059
00060 namespace KKeyServer
00061 {
00062
00063
00064
00065
00066
00067 struct Mod
00068 {
00069 int m_mod;
00070 };
00071
00072
00073
00074
00075
00076 struct ModInfo
00077 {
00078 KKey::ModFlag mod;
00079 int modQt;
00080 #ifdef Q_WS_X11
00081 uint modX;
00082 #endif
00083 const char* psName;
00084 QString sLabel;
00085 };
00086
00087 struct SymVariation
00088 {
00089 uint sym, symVariation;
00090 bool bActive;
00091 };
00092
00093 struct SymName
00094 {
00095 uint sym;
00096 const char* psName;
00097 };
00098
00099 struct TransKey {
00100 int keySymQt;
00101 uint keySymX;
00102 };
00103
00104
00105
00106
00107
00108 static ModInfo g_rgModInfo[KKey::MOD_FLAG_COUNT] =
00109 {
00110 { KKey::SHIFT, Qt::SHIFT, X11_ONLY(ShiftMask) I18N_NOOP("Shift"), QString() },
00111 { KKey::CTRL, Qt::CTRL, X11_ONLY(ControlMask) I18N_NOOP("Ctrl"), QString() },
00112 { KKey::ALT, Qt::ALT, X11_ONLY(Mod1Mask) I18N_NOOP("Alt"), QString() },
00113 { KKey::WIN, KKey::QtWIN, X11_ONLY(Mod4Mask) I18N_NOOP("Win"), QString() }
00114 };
00115
00116
00117 static const SymName g_rgSymNames[] = {
00118 { XK_ISO_Left_Tab, "Backtab" },
00119 { XK_BackSpace, I18N_NOOP("Backspace") },
00120 { XK_Sys_Req, I18N_NOOP("SysReq") },
00121 { XK_Caps_Lock, I18N_NOOP("CapsLock") },
00122 { XK_Num_Lock, I18N_NOOP("NumLock") },
00123 { XK_Scroll_Lock, I18N_NOOP("ScrollLock") },
00124 { XK_Prior, I18N_NOOP("PageUp") },
00125 { XK_Next, I18N_NOOP("PageDown") },
00126 #ifdef sun
00127 { XK_F11, I18N_NOOP("Stop") },
00128 { XK_F12, I18N_NOOP("Again") },
00129 { XK_F13, I18N_NOOP("Props") },
00130 { XK_F14, I18N_NOOP("Undo") },
00131 { XK_F15, I18N_NOOP("Front") },
00132 { XK_F16, I18N_NOOP("Copy") },
00133 { XK_F17, I18N_NOOP("Open") },
00134 { XK_F18, I18N_NOOP("Paste") },
00135 { XK_F19, I18N_NOOP("Find") },
00136 { XK_F20, I18N_NOOP("Cut") },
00137 { XK_F22, I18N_NOOP("Print") },
00138 #endif
00139 { 0, 0 }
00140 };
00141
00142 #ifdef Q_WS_X11
00143 static SymVariation g_rgSymVariation[] =
00144 {
00145 { '/', XK_KP_Divide, false },
00146 { '*', XK_KP_Multiply, false },
00147 { '-', XK_KP_Subtract, false },
00148 { '+', XK_KP_Add, false },
00149 { XK_Return, XK_KP_Enter, false },
00150 { 0, 0, false }
00151 };
00152
00153
00154
00155
00156 static const TransKey g_rgQtToSymX[] =
00157 {
00158 { Qt::Key_Escape, XK_Escape },
00159 { Qt::Key_Tab, XK_Tab },
00160 { Qt::Key_Backtab, XK_ISO_Left_Tab },
00161 { Qt::Key_Backspace, XK_BackSpace },
00162 { Qt::Key_Return, XK_Return },
00163 { Qt::Key_Enter, XK_KP_Enter },
00164 { Qt::Key_Insert, XK_Insert },
00165 { Qt::Key_Delete, XK_Delete },
00166 { Qt::Key_Pause, XK_Pause },
00167 #ifdef sun
00168 { Qt::Key_Print, XK_F22 },
00169 #else
00170 { Qt::Key_Print, XK_Print },
00171 #endif
00172 { Qt::Key_SysReq, XK_Sys_Req },
00173 { Qt::Key_Home, XK_Home },
00174 { Qt::Key_End, XK_End },
00175 { Qt::Key_Left, XK_Left },
00176 { Qt::Key_Up, XK_Up },
00177 { Qt::Key_Right, XK_Right },
00178 { Qt::Key_Down, XK_Down },
00179 { Qt::Key_Prior, XK_Prior },
00180 { Qt::Key_Next, XK_Next },
00181
00182
00183
00184
00185 { Qt::Key_CapsLock, XK_Caps_Lock },
00186 { Qt::Key_NumLock, XK_Num_Lock },
00187 { Qt::Key_ScrollLock, XK_Scroll_Lock },
00188 { Qt::Key_F1, XK_F1 },
00189 { Qt::Key_F2, XK_F2 },
00190 { Qt::Key_F3, XK_F3 },
00191 { Qt::Key_F4, XK_F4 },
00192 { Qt::Key_F5, XK_F5 },
00193 { Qt::Key_F6, XK_F6 },
00194 { Qt::Key_F7, XK_F7 },
00195 { Qt::Key_F8, XK_F8 },
00196 { Qt::Key_F9, XK_F9 },
00197 { Qt::Key_F10, XK_F10 },
00198 { Qt::Key_F11, XK_F11 },
00199 { Qt::Key_F12, XK_F12 },
00200 { Qt::Key_F13, XK_F13 },
00201 { Qt::Key_F14, XK_F14 },
00202 { Qt::Key_F15, XK_F15 },
00203 { Qt::Key_F16, XK_F16 },
00204 { Qt::Key_F17, XK_F17 },
00205 { Qt::Key_F18, XK_F18 },
00206 { Qt::Key_F19, XK_F19 },
00207 { Qt::Key_F20, XK_F20 },
00208 { Qt::Key_F21, XK_F21 },
00209 { Qt::Key_F22, XK_F22 },
00210 { Qt::Key_F23, XK_F23 },
00211 { Qt::Key_F24, XK_F24 },
00212 { Qt::Key_F25, XK_F25 },
00213 { Qt::Key_F26, XK_F26 },
00214 { Qt::Key_F27, XK_F27 },
00215 { Qt::Key_F28, XK_F28 },
00216 { Qt::Key_F29, XK_F29 },
00217 { Qt::Key_F30, XK_F30 },
00218 { Qt::Key_F31, XK_F31 },
00219 { Qt::Key_F32, XK_F32 },
00220 { Qt::Key_F33, XK_F33 },
00221 { Qt::Key_F34, XK_F34 },
00222 { Qt::Key_F35, XK_F35 },
00223 { Qt::Key_Super_L, XK_Super_L },
00224 { Qt::Key_Super_R, XK_Super_R },
00225 { Qt::Key_Menu, XK_Menu },
00226 { Qt::Key_Hyper_L, XK_Hyper_L },
00227 { Qt::Key_Hyper_R, XK_Hyper_R },
00228 { Qt::Key_Help, XK_Help },
00229
00230
00231
00232 { '/', XK_KP_Divide },
00233 { '*', XK_KP_Multiply },
00234 { '-', XK_KP_Subtract },
00235 { '+', XK_KP_Add },
00236 { Qt::Key_Return, XK_KP_Enter }
00237 #if QT_VERSION >= 0x030100
00238
00239
00240
00241 #define XF86XK_Standby 0x1008FF10
00242 #define XF86XK_AudioLowerVolume 0x1008FF11
00243 #define XF86XK_AudioMute 0x1008FF12
00244 #define XF86XK_AudioRaiseVolume 0x1008FF13
00245 #define XF86XK_AudioPlay 0x1008FF14
00246 #define XF86XK_AudioStop 0x1008FF15
00247 #define XF86XK_AudioPrev 0x1008FF16
00248 #define XF86XK_AudioNext 0x1008FF17
00249 #define XF86XK_HomePage 0x1008FF18
00250 #define XF86XK_Calculator 0x1008FF1D
00251 #define XF86XK_Mail 0x1008FF19
00252 #define XF86XK_Start 0x1008FF1A
00253 #define XF86XK_Search 0x1008FF1B
00254 #define XF86XK_AudioRecord 0x1008FF1C
00255 #define XF86XK_Back 0x1008FF26
00256 #define XF86XK_Forward 0x1008FF27
00257 #define XF86XK_Stop 0x1008FF28
00258 #define XF86XK_Refresh 0x1008FF29
00259 #define XF86XK_Favorites 0x1008FF30
00260 #define XF86XK_AudioPause 0x1008FF31
00261 #define XF86XK_AudioMedia 0x1008FF32
00262 #define XF86XK_MyComputer 0x1008FF33
00263 #define XF86XK_OpenURL 0x1008FF38
00264 #define XF86XK_Launch0 0x1008FF40
00265 #define XF86XK_Launch1 0x1008FF41
00266 #define XF86XK_Launch2 0x1008FF42
00267 #define XF86XK_Launch3 0x1008FF43
00268 #define XF86XK_Launch4 0x1008FF44
00269 #define XF86XK_Launch5 0x1008FF45
00270 #define XF86XK_Launch6 0x1008FF46
00271 #define XF86XK_Launch7 0x1008FF47
00272 #define XF86XK_Launch8 0x1008FF48
00273 #define XF86XK_Launch9 0x1008FF49
00274 #define XF86XK_LaunchA 0x1008FF4A
00275 #define XF86XK_LaunchB 0x1008FF4B
00276 #define XF86XK_LaunchC 0x1008FF4C
00277 #define XF86XK_LaunchD 0x1008FF4D
00278 #define XF86XK_LaunchE 0x1008FF4E
00279 #define XF86XK_LaunchF 0x1008FF4F
00280
00281 ,
00282 { Qt::Key_Standby, XF86XK_Standby },
00283 { Qt::Key_VolumeDown, XF86XK_AudioLowerVolume },
00284 { Qt::Key_VolumeMute, XF86XK_AudioMute },
00285 { Qt::Key_VolumeUp, XF86XK_AudioRaiseVolume },
00286 { Qt::Key_MediaPlay, XF86XK_AudioPlay },
00287 { Qt::Key_MediaStop, XF86XK_AudioStop },
00288 { Qt::Key_MediaPrev, XF86XK_AudioPrev },
00289 { Qt::Key_MediaNext, XF86XK_AudioNext },
00290 { Qt::Key_HomePage, XF86XK_HomePage },
00291 { Qt::Key_LaunchMail, XF86XK_Mail },
00292 { Qt::Key_Search, XF86XK_Search },
00293 { Qt::Key_MediaRecord, XF86XK_AudioRecord },
00294 { Qt::Key_LaunchMedia, XF86XK_AudioMedia },
00295 { Qt::Key_Launch1, XF86XK_Calculator },
00296 { Qt::Key_Back, XF86XK_Back },
00297 { Qt::Key_Forward, XF86XK_Forward },
00298 { Qt::Key_Stop, XF86XK_Stop },
00299 { Qt::Key_Refresh, XF86XK_Refresh },
00300 { Qt::Key_Favorites, XF86XK_Favorites },
00301 { Qt::Key_Launch0, XF86XK_MyComputer },
00302 { Qt::Key_OpenUrl, XF86XK_OpenURL },
00303 { Qt::Key_Launch2, XF86XK_Launch0 },
00304 { Qt::Key_Launch3, XF86XK_Launch1 },
00305 { Qt::Key_Launch4, XF86XK_Launch2 },
00306 { Qt::Key_Launch5, XF86XK_Launch3 },
00307 { Qt::Key_Launch6, XF86XK_Launch4 },
00308 { Qt::Key_Launch7, XF86XK_Launch5 },
00309 { Qt::Key_Launch8, XF86XK_Launch6 },
00310 { Qt::Key_Launch9, XF86XK_Launch7 },
00311 { Qt::Key_LaunchA, XF86XK_Launch8 },
00312 { Qt::Key_LaunchB, XF86XK_Launch9 },
00313 { Qt::Key_LaunchC, XF86XK_LaunchA },
00314 { Qt::Key_LaunchD, XF86XK_LaunchB },
00315 { Qt::Key_LaunchE, XF86XK_LaunchC },
00316 { Qt::Key_LaunchF, XF86XK_LaunchD },
00317 #endif
00318 };
00319 #endif //Q_WS_X11
00320
00321
00322
00323
00324 static bool g_bInitializedMods, g_bInitializedVariations, g_bInitializedKKeyLabels;
00325 static bool g_bMacLabels;
00326 #ifdef Q_WS_X11
00327 static uint g_modXNumLock, g_modXScrollLock, g_modXModeSwitch;
00328
00329 bool initializeMods()
00330 {
00331 XModifierKeymap* xmk = XGetModifierMapping( qt_xdisplay() );
00332
00333 g_rgModInfo[3].modX = g_modXNumLock = g_modXScrollLock = g_modXModeSwitch = 0;
00334
00335 int min_keycode, max_keycode;
00336 int keysyms_per_keycode = 0;
00337 XDisplayKeycodes( qt_xdisplay(), &min_keycode, &max_keycode );
00338 XFree( XGetKeyboardMapping( qt_xdisplay(), min_keycode, 1, &keysyms_per_keycode ));
00339
00340 for( int i = Mod2MapIndex; i < 8; i++ ) {
00341 uint mask = (1 << i);
00342 uint keySymX = NoSymbol;
00343
00344
00345
00346
00347 for( int j = 0; j < xmk->max_keypermod && keySymX == NoSymbol; ++j )
00348 for( int k = 0; k < keysyms_per_keycode && keySymX == NoSymbol; ++k )
00349 keySymX = XKeycodeToKeysym( qt_xdisplay(), xmk->modifiermap[xmk->max_keypermod * i + j], k );
00350 switch( keySymX ) {
00351 case XK_Num_Lock: g_modXNumLock = mask; break;
00352 case XK_Super_L:
00353 case XK_Super_R: g_rgModInfo[3].modX = mask; break;
00354 case XK_Meta_L:
00355 case XK_Meta_R: if( !g_rgModInfo[3].modX ) g_rgModInfo[3].modX = mask; break;
00356 case XK_Scroll_Lock: g_modXScrollLock = mask; break;
00357 case XK_Mode_switch: g_modXModeSwitch = mask; break;
00358 }
00359 }
00360
00361 XFreeModifiermap( xmk );
00362
00363
00364
00365
00366 g_bInitializedMods = true;
00367
00368 kdDebug(125) << "KKeyServer::initializeMods(): Win Mod = 0x" << QString::number(g_rgModInfo[3].modX, 16) << endl;
00369 return true;
00370 }
00371
00372 static void initializeVariations()
00373 {
00374 for( int i = 0; g_rgSymVariation[i].sym != 0; i++ )
00375 g_rgSymVariation[i].bActive = (XKeysymToKeycode( qt_xdisplay(), g_rgSymVariation[i].symVariation ) != 0);
00376 g_bInitializedVariations = true;
00377 }
00378 #endif //Q_WS_X11
00379
00380 static void intializeKKeyLabels()
00381 {
00382 KConfigGroupSaver cgs( KGlobal::config(), "Keyboard" );
00383 g_rgModInfo[0].sLabel = KGlobal::config()->readEntry( "Label Shift", i18n(g_rgModInfo[0].psName) );
00384 g_rgModInfo[1].sLabel = KGlobal::config()->readEntry( "Label Ctrl", i18n(g_rgModInfo[1].psName) );
00385 g_rgModInfo[2].sLabel = KGlobal::config()->readEntry( "Label Alt", i18n(g_rgModInfo[2].psName) );
00386 g_rgModInfo[3].sLabel = KGlobal::config()->readEntry( "Label Win", i18n(g_rgModInfo[3].psName) );
00387 g_bMacLabels = (g_rgModInfo[2].sLabel == "Command");
00388 g_bInitializedKKeyLabels = true;
00389 }
00390
00391
00392
00393
00394
00395
00396
00397
00398
00399
00400
00401
00402
00403
00404 bool Sym::initQt( int keyQt )
00405 {
00406 int symQt = keyQt & 0xffff;
00407
00408 if( (keyQt & Qt::UNICODE_ACCEL) || symQt < 0x1000 ) {
00409 m_sym = QChar(symQt).lower().unicode();
00410 return true;
00411 }
00412
00413 #ifdef Q_WS_WIN
00414 m_sym = symQt;
00415 return true;
00416 #elif defined(Q_WS_X11)
00417 for( uint i = 0; i < sizeof(g_rgQtToSymX)/sizeof(TransKey); i++ ) {
00418 if( g_rgQtToSymX[i].keySymQt == symQt ) {
00419 m_sym = g_rgQtToSymX[i].keySymX;
00420 return true;
00421 }
00422 }
00423
00424 m_sym = 0;
00425 if( symQt != Qt::Key_Shift && symQt != Qt::Key_Control && symQt != Qt::Key_Alt &&
00426 symQt != Qt::Key_Meta && symQt != Qt::Key_Direction_L && symQt != Qt::Key_Direction_R )
00427 kdDebug(125) << "Sym::initQt( " << QString::number(keyQt,16) << " ): failed to convert key." << endl;
00428 return false;
00429 #elif defined(Q_WS_MACX)
00430 m_sym = symQt;
00431 return true;
00432 #endif
00433 }
00434
00435 bool Sym::init( const QString& s )
00436 {
00437
00438 if( s.length() == 1 ) {
00439 m_sym = s[0].lower().unicode();
00440 return true;
00441 }
00442
00443
00444 for( int i = 0; g_rgSymNames[i].sym != 0; i++ ) {
00445 if( qstricmp( s.latin1(), g_rgSymNames[i].psName ) == 0 ) {
00446 m_sym = g_rgSymNames[i].sym;
00447 return true;
00448 }
00449 }
00450
00451 #ifdef Q_WS_WIN
00452
00453 for ( KKeys const *pKey = kde_KKEYS; pKey->code != 0xffff; pKey++) {
00454 if( qstricmp( s.latin1(), pKey->name ) == 0 ) {
00455 m_sym = pKey->code;
00456 return true;
00457 }
00458 }
00459 m_sym = 0;
00460 #elif defined(Q_WS_X11)
00461
00462 m_sym = XStringToKeysym( s.latin1() );
00463 if( !m_sym ) {
00464 m_sym = XStringToKeysym( s.lower().latin1() );
00465 if( !m_sym ) {
00466 QString s2 = s;
00467 s2[0] = s2[0].upper();
00468 m_sym = XStringToKeysym( s2.latin1() );
00469 }
00470 }
00471 #endif
00472 return m_sym != 0;
00473 }
00474
00475 int Sym::qt() const
00476 {
00477 if( m_sym < 0x1000 ) {
00478 if( m_sym >= 'a' && m_sym <= 'z' )
00479 return QChar(m_sym).upper();
00480 return m_sym;
00481 }
00482 #ifdef Q_WS_WIN
00483 if( m_sym < 0x3000 )
00484 return m_sym;
00485 #elif defined(Q_WS_X11)
00486 if( m_sym < 0x3000 )
00487 return m_sym | Qt::UNICODE_ACCEL;
00488
00489 for( uint i = 0; i < sizeof(g_rgQtToSymX)/sizeof(TransKey); i++ )
00490 if( g_rgQtToSymX[i].keySymX == m_sym )
00491 return g_rgQtToSymX[i].keySymQt;
00492 #endif
00493 return Qt::Key_unknown;
00494 }
00495
00496 QString Sym::toString( bool bUserSpace ) const
00497 {
00498 if( m_sym == 0 )
00499 return QString::null;
00500
00501
00502 #ifdef Q_WS_WIN
00503 else if( m_sym < 0x1000 ) {
00504 #else
00505 else if( m_sym < 0x3000 ) {
00506 #endif
00507 QChar c = QChar(m_sym).upper();
00508
00509
00510 if( (c.latin1() && c.isLetterOrNumber())
00511 || (bUserSpace && !c.isSpace()) )
00512 return c;
00513 }
00514
00515
00516 for( int i = 0; g_rgSymNames[i].sym != 0; i++ ) {
00517 if( m_sym == g_rgSymNames[i].sym )
00518 return bUserSpace ? i18n(g_rgSymNames[i].psName) : QString(g_rgSymNames[i].psName);
00519 }
00520
00521 QString s;
00522 #ifdef Q_WS_WIN
00523 s = QKeySequence( m_sym );
00524 #elif defined(Q_WS_X11)
00525
00526 s = XKeysymToString( m_sym );
00527 #endif
00528 capitalizeKeyname( s );
00529 return bUserSpace ? i18n("QAccel", s.latin1()) : s;
00530 }
00531
00532 QString Sym::toStringInternal() const { return toString( false ); }
00533 QString Sym::toString() const { return toString( true ); }
00534
00535 uint Sym::getModsRequired() const
00536 {
00537 uint mod = 0;
00538 #ifdef Q_WS_X11
00539
00540 if( m_sym == XK_Sys_Req ) return KKey::ALT;
00541 if( m_sym == XK_Break ) return KKey::CTRL;
00542
00543 if( m_sym < 0x3000 ) {
00544 QChar c(m_sym);
00545 if( c.isLetter() && c.lower() != c.upper() && m_sym == c.upper().unicode() )
00546 return KKey::SHIFT;
00547 }
00548
00549 uchar code = XKeysymToKeycode( qt_xdisplay(), m_sym );
00550 if( code ) {
00551
00552
00553
00554 if( m_sym == XKeycodeToKeysym( qt_xdisplay(), code, 0 ) )
00555 ;
00556 else if( m_sym == XKeycodeToKeysym( qt_xdisplay(), code, 1 ) )
00557 mod = KKey::SHIFT;
00558 else if( m_sym == XKeycodeToKeysym( qt_xdisplay(), code, 2 ) )
00559 mod = KKeyServer::MODE_SWITCH;
00560 else if( m_sym == XKeycodeToKeysym( qt_xdisplay(), code, 3 ) )
00561 mod = KKey::SHIFT | KKeyServer::MODE_SWITCH;
00562 }
00563 #endif
00564 return mod;
00565 }
00566
00567 uint Sym::getSymVariation() const
00568 {
00569 #ifdef Q_WS_X11
00570 if( !g_bInitializedVariations )
00571 initializeVariations();
00572 for( int i = 0; g_rgSymVariation[i].sym != 0; i++ )
00573 if( g_rgSymVariation[i].sym == m_sym && g_rgSymVariation[i].bActive )
00574 return g_rgSymVariation[i].symVariation;
00575 #endif
00576 return 0;
00577 }
00578
00579 void Sym::capitalizeKeyname( QString& s )
00580 {
00581 s[0] = s[0].upper();
00582 int len = s.length();
00583 if( s.endsWith( "left" ) ) s[len-4] = 'L';
00584 else if( s.endsWith( "right" ) ) s[len-5] = 'R';
00585 else if( s == "Sysreq" ) s[len-3] = 'R';
00586 }
00587
00588
00589
00590
00591
00592 #ifdef Q_WS_X11
00593 uint modX( KKey::ModFlag mod )
00594 {
00595 if( mod == KKey::WIN && !g_bInitializedMods )
00596 initializeMods();
00597
00598 for( uint i = 0; i < KKey::MOD_FLAG_COUNT; i++ ) {
00599 if( g_rgModInfo[i].mod == mod )
00600 return g_rgModInfo[i].modX;
00601 }
00602 return 0;
00603 }
00604
00605 bool keyboardHasWinKey() { if( !g_bInitializedMods ) { initializeMods(); } return g_rgModInfo[3].modX != 0; }
00606 uint modXShift() { return ShiftMask; }
00607 uint modXLock() { return LockMask; }
00608 uint modXCtrl() { return ControlMask; }
00609 uint modXAlt() { return Mod1Mask; }
00610 uint modXNumLock() { if( !g_bInitializedMods ) { initializeMods(); } return g_modXNumLock; }
00611 uint modXWin() { if( !g_bInitializedMods ) { initializeMods(); } return g_rgModInfo[3].modX; }
00612 uint modXScrollLock() { if( !g_bInitializedMods ) { initializeMods(); } return g_modXScrollLock; }
00613 uint modXModeSwitch() { if( !g_bInitializedMods ) { initializeMods(); } return g_modXModeSwitch; }
00614
00615 uint accelModMaskX()
00616 {
00617 if( !g_bInitializedMods )
00618 initializeMods();
00619 return ShiftMask | ControlMask | Mod1Mask | g_rgModInfo[3].modX;
00620 }
00621 #endif //Q_WS_X11
00622
00623 bool keyQtToSym( int keyQt, uint& keySym )
00624 {
00625 Sym sym;
00626 if( sym.initQt( keyQt ) ) {
00627 keySym = sym.m_sym;
00628 return true;
00629 } else
00630 return false;
00631 }
00632
00633 bool keyQtToMod( int keyQt, uint& mod )
00634 {
00635 mod = 0;
00636
00637 if( keyQt & Qt::SHIFT ) mod |= KKey::SHIFT;
00638 if( keyQt & Qt::CTRL ) mod |= KKey::CTRL;
00639 if( keyQt & Qt::ALT ) mod |= KKey::ALT;
00640 if( keyQt & Qt::META ) mod |= KKey::WIN;
00641
00642 return true;
00643 }
00644
00645 bool symToKeyQt( uint keySym, int& keyQt )
00646 {
00647 Sym sym( keySym );
00648 keyQt = sym.qt();
00649 return (keyQt != Qt::Key_unknown);
00650 }
00651
00652 bool modToModQt( uint mod, int& modQt )
00653 {
00654 modQt = 0;
00655 for( int i = 0; i < KKey::MOD_FLAG_COUNT; i++ ) {
00656 if( mod & g_rgModInfo[i].mod ) {
00657 if( !g_rgModInfo[i].modQt ) {
00658 modQt = 0;
00659 return false;
00660 }
00661 modQt |= g_rgModInfo[i].modQt;
00662 }
00663 }
00664 return true;
00665 }
00666
00667 #ifdef Q_WS_WIN
00668
00669 bool modXToModQt( uint modX, int& modQt )
00670 {
00671 return modToModQt( modX, modQt );
00672 }
00673
00674 KDECORE_EXPORT int qtButtonStateToMod( Qt::ButtonState s )
00675 {
00676 int modQt = 0;
00677 if (s & Qt::ShiftButton) modQt |= KKey::SHIFT;
00678 if (s & Qt::ControlButton) modQt |= KKey::CTRL;
00679 if (s & Qt::AltButton) modQt |= KKey::ALT;
00680 return modQt;
00681 }
00682
00683 bool keyboardHasWinKey() {
00685 return true;
00686 }
00687
00688 #elif defined(Q_WS_MACX)
00689
00690 bool modXToModQt(uint modX, int& modQt)
00691 {
00692 return modToModQt( modX, modQt );
00693 }
00694
00695 bool keyboardHasWinKey() {
00697 return false;
00698 }
00699
00700 bool modXToMod( uint , uint& )
00701 {
00702 return false;
00703 }
00704 #elif defined(Q_WS_X11)
00705
00706 bool modToModX( uint mod, uint& modX )
00707 {
00708 if( !g_bInitializedMods )
00709 initializeMods();
00710
00711 modX = 0;
00712 for( int i = 0; i < KKey::MOD_FLAG_COUNT; i++ ) {
00713 if( mod & g_rgModInfo[i].mod ) {
00714 if( !g_rgModInfo[i].modX ) {
00715 kdDebug(125) << "Invalid modifier flag." << endl;
00716 modX = 0;
00717 return false;
00718 }
00719 modX |= g_rgModInfo[i].modX;
00720 }
00721 }
00722
00723 if( mod & 0x2000 )
00724 modX |= 0x2000;
00725 return true;
00726 }
00727
00728 bool modXToModQt( uint modX, int& modQt )
00729 {
00730 if( !g_bInitializedMods )
00731 initializeMods();
00732
00733 modQt = 0;
00734 for( int i = 0; i < KKey::MOD_FLAG_COUNT; i++ ) {
00735 if( modX & g_rgModInfo[i].modX ) {
00736 if( !g_rgModInfo[i].modQt ) {
00737 modQt = 0;
00738 return false;
00739 }
00740 modQt |= g_rgModInfo[i].modQt;
00741 }
00742 }
00743 return true;
00744 }
00745
00746 bool modXToMod( uint modX, uint& mod )
00747 {
00748 if( !g_bInitializedMods )
00749 initializeMods();
00750
00751 mod = 0;
00752 for( int i = 0; i < KKey::MOD_FLAG_COUNT; i++ ) {
00753 if( modX & g_rgModInfo[i].modX )
00754 mod |= g_rgModInfo[i].mod;
00755 }
00756 return true;
00757 }
00758
00759 bool codeXToSym( uchar codeX, uint modX, uint& sym )
00760 {
00761 KeySym keySym;
00762 XKeyPressedEvent event;
00763
00764 event.type = KeyPress;
00765 event.display = qt_xdisplay();
00766 event.state = modX;
00767 event.keycode = codeX;
00768
00769 XLookupString( &event, 0, 0, &keySym, 0 );
00770 sym = (uint) keySym;
00771 return true;
00772 }
00773 #endif
00774
00775 static QString modToString( uint mod, bool bUserSpace )
00776 {
00777 if( bUserSpace && !g_bInitializedKKeyLabels )
00778 intializeKKeyLabels();
00779
00780 QString s;
00781 for( int i = KKey::MOD_FLAG_COUNT-1; i >= 0; i-- ) {
00782 if( mod & g_rgModInfo[i].mod ) {
00783 if( !s.isEmpty() )
00784 s += '+';
00785 s += (bUserSpace)
00786 ? g_rgModInfo[i].sLabel
00787 : QString(g_rgModInfo[i].psName);
00788 }
00789 }
00790 return s;
00791 }
00792
00793 QString modToStringInternal( uint mod ) { return modToString( mod, false ); }
00794 QString modToStringUser( uint mod ) { return modToString( mod, true ); }
00795
00796 uint stringUserToMod( const QString& mod )
00797 {
00798 if( !g_bInitializedKKeyLabels )
00799 intializeKKeyLabels();
00800
00801 QString s;
00802 for( int i = KKey::MOD_FLAG_COUNT-1; i >= 0; i-- ) {
00803 if( mod.lower() == g_rgModInfo[i].sLabel.lower())
00804 return g_rgModInfo[i].mod;
00805 }
00806 return 0;
00807 }
00808
00809
00810
00811
00812
00813
00814
00815
00816
00817
00818
00819
00820
00821
00822
00823
00824
00825
00826
00827
00828
00829
00830
00831
00832
00833
00834
00835
00836
00837
00838
00839
00840
00841
00842
00843
00844
00845
00846
00847
00848
00849
00850
00851
00852
00853
00854
00855
00856
00857
00858
00859
00860
00861
00862
00863
00864
00865
00866
00867
00868
00869
00870
00871
00872
00873
00874
00875
00876
00877
00878
00879
00880
00881
00882
00883
00884
00885
00886
00887
00888
00889
00890
00891
00892
00893
00894
00895
00896
00897
00898
00899
00900
00901
00902
00903
00904
00905
00906
00907
00908
00909
00910
00911
00912
00913
00914
00915
00916
00917
00918
00919
00920
00921
00922
00923
00924
00925 bool Key::init( const KKey& key, bool bQt )
00926 {
00927 if( bQt ) {
00928 m_code = CODE_FOR_QT;
00929 m_sym = key.keyCodeQt();
00930 } else {
00931 KKeyNative keyNative( key );
00932 *this = keyNative;
00933 }
00934 return true;
00935 }
00936
00937 KKey Key::key() const
00938 {
00939 if( m_code == CODE_FOR_QT )
00940 return KKey( keyCodeQt() );
00941 else {
00942 #if defined(Q_WS_WIN) || defined(Q_WS_MACX)
00943 return KKey();
00944 #else
00945 uint mod;
00946 modXToMod( m_mod, mod );
00947 return KKey( m_sym, mod );
00948 #endif
00949 }
00950 }
00951
00952 Key& Key::operator =( const KKeyNative& key )
00953 {
00954 m_code = key.code(); m_mod = key.mod(); m_sym = key.sym();
00955 return *this;
00956 }
00957
00958 int Key::compare( const Key& b ) const
00959 {
00960 if( m_code == CODE_FOR_QT )
00961 return m_sym - b.m_sym;
00962 if( m_sym != b.m_sym ) return m_sym - b.m_sym;
00963 if( m_mod != b.m_mod ) return m_mod - b.m_mod;
00964 return m_code - b.m_code;
00965 }
00966
00967
00968
00969
00970
00971
00972 void Variations::init( const KKey& key, bool bQt )
00973 {
00974 if( key.isNull() ) {
00975 m_nVariations = 0;
00976 return;
00977 }
00978
00979 m_nVariations = 1;
00980 m_rgkey[0] = KKeyNative(key);
00981 uint symVar = Sym(key.sym()).getSymVariation();
00982 if( symVar ) {
00983 uint modReq = Sym(m_rgkey[0].sym()).getModsRequired();
00984 uint modReqVar = Sym(symVar).getModsRequired();
00985
00986
00987 if( (key.modFlags() & modReq) == (key.modFlags() & modReqVar) ) {
00988 m_rgkey[1] = KKeyNative(KKey(symVar, key.modFlags()));
00989 m_nVariations = 2;
00990 }
00991 }
00992
00993 if( bQt ) {
00994 uint nVariations = 0;
00995 for( uint i = 0; i < m_nVariations; i++ ) {
00996 int keyQt = KKeyNative( m_rgkey[i].code(), m_rgkey[i].mod(), m_rgkey[i].sym() ).keyCodeQt();
00997 if( keyQt )
00998 m_rgkey[nVariations++].setKeycodeQt( keyQt );
00999 }
01000 m_nVariations = nVariations;
01001
01002
01003
01004 for( uint i = 1; i < m_nVariations; i++ ) {
01005 for( uint j = 0; j < i; j++ ) {
01006
01007 if( m_rgkey[i].keyCodeQt() == m_rgkey[j].keyCodeQt() ) {
01008 for( uint k = i; k < m_nVariations - 1; k++ )
01009 m_rgkey[k].setKeycodeQt( m_rgkey[k+1].keyCodeQt() );
01010 m_nVariations--;
01011 i--;
01012 break;
01013 }
01014 }
01015 }
01016 }
01017 }
01018
01019 }
01020
01021
01022
01023
01024
01025
01026
01027 void KKey::simplify()
01028 {
01029 #ifdef Q_WS_X11
01030 if( m_sym == XK_Sys_Req ) {
01031 m_sym = XK_Print;
01032 m_mod |= ALT;
01033 } else if( m_sym == XK_ISO_Left_Tab ) {
01034 m_sym = XK_Tab;
01035 m_mod |= SHIFT;
01036 } else {
01037
01038 m_sym = KKeyNative(*this).sym();
01039 }
01040
01041
01042 if( m_sym < 0x3000 && QChar(m_sym).isLetter() )
01043 m_sym = QChar(m_sym).lower().unicode();
01044
01045
01046
01047 m_mod &= ~KKeyServer::Sym(m_sym).getModsRequired();
01048 #endif
01049 }
01050
01051 #endif //Q_WS_X11 || Q_WS_WIN
01052