• Skip to content
  • Skip to link menu
Trinity API Reference
  • Trinity API Reference
  • kdecore
 

kdecore

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., 51 Franklin Street, Fifth Floor,
00020     Boston, MA 02110-1301, USA.
00021 */
00022 
00023 #include <config.h>
00024 
00025 #include <tqnamespace.h>
00026 #include <tqwindowdefs.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     TQString 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"), TQString() },
00111     { KKey::CTRL,  Qt::CTRL,    X11_ONLY(ControlMask) I18N_NOOP("Ctrl"), TQString() },
00112     { KKey::ALT,   Qt::ALT,     X11_ONLY(Mod1Mask)    I18N_NOOP("Alt"), TQString() },
00113     { KKey::WIN,   KKey::QtWIN, X11_ONLY(Mod4Mask)    I18N_NOOP("Win"), TQString() }
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     { TQt::Key_Prior,      XK_Prior },
00180     { TQt::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 #define XF86XK_MonBrightnessUp      0x1008FF02  /* Monitor/panel brightness */
00281 #define XF86XK_MonBrightnessDown    0x1008FF03  /* Monitor/panel brightness */
00282 #define XF86XK_KbdLightOnOff        0x1008FF04  /* Keyboards may be lit     */
00283 #define XF86XK_KbdBrightnessUp      0x1008FF05  /* Keyboards may be lit     */
00284 #define XF86XK_KbdBrightnessDown    0x1008FF06  /* Keyboards may be lit     */
00285 // end of XF86keysyms.h
00286         ,
00287     { Qt::Key_Standby,    XF86XK_Standby },
00288     { Qt::Key_VolumeDown, XF86XK_AudioLowerVolume },
00289     { Qt::Key_VolumeMute, XF86XK_AudioMute },
00290     { Qt::Key_VolumeUp,   XF86XK_AudioRaiseVolume },
00291     { Qt::Key_MediaPlay,  XF86XK_AudioPlay },
00292     { Qt::Key_MediaStop,  XF86XK_AudioStop },
00293     { TQt::Key_MediaPrev,  XF86XK_AudioPrev },
00294     { Qt::Key_MediaNext,  XF86XK_AudioNext },
00295     { Qt::Key_HomePage,   XF86XK_HomePage },
00296     { Qt::Key_LaunchMail, XF86XK_Mail },
00297     { Qt::Key_Search,     XF86XK_Search },
00298     { Qt::Key_MediaRecord, XF86XK_AudioRecord },
00299     { Qt::Key_LaunchMedia, XF86XK_AudioMedia },
00300     { Qt::Key_Launch1,    XF86XK_Calculator },
00301     { Qt::Key_Back,       XF86XK_Back },
00302     { Qt::Key_Forward,    XF86XK_Forward },
00303     { Qt::Key_Stop,       XF86XK_Stop },
00304     { Qt::Key_Refresh,    XF86XK_Refresh },
00305     { Qt::Key_Favorites,  XF86XK_Favorites },
00306     { Qt::Key_Launch0,    XF86XK_MyComputer },
00307     { Qt::Key_OpenUrl,    XF86XK_OpenURL },
00308     { Qt::Key_Launch2,    XF86XK_Launch0 },
00309     { Qt::Key_Launch3,    XF86XK_Launch1 },
00310     { Qt::Key_Launch4,    XF86XK_Launch2 },
00311     { Qt::Key_Launch5,    XF86XK_Launch3 },
00312     { Qt::Key_Launch6,    XF86XK_Launch4 },
00313     { Qt::Key_Launch7,    XF86XK_Launch5 },
00314     { Qt::Key_Launch8,    XF86XK_Launch6 },
00315     { Qt::Key_Launch9,    XF86XK_Launch7 },
00316     { Qt::Key_LaunchA,    XF86XK_Launch8 },
00317     { Qt::Key_LaunchB,    XF86XK_Launch9 },
00318     { Qt::Key_LaunchC,    XF86XK_LaunchA },
00319     { Qt::Key_LaunchD,    XF86XK_LaunchB },
00320     { Qt::Key_LaunchE,    XF86XK_LaunchC },
00321     { Qt::Key_LaunchF,    XF86XK_LaunchD },
00322     { Qt::Key_MonBrightnessUp, XF86XK_MonBrightnessUp },
00323     { Qt::Key_MonBrightnessDown, XF86XK_MonBrightnessDown },
00324     { Qt::Key_KeyboardLightOnOff, XF86XK_KbdLightOnOff },
00325     { Qt::Key_KeyboardBrightnessUp, XF86XK_KbdBrightnessUp },
00326     { Qt::Key_KeyboardBrightnessDown, XF86XK_KbdBrightnessDown },
00327 #endif
00328 };
00329 #endif //Q_WS_X11
00330 
00331 //---------------------------------------------------------------------
00332 // Initialization
00333 //---------------------------------------------------------------------
00334 static bool g_bInitializedMods, g_bInitializedVariations, g_bInitializedKKeyLabels;
00335 static bool g_bMacLabels;
00336 #ifdef Q_WS_X11
00337 static uint g_modXNumLock, g_modXScrollLock, g_modXModeSwitch; 
00338 
00339 bool initializeMods()
00340 {
00341     XModifierKeymap* xmk = XGetModifierMapping( qt_xdisplay() );
00342 
00343     g_rgModInfo[3].modX = g_modXNumLock = g_modXScrollLock = g_modXModeSwitch = 0; 
00344 
00345         int min_keycode, max_keycode;
00346         int keysyms_per_keycode = 0;
00347         XDisplayKeycodes( qt_xdisplay(), &min_keycode, &max_keycode );
00348         XFree( XGetKeyboardMapping( qt_xdisplay(), min_keycode, 1, &keysyms_per_keycode ));
00349     // Qt assumes that Alt is always Mod1Mask, so start at Mod2Mask.
00350     for( int i = Mod2MapIndex; i < 8; i++ ) {
00351         uint mask = (1 << i);
00352         uint keySymX = NoSymbol;
00353                 // This used to be only XKeycodeToKeysym( ... , 0 ), but that fails with XFree4.3.99
00354                 // and X.org R6.7 , where for some reason only ( ... , 1 ) works. I have absolutely no
00355                 // idea what the problem is, but searching all posibilities until something valid is
00356                 // found fixes the problem.
00357                 for( int j = 0; j < xmk->max_keypermod && keySymX == NoSymbol; ++j )
00358                     for( int k = 0; k < keysyms_per_keycode && keySymX == NoSymbol; ++k )
00359                         keySymX = XKeycodeToKeysym( qt_xdisplay(), xmk->modifiermap[xmk->max_keypermod * i + j], k );
00360         switch( keySymX ) {
00361             case XK_Num_Lock:    g_modXNumLock = mask; break;     // Normally Mod2Mask
00362             case XK_Super_L:
00363             case XK_Super_R:     g_rgModInfo[3].modX = mask; break; // Win key, Normally Mod4Mask
00364             case XK_Meta_L:
00365             case XK_Meta_R:      if( !g_rgModInfo[3].modX ) g_rgModInfo[3].modX = mask; break; // Win alternate
00366             case XK_Scroll_Lock: g_modXScrollLock = mask; break;  // Normally Mod5Mask
00367             case XK_Mode_switch: g_modXModeSwitch = mask; break; 
00368         }
00369     }
00370 
00371     XFreeModifiermap( xmk );
00372 
00373     //KConfigGroupSaver cgs( KGlobal::config(), "Keyboard" );
00374     // read in mod that win should be attached to
00375 
00376     g_bInitializedMods = true;
00377 
00378     kdDebug(125) << "KKeyServer::initializeMods(): Win Mod = 0x" << TQString::number(g_rgModInfo[3].modX, 16) << endl;
00379     return true;
00380 }
00381 
00382 static void initializeVariations()
00383 {
00384     for( int i = 0; g_rgSymVariation[i].sym != 0; i++ )
00385         g_rgSymVariation[i].bActive = (XKeysymToKeycode( qt_xdisplay(), g_rgSymVariation[i].symVariation ) != 0);
00386     g_bInitializedVariations = true;
00387 }
00388 #endif //Q_WS_X11
00389 
00390 static void intializeKKeyLabels()
00391 {
00392     KConfigGroupSaver cgs( KGlobal::config(), "Keyboard" );
00393     g_rgModInfo[0].sLabel = KGlobal::config()->readEntry( "Label Shift", i18n(g_rgModInfo[0].psName) );
00394     g_rgModInfo[1].sLabel = KGlobal::config()->readEntry( "Label Ctrl", i18n(g_rgModInfo[1].psName) );
00395     g_rgModInfo[2].sLabel = KGlobal::config()->readEntry( "Label Alt", i18n(g_rgModInfo[2].psName) );
00396     g_rgModInfo[3].sLabel = KGlobal::config()->readEntry( "Label Win", i18n(g_rgModInfo[3].psName) );
00397     g_bMacLabels = (g_rgModInfo[2].sLabel == "Command");
00398     g_bInitializedKKeyLabels = true;
00399 }
00400 
00401 //---------------------------------------------------------------------
00402 // class Mod
00403 //---------------------------------------------------------------------
00404 
00405 /*void Mod::init( const TQString& s )
00406 {
00407 
00408 }*/
00409 
00410 //---------------------------------------------------------------------
00411 // class Sym
00412 //---------------------------------------------------------------------
00413 
00414 bool Sym::initQt( int keyQt )
00415 {
00416     int symQt = keyQt & 0xffff;
00417 
00418     if( (keyQt & Qt::UNICODE_ACCEL) || symQt < 0x1000 ) {
00419         m_sym = TQChar(symQt).lower().unicode();
00420         return true;
00421     }
00422 
00423 #ifdef Q_WS_WIN
00424     m_sym = symQt;
00425     return true;
00426 #elif defined(Q_WS_X11)
00427     for( uint i = 0; i < sizeof(g_rgQtToSymX)/sizeof(TransKey); i++ ) {
00428         if( g_rgQtToSymX[i].keySymQt == symQt ) {
00429             m_sym = g_rgQtToSymX[i].keySymX;
00430             return true;
00431         }
00432     }
00433 
00434     m_sym = 0;
00435     if( symQt != Qt::Key_Shift && symQt != Qt::Key_Control && symQt != Qt::Key_Alt &&
00436         symQt != Qt::Key_Meta && symQt != Qt::Key_Direction_L && symQt != Qt::Key_Direction_R )
00437         kdDebug(125) << "Sym::initQt( " << TQString::number(keyQt,16) << " ): failed to convert key." << endl;
00438     return false;
00439 #elif defined(Q_WS_MACX)
00440         m_sym = symQt;
00441         return true;
00442 #endif
00443 }
00444 
00445 bool Sym::init( const TQString& s )
00446 {
00447     // If it's a single character, get unicode value.
00448     if( s.length() == 1 ) {
00449         m_sym = s[0].lower().unicode();
00450         return true;
00451     }
00452 
00453     // Look up in special names list
00454     for( int i = 0; g_rgSymNames[i].sym != 0; i++ ) {
00455         if( qstricmp( s.latin1(), g_rgSymNames[i].psName ) == 0 ) {
00456             m_sym = g_rgSymNames[i].sym;
00457             return true;
00458         }
00459     }
00460 
00461 #ifdef Q_WS_WIN
00462     // search for name in KKeys array
00463     for ( KKeys const *pKey  = kde_KKEYS; pKey->code != 0xffff; pKey++) {
00464         if( qstricmp( s.latin1(), pKey->name ) == 0 ) {
00465             m_sym = pKey->code;
00466             return true;
00467         }
00468     }
00469     m_sym = 0;
00470 #elif defined(Q_WS_X11)
00471     // search X list: 's' as is, all lower, first letter in caps
00472     m_sym = XStringToKeysym( s.latin1() );
00473     if( !m_sym ) {
00474         m_sym = XStringToKeysym( s.lower().latin1() );
00475         if( !m_sym ) {
00476             TQString s2 = s;
00477             s2[0] = s2[0].upper();
00478             m_sym = XStringToKeysym( s2.latin1() );
00479         }
00480     }
00481 #endif
00482     return m_sym != 0;
00483 }
00484 
00485 int Sym::qt() const
00486 {
00487     if( m_sym < 0x1000 ) {
00488         if( m_sym >= 'a' && m_sym <= 'z' )
00489             return TQChar(m_sym).upper();
00490         return m_sym;
00491     }
00492 #ifdef Q_WS_WIN
00493     if( m_sym < 0x3000 )
00494         return m_sym;
00495 #elif defined(Q_WS_X11)
00496     if( m_sym < 0x3000 )
00497         return m_sym | Qt::UNICODE_ACCEL;
00498 
00499     for( uint i = 0; i < sizeof(g_rgQtToSymX)/sizeof(TransKey); i++ )
00500         if( g_rgQtToSymX[i].keySymX == m_sym )
00501             return g_rgQtToSymX[i].keySymQt;
00502 #endif
00503     return TQt::Key_unknown;
00504 }
00505 
00506 TQString Sym::toString( bool bUserSpace ) const
00507 {
00508     if( m_sym == 0 ) {
00509         return TQString::null;
00510     }
00511 
00512     // If it's a unicode character,
00513 #ifdef Q_WS_WIN
00514     else if( m_sym < 0x1000 ) {
00515 #else
00516     else if( m_sym < 0x3000 ) {
00517 #endif
00518         TQChar c = TQChar(m_sym).upper();
00519         // Print all non-space characters directly when output is user-visible.
00520         // Otherwise only print alphanumeric latin1 characters directly (A,B,C,1,2,3).
00521         if( (c.latin1() && c.isLetterOrNumber())
00522             || (bUserSpace && !c.isSpace()) ) {
00523                 return c;
00524         }
00525     }
00526 
00527     // Look up in special names list
00528     for( int i = 0; g_rgSymNames[i].sym != 0; i++ ) {
00529         if( m_sym == g_rgSymNames[i].sym ) {
00530             return bUserSpace ? i18n(g_rgSymNames[i].psName) : TQString(g_rgSymNames[i].psName);
00531         }
00532     }
00533 
00534     TQString s;
00535 #ifdef Q_WS_WIN
00536     s = TQKeySequence( m_sym );
00537 #elif defined(Q_WS_X11)
00538     // Get X-name
00539     s = XKeysymToString( m_sym );
00540 #endif
00541     capitalizeKeyname( s );
00542     return bUserSpace ? i18n(TQACCEL_OBJECT_NAME_STRING, s.latin1()) : s;
00543 }
00544 
00545 TQString Sym::toStringInternal() const { return toString( false ); }
00546 TQString Sym::toString() const         { return toString( true ); }
00547 
00548 uint Sym::getModsRequired() const
00549 {
00550     uint mod = 0;
00551 #ifdef Q_WS_X11
00552     // FIXME: This might not be true on all keyboard layouts!
00553     if( m_sym == XK_Sys_Req ) return KKey::ALT;
00554     if( m_sym == XK_Break ) return KKey::CTRL;
00555 
00556     if( m_sym < 0x3000 ) {
00557         TQChar c(m_sym);
00558         if( c.isLetter() && c.lower() != c.upper() && m_sym == c.upper().unicode() )
00559             return KKey::SHIFT;
00560     }
00561 
00562     uchar code = XKeysymToKeycode( qt_xdisplay(), m_sym );
00563     if( code ) {
00564         // need to check index 0 before the others, so that a null-mod
00565         //  can take precedence over the others, in case the modified
00566         //  key produces the same symbol.
00567         if( m_sym == XKeycodeToKeysym( qt_xdisplay(), code, 0 ) )
00568             ;
00569         else if( m_sym == XKeycodeToKeysym( qt_xdisplay(), code, 1 ) )
00570             mod = KKey::SHIFT;
00571         else if( m_sym == XKeycodeToKeysym( qt_xdisplay(), code, 2 ) )
00572             mod = KKeyServer::MODE_SWITCH;
00573         else if( m_sym == XKeycodeToKeysym( qt_xdisplay(), code, 3 ) )
00574             mod = KKey::SHIFT | KKeyServer::MODE_SWITCH;
00575     }
00576 #endif
00577     return mod;
00578 }
00579 
00580 uint Sym::getSymVariation() const
00581 {
00582 #ifdef Q_WS_X11
00583     if( !g_bInitializedVariations )
00584         initializeVariations();
00585     for( int i = 0; g_rgSymVariation[i].sym != 0; i++ )
00586         if( g_rgSymVariation[i].sym == m_sym && g_rgSymVariation[i].bActive )
00587             return g_rgSymVariation[i].symVariation;
00588 #endif
00589     return 0;
00590 }
00591 
00592 void Sym::capitalizeKeyname( TQString& s )
00593 {
00594     s[0] = s[0].upper();
00595     int len = s.length();
00596     if( s.endsWith( "left" ) )       s[len-4] = 'L';
00597     else if( s.endsWith( "right" ) ) s[len-5] = 'R';
00598     else if( s == "Sysreq" )         s[len-3] = 'R';
00599 }
00600 
00601 //---------------------------------------------------------------------
00602 // Public functions
00603 //---------------------------------------------------------------------
00604 
00605 #ifdef Q_WS_X11
00606 uint modX( KKey::ModFlag mod )
00607 {
00608     if( mod == KKey::WIN && !g_bInitializedMods )
00609         initializeMods();
00610 
00611     for( uint i = 0; i < KKey::MOD_FLAG_COUNT; i++ ) {
00612         if( g_rgModInfo[i].mod == mod )
00613             return g_rgModInfo[i].modX;
00614     }
00615     return 0;
00616 }
00617 
00618 bool keyboardHasWinKey() { if( !g_bInitializedMods ) { initializeMods(); } return g_rgModInfo[3].modX != 0; }
00619 uint modXShift()      { return ShiftMask; }
00620 uint modXLock()       { return LockMask; }
00621 uint modXCtrl()       { return ControlMask; }
00622 uint modXAlt()        { return Mod1Mask; }
00623 uint modXNumLock()    { if( !g_bInitializedMods ) { initializeMods(); } return g_modXNumLock; }
00624 uint modXWin()        { if( !g_bInitializedMods ) { initializeMods(); } return g_rgModInfo[3].modX; }
00625 uint modXScrollLock() { if( !g_bInitializedMods ) { initializeMods(); } return g_modXScrollLock; }
00626 uint modXModeSwitch() { if( !g_bInitializedMods ) { initializeMods(); } return g_modXModeSwitch; } 
00627 
00628 uint accelModMaskX()
00629 {
00630     if( !g_bInitializedMods )
00631         initializeMods();
00632     return ShiftMask | ControlMask | Mod1Mask | g_rgModInfo[3].modX;
00633 }
00634 #endif //Q_WS_X11
00635 
00636 bool keyQtToSym( int keyQt, uint& keySym )
00637 {
00638     Sym sym;
00639     if( sym.initQt( keyQt ) ) {
00640         keySym = sym.m_sym;
00641         return true;
00642     } else
00643         return false;
00644 }
00645 
00646 bool keyQtToMod( int keyQt, uint& mod )
00647 {
00648     mod = 0;
00649 
00650     if( keyQt & Qt::SHIFT )    mod |= KKey::SHIFT;
00651     if( keyQt & Qt::CTRL )     mod |= KKey::CTRL;
00652     if( keyQt & Qt::ALT )      mod |= KKey::ALT;
00653     if( keyQt & Qt::META ) mod |= KKey::WIN;
00654 
00655     return true;
00656 }
00657 
00658 bool symToKeyQt( uint keySym, int& keyQt )
00659 {
00660     Sym sym( keySym );
00661     keyQt = sym.qt();
00662     return (keyQt != TQt::Key_unknown);
00663 }
00664 
00665 bool modToModQt( uint mod, int& modQt )
00666 {
00667     modQt = 0;
00668     for( int i = 0; i < KKey::MOD_FLAG_COUNT; i++ ) {
00669         if( mod & g_rgModInfo[i].mod ) {
00670             if( !g_rgModInfo[i].modQt ) {
00671                 modQt = 0;
00672                 return false;
00673             }
00674             modQt |= g_rgModInfo[i].modQt;
00675         }
00676     }
00677     return true;
00678 }
00679 
00680 #ifdef Q_WS_WIN
00681 //wrapped
00682 bool modXToModQt( uint modX, int& modQt )
00683 {
00684     return modToModQt( modX, modQt );
00685 }
00686 
00687 KDECORE_EXPORT int qtButtonStateToMod( TQt::ButtonState s )
00688 {
00689     int modQt = 0;
00690     if (s & Qt::ShiftButton) modQt |= KKey::SHIFT;
00691     if (s & Qt::ControlButton) modQt |= KKey::CTRL;
00692     if (s & Qt::AltButton) modQt |= KKey::ALT;
00693     return modQt;
00694 }
00695 
00696 bool keyboardHasWinKey() { 
00698   return true;
00699 }
00700 
00701 #elif defined(Q_WS_MACX)
00702 
00703 bool modXToModQt(uint modX, int& modQt)
00704 {
00705     return modToModQt( modX, modQt );
00706 }
00707 
00708 bool keyboardHasWinKey() {
00710   return false;
00711 }
00712 
00713 bool modXToMod( uint , uint& )
00714 {
00715     return false;
00716 }
00717 #elif defined(Q_WS_X11)
00718 
00719 bool modToModX( uint mod, uint& modX )
00720 {
00721     if( !g_bInitializedMods )
00722         initializeMods();
00723 
00724     modX = 0;
00725     for( int i = 0; i < KKey::MOD_FLAG_COUNT; i++ ) {
00726         if( mod & g_rgModInfo[i].mod ) {
00727             if( !g_rgModInfo[i].modX ) {
00728                 kdDebug(125) << "Invalid modifier flag." << endl;
00729                 modX = 0;
00730                 return false;
00731             }
00732             modX |= g_rgModInfo[i].modX;
00733         }
00734     }
00735     // TODO: document 0x2000 flag
00736     if( mod & 0x2000 )
00737       modX |= 0x2000;
00738     return true;
00739 }
00740 
00741 bool modXToModQt( uint modX, int& modQt )
00742 {
00743     if( !g_bInitializedMods )
00744         initializeMods();
00745     
00746     modQt = 0;
00747     for( int i = 0; i < KKey::MOD_FLAG_COUNT; i++ ) {
00748         if( modX & g_rgModInfo[i].modX ) {
00749             if( !g_rgModInfo[i].modQt ) {
00750                 modQt = 0;
00751                 return false;
00752             }
00753             modQt |= g_rgModInfo[i].modQt;
00754         }
00755     }
00756     return true;
00757 }
00758 
00759 bool modXToMod( uint modX, uint& mod )
00760 {
00761     if( !g_bInitializedMods )
00762         initializeMods();
00763     
00764     mod = 0;
00765     for( int i = 0; i < KKey::MOD_FLAG_COUNT; i++ ) {
00766         if( modX & g_rgModInfo[i].modX )
00767             mod |= g_rgModInfo[i].mod;
00768     }
00769     return true;
00770 }
00771 
00772 bool codeXToSym( uchar codeX, uint modX, uint& sym )
00773 {
00774     KeySym keySym;
00775     XKeyPressedEvent event;
00776 
00777     event.type = KeyPress;
00778     event.display = qt_xdisplay();
00779     event.state = modX;
00780     event.keycode = codeX;
00781 
00782     char buffer[64];
00783     XLookupString( &event, buffer, 63, &keySym, NULL );
00784     sym = (uint) keySym;
00785     return true;
00786 }
00787 #endif //!Q_WS_WIN
00788 
00789 static TQString modToString( uint mod, bool bUserSpace )
00790 {
00791     if( bUserSpace && !g_bInitializedKKeyLabels )
00792         intializeKKeyLabels();
00793 
00794     TQString s;
00795     for( int i = KKey::MOD_FLAG_COUNT-1; i >= 0; i-- ) {
00796         if( mod & g_rgModInfo[i].mod ) {
00797             if( !s.isEmpty() )
00798                 s += '+';
00799             s += (bUserSpace)
00800                       ? g_rgModInfo[i].sLabel
00801                   : TQString(g_rgModInfo[i].psName);
00802         }
00803     }
00804     return s;
00805 }
00806 
00807 TQString modToStringInternal( uint mod ) { return modToString( mod, false ); }
00808 TQString modToStringUser( uint mod )     { return modToString( mod, true ); }
00809 
00810 uint stringUserToMod( const TQString& mod )
00811 {
00812     if( !g_bInitializedKKeyLabels )
00813         intializeKKeyLabels();
00814 
00815     TQString s;
00816     for( int i = KKey::MOD_FLAG_COUNT-1; i >= 0; i-- ) {
00817         if( mod.lower() == g_rgModInfo[i].sLabel.lower())
00818             return g_rgModInfo[i].mod;
00819     }
00820     return 0;
00821 }
00822 
00823 /*void keySymModToKeyX( uint sym, uint mod, unsigned char *pKeyCodeX, uint *pKeySymX, uint *pKeyModX )
00824 {
00825 ...
00826     uint    keySymQt;
00827     uint    keySymX = 0;
00828     unsigned char   keyCodeX = 0;
00829     uint    keyModX = 0;
00830 
00831     const char *psKeySym = 0;
00832 
00833     if( !g_bInitialized )
00834         Initialize();
00835 
00836     // Get code of just the primary key
00837     keySymQt = keyCombQt & 0xffff;
00838 
00839     // If unicode value beneath 0x1000 (special Qt codes begin thereafter),
00840     if( keySymQt < 0x1000 ) {
00841         // For reasons unbeknownst to me, Qt converts 'a-z' to 'A-Z'.
00842         // So convert it back to lowercase if SHIFT isn't held down.
00843         if( keySymQt >= Qt::Key_A && keySymQt <= Qt::Key_Z && !(keyCombQt & Qt::SHIFT) )
00844             keySymQt = tolower( keySymQt );
00845         keySymX = keySymQt;
00846     }
00847     // Else, special key (e.g. Delete, F1, etc.)
00848     else {
00849         for( int i = 0; i < NB_KEYS; i++ ) {
00850             if( keySymQt == (uint) KKEYS[i].code ) {
00851                 psKeySym = KKEYS[i].name;
00852                 //kdDebug(125) << " symbol found: \"" << psKeySym << "\"" << endl;
00853                 break;
00854             }
00855         }
00856 
00857         // Get X key symbol.  Only works if Qt name is same as X name.
00858         if( psKeySym ) {
00859             TQString sKeySym = psKeySym;
00860 
00861             // Check for lower-case equalent first because most
00862             //  X11 names are all lower-case.
00863             keySymX = XStringToKeysym( sKeySym.lower().ascii() );
00864             if( keySymX == 0 )
00865                 keySymX = XStringToKeysym( psKeySym );
00866         }
00867 
00868         if( keySymX == 0 )
00869             keySymX = getSymXEquiv( keySymQt );
00870     }
00871 
00872     if( keySymX != 0 ) {
00873         // Get X keyboard code
00874         keyCodeX = XKeysymToKeycode( qt_xdisplay(), keySymX );
00875         // Add ModeSwitch modifier bit, if necessary
00876         keySymXMods( keySymX, 0, &keyModX );
00877 
00878         // Get X modifier flags
00879         for( int i = 0; i < MOD_KEYS; i++ ) {
00880             if( keyCombQt & g_aModKeys[i].keyModMaskQt ) {
00881                 if( g_aModKeys[i].keyModMaskX )
00882                     keyModX |= g_aModKeys[i].keyModMaskX;
00883                 // Qt key calls for a modifier which the current
00884                 //  X modifier map doesn't support.
00885                 else {
00886                     keySymX = 0;
00887                     keyCodeX = 0;
00888                     keyModX = 0;
00889                     break;
00890                 }
00891             }
00892         }
00893     }
00894 
00895     // Take care of complications:
00896     //  The following keys will not have been correctly interpreted,
00897     //   because their shifted values are not activated with the
00898     //   Shift key, but rather something else.  They are also
00899     //   defined twice under different keycodes.
00900     //  keycode 111 & 92:  Print Sys_Req -> Sys_Req = Alt+Print
00901     //  keycode 110 & 114: Pause Break   -> Break = Ctrl+Pause
00902     if( (keyCodeX == 92 || keyCodeX == 111) &&
00903         XKeycodeToKeysym( qt_xdisplay(), 92, 0 ) == XK_Print &&
00904         XKeycodeToKeysym( qt_xdisplay(), 111, 0 ) == XK_Print )
00905     {
00906         // If Alt is pressed, then we need keycode 92, keysym XK_Sys_Req
00907         if( keyModX & keyModXAlt() ) {
00908             keyCodeX = 92;
00909             keySymX = XK_Sys_Req;
00910         }
00911         // Otherwise, keycode 111, keysym XK_Print
00912         else {
00913             keyCodeX = 111;
00914             keySymX = XK_Print;
00915         }
00916     }
00917     else if( (keyCodeX == 110 || keyCodeX == 114) &&
00918         XKeycodeToKeysym( qt_xdisplay(), 110, 0 ) == XK_Pause &&
00919         XKeycodeToKeysym( qt_xdisplay(), 114, 0 ) == XK_Pause )
00920     {
00921         if( keyModX & keyModXCtrl() ) {
00922             keyCodeX = 114;
00923             keySymX = XK_Break;
00924         } else {
00925             keyCodeX = 110;
00926             keySymX = XK_Pause;
00927         }
00928     }
00929 
00930     if( pKeySymX )  *pKeySymX = keySymX;
00931     if( pKeyCodeX ) *pKeyCodeX = keyCodeX;
00932     if( pKeyModX )  *pKeyModX = keyModX;
00933 }*/
00934 
00935 //---------------------------------------------------------------------
00936 // Key
00937 //---------------------------------------------------------------------
00938 
00939 bool Key::init( const KKey& key, bool bQt )
00940 {
00941     if( bQt ) {
00942         m_code = CODE_FOR_QT;
00943         m_sym = key.keyCodeQt();
00944     } else {
00945         KKeyNative keyNative( key );
00946         *this = keyNative;
00947     }
00948     return true;
00949 }
00950 
00951 KKey Key::key() const
00952 {
00953     if( m_code == CODE_FOR_QT )
00954         return KKey( keyCodeQt() );
00955     else {
00956 #if defined(Q_WS_WIN) || defined(Q_WS_MACX)
00957         return KKey();
00958 #else
00959         uint mod;
00960         modXToMod( m_mod, mod );
00961         return KKey( m_sym, mod );
00962 #endif
00963     }
00964 }
00965 
00966 Key& Key::operator =( const KKeyNative& key )
00967 {
00968     m_code = key.code(); m_mod = key.mod(); m_sym = key.sym();
00969     return *this;
00970 }
00971 
00972 int Key::compare( const Key& b ) const
00973 {
00974     if( m_code == CODE_FOR_QT )
00975         return m_sym - b.m_sym;
00976     if( m_sym != b.m_sym )  return m_sym - b.m_sym;
00977     if( m_mod != b.m_mod )  return m_mod - b.m_mod;
00978     return m_code - b.m_code;
00979 }
00980 
00981 //---------------------------------------------------------------------
00982 // Variations
00983 //---------------------------------------------------------------------
00984 
00985 // TODO: allow for sym to have variations, such as Plus => { Plus, KP_Add }
00986 void Variations::init( const KKey& key, bool bQt )
00987 {
00988     if( key.isNull() ) {
00989         m_nVariations = 0;
00990         return;
00991     }
00992 
00993     m_nVariations = 1;
00994     m_rgkey[0] = KKeyNative(key);
00995     uint symVar = Sym(key.sym()).getSymVariation();
00996     if( symVar ) {
00997         uint modReq = Sym(m_rgkey[0].sym()).getModsRequired();
00998         uint modReqVar = Sym(symVar).getModsRequired();
00999         // If 'key' doesn't require any mods that are inherent in
01000         //  the primary key but not required for the alternate,
01001         if( (key.modFlags() & modReq) == (key.modFlags() & modReqVar) ) {
01002             m_rgkey[1] = KKeyNative(KKey(symVar, key.modFlags()));
01003             m_nVariations = 2;
01004         }
01005     }
01006 
01007     if( bQt ) {
01008         uint nVariations = 0;
01009         for( uint i = 0; i < m_nVariations; i++ ) {
01010             int keyQt = KKeyNative( m_rgkey[i].code(), m_rgkey[i].mod(), m_rgkey[i].sym() ).keyCodeQt();
01011             if( keyQt ) {
01012                 m_rgkey[nVariations++].setKeycodeQt( keyQt );
01013             }
01014         }
01015         m_nVariations = nVariations;
01016 
01017         // Two different native codes may produce a single
01018         //  Qt code.  Search for duplicates.
01019         for( uint i = 1; i < m_nVariations; i++ ) {
01020             for( uint j = 0; j < i; j++ ) {
01021                 // If key is already present in list, then remove it.
01022                 if( m_rgkey[i].keyCodeQt() == m_rgkey[j].keyCodeQt() ) {
01023                     for( uint k = i; k < m_nVariations - 1; k++ ) {
01024                         m_rgkey[k].setKeycodeQt( m_rgkey[k+1].keyCodeQt() );
01025                     }
01026                     m_nVariations--;
01027                     i--;
01028                     break;
01029                 }
01030             }
01031         }
01032     }
01033 }
01034 
01035 } // end of namespace KKeyServer block
01036 
01037 // FIXME: This needs to be moved to kshortcut.cpp, and create a
01038 //  KKeyServer::method which it will call.
01039 // Alt+SysReq => Alt+Print
01040 // Ctrl+Shift+Plus => Ctrl+Plus (en)
01041 // Ctrl+Shift+Equal => Ctrl+Plus
01042 // Ctrl+Pause => Ctrl+Break
01043 void KKey::simplify()
01044 {
01045 #ifdef Q_WS_X11
01046     if( m_sym == XK_Sys_Req ) {
01047         m_sym = XK_Print;
01048         m_mod |= ALT;
01049     } else if( m_sym == XK_ISO_Left_Tab ) {
01050         m_sym = XK_Tab;
01051         m_mod |= SHIFT;
01052     } else {
01053         // Shift+Equal => Shift+Plus (en)
01054         m_sym = KKeyNative(*this).sym();
01055     }
01056 
01057     // If this is a letter, don't remove any modifiers.
01058     if( m_sym < 0x3000 && TQChar(m_sym).isLetter() ) {
01059         m_sym = TQChar(m_sym).lower().unicode();
01060     }
01061 
01062     // Remove modifers from modifier list which are implicit in the symbol.
01063     // Ex. Shift+Plus => Plus (en)
01064     m_mod &= ~KKeyServer::Sym(m_sym).getModsRequired();
01065 #endif
01066 }
01067 
01068 #endif //Q_WS_X11 || Q_WS_WIN
01069 

kdecore

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

kdecore

Skip menu "kdecore"
  • arts
  • dcop
  • dnssd
  • interfaces
  •     interface
  •     library
  •   kspeech
  •   ktexteditor
  • kabc
  • kate
  • kcmshell
  • kdecore
  • kded
  • kdefx
  • kdeprint
  • kdesu
  • kdeui
  • kdoctools
  • khtml
  • kimgio
  • kinit
  • kio
  •   bookmarks
  •   httpfilter
  •   kfile
  •   kio
  •   kioexec
  •   kpasswdserver
  •   kssl
  • kioslave
  •   http
  • kjs
  • kmdi
  •   kmdi
  • knewstuff
  • kparts
  • krandr
  • kresources
  • kspell2
  • kunittest
  • kutils
  • kwallet
  • libkmid
  • libkscreensaver
Generated for kdecore by doxygen 1.7.6.1
This website is maintained by Timothy Pearson.
KDE® and the K Desktop Environment® logo are registered trademarks of KDE e.V. |