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, g_modXModeSwitch;
00287
00288 bool initializeMods()
00289 {
00290 XModifierKeymap* xmk = XGetModifierMapping( qt_xdisplay() );
00291
00292 g_rgModInfo[3].modX = g_modXNumLock = g_modXScrollLock = g_modXModeSwitch = 0;
00293
00294 int min_keycode, max_keycode;
00295 int keysyms_per_keycode = 0;
00296 XDisplayKeycodes( qt_xdisplay(), &min_keycode, &max_keycode );
00297 XFree( XGetKeyboardMapping( qt_xdisplay(), min_keycode, 1, &keysyms_per_keycode ));
00298
00299 for( int i = Mod2MapIndex; i < 8; i++ ) {
00300 uint mask = (1 << i);
00301 uint keySymX = NoSymbol;
00302
00303
00304
00305
00306 for( int j = 0; j < xmk->max_keypermod && keySymX == NoSymbol; ++j )
00307 for( int k = 0; k < keysyms_per_keycode && keySymX == NoSymbol; ++k )
00308 keySymX = XKeycodeToKeysym( qt_xdisplay(), xmk->modifiermap[xmk->max_keypermod * i + j], k );
00309 switch( keySymX ) {
00310 case XK_Num_Lock: g_modXNumLock = mask; break;
00311 case XK_Super_L:
00312 case XK_Super_R: g_rgModInfo[3].modX = mask; break;
00313 case XK_Meta_L:
00314 case XK_Meta_R: if( !g_rgModInfo[3].modX ) g_rgModInfo[3].modX = mask; break;
00315 case XK_Scroll_Lock: g_modXScrollLock = mask; break;
00316 case XK_Mode_switch: g_modXModeSwitch = mask; break;
00317 }
00318 }
00319
00320 XFreeModifiermap( xmk );
00321
00322
00323
00324
00325 g_bInitializedMods = true;
00326
00327 kdDebug(125) << "KKeyServer::initializeMods(): Win Mod = 0x" << QString::number(g_rgModInfo[3].modX, 16) << endl;
00328 return true;
00329 }
00330
00331 static void initializeVariations()
00332 {
00333 for( int i = 0; g_rgSymVariation[i].sym != 0; i++ )
00334 g_rgSymVariation[i].bActive = (XKeysymToKeycode( qt_xdisplay(), g_rgSymVariation[i].symVariation ) != 0);
00335 g_bInitializedVariations = true;
00336 }
00337
00338 static void intializeKKeyLabels()
00339 {
00340 KConfigGroupSaver cgs( KGlobal::config(), "Keyboard" );
00341 g_rgModInfo[0].sLabel = KGlobal::config()->readEntry( "Label Shift", i18n(g_rgModInfo[0].psName) );
00342 g_rgModInfo[1].sLabel = KGlobal::config()->readEntry( "Label Ctrl", i18n(g_rgModInfo[1].psName) );
00343 g_rgModInfo[2].sLabel = KGlobal::config()->readEntry( "Label Alt", i18n(g_rgModInfo[2].psName) );
00344 g_rgModInfo[3].sLabel = KGlobal::config()->readEntry( "Label Win", i18n(g_rgModInfo[3].psName) );
00345 g_bMacLabels = (g_rgModInfo[2].sLabel == "Command");
00346 g_bInitializedKKeyLabels = true;
00347 }
00348
00349
00350
00351
00352
00353
00354
00355
00356
00357
00358
00359
00360
00361
00362 bool Sym::initQt( int keyQt )
00363 {
00364 int symQt = keyQt & 0xffff;
00365
00366 if( (keyQt & Qt::UNICODE_ACCEL) || symQt < 0x1000 ) {
00367 m_sym = QChar(symQt).lower().unicode();
00368 return true;
00369 }
00370
00371 for( uint i = 0; i < sizeof(g_rgQtToSymX)/sizeof(TransKey); i++ ) {
00372 if( g_rgQtToSymX[i].keySymQt == symQt ) {
00373 m_sym = g_rgQtToSymX[i].keySymX;
00374 return true;
00375 }
00376 }
00377
00378 m_sym = 0;
00379 if( symQt != Qt::Key_Shift && symQt != Qt::Key_Control && symQt != Qt::Key_Alt &&
00380 symQt != Qt::Key_Meta && symQt != Qt::Key_Direction_L && symQt != Qt::Key_Direction_R )
00381 kdDebug(125) << "Sym::initQt( " << QString::number(keyQt,16) << " ): failed to convert key." << endl;
00382 return false;
00383 }
00384
00385 bool Sym::init( const QString& s )
00386 {
00387
00388 if( s.length() == 1 ) {
00389 m_sym = s[0].lower().unicode();
00390 return true;
00391 }
00392
00393
00394 for( int i = 0; g_rgSymNames[i].sym != 0; i++ ) {
00395 if( qstricmp( s.latin1(), g_rgSymNames[i].psName ) == 0 ) {
00396 m_sym = g_rgSymNames[i].sym;
00397 return true;
00398 }
00399 }
00400
00401
00402 m_sym = XStringToKeysym( s.latin1() );
00403 if( !m_sym ) {
00404 m_sym = XStringToKeysym( s.lower().latin1() );
00405 if( !m_sym ) {
00406 QString s2 = s;
00407 s2[0] = s2[0].upper();
00408 m_sym = XStringToKeysym( s2.latin1() );
00409 }
00410 }
00411
00412 return m_sym != 0;
00413 }
00414
00415 int Sym::qt() const
00416 {
00417 if( m_sym < 0x1000 ) {
00418 if( m_sym >= 'a' && m_sym <= 'z' )
00419 return QChar(m_sym).upper();
00420 return m_sym;
00421 }
00422 if( m_sym < 0x3000 )
00423 return m_sym | Qt::UNICODE_ACCEL;
00424
00425 for( uint i = 0; i < sizeof(g_rgQtToSymX)/sizeof(TransKey); i++ )
00426 if( g_rgQtToSymX[i].keySymX == m_sym )
00427 return g_rgQtToSymX[i].keySymQt;
00428 return Qt::Key_unknown;
00429 }
00430
00431 QString Sym::toString( bool bUserSpace ) const
00432 {
00433 if( m_sym == 0 )
00434 return QString::null;
00435
00436
00437 else if( m_sym < 0x3000 ) {
00438 QChar c = QChar(m_sym).upper();
00439
00440
00441 if( (c.latin1() && c.isLetterOrNumber())
00442 || (bUserSpace && !c.isSpace()) )
00443 return c;
00444 }
00445
00446
00447 for( int i = 0; g_rgSymNames[i].sym != 0; i++ ) {
00448 if( m_sym == g_rgSymNames[i].sym )
00449 return bUserSpace ? i18n(g_rgSymNames[i].psName) : QString(g_rgSymNames[i].psName);
00450 }
00451
00452
00453 QString s = XKeysymToString( m_sym );
00454 capitalizeKeyname( s );
00455 return bUserSpace ? i18n("QAccel", s.latin1()) : s;
00456 }
00457
00458 QString Sym::toStringInternal() const { return toString( false ); }
00459 QString Sym::toString() const { return toString( true ); }
00460
00461 uint Sym::getModsRequired() const
00462 {
00463 uint mod = 0;
00464
00465
00466 if( m_sym == XK_Sys_Req ) return KKey::ALT;
00467 if( m_sym == XK_Break ) return KKey::CTRL;
00468
00469 if( m_sym < 0x3000 ) {
00470 QChar c(m_sym);
00471 if( c.isLetter() && c.lower() != c.upper() && m_sym == c.upper().unicode() )
00472 return KKey::SHIFT;
00473 }
00474
00475 uchar code = XKeysymToKeycode( qt_xdisplay(), m_sym );
00476 if( code ) {
00477
00478
00479
00480 if( m_sym == XKeycodeToKeysym( qt_xdisplay(), code, 0 ) )
00481 ;
00482 else if( m_sym == XKeycodeToKeysym( qt_xdisplay(), code, 1 ) )
00483 mod = KKey::SHIFT;
00484 else if( m_sym == XKeycodeToKeysym( qt_xdisplay(), code, 2 ) )
00485 mod = KKeyServer::MODE_SWITCH;
00486 else if( m_sym == XKeycodeToKeysym( qt_xdisplay(), code, 3 ) )
00487 mod = KKey::SHIFT | KKeyServer::MODE_SWITCH;
00488 }
00489
00490 return mod;
00491 }
00492
00493 uint Sym::getSymVariation() const
00494 {
00495 if( !g_bInitializedVariations )
00496 initializeVariations();
00497
00498 for( int i = 0; g_rgSymVariation[i].sym != 0; i++ )
00499 if( g_rgSymVariation[i].sym == m_sym && g_rgSymVariation[i].bActive )
00500 return g_rgSymVariation[i].symVariation;
00501 return 0;
00502 }
00503
00504 void Sym::capitalizeKeyname( QString& s )
00505 {
00506 s[0] = s[0].upper();
00507 int len = s.length();
00508 if( s.endsWith( "left" ) ) s[len-4] = 'L';
00509 else if( s.endsWith( "right" ) ) s[len-5] = 'R';
00510 else if( s == "Sysreq" ) s[len-3] = 'R';
00511 }
00512
00513
00514
00515
00516
00517 uint modX( KKey::ModFlag mod )
00518 {
00519 if( mod == KKey::WIN && !g_bInitializedMods )
00520 initializeMods();
00521
00522 for( uint i = 0; i < KKey::MOD_FLAG_COUNT; i++ ) {
00523 if( g_rgModInfo[i].mod == mod )
00524 return g_rgModInfo[i].modX;
00525 }
00526 return 0;
00527 }
00528
00529 bool keyboardHasWinKey() { if( !g_bInitializedMods ) { initializeMods(); } return g_rgModInfo[3].modX != 0; }
00530 uint modXShift() { return ShiftMask; }
00531 uint modXLock() { return LockMask; }
00532 uint modXCtrl() { return ControlMask; }
00533 uint modXAlt() { return Mod1Mask; }
00534 uint modXNumLock() { if( !g_bInitializedMods ) { initializeMods(); } return g_modXNumLock; }
00535 uint modXWin() { if( !g_bInitializedMods ) { initializeMods(); } return g_rgModInfo[3].modX; }
00536 uint modXScrollLock() { if( !g_bInitializedMods ) { initializeMods(); } return g_modXScrollLock; }
00537 uint modXModeSwitch() { if( !g_bInitializedMods ) { initializeMods(); } return g_modXModeSwitch; }
00538
00539 uint accelModMaskX()
00540 {
00541 if( !g_bInitializedMods )
00542 initializeMods();
00543 return ShiftMask | ControlMask | Mod1Mask | g_rgModInfo[3].modX;
00544 }
00545
00546 bool keyQtToSym( int keyQt, uint& keySym )
00547 {
00548 Sym sym;
00549 if( sym.initQt( keyQt ) ) {
00550 keySym = sym.m_sym;
00551 return true;
00552 } else
00553 return false;
00554 }
00555
00556 bool keyQtToMod( int keyQt, uint& mod )
00557 {
00558 mod = 0;
00559
00560 if( keyQt & Qt::SHIFT ) mod |= KKey::SHIFT;
00561 if( keyQt & Qt::CTRL ) mod |= KKey::CTRL;
00562 if( keyQt & Qt::ALT ) mod |= KKey::ALT;
00563 if( keyQt & Qt::META ) mod |= KKey::WIN;
00564
00565 return true;
00566 }
00567
00568 bool symToKeyQt( uint keySym, int& keyQt )
00569 {
00570 Sym sym( keySym );
00571 keyQt = sym.qt();
00572 return (keyQt != Qt::Key_unknown);
00573 }
00574
00575 bool modToModQt( uint mod, int& modQt )
00576 {
00577 modQt = 0;
00578 for( int i = 0; i < KKey::MOD_FLAG_COUNT; i++ ) {
00579 if( mod & g_rgModInfo[i].mod ) {
00580 if( !g_rgModInfo[i].modQt ) {
00581 modQt = 0;
00582 return false;
00583 }
00584 modQt |= g_rgModInfo[i].modQt;
00585 }
00586 }
00587 return true;
00588 }
00589
00590 bool modToModX( uint mod, uint& modX )
00591 {
00592 if( !g_bInitializedMods )
00593 initializeMods();
00594
00595 modX = 0;
00596 for( int i = 0; i < KKey::MOD_FLAG_COUNT; i++ ) {
00597 if( mod & g_rgModInfo[i].mod ) {
00598 if( !g_rgModInfo[i].modX ) {
00599 kdDebug(125) << "Invalid modifier flag." << endl;
00600 modX = 0;
00601 return false;
00602 }
00603 modX |= g_rgModInfo[i].modX;
00604 }
00605 }
00606
00607 if( mod & 0x2000 )
00608 modX |= 0x2000;
00609 return true;
00610 }
00611
00612 bool modXToModQt( uint modX, int& modQt )
00613 {
00614 if( !g_bInitializedMods )
00615 initializeMods();
00616
00617 modQt = 0;
00618 for( int i = 0; i < KKey::MOD_FLAG_COUNT; i++ ) {
00619 if( modX & g_rgModInfo[i].modX ) {
00620 if( !g_rgModInfo[i].modQt ) {
00621 modQt = 0;
00622 return false;
00623 }
00624 modQt |= g_rgModInfo[i].modQt;
00625 }
00626 }
00627 return true;
00628 }
00629
00630 bool modXToMod( uint modX, uint& mod )
00631 {
00632 if( !g_bInitializedMods )
00633 initializeMods();
00634
00635 mod = 0;
00636 for( int i = 0; i < KKey::MOD_FLAG_COUNT; i++ ) {
00637 if( modX & g_rgModInfo[i].modX )
00638 mod |= g_rgModInfo[i].mod;
00639 }
00640 return true;
00641 }
00642
00643 bool codeXToSym( uchar codeX, uint modX, uint& sym )
00644 {
00645 XKeyPressedEvent event;
00646
00647 event.type = KeyPress;
00648 event.display = qt_xdisplay();
00649 event.state = modX;
00650 event.keycode = codeX;
00651
00652 XLookupString( &event, 0, 0, (KeySym*) &sym, 0 );
00653 return true;
00654 }
00655
00656 static QString modToString( uint mod, bool bUserSpace )
00657 {
00658 if( bUserSpace && !g_bInitializedKKeyLabels )
00659 intializeKKeyLabels();
00660
00661 QString s;
00662 for( int i = KKey::MOD_FLAG_COUNT-1; i >= 0; i-- ) {
00663 if( mod & g_rgModInfo[i].mod ) {
00664 if( !s.isEmpty() )
00665 s += '+';
00666 s += (bUserSpace)
00667 ? g_rgModInfo[i].sLabel
00668 : QString(g_rgModInfo[i].psName);
00669 }
00670 }
00671 return s;
00672 }
00673
00674 QString modToStringInternal( uint mod ) { return modToString( mod, false ); }
00675 QString modToStringUser( uint mod ) { return modToString( mod, true ); }
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
00781
00782
00783
00784
00785
00786
00787
00788
00789
00790
00791
00792
00793 bool Key::init( const KKey& key, bool bQt )
00794 {
00795 if( bQt ) {
00796 m_code = CODE_FOR_QT;
00797 m_sym = key.keyCodeQt();
00798 } else {
00799 KKeyNative keyNative( key );
00800 *this = keyNative;
00801 }
00802 return true;
00803 }
00804
00805 KKey Key::key() const
00806 {
00807 if( m_code == CODE_FOR_QT )
00808 return KKey( keyCodeQt() );
00809 else {
00810 uint mod;
00811 modXToMod( m_mod, mod );
00812 return KKey( m_sym, mod );
00813 }
00814 }
00815
00816 Key& Key::operator =( const KKeyNative& key )
00817 {
00818 m_code = key.code(); m_mod = key.mod(); m_sym = key.sym();
00819 return *this;
00820 }
00821
00822 int Key::compare( const Key& b ) const
00823 {
00824 if( m_code == CODE_FOR_QT )
00825 return m_sym - b.m_sym;
00826 if( m_sym != b.m_sym ) return m_sym - b.m_sym;
00827 if( m_mod != b.m_mod ) return m_mod - b.m_mod;
00828 return m_code - b.m_code;
00829 }
00830
00831
00832
00833
00834
00835
00836 void Variations::init( const KKey& key, bool bQt )
00837 {
00838 if( key.isNull() ) {
00839 m_nVariations = 0;
00840 return;
00841 }
00842
00843 m_nVariations = 1;
00844 m_rgkey[0] = KKeyNative(key);
00845 uint symVar = Sym(key.sym()).getSymVariation();
00846 if( symVar ) {
00847 uint modReq = Sym(m_rgkey[0].sym()).getModsRequired();
00848 uint modReqVar = Sym(symVar).getModsRequired();
00849
00850
00851 if( (key.modFlags() & modReq) == (key.modFlags() & modReqVar) ) {
00852 m_rgkey[1] = KKeyNative(KKey(symVar, key.modFlags()));
00853 m_nVariations = 2;
00854 }
00855 }
00856
00857 if( bQt ) {
00858 uint nVariations = 0;
00859 for( uint i = 0; i < m_nVariations; i++ ) {
00860 int keyQt = KKeyNative( m_rgkey[i].code(), m_rgkey[i].mod(), m_rgkey[i].sym() ).keyCodeQt();
00861 if( keyQt )
00862 m_rgkey[nVariations++].setKeycodeQt( keyQt );
00863 }
00864 m_nVariations = nVariations;
00865
00866
00867
00868 for( uint i = 1; i < m_nVariations; i++ ) {
00869 for( uint j = 0; j < i; j++ ) {
00870
00871 if( m_rgkey[i].keyCodeQt() == m_rgkey[j].keyCodeQt() ) {
00872 for( uint k = i; k < m_nVariations - 1; k++ )
00873 m_rgkey[k].setKeycodeQt( m_rgkey[k+1].keyCodeQt() );
00874 m_nVariations--;
00875 i--;
00876 break;
00877 }
00878 }
00879 }
00880 }
00881 }
00882
00883 }
00884
00885
00886
00887
00888
00889
00890
00891 void KKey::simplify()
00892 {
00893 if( m_sym == XK_Sys_Req ) {
00894 m_sym = XK_Print;
00895 m_mod |= ALT;
00896 } else if( m_sym == XK_ISO_Left_Tab ) {
00897 m_sym = XK_Tab;
00898 m_mod |= SHIFT;
00899 } else {
00900
00901 m_sym = KKeyNative(*this).sym();
00902 }
00903
00904
00905 if( m_sym < 0x3000 && QChar(m_sym).isLetter() )
00906 m_sym = QChar(m_sym).lower().unicode();
00907
00908
00909
00910 m_mod &= ~KKeyServer::Sym(m_sym).getModsRequired();
00911 }
00912
00913 #endif // Q_WS_X11