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