• Skip to content
  • Skip to link menu
KDE 4.1 API Reference
  • KDE API Reference
  • kdelibs
  • Sitemap
  • Contact Us
 

KDEUI

kkeyserver_x11.cpp

Go to the documentation of this file.
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., 51 Franklin Street, Fifth Floor,
00020     Boston, MA 02110-1301, USA.
00021 */
00022 
00023 #include "kkeyserver_x11.h"
00024 #include "kshortcut.h"
00025 
00026 #include <config.h>
00027 
00028 #include <QtCore/QCOORD>
00029 #include <QtGui/QWidgetList>
00030 #include <QFlags>
00031 
00032 #include <kconfig.h>
00033 #include <kdebug.h>
00034 #include <kglobal.h>
00035 #include <klocale.h>
00036 
00037 #include <QX11Info>
00038 # define XK_MISCELLANY
00039 # define XK_XKB_KEYS
00040 # include <X11/X.h>
00041 # include <X11/Xlib.h>
00042 # include <X11/Xutil.h>
00043 # include <X11/keysymdef.h>
00044 # define X11_ONLY(arg) arg, //allows to omit an argument
00045 
00046 
00047 namespace KKeyServer
00048 {
00049 
00050 //---------------------------------------------------------------------
00051 // Data Structures
00052 //---------------------------------------------------------------------
00053 
00054 struct Mod
00055 {
00056     int m_mod;
00057 };
00058 
00059 //---------------------------------------------------------------------
00060 // Array Structures
00061 //---------------------------------------------------------------------
00062 
00063 struct X11ModInfo
00064 {
00065     int modQt;
00066     int modX;
00067 };
00068 
00069 struct SymVariation
00070 {
00071     uint sym, symVariation;
00072     bool bActive;
00073 };
00074 
00075 struct SymName
00076 {
00077     uint sym;
00078     const char* psName;
00079 };
00080 
00081 struct TransKey {
00082     int keySymQt;
00083     uint keySymX;
00084 };
00085 
00086 //---------------------------------------------------------------------
00087 // Arrays
00088 //---------------------------------------------------------------------
00089 
00090 static X11ModInfo g_rgX11ModInfo[4] =
00091 {
00092     { Qt::SHIFT,   X11_ONLY(ShiftMask) },
00093     { Qt::CTRL,    X11_ONLY(ControlMask) },
00094     { Qt::ALT,     X11_ONLY(Mod1Mask) },
00095     { Qt::META,    X11_ONLY(Mod4Mask) }
00096 };
00097 
00098 // Special Names List
00099 static const SymName g_rgSymNames[] = {
00100     { XK_ISO_Left_Tab, "Backtab" },
00101     { XK_BackSpace,    I18N_NOOP("Backspace") },
00102     { XK_Sys_Req,      I18N_NOOP("SysReq") },
00103     { XK_Caps_Lock,    I18N_NOOP("CapsLock") },
00104     { XK_Num_Lock,     I18N_NOOP("NumLock") },
00105     { XK_Scroll_Lock,  I18N_NOOP("ScrollLock") },
00106     { XK_Prior,        I18N_NOOP("PageUp") },
00107     { XK_Next,         I18N_NOOP("PageDown") },
00108 #ifdef sun
00109     { XK_F11,          I18N_NOOP("Stop") },
00110     { XK_F12,          I18N_NOOP("Again") },
00111     { XK_F13,          I18N_NOOP("Props") },
00112     { XK_F14,          I18N_NOOP("Undo") },
00113     { XK_F15,          I18N_NOOP("Front") },
00114     { XK_F16,          I18N_NOOP("Copy") },
00115     { XK_F17,          I18N_NOOP("Open") },
00116     { XK_F18,          I18N_NOOP("Paste") },
00117     { XK_F19,          I18N_NOOP("Find") },
00118     { XK_F20,          I18N_NOOP("Cut") },
00119     { XK_F22,          I18N_NOOP("Print") },
00120 #endif
00121     { 0, 0 }
00122 };
00123 
00124 // These are the X equivalents to the Qt keycodes 0x1000 - 0x1026
00125 static const TransKey g_rgQtToSymX[] =
00126 {
00127     { Qt::Key_Escape,     XK_Escape },
00128     { Qt::Key_Tab,        XK_Tab },
00129     { Qt::Key_Backtab,    XK_ISO_Left_Tab },
00130     { Qt::Key_Backspace,  XK_BackSpace },
00131     { Qt::Key_Return,     XK_Return },
00132     { Qt::Key_Enter,      XK_KP_Enter },
00133     { Qt::Key_Insert,     XK_Insert },
00134     { Qt::Key_Delete,     XK_Delete },
00135     { Qt::Key_Pause,      XK_Pause },
00136 #ifdef sun
00137     { Qt::Key_Print,      XK_F22 },
00138 #else
00139     { Qt::Key_Print,      XK_Print },
00140 #endif
00141     { Qt::Key_SysReq,     XK_Sys_Req },
00142     { Qt::Key_Home,       XK_Home },
00143     { Qt::Key_End,        XK_End },
00144     { Qt::Key_Left,       XK_Left },
00145     { Qt::Key_Up,         XK_Up },
00146     { Qt::Key_Right,      XK_Right },
00147     { Qt::Key_Down,       XK_Down },
00148     { Qt::Key_PageUp,      XK_Prior },
00149     { Qt::Key_PageDown,       XK_Next },
00150     //{ Qt::Key_Shift,      0 },
00151     //{ Qt::Key_Control,    0 },
00152     //{ Qt::Key_Meta,       0 },
00153     //{ Qt::Key_Alt,        0 },
00154     { Qt::Key_CapsLock,   XK_Caps_Lock },
00155     { Qt::Key_NumLock,    XK_Num_Lock },
00156     { Qt::Key_ScrollLock, XK_Scroll_Lock },
00157     { Qt::Key_F1,         XK_F1 },
00158     { Qt::Key_F2,         XK_F2 },
00159     { Qt::Key_F3,         XK_F3 },
00160     { Qt::Key_F4,         XK_F4 },
00161     { Qt::Key_F5,         XK_F5 },
00162     { Qt::Key_F6,         XK_F6 },
00163     { Qt::Key_F7,         XK_F7 },
00164     { Qt::Key_F8,         XK_F8 },
00165     { Qt::Key_F9,         XK_F9 },
00166     { Qt::Key_F10,        XK_F10 },
00167     { Qt::Key_F11,        XK_F11 },
00168     { Qt::Key_F12,        XK_F12 },
00169     { Qt::Key_F13,        XK_F13 },
00170     { Qt::Key_F14,        XK_F14 },
00171     { Qt::Key_F15,        XK_F15 },
00172     { Qt::Key_F16,        XK_F16 },
00173     { Qt::Key_F17,        XK_F17 },
00174     { Qt::Key_F18,        XK_F18 },
00175     { Qt::Key_F19,        XK_F19 },
00176     { Qt::Key_F20,        XK_F20 },
00177     { Qt::Key_F21,        XK_F21 },
00178     { Qt::Key_F22,        XK_F22 },
00179     { Qt::Key_F23,        XK_F23 },
00180     { Qt::Key_F24,        XK_F24 },
00181     { Qt::Key_F25,        XK_F25 },
00182     { Qt::Key_F26,        XK_F26 },
00183     { Qt::Key_F27,        XK_F27 },
00184     { Qt::Key_F28,        XK_F28 },
00185     { Qt::Key_F29,        XK_F29 },
00186     { Qt::Key_F30,        XK_F30 },
00187     { Qt::Key_F31,        XK_F31 },
00188     { Qt::Key_F32,        XK_F32 },
00189     { Qt::Key_F33,        XK_F33 },
00190     { Qt::Key_F34,        XK_F34 },
00191     { Qt::Key_F35,        XK_F35 },
00192     { Qt::Key_Super_L,    XK_Super_L },
00193     { Qt::Key_Super_R,    XK_Super_R },
00194     { Qt::Key_Menu,       XK_Menu },
00195     { Qt::Key_Hyper_L,    XK_Hyper_L },
00196     { Qt::Key_Hyper_R,    XK_Hyper_R },
00197     { Qt::Key_Help,       XK_Help },
00198     //{ Qt::Key_Direction_L, XK_Direction_L }, These keys don't exist in X11
00199     //{ Qt::Key_Direction_R, XK_Direction_R },
00200 
00201     { '/',                XK_KP_Divide },
00202     { '*',                XK_KP_Multiply },
00203     { '-',                XK_KP_Subtract },
00204     { '+',                XK_KP_Add },
00205     { Qt::Key_Return,     XK_KP_Enter }
00206 
00207 // the next lines are taken from XFree > 4.0 (X11/XF86keysyms.h), defining some special
00208 // multimedia keys. They are included here as not every system has them.
00209 #define XF86XK_Standby      0x1008FF10
00210 #define XF86XK_AudioLowerVolume 0x1008FF11
00211 #define XF86XK_AudioMute    0x1008FF12
00212 #define XF86XK_AudioRaiseVolume 0x1008FF13
00213 #define XF86XK_AudioPlay    0x1008FF14
00214 #define XF86XK_AudioStop    0x1008FF15
00215 #define XF86XK_AudioPrev    0x1008FF16
00216 #define XF86XK_AudioNext    0x1008FF17
00217 #define XF86XK_HomePage     0x1008FF18
00218 #define XF86XK_Calculator   0x1008FF1D
00219 #define XF86XK_Mail     0x1008FF19
00220 #define XF86XK_Start        0x1008FF1A
00221 #define XF86XK_Search       0x1008FF1B
00222 #define XF86XK_AudioRecord  0x1008FF1C
00223 #define XF86XK_Back     0x1008FF26
00224 #define XF86XK_Forward      0x1008FF27
00225 #define XF86XK_Stop     0x1008FF28
00226 #define XF86XK_Refresh      0x1008FF29
00227 #define XF86XK_Favorites    0x1008FF30
00228 #define XF86XK_AudioPause   0x1008FF31
00229 #define XF86XK_AudioMedia   0x1008FF32
00230 #define XF86XK_MyComputer   0x1008FF33
00231 #define XF86XK_OpenURL      0x1008FF38
00232 #define XF86XK_Launch0      0x1008FF40
00233 #define XF86XK_Launch1      0x1008FF41
00234 #define XF86XK_Launch2      0x1008FF42
00235 #define XF86XK_Launch3      0x1008FF43
00236 #define XF86XK_Launch4      0x1008FF44
00237 #define XF86XK_Launch5      0x1008FF45
00238 #define XF86XK_Launch6      0x1008FF46
00239 #define XF86XK_Launch7      0x1008FF47
00240 #define XF86XK_Launch8      0x1008FF48
00241 #define XF86XK_Launch9      0x1008FF49
00242 #define XF86XK_LaunchA      0x1008FF4A
00243 #define XF86XK_LaunchB      0x1008FF4B
00244 #define XF86XK_LaunchC      0x1008FF4C
00245 #define XF86XK_LaunchD      0x1008FF4D
00246 #define XF86XK_LaunchE      0x1008FF4E
00247 #define XF86XK_LaunchF      0x1008FF4F
00248 // end of XF86keysyms.h
00249         ,
00250     { Qt::Key_Standby,    XF86XK_Standby },
00251     { Qt::Key_VolumeDown, XF86XK_AudioLowerVolume },
00252     { Qt::Key_VolumeMute, XF86XK_AudioMute },
00253     { Qt::Key_VolumeUp,   XF86XK_AudioRaiseVolume },
00254     { Qt::Key_MediaPlay,  XF86XK_AudioPlay },
00255     { Qt::Key_MediaStop,  XF86XK_AudioStop },
00256     { Qt::Key_MediaPrevious,  XF86XK_AudioPrev },
00257     { Qt::Key_MediaNext,  XF86XK_AudioNext },
00258     { Qt::Key_HomePage,   XF86XK_HomePage },
00259     { Qt::Key_LaunchMail, XF86XK_Mail },
00260     { Qt::Key_Search,     XF86XK_Search },
00261     { Qt::Key_MediaRecord, XF86XK_AudioRecord },
00262     { Qt::Key_LaunchMedia, XF86XK_AudioMedia },
00263     { Qt::Key_Launch1,    XF86XK_Calculator },
00264     { Qt::Key_Back,       XF86XK_Back },
00265     { Qt::Key_Forward,    XF86XK_Forward },
00266     { Qt::Key_Stop,       XF86XK_Stop },
00267     { Qt::Key_Refresh,    XF86XK_Refresh },
00268     { Qt::Key_Favorites,  XF86XK_Favorites },
00269     { Qt::Key_Launch0,    XF86XK_MyComputer },
00270     { Qt::Key_OpenUrl,    XF86XK_OpenURL },
00271     { Qt::Key_Launch2,    XF86XK_Launch0 },
00272     { Qt::Key_Launch3,    XF86XK_Launch1 },
00273     { Qt::Key_Launch4,    XF86XK_Launch2 },
00274     { Qt::Key_Launch5,    XF86XK_Launch3 },
00275     { Qt::Key_Launch6,    XF86XK_Launch4 },
00276     { Qt::Key_Launch7,    XF86XK_Launch5 },
00277     { Qt::Key_Launch8,    XF86XK_Launch6 },
00278     { Qt::Key_Launch9,    XF86XK_Launch7 },
00279     { Qt::Key_LaunchA,    XF86XK_Launch8 },
00280     { Qt::Key_LaunchB,    XF86XK_Launch9 },
00281     { Qt::Key_LaunchC,    XF86XK_LaunchA },
00282     { Qt::Key_LaunchD,    XF86XK_LaunchB },
00283     { Qt::Key_LaunchE,    XF86XK_LaunchC },
00284     { Qt::Key_LaunchF,    XF86XK_LaunchD },
00285 };
00286 
00287 //---------------------------------------------------------------------
00288 // Debugging
00289 //---------------------------------------------------------------------
00290 #ifndef NDEBUG 
00291 inline void checkDisplay()
00292 {
00293     // Some non-GUI apps might try to use us.
00294     if ( !QX11Info::display() ) {
00295         kError() << "QX11Info::display() returns 0.  I'm probably going to crash now." << endl;
00296         kError() << "If this is a KApplication initialized without GUI stuff, change it to be "
00297                     "initialized with GUI stuff." << endl;
00298     }
00299 }
00300 #else // NDEBUG
00301 # define checkDisplay()
00302 #endif
00303 
00304 //---------------------------------------------------------------------
00305 // Initialization
00306 //---------------------------------------------------------------------
00307 
00308 static bool g_bInitializedMods;
00309 static uint g_modXNumLock, g_modXScrollLock, g_modXModeSwitch, g_alt_mask, g_meta_mask;
00310 
00311 bool initializeMods()
00312 {
00313     checkDisplay();
00314     XModifierKeymap* xmk = XGetModifierMapping( QX11Info::display() );
00315 
00316     g_rgX11ModInfo[3].modX = g_modXNumLock = g_modXScrollLock = g_modXModeSwitch = 0; 
00317 
00318     int min_keycode, max_keycode;   
00319     int keysyms_per_keycode = 0;
00320     
00321     XDisplayKeycodes( QX11Info::display(), &min_keycode, &max_keycode );
00322     XFree( XGetKeyboardMapping( QX11Info::display(), min_keycode, 1, &keysyms_per_keycode ));
00323     
00324     // Defaults
00325     g_alt_mask = Mod1Mask;
00326     g_meta_mask = Mod4Mask;
00327 
00328     for( int i = Mod1MapIndex; i < 8; i++ ) {
00329         uint mask = (1 << i);
00330         uint keySymX = NoSymbol;
00331 
00332                 // This used to be only XKeycodeToKeysym( ... , 0 ), but that fails with XFree4.3.99
00333                 // and X.org R6.7 , where for some reason only ( ... , 1 ) works. I have absolutely no
00334                 // idea what the problem is, but searching all possibilities until something valid is
00335                 // found fixes the problem.
00336                 for( int j = 0; j < xmk->max_keypermod && keySymX == NoSymbol; ++j )
00337                     for( int k = 0; k < keysyms_per_keycode && keySymX == NoSymbol; ++k )
00338                         keySymX = XKeycodeToKeysym( QX11Info::display(), xmk->modifiermap[xmk->max_keypermod * i + j], k );
00339         switch( keySymX ) {
00340             case XK_Alt_L:
00341             case XK_Alt_R:     g_alt_mask = mask; break; // Alt key, Normally Mod1Mask
00342 
00343             case XK_Super_L:
00344             case XK_Super_R:     g_meta_mask = mask; break; // Win key, Normally Mod4Mask
00345 
00346             case XK_Meta_L:
00347             case XK_Meta_R:      if( !g_meta_mask ) g_meta_mask = mask; break; // Win alternate
00348 
00349             case XK_Num_Lock:    g_modXNumLock = mask; break;     // Normally Mod2Mask
00350             case XK_Scroll_Lock: g_modXScrollLock = mask; break;  // Normally Mod5Mask
00351             case XK_Mode_switch: g_modXModeSwitch = mask; break; 
00352         }
00353     }
00354 
00355     g_rgX11ModInfo[3].modX = g_meta_mask;
00356     g_rgX11ModInfo[2].modX = g_alt_mask;
00357 
00358     XFreeModifiermap( xmk );
00359 
00360     //KConfigGroup cg( KGlobal::config(), "Keyboard" );
00361     // read in mod that win should be attached to
00362 
00363     g_bInitializedMods = true;
00364 
00365     kDebug(125) << "KKeyServer::initializeMods(): Win Mod = 0x" << QString::number(g_rgX11ModInfo[3].modX, 16);
00366     return true;
00367 }
00368 
00369 
00370 //---------------------------------------------------------------------
00371 // Public functions
00372 //---------------------------------------------------------------------
00373 
00374 
00375 uint modXShift()      { return ShiftMask; }
00376 uint modXCtrl()       { return ControlMask; }
00377 uint modXAlt()        { if( !g_bInitializedMods ) { initializeMods(); } return g_alt_mask; }
00378 uint modXMeta()       { if( !g_bInitializedMods ) { initializeMods(); } return g_meta_mask; }
00379 
00380 uint modXNumLock()    { if( !g_bInitializedMods ) { initializeMods(); } return g_modXNumLock; }
00381 uint modXLock()       { return LockMask; }
00382 uint modXScrollLock() { if( !g_bInitializedMods ) { initializeMods(); } return g_modXScrollLock; }
00383 uint modXModeSwitch() { if( !g_bInitializedMods ) { initializeMods(); } return g_modXModeSwitch; } 
00384 
00385 bool keyboardHasMetaKey() { return modXMeta() != 0; }
00386 
00387 
00388 uint getModsRequired(uint sym)
00389 {
00390     uint mod = 0;
00391 
00392     // FIXME: This might not be true on all keyboard layouts!
00393     if( sym == XK_Sys_Req ) return Qt::ALT;
00394     if( sym == XK_Break ) return Qt::CTRL;
00395 
00396     if( sym < 0x3000 ) {
00397         QChar c(sym);
00398         if( c.isLetter() && c.toLower() != c.toUpper() && sym == c.toUpper().unicode() )
00399             return Qt::SHIFT;
00400     }
00401 
00402     uchar code = XKeysymToKeycode( QX11Info::display(), sym );
00403     if( code ) {
00404         // need to check index 0 before the others, so that a null-mod
00405         //  can take precedence over the others, in case the modified
00406         //  key produces the same symbol.
00407         if( sym == XKeycodeToKeysym( QX11Info::display(), code, 0 ) )
00408             ;
00409         else if( sym == XKeycodeToKeysym( QX11Info::display(), code, 1 ) )
00410             mod = Qt::SHIFT;
00411         else if( sym == XKeycodeToKeysym( QX11Info::display(), code, 2 ) )
00412             mod = MODE_SWITCH;
00413         else if( sym == XKeycodeToKeysym( QX11Info::display(), code, 3 ) )
00414             mod = Qt::SHIFT | MODE_SWITCH;
00415     }
00416     return mod;
00417 }
00418 
00419 bool keyQtToCodeX( int keyQt, int* keyCode )
00420 {
00421     int sym;
00422     uint mod;
00423     keyQtToSymX(keyQt, &sym);
00424     keyQtToModX(keyQt, &mod);
00425 
00426     // Get any extra mods required by the sym.
00427     //  E.g., XK_Plus requires SHIFT on the en layout.
00428     uint modExtra = getModsRequired(sym);
00429     // Get the X modifier equivalent.
00430     if( !sym || !keyQtToModX( (keyQt & Qt::KeyboardModifierMask) | modExtra, &mod ) ) {
00431         *keyCode = 0;
00432         return false;
00433     }
00434 
00435     // XKeysymToKeycode returns the wrong keycode for XK_Print and XK_Break.
00436     // Specifically, it returns the code for SysReq instead of Print
00437     // Only do this for the default Xorg layout, other keycode mappings
00438     // (e.g. evdev) don't need or want it.
00439     if( sym == XK_Print && !(mod & Mod1Mask) &&
00440             XKeycodeToKeysym( QX11Info::display(), 111, 0 ) == XK_Print )
00441         *keyCode = 111; // code for Print
00442     else if( sym == XK_Break || ((sym == XK_Pause && (mod & ControlMask)) &&
00443             XKeycodeToKeysym( QX11Info::display(), 114, 0 ) == XK_Pause) )
00444         *keyCode = 114;
00445     else
00446         *keyCode = XKeysymToKeycode( QX11Info::display(), sym );
00447 
00448     return true;
00449 }
00450 
00451 bool keyQtToSymX( int keyQt, int* keySym )
00452 {
00453     int symQt = keyQt & ~Qt::KeyboardModifierMask;
00454 
00455     if( symQt < 0x1000 ) {
00456         *keySym = QChar(symQt).toUpper().unicode();
00457         return true;
00458     }
00459 
00460 
00461     for( uint i = 0; i < sizeof(g_rgQtToSymX)/sizeof(TransKey); i++ ) {
00462         if( g_rgQtToSymX[i].keySymQt == symQt ) {
00463             *keySym = g_rgQtToSymX[i].keySymX;
00464             return true;
00465         }
00466     }
00467 
00468     *keySym = 0;
00469     if( symQt != Qt::Key_Shift && symQt != Qt::Key_Control && symQt != Qt::Key_Alt &&
00470         symQt != Qt::Key_Meta && symQt != Qt::Key_Direction_L && symQt != Qt::Key_Direction_R )
00471         kDebug(125) << "Sym::initQt( " << QString::number(keyQt,16) << " ): failed to convert key.";
00472     return false;
00473 }
00474 
00475 bool symXToKeyQt( uint keySym, int* keyQt )
00476 {
00477     *keyQt = Qt::Key_unknown;
00478     if( keySym < 0x1000 ) {
00479         if( keySym >= 'a' && keySym <= 'z' )
00480             *keyQt = QChar(keySym).toUpper().unicode();
00481         else
00482             *keyQt = keySym;
00483     }
00484 
00485     else if( keySym < 0x3000 )
00486         *keyQt = keySym;
00487 
00488     else {
00489         for( uint i = 0; i < sizeof(g_rgQtToSymX)/sizeof(TransKey); i++ )
00490             if( g_rgQtToSymX[i].keySymX == keySym ) {
00491                 *keyQt = g_rgQtToSymX[i].keySymQt;
00492                 break;
00493             }
00494     }
00495     
00496     return (*keyQt != Qt::Key_unknown);
00497 }
00498 
00499 /* are these things actually used anywhere?  there's no way
00500    they can do anything on non-X11 */
00501 
00502 bool keyQtToModX( int modQt, uint* modX )
00503 {
00504     if( !g_bInitializedMods )
00505         initializeMods();
00506 
00507     *modX = 0;
00508     for( int i = 0; i < 4; i++ ) {
00509         if( modQt & g_rgX11ModInfo[i].modQt ) {
00510             *modX |= g_rgX11ModInfo[i].modX;
00511             continue;
00512         }
00513     }
00514     return true;
00515 }
00516 
00517 bool modXToQt( uint modX, int* modQt )
00518 {
00519     if( !g_bInitializedMods )
00520         initializeMods();
00521 
00522     *modQt = 0;
00523     for( int i = 0; i < 4; i++ ) {
00524         if( modX & g_rgX11ModInfo[i].modX ) {
00525             *modQt |= g_rgX11ModInfo[i].modQt;
00526             continue;
00527         }
00528     }
00529     return true;
00530 }
00531 
00532 
00533 bool codeXToSym( uchar codeX, uint modX, uint* sym )
00534 {
00535     KeySym keySym;
00536     XKeyPressedEvent event;
00537 
00538     checkDisplay();
00539 
00540     event.type = KeyPress;
00541     event.display = QX11Info::display();
00542     event.state = modX;
00543     event.keycode = codeX;
00544 
00545     XLookupString( &event, 0, 0, &keySym, 0 );
00546     *sym = (uint) keySym;
00547     return true;
00548 }
00549 
00550 
00551 uint accelModMaskX()
00552 {
00553     return modXShift() | modXCtrl() | modXAlt() | modXMeta();
00554 }
00555 
00556 
00557 bool xEventToQt( XEvent* e, int* keyQt )
00558 {
00559     uchar keyCodeX = e->xkey.keycode;
00560     uint keyModX = e->xkey.state & (accelModMaskX() | MODE_SWITCH);
00561 
00562     KeySym keySym;
00563     XLookupString( (XKeyEvent*) e, 0, 0, &keySym, 0 );
00564     uint keySymX = (uint)keySym;
00565 
00566     // If numlock is active and a keypad key is pressed, XOR the SHIFT state.
00567     //  e.g., KP_4 => Shift+KP_Left, and Shift+KP_4 => KP_Left.
00568     if( e->xkey.state & modXNumLock() ) {
00569         uint sym = XKeycodeToKeysym( QX11Info::display(), keyCodeX, 0 );
00570         // TODO: what's the xor operator in c++?
00571         // If this is a keypad key,
00572         if( sym >= XK_KP_Space && sym <= XK_KP_9 ) {
00573             switch( sym ) {
00574                 // Leave the following keys unaltered
00575                 // FIXME: The proper solution is to see which keysyms don't change when shifted.
00576                 case XK_KP_Multiply:
00577                 case XK_KP_Add:
00578                 case XK_KP_Subtract:
00579                 case XK_KP_Divide:
00580                     break;
00581                 default:
00582                     if( keyModX & modXShift() )
00583                         keyModX &= ~modXShift();
00584                     else
00585                         keyModX |= modXShift();
00586             }
00587         }
00588     }
00589 
00590     int keyCodeQt;
00591     int keyModQt;
00592     symXToKeyQt(keySymX, &keyCodeQt);
00593     modXToQt(keyModX, &keyModQt);
00594     
00595     *keyQt = keyCodeQt | keyModQt;
00596     return true;
00597 }
00598 
00599 
00600 } // end of namespace KKeyServer block

KDEUI

Skip menu "KDEUI"
  • Main Page
  • Modules
  • Namespace List
  • Class Hierarchy
  • Alphabetical List
  • Class List
  • File List
  • Namespace Members
  • Class Members
  • Related Pages

kdelibs

Skip menu "kdelibs"
  • DNSSD
  • Interfaces
  •   KHexEdit
  •   KMediaPlayer
  •   KSpeech
  •   KTextEditor
  • Kate
  • kconf_update
  • KDE3Support
  •   KUnitTest
  • KDECore
  • KDED
  • KDEsu
  • KDEUI
  • KDocTools
  • KFile
  • KHTML
  • KImgIO
  • KInit
  • KIO
  • KIOSlave
  • KJS
  •   KJS-API
  •   WTF
  • kjsembed
  • KNewStuff
  • KParts
  • Kross
  • KUtils
  • Nepomuk
  • Solid
  • Sonnet
  • ThreadWeaver
Generated for kdelibs by doxygen 1.5.4
This website is maintained by Adriaan de Groot and Allen Winter.
KDE® and the K Desktop Environment® logo are registered trademarks of KDE e.V. | Legal