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

kdecore

  • kdecore
kkeyserver_x11.cpp
1 /*
2  Copyright (C) 2001 Ellis Whitehead <ellis@kde.org>
3 
4  Win32 port:
5  Copyright (C) 2004 Jaroslaw Staniek <js@iidea.pl>
6 
7  This library is free software; you can redistribute it and/or
8  modify it under the terms of the GNU Library General Public
9  License as published by the Free Software Foundation; either
10  version 2 of the License, or (at your option) any later version.
11 
12  This library is distributed in the hope that it will be useful,
13  but WITHOUT ANY WARRANTY; without even the implied warranty of
14  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15  Library General Public License for more details.
16 
17  You should have received a copy of the GNU Library General Public License
18  along with this library; see the file COPYING.LIB. If not, write to
19  the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
20  Boston, MA 02110-1301, USA.
21 */
22 
23 #include <config.h>
24 
25 #include <tqnamespace.h>
26 #include <tqwindowdefs.h>
27 
28 #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
29 
30 #include "kkeyserver_x11.h"
31 #include "kkeynative.h"
32 #include "kshortcut.h"
33 
34 #include <kconfig.h>
35 #include <kdebug.h>
36 #include <kglobal.h>
37 #include <klocale.h>
38 
39 #ifdef Q_WS_X11
40 # define XK_MISCELLANY
41 # define XK_XKB_KEYS
42 # include <X11/X.h>
43 # include <X11/Xlib.h>
44 # include <X11/Xutil.h>
45 # include <X11/keysymdef.h>
46 # define X11_ONLY(arg) arg, //allows to omit an argument
47 #else
48 # include <kckey.h>
49 # define X11_ONLY(arg)
50 # define XK_ISO_Left_Tab Qt::Key_Backtab
51 # define XK_BackSpace Qt::Key_Backspace
52 # define XK_Sys_Req Qt::Key_SysReq
53 # define XK_Caps_Lock Qt::Key_CapsLock
54 # define XK_Num_Lock Qt::Key_NumLock
55 # define XK_Scroll_Lock Qt::Key_ScrollLock
56 # define XK_Prior Qt::Key_Prior
57 # define XK_Next Qt::Key_Next
58 #endif
59 
60 namespace KKeyServer
61 {
62 
63 //---------------------------------------------------------------------
64 // Data Structures
65 //---------------------------------------------------------------------
66 
67 struct Mod
68 {
69  int m_mod;
70 };
71 
72 //---------------------------------------------------------------------
73 // Array Structures
74 //---------------------------------------------------------------------
75 
76 struct ModInfo
77 {
78  KKey::ModFlag mod;
79  int modQt;
80 #ifdef Q_WS_X11
81  uint modX;
82 #endif
83  const char* psName;
84  TQString sLabel;
85 };
86 
87 struct SymVariation
88 {
89  uint sym, symVariation;
90  bool bActive;
91 };
92 
93 struct SymName
94 {
95  uint sym;
96  const char* psName;
97 };
98 
99 struct TransKey {
100  int keySymQt;
101  uint keySymX;
102 };
103 
104 //---------------------------------------------------------------------
105 // Arrays
106 //---------------------------------------------------------------------
107 
108 static ModInfo g_rgModInfo[KKey::MOD_FLAG_COUNT] =
109 {
110  { KKey::SHIFT, Qt::SHIFT, X11_ONLY(ShiftMask) I18N_NOOP("Shift"), TQString() },
111  { KKey::CTRL, Qt::CTRL, X11_ONLY(ControlMask) I18N_NOOP("Ctrl"), TQString() },
112  { KKey::ALT, Qt::ALT, X11_ONLY(Mod1Mask) I18N_NOOP("Alt"), TQString() },
113  { KKey::WIN, KKey::QtWIN, X11_ONLY(Mod4Mask) I18N_NOOP("Win"), TQString() }
114 };
115 
116 // Special Names List
117 static const SymName g_rgSymNames[] = {
118  { XK_ISO_Left_Tab, "Backtab" },
119  { XK_BackSpace, I18N_NOOP("Backspace") },
120  { XK_Sys_Req, I18N_NOOP("SysReq") },
121  { XK_Caps_Lock, I18N_NOOP("CapsLock") },
122  { XK_Num_Lock, I18N_NOOP("NumLock") },
123  { XK_Scroll_Lock, I18N_NOOP("ScrollLock") },
124  { XK_Prior, I18N_NOOP("PageUp") },
125  { XK_Next, I18N_NOOP("PageDown") },
126 #ifdef sun
127  { XK_F11, I18N_NOOP("Stop") },
128  { XK_F12, I18N_NOOP("Again") },
129  { XK_F13, I18N_NOOP("Props") },
130  { XK_F14, I18N_NOOP("Undo") },
131  { XK_F15, I18N_NOOP("Front") },
132  { XK_F16, I18N_NOOP("Copy") },
133  { XK_F17, I18N_NOOP("Open") },
134  { XK_F18, I18N_NOOP("Paste") },
135  { XK_F19, I18N_NOOP("Find") },
136  { XK_F20, I18N_NOOP("Cut") },
137  { XK_F22, I18N_NOOP("Print") },
138 #endif
139  { 0, 0 }
140 };
141 
142 #ifdef Q_WS_X11
143 static SymVariation g_rgSymVariation[] =
144 {
145  { '/', XK_KP_Divide, false },
146  { '*', XK_KP_Multiply, false },
147  { '-', XK_KP_Subtract, false },
148  { '+', XK_KP_Add, false },
149  { XK_Return, XK_KP_Enter, false },
150  { 0, 0, false }
151 };
152 
153 // TODO: Add Mac key names list: Key_Backspace => "Delete", Key_Delete => "Del"
154 
155 // These are the X equivalents to the Qt keycodes 0x1000 - 0x1026
156 static const TransKey g_rgQtToSymX[] =
157 {
158  { Qt::Key_Escape, XK_Escape },
159  { Qt::Key_Tab, XK_Tab },
160  { Qt::Key_Backtab, XK_ISO_Left_Tab },
161  { Qt::Key_Backspace, XK_BackSpace },
162  { Qt::Key_Return, XK_Return },
163  { Qt::Key_Enter, XK_KP_Enter },
164  { Qt::Key_Insert, XK_Insert },
165  { Qt::Key_Delete, XK_Delete },
166  { Qt::Key_Pause, XK_Pause },
167 #ifdef sun
168  { Qt::Key_Print, XK_F22 },
169 #else
170  { Qt::Key_Print, XK_Print },
171 #endif
172  { Qt::Key_SysReq, XK_Sys_Req },
173  { Qt::Key_Home, XK_Home },
174  { Qt::Key_End, XK_End },
175  { Qt::Key_Left, XK_Left },
176  { Qt::Key_Up, XK_Up },
177  { Qt::Key_Right, XK_Right },
178  { Qt::Key_Down, XK_Down },
179  { TQt::Key_Prior, XK_Prior },
180  { TQt::Key_Next, XK_Next },
181  //{ Qt::Key_Shift, 0 },
182  //{ Qt::Key_Control, 0 },
183  //{ Qt::Key_Meta, 0 },
184  //{ Qt::Key_Alt, 0 },
185  { Qt::Key_CapsLock, XK_Caps_Lock },
186  { Qt::Key_NumLock, XK_Num_Lock },
187  { Qt::Key_ScrollLock, XK_Scroll_Lock },
188  { Qt::Key_F1, XK_F1 },
189  { Qt::Key_F2, XK_F2 },
190  { Qt::Key_F3, XK_F3 },
191  { Qt::Key_F4, XK_F4 },
192  { Qt::Key_F5, XK_F5 },
193  { Qt::Key_F6, XK_F6 },
194  { Qt::Key_F7, XK_F7 },
195  { Qt::Key_F8, XK_F8 },
196  { Qt::Key_F9, XK_F9 },
197  { Qt::Key_F10, XK_F10 },
198  { Qt::Key_F11, XK_F11 },
199  { Qt::Key_F12, XK_F12 },
200  { Qt::Key_F13, XK_F13 },
201  { Qt::Key_F14, XK_F14 },
202  { Qt::Key_F15, XK_F15 },
203  { Qt::Key_F16, XK_F16 },
204  { Qt::Key_F17, XK_F17 },
205  { Qt::Key_F18, XK_F18 },
206  { Qt::Key_F19, XK_F19 },
207  { Qt::Key_F20, XK_F20 },
208  { Qt::Key_F21, XK_F21 },
209  { Qt::Key_F22, XK_F22 },
210  { Qt::Key_F23, XK_F23 },
211  { Qt::Key_F24, XK_F24 },
212  { Qt::Key_F25, XK_F25 },
213  { Qt::Key_F26, XK_F26 },
214  { Qt::Key_F27, XK_F27 },
215  { Qt::Key_F28, XK_F28 },
216  { Qt::Key_F29, XK_F29 },
217  { Qt::Key_F30, XK_F30 },
218  { Qt::Key_F31, XK_F31 },
219  { Qt::Key_F32, XK_F32 },
220  { Qt::Key_F33, XK_F33 },
221  { Qt::Key_F34, XK_F34 },
222  { Qt::Key_F35, XK_F35 },
223  { Qt::Key_Super_L, XK_Super_L },
224  { Qt::Key_Super_R, XK_Super_R },
225  { Qt::Key_Menu, XK_Menu },
226  { Qt::Key_Hyper_L, XK_Hyper_L },
227  { Qt::Key_Hyper_R, XK_Hyper_R },
228  { Qt::Key_Help, XK_Help },
229  //{ Qt::Key_Direction_L, XK_Direction_L }, These keys don't exist in X11
230  //{ Qt::Key_Direction_R, XK_Direction_R },
231 
232  { '/', XK_KP_Divide },
233  { '*', XK_KP_Multiply },
234  { '-', XK_KP_Subtract },
235  { '+', XK_KP_Add },
236  { Qt::Key_Return, XK_KP_Enter }
237 #if QT_VERSION >= 0x030100
238 
239 // the next lines are taken from XFree > 4.0 (X11/XF86keysyms.h), defining some special
240 // multimedia keys. They are included here as not every system has them.
241 #define XF86XK_Standby 0x1008FF10
242 #define XF86XK_AudioLowerVolume 0x1008FF11
243 #define XF86XK_AudioMute 0x1008FF12
244 #define XF86XK_AudioRaiseVolume 0x1008FF13
245 #define XF86XK_AudioPlay 0x1008FF14
246 #define XF86XK_AudioStop 0x1008FF15
247 #define XF86XK_AudioPrev 0x1008FF16
248 #define XF86XK_AudioNext 0x1008FF17
249 #define XF86XK_HomePage 0x1008FF18
250 #define XF86XK_Calculator 0x1008FF1D
251 #define XF86XK_Mail 0x1008FF19
252 #define XF86XK_Start 0x1008FF1A
253 #define XF86XK_Search 0x1008FF1B
254 #define XF86XK_AudioRecord 0x1008FF1C
255 #define XF86XK_Back 0x1008FF26
256 #define XF86XK_Forward 0x1008FF27
257 #define XF86XK_Stop 0x1008FF28
258 #define XF86XK_Refresh 0x1008FF29
259 #define XF86XK_Favorites 0x1008FF30
260 #define XF86XK_AudioPause 0x1008FF31
261 #define XF86XK_AudioMedia 0x1008FF32
262 #define XF86XK_MyComputer 0x1008FF33
263 #define XF86XK_OpenURL 0x1008FF38
264 #define XF86XK_Launch0 0x1008FF40
265 #define XF86XK_Launch1 0x1008FF41
266 #define XF86XK_Launch2 0x1008FF42
267 #define XF86XK_Launch3 0x1008FF43
268 #define XF86XK_Launch4 0x1008FF44
269 #define XF86XK_Launch5 0x1008FF45
270 #define XF86XK_Launch6 0x1008FF46
271 #define XF86XK_Launch7 0x1008FF47
272 #define XF86XK_Launch8 0x1008FF48
273 #define XF86XK_Launch9 0x1008FF49
274 #define XF86XK_LaunchA 0x1008FF4A
275 #define XF86XK_LaunchB 0x1008FF4B
276 #define XF86XK_LaunchC 0x1008FF4C
277 #define XF86XK_LaunchD 0x1008FF4D
278 #define XF86XK_LaunchE 0x1008FF4E
279 #define XF86XK_LaunchF 0x1008FF4F
280 // end of XF86keysyms.h
281  ,
282  { Qt::Key_Standby, XF86XK_Standby },
283  { Qt::Key_VolumeDown, XF86XK_AudioLowerVolume },
284  { Qt::Key_VolumeMute, XF86XK_AudioMute },
285  { Qt::Key_VolumeUp, XF86XK_AudioRaiseVolume },
286  { Qt::Key_MediaPlay, XF86XK_AudioPlay },
287  { Qt::Key_MediaStop, XF86XK_AudioStop },
288  { TQt::Key_MediaPrev, XF86XK_AudioPrev },
289  { Qt::Key_MediaNext, XF86XK_AudioNext },
290  { Qt::Key_HomePage, XF86XK_HomePage },
291  { Qt::Key_LaunchMail, XF86XK_Mail },
292  { Qt::Key_Search, XF86XK_Search },
293  { Qt::Key_MediaRecord, XF86XK_AudioRecord },
294  { Qt::Key_LaunchMedia, XF86XK_AudioMedia },
295  { Qt::Key_Launch1, XF86XK_Calculator },
296  { Qt::Key_Back, XF86XK_Back },
297  { Qt::Key_Forward, XF86XK_Forward },
298  { Qt::Key_Stop, XF86XK_Stop },
299  { Qt::Key_Refresh, XF86XK_Refresh },
300  { Qt::Key_Favorites, XF86XK_Favorites },
301  { Qt::Key_Launch0, XF86XK_MyComputer },
302  { Qt::Key_OpenUrl, XF86XK_OpenURL },
303  { Qt::Key_Launch2, XF86XK_Launch0 },
304  { Qt::Key_Launch3, XF86XK_Launch1 },
305  { Qt::Key_Launch4, XF86XK_Launch2 },
306  { Qt::Key_Launch5, XF86XK_Launch3 },
307  { Qt::Key_Launch6, XF86XK_Launch4 },
308  { Qt::Key_Launch7, XF86XK_Launch5 },
309  { Qt::Key_Launch8, XF86XK_Launch6 },
310  { Qt::Key_Launch9, XF86XK_Launch7 },
311  { Qt::Key_LaunchA, XF86XK_Launch8 },
312  { Qt::Key_LaunchB, XF86XK_Launch9 },
313  { Qt::Key_LaunchC, XF86XK_LaunchA },
314  { Qt::Key_LaunchD, XF86XK_LaunchB },
315  { Qt::Key_LaunchE, XF86XK_LaunchC },
316  { Qt::Key_LaunchF, XF86XK_LaunchD },
317 #endif
318 };
319 #endif //Q_WS_X11
320 
321 //---------------------------------------------------------------------
322 // Initialization
323 //---------------------------------------------------------------------
324 static bool g_bInitializedMods, g_bInitializedVariations, g_bInitializedKKeyLabels;
325 static bool g_bMacLabels;
326 #ifdef Q_WS_X11
327 static uint g_modXNumLock, g_modXScrollLock, g_modXModeSwitch;
328 
329 bool initializeMods()
330 {
331  XModifierKeymap* xmk = XGetModifierMapping( qt_xdisplay() );
332 
333  g_rgModInfo[3].modX = g_modXNumLock = g_modXScrollLock = g_modXModeSwitch = 0;
334 
335  int min_keycode, max_keycode;
336  int keysyms_per_keycode = 0;
337  XDisplayKeycodes( qt_xdisplay(), &min_keycode, &max_keycode );
338  XFree( XGetKeyboardMapping( qt_xdisplay(), min_keycode, 1, &keysyms_per_keycode ));
339  // Qt assumes that Alt is always Mod1Mask, so start at Mod2Mask.
340  for( int i = Mod2MapIndex; i < 8; i++ ) {
341  uint mask = (1 << i);
342  uint keySymX = NoSymbol;
343  // This used to be only XKeycodeToKeysym( ... , 0 ), but that fails with XFree4.3.99
344  // and X.org R6.7 , where for some reason only ( ... , 1 ) works. I have absolutely no
345  // idea what the problem is, but searching all posibilities until something valid is
346  // found fixes the problem.
347  for( int j = 0; j < xmk->max_keypermod && keySymX == NoSymbol; ++j )
348  for( int k = 0; k < keysyms_per_keycode && keySymX == NoSymbol; ++k )
349  keySymX = XKeycodeToKeysym( qt_xdisplay(), xmk->modifiermap[xmk->max_keypermod * i + j], k );
350  switch( keySymX ) {
351  case XK_Num_Lock: g_modXNumLock = mask; break; // Normally Mod2Mask
352  case XK_Super_L:
353  case XK_Super_R: g_rgModInfo[3].modX = mask; break; // Win key, Normally Mod4Mask
354  case XK_Meta_L:
355  case XK_Meta_R: if( !g_rgModInfo[3].modX ) g_rgModInfo[3].modX = mask; break; // Win alternate
356  case XK_Scroll_Lock: g_modXScrollLock = mask; break; // Normally Mod5Mask
357  case XK_Mode_switch: g_modXModeSwitch = mask; break;
358  }
359  }
360 
361  XFreeModifiermap( xmk );
362 
363  //KConfigGroupSaver cgs( KGlobal::config(), "Keyboard" );
364  // read in mod that win should be attached to
365 
366  g_bInitializedMods = true;
367 
368  kdDebug(125) << "KKeyServer::initializeMods(): Win Mod = 0x" << TQString::number(g_rgModInfo[3].modX, 16) << endl;
369  return true;
370 }
371 
372 static void initializeVariations()
373 {
374  for( int i = 0; g_rgSymVariation[i].sym != 0; i++ )
375  g_rgSymVariation[i].bActive = (XKeysymToKeycode( qt_xdisplay(), g_rgSymVariation[i].symVariation ) != 0);
376  g_bInitializedVariations = true;
377 }
378 #endif //Q_WS_X11
379 
380 static void intializeKKeyLabels()
381 {
382  KConfigGroupSaver cgs( KGlobal::config(), "Keyboard" );
383  g_rgModInfo[0].sLabel = KGlobal::config()->readEntry( "Label Shift", i18n(g_rgModInfo[0].psName) );
384  g_rgModInfo[1].sLabel = KGlobal::config()->readEntry( "Label Ctrl", i18n(g_rgModInfo[1].psName) );
385  g_rgModInfo[2].sLabel = KGlobal::config()->readEntry( "Label Alt", i18n(g_rgModInfo[2].psName) );
386  g_rgModInfo[3].sLabel = KGlobal::config()->readEntry( "Label Win", i18n(g_rgModInfo[3].psName) );
387  g_bMacLabels = (g_rgModInfo[2].sLabel == "Command");
388  g_bInitializedKKeyLabels = true;
389 }
390 
391 //---------------------------------------------------------------------
392 // class Mod
393 //---------------------------------------------------------------------
394 
395 /*void Mod::init( const TQString& s )
396 {
397 
398 }*/
399 
400 //---------------------------------------------------------------------
401 // class Sym
402 //---------------------------------------------------------------------
403 
404 bool Sym::initQt( int keyQt )
405 {
406  int symQt = keyQt & 0xffff;
407 
408  if( (keyQt & Qt::UNICODE_ACCEL) || symQt < 0x1000 ) {
409  m_sym = TQChar(symQt).lower().unicode();
410  return true;
411  }
412 
413 #ifdef Q_WS_WIN
414  m_sym = symQt;
415  return true;
416 #elif defined(Q_WS_X11)
417  for( uint i = 0; i < sizeof(g_rgQtToSymX)/sizeof(TransKey); i++ ) {
418  if( g_rgQtToSymX[i].keySymQt == symQt ) {
419  m_sym = g_rgQtToSymX[i].keySymX;
420  return true;
421  }
422  }
423 
424  m_sym = 0;
425  if( symQt != Qt::Key_Shift && symQt != Qt::Key_Control && symQt != Qt::Key_Alt &&
426  symQt != Qt::Key_Meta && symQt != Qt::Key_Direction_L && symQt != Qt::Key_Direction_R )
427  kdDebug(125) << "Sym::initQt( " << TQString::number(keyQt,16) << " ): failed to convert key." << endl;
428  return false;
429 #elif defined(Q_WS_MACX)
430  m_sym = symQt;
431  return true;
432 #endif
433 }
434 
435 bool Sym::init( const TQString& s )
436 {
437  // If it's a single character, get unicode value.
438  if( s.length() == 1 ) {
439  m_sym = s[0].lower().unicode();
440  return true;
441  }
442 
443  // Look up in special names list
444  for( int i = 0; g_rgSymNames[i].sym != 0; i++ ) {
445  if( qstricmp( s.latin1(), g_rgSymNames[i].psName ) == 0 ) {
446  m_sym = g_rgSymNames[i].sym;
447  return true;
448  }
449  }
450 
451 #ifdef Q_WS_WIN
452  // search for name in KKeys array
453  for ( KKeys const *pKey = kde_KKEYS; pKey->code != 0xffff; pKey++) {
454  if( qstricmp( s.latin1(), pKey->name ) == 0 ) {
455  m_sym = pKey->code;
456  return true;
457  }
458  }
459  m_sym = 0;
460 #elif defined(Q_WS_X11)
461  // search X list: 's' as is, all lower, first letter in caps
462  m_sym = XStringToKeysym( s.latin1() );
463  if( !m_sym ) {
464  m_sym = XStringToKeysym( s.lower().latin1() );
465  if( !m_sym ) {
466  TQString s2 = s;
467  s2[0] = s2[0].upper();
468  m_sym = XStringToKeysym( s2.latin1() );
469  }
470  }
471 #endif
472  return m_sym != 0;
473 }
474 
475 int Sym::qt() const
476 {
477  if( m_sym < 0x1000 ) {
478  if( m_sym >= 'a' && m_sym <= 'z' )
479  return TQChar(m_sym).upper();
480  return m_sym;
481  }
482 #ifdef Q_WS_WIN
483  if( m_sym < 0x3000 )
484  return m_sym;
485 #elif defined(Q_WS_X11)
486  if( m_sym < 0x3000 )
487  return m_sym | Qt::UNICODE_ACCEL;
488 
489  for( uint i = 0; i < sizeof(g_rgQtToSymX)/sizeof(TransKey); i++ )
490  if( g_rgQtToSymX[i].keySymX == m_sym )
491  return g_rgQtToSymX[i].keySymQt;
492 #endif
493  return TQt::Key_unknown;
494 }
495 
496 TQString Sym::toString( bool bUserSpace ) const
497 {
498  if( m_sym == 0 )
499  return TQString::null;
500 
501  // If it's a unicode character,
502 #ifdef Q_WS_WIN
503  else if( m_sym < 0x1000 ) {
504 #else
505  else if( m_sym < 0x3000 ) {
506 #endif
507  TQChar c = TQChar(m_sym).upper();
508  // Print all non-space characters directly when output is user-visible.
509  // Otherwise only print alphanumeric latin1 characters directly (A,B,C,1,2,3).
510  if( (c.latin1() && c.isLetterOrNumber())
511  || (bUserSpace && !c.isSpace()) )
512  return c;
513  }
514 
515  // Look up in special names list
516  for( int i = 0; g_rgSymNames[i].sym != 0; i++ ) {
517  if( m_sym == g_rgSymNames[i].sym )
518  return bUserSpace ? i18n(g_rgSymNames[i].psName) : TQString(g_rgSymNames[i].psName);
519  }
520 
521  TQString s;
522 #ifdef Q_WS_WIN
523  s = TQKeySequence( m_sym );
524 #elif defined(Q_WS_X11)
525  // Get X-name
526  s = XKeysymToString( m_sym );
527 #endif
528  capitalizeKeyname( s );
529  return bUserSpace ? i18n(TQACCEL_OBJECT_NAME_STRING, s.latin1()) : s;
530 }
531 
532 TQString Sym::toStringInternal() const { return toString( false ); }
533 TQString Sym::toString() const { return toString( true ); }
534 
535 uint Sym::getModsRequired() const
536 {
537  uint mod = 0;
538 #ifdef Q_WS_X11
539  // FIXME: This might not be true on all keyboard layouts!
540  if( m_sym == XK_Sys_Req ) return KKey::ALT;
541  if( m_sym == XK_Break ) return KKey::CTRL;
542 
543  if( m_sym < 0x3000 ) {
544  TQChar c(m_sym);
545  if( c.isLetter() && c.lower() != c.upper() && m_sym == c.upper().unicode() )
546  return KKey::SHIFT;
547  }
548 
549  uchar code = XKeysymToKeycode( qt_xdisplay(), m_sym );
550  if( code ) {
551  // need to check index 0 before the others, so that a null-mod
552  // can take precedence over the others, in case the modified
553  // key produces the same symbol.
554  if( m_sym == XKeycodeToKeysym( qt_xdisplay(), code, 0 ) )
555  ;
556  else if( m_sym == XKeycodeToKeysym( qt_xdisplay(), code, 1 ) )
557  mod = KKey::SHIFT;
558  else if( m_sym == XKeycodeToKeysym( qt_xdisplay(), code, 2 ) )
559  mod = KKeyServer::MODE_SWITCH;
560  else if( m_sym == XKeycodeToKeysym( qt_xdisplay(), code, 3 ) )
561  mod = KKey::SHIFT | KKeyServer::MODE_SWITCH;
562  }
563 #endif
564  return mod;
565 }
566 
567 uint Sym::getSymVariation() const
568 {
569 #ifdef Q_WS_X11
570  if( !g_bInitializedVariations )
571  initializeVariations();
572  for( int i = 0; g_rgSymVariation[i].sym != 0; i++ )
573  if( g_rgSymVariation[i].sym == m_sym && g_rgSymVariation[i].bActive )
574  return g_rgSymVariation[i].symVariation;
575 #endif
576  return 0;
577 }
578 
579 void Sym::capitalizeKeyname( TQString& s )
580 {
581  s[0] = s[0].upper();
582  int len = s.length();
583  if( s.endsWith( "left" ) ) s[len-4] = 'L';
584  else if( s.endsWith( "right" ) ) s[len-5] = 'R';
585  else if( s == "Sysreq" ) s[len-3] = 'R';
586 }
587 
588 //---------------------------------------------------------------------
589 // Public functions
590 //---------------------------------------------------------------------
591 
592 #ifdef Q_WS_X11
593 uint modX( KKey::ModFlag mod )
594 {
595  if( mod == KKey::WIN && !g_bInitializedMods )
596  initializeMods();
597 
598  for( uint i = 0; i < KKey::MOD_FLAG_COUNT; i++ ) {
599  if( g_rgModInfo[i].mod == mod )
600  return g_rgModInfo[i].modX;
601  }
602  return 0;
603 }
604 
605 bool keyboardHasWinKey() { if( !g_bInitializedMods ) { initializeMods(); } return g_rgModInfo[3].modX != 0; }
606 uint modXShift() { return ShiftMask; }
607 uint modXLock() { return LockMask; }
608 uint modXCtrl() { return ControlMask; }
609 uint modXAlt() { return Mod1Mask; }
610 uint modXNumLock() { if( !g_bInitializedMods ) { initializeMods(); } return g_modXNumLock; }
611 uint modXWin() { if( !g_bInitializedMods ) { initializeMods(); } return g_rgModInfo[3].modX; }
612 uint modXScrollLock() { if( !g_bInitializedMods ) { initializeMods(); } return g_modXScrollLock; }
613 uint modXModeSwitch() { if( !g_bInitializedMods ) { initializeMods(); } return g_modXModeSwitch; }
614 
615 uint accelModMaskX()
616 {
617  if( !g_bInitializedMods )
618  initializeMods();
619  return ShiftMask | ControlMask | Mod1Mask | g_rgModInfo[3].modX;
620 }
621 #endif //Q_WS_X11
622 
623 bool keyQtToSym( int keyQt, uint& keySym )
624 {
625  Sym sym;
626  if( sym.initQt( keyQt ) ) {
627  keySym = sym.m_sym;
628  return true;
629  } else
630  return false;
631 }
632 
633 bool keyQtToMod( int keyQt, uint& mod )
634 {
635  mod = 0;
636 
637  if( keyQt & Qt::SHIFT ) mod |= KKey::SHIFT;
638  if( keyQt & Qt::CTRL ) mod |= KKey::CTRL;
639  if( keyQt & Qt::ALT ) mod |= KKey::ALT;
640  if( keyQt & Qt::META ) mod |= KKey::WIN;
641 
642  return true;
643 }
644 
645 bool symToKeyQt( uint keySym, int& keyQt )
646 {
647  Sym sym( keySym );
648  keyQt = sym.qt();
649  return (keyQt != TQt::Key_unknown);
650 }
651 
652 bool modToModQt( uint mod, int& modQt )
653 {
654  modQt = 0;
655  for( int i = 0; i < KKey::MOD_FLAG_COUNT; i++ ) {
656  if( mod & g_rgModInfo[i].mod ) {
657  if( !g_rgModInfo[i].modQt ) {
658  modQt = 0;
659  return false;
660  }
661  modQt |= g_rgModInfo[i].modQt;
662  }
663  }
664  return true;
665 }
666 
667 #ifdef Q_WS_WIN
668 //wrapped
669 bool modXToModQt( uint modX, int& modQt )
670 {
671  return modToModQt( modX, modQt );
672 }
673 
674 KDECORE_EXPORT int qtButtonStateToMod( TQt::ButtonState s )
675 {
676  int modQt = 0;
677  if (s & Qt::ShiftButton) modQt |= KKey::SHIFT;
678  if (s & Qt::ControlButton) modQt |= KKey::CTRL;
679  if (s & Qt::AltButton) modQt |= KKey::ALT;
680  return modQt;
681 }
682 
683 bool keyboardHasWinKey() {
685  return true;
686 }
687 
688 #elif defined(Q_WS_MACX)
689 
690 bool modXToModQt(uint modX, int& modQt)
691 {
692  return modToModQt( modX, modQt );
693 }
694 
695 bool keyboardHasWinKey() {
697  return false;
698 }
699 
700 bool modXToMod( uint , uint& )
701 {
702  return false;
703 }
704 #elif defined(Q_WS_X11)
705 
706 bool modToModX( uint mod, uint& modX )
707 {
708  if( !g_bInitializedMods )
709  initializeMods();
710 
711  modX = 0;
712  for( int i = 0; i < KKey::MOD_FLAG_COUNT; i++ ) {
713  if( mod & g_rgModInfo[i].mod ) {
714  if( !g_rgModInfo[i].modX ) {
715  kdDebug(125) << "Invalid modifier flag." << endl;
716  modX = 0;
717  return false;
718  }
719  modX |= g_rgModInfo[i].modX;
720  }
721  }
722  // TODO: document 0x2000 flag
723  if( mod & 0x2000 )
724  modX |= 0x2000;
725  return true;
726 }
727 
728 bool modXToModQt( uint modX, int& modQt )
729 {
730  if( !g_bInitializedMods )
731  initializeMods();
732 
733  modQt = 0;
734  for( int i = 0; i < KKey::MOD_FLAG_COUNT; i++ ) {
735  if( modX & g_rgModInfo[i].modX ) {
736  if( !g_rgModInfo[i].modQt ) {
737  modQt = 0;
738  return false;
739  }
740  modQt |= g_rgModInfo[i].modQt;
741  }
742  }
743  return true;
744 }
745 
746 bool modXToMod( uint modX, uint& mod )
747 {
748  if( !g_bInitializedMods )
749  initializeMods();
750 
751  mod = 0;
752  for( int i = 0; i < KKey::MOD_FLAG_COUNT; i++ ) {
753  if( modX & g_rgModInfo[i].modX )
754  mod |= g_rgModInfo[i].mod;
755  }
756  return true;
757 }
758 
759 bool codeXToSym( uchar codeX, uint modX, uint& sym )
760 {
761  KeySym keySym;
762  XKeyPressedEvent event;
763 
764  event.type = KeyPress;
765  event.display = qt_xdisplay();
766  event.state = modX;
767  event.keycode = codeX;
768 
769  char buffer[64];
770  XLookupString( &event, buffer, 63, &keySym, NULL );
771  sym = (uint) keySym;
772  return true;
773 }
774 #endif
775 
776 static TQString modToString( uint mod, bool bUserSpace )
777 {
778  if( bUserSpace && !g_bInitializedKKeyLabels )
779  intializeKKeyLabels();
780 
781  TQString s;
782  for( int i = KKey::MOD_FLAG_COUNT-1; i >= 0; i-- ) {
783  if( mod & g_rgModInfo[i].mod ) {
784  if( !s.isEmpty() )
785  s += '+';
786  s += (bUserSpace)
787  ? g_rgModInfo[i].sLabel
788  : TQString(g_rgModInfo[i].psName);
789  }
790  }
791  return s;
792 }
793 
794 TQString modToStringInternal( uint mod ) { return modToString( mod, false ); }
795 TQString modToStringUser( uint mod ) { return modToString( mod, true ); }
796 
797 uint stringUserToMod( const TQString& mod )
798 {
799  if( !g_bInitializedKKeyLabels )
800  intializeKKeyLabels();
801 
802  TQString s;
803  for( int i = KKey::MOD_FLAG_COUNT-1; i >= 0; i-- ) {
804  if( mod.lower() == g_rgModInfo[i].sLabel.lower())
805  return g_rgModInfo[i].mod;
806  }
807  return 0;
808 }
809 
810 /*void keySymModToKeyX( uint sym, uint mod, unsigned char *pKeyCodeX, uint *pKeySymX, uint *pKeyModX )
811 {
812 ...
813  uint keySymQt;
814  uint keySymX = 0;
815  unsigned char keyCodeX = 0;
816  uint keyModX = 0;
817 
818  const char *psKeySym = 0;
819 
820  if( !g_bInitialized )
821  Initialize();
822 
823  // Get code of just the primary key
824  keySymQt = keyCombQt & 0xffff;
825 
826  // If unicode value beneath 0x1000 (special Qt codes begin thereafter),
827  if( keySymQt < 0x1000 ) {
828  // For reasons unbeknownst to me, Qt converts 'a-z' to 'A-Z'.
829  // So convert it back to lowercase if SHIFT isn't held down.
830  if( keySymQt >= Qt::Key_A && keySymQt <= Qt::Key_Z && !(keyCombQt & Qt::SHIFT) )
831  keySymQt = tolower( keySymQt );
832  keySymX = keySymQt;
833  }
834  // Else, special key (e.g. Delete, F1, etc.)
835  else {
836  for( int i = 0; i < NB_KEYS; i++ ) {
837  if( keySymQt == (uint) KKEYS[i].code ) {
838  psKeySym = KKEYS[i].name;
839  //kdDebug(125) << " symbol found: \"" << psKeySym << "\"" << endl;
840  break;
841  }
842  }
843 
844  // Get X key symbol. Only works if Qt name is same as X name.
845  if( psKeySym ) {
846  TQString sKeySym = psKeySym;
847 
848  // Check for lower-case equalent first because most
849  // X11 names are all lower-case.
850  keySymX = XStringToKeysym( sKeySym.lower().ascii() );
851  if( keySymX == 0 )
852  keySymX = XStringToKeysym( psKeySym );
853  }
854 
855  if( keySymX == 0 )
856  keySymX = getSymXEquiv( keySymQt );
857  }
858 
859  if( keySymX != 0 ) {
860  // Get X keyboard code
861  keyCodeX = XKeysymToKeycode( qt_xdisplay(), keySymX );
862  // Add ModeSwitch modifier bit, if necessary
863  keySymXMods( keySymX, 0, &keyModX );
864 
865  // Get X modifier flags
866  for( int i = 0; i < MOD_KEYS; i++ ) {
867  if( keyCombQt & g_aModKeys[i].keyModMaskQt ) {
868  if( g_aModKeys[i].keyModMaskX )
869  keyModX |= g_aModKeys[i].keyModMaskX;
870  // Qt key calls for a modifier which the current
871  // X modifier map doesn't support.
872  else {
873  keySymX = 0;
874  keyCodeX = 0;
875  keyModX = 0;
876  break;
877  }
878  }
879  }
880  }
881 
882  // Take care of complications:
883  // The following keys will not have been correctly interpreted,
884  // because their shifted values are not activated with the
885  // Shift key, but rather something else. They are also
886  // defined twice under different keycodes.
887  // keycode 111 & 92: Print Sys_Req -> Sys_Req = Alt+Print
888  // keycode 110 & 114: Pause Break -> Break = Ctrl+Pause
889  if( (keyCodeX == 92 || keyCodeX == 111) &&
890  XKeycodeToKeysym( qt_xdisplay(), 92, 0 ) == XK_Print &&
891  XKeycodeToKeysym( qt_xdisplay(), 111, 0 ) == XK_Print )
892  {
893  // If Alt is pressed, then we need keycode 92, keysym XK_Sys_Req
894  if( keyModX & keyModXAlt() ) {
895  keyCodeX = 92;
896  keySymX = XK_Sys_Req;
897  }
898  // Otherwise, keycode 111, keysym XK_Print
899  else {
900  keyCodeX = 111;
901  keySymX = XK_Print;
902  }
903  }
904  else if( (keyCodeX == 110 || keyCodeX == 114) &&
905  XKeycodeToKeysym( qt_xdisplay(), 110, 0 ) == XK_Pause &&
906  XKeycodeToKeysym( qt_xdisplay(), 114, 0 ) == XK_Pause )
907  {
908  if( keyModX & keyModXCtrl() ) {
909  keyCodeX = 114;
910  keySymX = XK_Break;
911  } else {
912  keyCodeX = 110;
913  keySymX = XK_Pause;
914  }
915  }
916 
917  if( pKeySymX ) *pKeySymX = keySymX;
918  if( pKeyCodeX ) *pKeyCodeX = keyCodeX;
919  if( pKeyModX ) *pKeyModX = keyModX;
920 }*/
921 
922 //---------------------------------------------------------------------
923 // Key
924 //---------------------------------------------------------------------
925 
926 bool Key::init( const KKey& key, bool bQt )
927 {
928  if( bQt ) {
929  m_code = CODE_FOR_QT;
930  m_sym = key.keyCodeQt();
931  } else {
932  KKeyNative keyNative( key );
933  *this = keyNative;
934  }
935  return true;
936 }
937 
938 KKey Key::key() const
939 {
940  if( m_code == CODE_FOR_QT )
941  return KKey( keyCodeQt() );
942  else {
943 #if defined(Q_WS_WIN) || defined(Q_WS_MACX)
944  return KKey();
945 #else
946  uint mod;
947  modXToMod( m_mod, mod );
948  return KKey( m_sym, mod );
949 #endif
950  }
951 }
952 
953 Key& Key::operator =( const KKeyNative& key )
954 {
955  m_code = key.code(); m_mod = key.mod(); m_sym = key.sym();
956  return *this;
957 }
958 
959 int Key::compare( const Key& b ) const
960 {
961  if( m_code == CODE_FOR_QT )
962  return m_sym - b.m_sym;
963  if( m_sym != b.m_sym ) return m_sym - b.m_sym;
964  if( m_mod != b.m_mod ) return m_mod - b.m_mod;
965  return m_code - b.m_code;
966 }
967 
968 //---------------------------------------------------------------------
969 // Variations
970 //---------------------------------------------------------------------
971 
972 // TODO: allow for sym to have variations, such as Plus => { Plus, KP_Add }
973 void Variations::init( const KKey& key, bool bQt )
974 {
975  if( key.isNull() ) {
976  m_nVariations = 0;
977  return;
978  }
979 
980  m_nVariations = 1;
981  m_rgkey[0] = KKeyNative(key);
982  uint symVar = Sym(key.sym()).getSymVariation();
983  if( symVar ) {
984  uint modReq = Sym(m_rgkey[0].sym()).getModsRequired();
985  uint modReqVar = Sym(symVar).getModsRequired();
986  // If 'key' doesn't require any mods that are inherent in
987  // the primary key but not required for the alternate,
988  if( (key.modFlags() & modReq) == (key.modFlags() & modReqVar) ) {
989  m_rgkey[1] = KKeyNative(KKey(symVar, key.modFlags()));
990  m_nVariations = 2;
991  }
992  }
993 
994  if( bQt ) {
995  uint nVariations = 0;
996  for( uint i = 0; i < m_nVariations; i++ ) {
997  int keyQt = KKeyNative( m_rgkey[i].code(), m_rgkey[i].mod(), m_rgkey[i].sym() ).keyCodeQt();
998  if( keyQt )
999  m_rgkey[nVariations++].setKeycodeQt( keyQt );
1000  }
1001  m_nVariations = nVariations;
1002 
1003  // Two different native codes may produce a single
1004  // Qt code. Search for duplicates.
1005  for( uint i = 1; i < m_nVariations; i++ ) {
1006  for( uint j = 0; j < i; j++ ) {
1007  // If key is already present in list, then remove it.
1008  if( m_rgkey[i].keyCodeQt() == m_rgkey[j].keyCodeQt() ) {
1009  for( uint k = i; k < m_nVariations - 1; k++ )
1010  m_rgkey[k].setKeycodeQt( m_rgkey[k+1].keyCodeQt() );
1011  m_nVariations--;
1012  i--;
1013  break;
1014  }
1015  }
1016  }
1017  }
1018 }
1019 
1020 } // end of namespace KKeyServer block
1021 
1022 // FIXME: This needs to be moved to kshortcut.cpp, and create a
1023 // KKeyServer::method which it will call.
1024 // Alt+SysReq => Alt+Print
1025 // Ctrl+Shift+Plus => Ctrl+Plus (en)
1026 // Ctrl+Shift+Equal => Ctrl+Plus
1027 // Ctrl+Pause => Ctrl+Break
1028 void KKey::simplify()
1029 {
1030 #ifdef Q_WS_X11
1031  if( m_sym == XK_Sys_Req ) {
1032  m_sym = XK_Print;
1033  m_mod |= ALT;
1034  } else if( m_sym == XK_ISO_Left_Tab ) {
1035  m_sym = XK_Tab;
1036  m_mod |= SHIFT;
1037  } else {
1038  // Shift+Equal => Shift+Plus (en)
1039  m_sym = KKeyNative(*this).sym();
1040  }
1041 
1042  // If this is a letter, don't remove any modifiers.
1043  if( m_sym < 0x3000 && TQChar(m_sym).isLetter() )
1044  m_sym = TQChar(m_sym).lower().unicode();
1045 
1046  // Remove modifers from modifier list which are implicit in the symbol.
1047  // Ex. Shift+Plus => Plus (en)
1048  m_mod &= ~KKeyServer::Sym(m_sym).getModsRequired();
1049 #endif
1050 }
1051 
1052 #endif //Q_WS_X11 || Q_WS_WIN
1053 

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.8.3.1
This website is maintained by Timothy Pearson.
KDE® and the K Desktop Environment® logo are registered trademarks of KDE e.V. |