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

tdecore

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

tdecore

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

tdecore

Skip menu "tdecore"
  • arts
  • dcop
  • dnssd
  • interfaces
  •   kspeech
  •     interface
  •     library
  •   tdetexteditor
  • kate
  • kded
  • kdoctools
  • kimgio
  • kjs
  • libtdemid
  • libtdescreensaver
  • tdeabc
  • tdecmshell
  • tdecore
  • tdefx
  • tdehtml
  • tdeinit
  • tdeio
  •   bookmarks
  •   httpfilter
  •   kpasswdserver
  •   kssl
  •   tdefile
  •   tdeio
  •   tdeioexec
  • tdeioslave
  •   http
  • tdemdi
  •   tdemdi
  • tdenewstuff
  • tdeparts
  • tdeprint
  • tderandr
  • tderesources
  • tdespell2
  • tdesu
  • tdeui
  • tdeunittest
  • tdeutils
  • tdewallet
Generated for tdecore by doxygen 1.6.3
This website is maintained by Timothy Pearson.