| # kdecore Library API Documentation
Overview | Class Hierarchy | Classes | Classes (annotated) | Members | Source Files

# kkeyserver_x11.cpp

    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 // Data Structures
    00035 //---------------------------------------------------------------------
    00036
    00037 struct Mod
    00038 {
    00039         int m_mod;
    00040 };
    00041
    00042 //---------------------------------------------------------------------
    00043 // Array Structures
    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 // Arrays
    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 // Special Names List
    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 // TODO: Add Mac key names list: Key_Backspace => "Delete", Key_Delete => "Del"
    00108
    00109 // These are the X equivalents to the Qt keycodes 0x1000 - 0x1026
    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         //{ Qt::Key_Shift,      0 },
    00132         //{ Qt::Key_Control,    0 },
    00133         //{ Qt::Key_Meta,       0 },
    00134         //{ Qt::Key_Alt,        0 },
    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         //{ Qt::Key_Direction_L, XK_Direction_L }, These keys don't exist in X11
    00180         //{ Qt::Key_Direction_R, XK_Direction_R },
    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 // the next lines are taken from XFree > 4.0 (X11/XF86keysyms.h), defining some special
    00190 // multimedia keys. They are included here as not every system has them.
    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 // end of XF86keysyms.h
    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 // Initialization
    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         // Qt assumes that Alt is always Mod1Mask, so start at Mod2Mask.
    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;     // Normally Mod2Mask
    00289                         case XK_Super_L:
    00290                         case XK_Super_R:     g_rgModInfo[3].modX = mask; break; // Win key, Normally Mod4Mask
    00291                         case XK_Meta_L:
    00292                         case XK_Meta_R:      if( !g_rgModInfo[3].modX ) g_rgModInfo[3].modX = mask; break; // Win alternate
    00293                         case XK_Scroll_Lock: g_modXScrollLock = mask; break;  // Normally Mod5Mask
    00294                 }
    00295         }
    00296
    00297         XFreeModifiermap( xmk );
    00298
    00299         //KConfigGroupSaver cgs( KGlobal::config(), "Keyboard" );
    00300         // read in mod that win should be attached to
    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 // class Mod
    00328 //---------------------------------------------------------------------
    00329
    00330 /*void Mod::init( const QString& s )
    00331 {
    00332
    00333 }*/
    00334
    00335 //---------------------------------------------------------------------
    00336 // class Sym
    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         // Look up in special names list
    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         // search X list: 's' as is, all lower, first letter in caps
    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         // If it's a unicode character,
    00410         if( m_sym == 0 )
    00411                 return QString::null;
    00412
    00413         else if( m_sym < 0x3000 ) {
    00414                 QChar c = QChar(m_sym).upper();
    00415                 // Print all non-space characters directly when output is user-visible.
    00416                 // Otherwise only print alphanumeric latin1 characters directly (A,B,C,1,2,3).
    00417                 if( (c.latin1() && c.isLetterOrNumber())
    00418                     || (bUserSpace && !c.isSpace()) )
    00419                                 return c;
    00420         }
    00421
    00422         // Look up in special names list
    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         // Get X-name
    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         // FIXME: This might not be true on all keyboard layouts!
    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                 // need to check index 0 before the others, so that a null-mod
    00454                 //  can take precedence over the others, in case the modified
    00455                 //  key produces the same symbol.
    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 // Public functions
    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         // TODO: document 0x2000 flag
    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 /*void keySymModToKeyX( uint sym, uint mod, unsigned char *pKeyCodeX, uint *pKeySymX, uint *pKeyModX )
    00653 {
    00654 ...
    00655         uint    keySymQt;
    00656         uint    keySymX = 0;
    00657         unsigned char   keyCodeX = 0;
    00658         uint    keyModX = 0;
    00659
    00660         const char *psKeySym = 0;
    00661
    00662         if( !g_bInitialized )
    00663                 Initialize();
    00664
    00665         // Get code of just the primary key
    00666         keySymQt = keyCombQt & 0xffff;
    00667
    00668         // If unicode value beneath 0x1000 (special Qt codes begin thereafter),
    00669         if( keySymQt < 0x1000 ) {
    00670                 // For reasons unbeknownst to me, Qt converts 'a-z' to 'A-Z'.
    00671                 // So convert it back to lowercase if SHIFT isn't held down.
    00672                 if( keySymQt >= Qt::Key_A && keySymQt <= Qt::Key_Z && !(keyCombQt & Qt::SHIFT) )
    00673                         keySymQt = tolower( keySymQt );
    00674                 keySymX = keySymQt;
    00675         }
    00676         // Else, special key (e.g. Delete, F1, etc.)
    00677         else {
    00678                 for( int i = 0; i < NB_KEYS; i++ ) {
    00679                         if( keySymQt == (uint) KKEYS[i].code ) {
    00680                                 psKeySym = KKEYS[i].name;
    00681                                 //kdDebug(125) << " symbol found: \"" << psKeySym << "\"" << endl;
    00682                                 break;
    00683                         }
    00684                 }
    00685
    00686                 // Get X key symbol.  Only works if Qt name is same as X name.
    00687                 if( psKeySym ) {
    00688                         QString sKeySym = psKeySym;
    00689
    00690                         // Check for lower-case equalent first because most
    00691                         //  X11 names are all lower-case.
    00692                         keySymX = XStringToKeysym( sKeySym.lower().ascii() );
    00693                         if( keySymX == 0 )
    00694                                 keySymX = XStringToKeysym( psKeySym );
    00695                 }
    00696
    00697                 if( keySymX == 0 )
    00698                         keySymX = getSymXEquiv( keySymQt );
    00699         }
    00700
    00701         if( keySymX != 0 ) {
    00702                 // Get X keyboard code
    00703                 keyCodeX = XKeysymToKeycode( qt_xdisplay(), keySymX );
    00704                 // Add ModeSwitch modifier bit, if necessary
    00705                 keySymXMods( keySymX, 0, &keyModX );
    00706
    00707                 // Get X modifier flags
    00708                 for( int i = 0; i < MOD_KEYS; i++ ) {
    00709                         if( keyCombQt & g_aModKeys[i].keyModMaskQt ) {
    00710                                 if( g_aModKeys[i].keyModMaskX )
    00711                                         keyModX |= g_aModKeys[i].keyModMaskX;
    00712                                 // Qt key calls for a modifier which the current
    00713                                 //  X modifier map doesn't support.
    00714                                 else {
    00715                                         keySymX = 0;
    00716                                         keyCodeX = 0;
    00717                                         keyModX = 0;
    00718                                         break;
    00719                                 }
    00720                         }
    00721                 }
    00722         }
    00723
    00724         // Take care of complications:
    00725         //  The following keys will not have been correctly interpreted,
    00726         //   because their shifted values are not activated with the
    00727         //   Shift key, but rather something else.  They are also
    00728         //   defined twice under different keycodes.
    00729         //  keycode 111 & 92:  Print Sys_Req -> Sys_Req = Alt+Print
    00730         //  keycode 110 & 114: Pause Break   -> Break = Ctrl+Pause
    00731         if( (keyCodeX == 92 || keyCodeX == 111) &&
    00732             XKeycodeToKeysym( qt_xdisplay(), 92, 0 ) == XK_Print &&
    00733             XKeycodeToKeysym( qt_xdisplay(), 111, 0 ) == XK_Print )
    00734         {
    00735                 // If Alt is pressed, then we need keycode 92, keysym XK_Sys_Req
    00736                 if( keyModX & keyModXAlt() ) {
    00737                         keyCodeX = 92;
    00738                         keySymX = XK_Sys_Req;
    00739                 }
    00740                 // Otherwise, keycode 111, keysym XK_Print
    00741                 else {
    00742                         keyCodeX = 111;
    00743                         keySymX = XK_Print;
    00744                 }
    00745         }
    00746         else if( (keyCodeX == 110 || keyCodeX == 114) &&
    00747             XKeycodeToKeysym( qt_xdisplay(), 110, 0 ) == XK_Pause &&
    00748             XKeycodeToKeysym( qt_xdisplay(), 114, 0 ) == XK_Pause )
    00749         {
    00750                 if( keyModX & keyModXCtrl() ) {
    00751                         keyCodeX = 114;
    00752                         keySymX = XK_Break;
    00753                 } else {
    00754                         keyCodeX = 110;
    00755                         keySymX = XK_Pause;
    00756                 }
    00757         }
    00758
    00759         if( pKeySymX )  *pKeySymX = keySymX;
    00760         if( pKeyCodeX ) *pKeyCodeX = keyCodeX;
    00761         if( pKeyModX )  *pKeyModX = keyModX;
    00762 }*/
    00763
    00764 //---------------------------------------------------------------------
    00765 // Key
    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 // Variations
    00808 //---------------------------------------------------------------------
    00809
    00810 // TODO: allow for sym to have variations, such as Plus => { Plus, KP_Add }
    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                 // If 'key' doesn't require any mods that are inherent in
    00825                 //  the primary key but not required for the alternate,
    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                 // Two different native codes may produce a single
    00842                 //  Qt code.  Search for duplicates.
    00843                 for( uint i = 1; i < m_nVariations; i++ ) {
    00844                         for( uint j = 0; j < i; j++ ) {
    00845                                 // If key is already present in list, then remove it.
    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 } // end of namespace KKeyServer block
    00859 #undef KeyPress
    00860
    00861 // FIXME: This needs to be moved to kshortcut.cpp, and create a
    00862 //  KKeyServer::method which it will call.
    00863 // Alt+SysReq => Alt+Print
    00864 // Ctrl+Shift+Plus => Ctrl+Plus (en)
    00865 // Ctrl+Shift+Equal => Ctrl+Plus
    00866 // Ctrl+Pause => Ctrl+Break
    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                 // Shift+Equal => Shift+Plus (en)
    00877                 m_sym = KKeyNative(*this).sym();
    00878         }
    00879
    00880         // If this is a letter, don't remove any modifiers.
    00881         if( m_sym < 0x3000 && QChar(m_sym).isLetter() )
    00882                 m_sym = QChar(m_sym).lower().unicode();
    00883
    00884         // Remove modifers from modifier list which are implicit in the symbol.
    00885         // Ex. Shift+Plus => Plus (en)
    00886         m_mod &= ~KKeyServer::Sym(m_sym).getModsRequired();
    00887 }
    00888
    00889 #endif // Q_WS_X11

This file is part of the documentation for kdelibs Version 3.1.5.
Documentation copyright © 1996-2002 the KDE developers.
Generated on Wed Jan 28 12:46:35 2004 by doxygen 1.3.4 written by Dimitri van Heesch, © 1997-2001