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