kdecore Library: kkeyserver_x11.cpp Source File (kdecore Library)

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

# kkeyserver_x11.cpp

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

This file is part of the documentation for kdecore Library Version 3.4.1.
Documentation copyright © 1996-2004 the KDE developers.
Generated on Sat Jun 11 20:18:08 2005 by doxygen 1.4.1 written by Dimitri van Heesch, © 1997-2003