Qt 4.8
qkeymapper_x11.cpp
Go to the documentation of this file.
1 /****************************************************************************
2 **
3 ** Copyright (C) 2014 Digia Plc and/or its subsidiary(-ies).
4 ** Contact: http://www.qt-project.org/legal
5 **
6 ** This file is part of the QtGui module of the Qt Toolkit.
7 **
8 ** $QT_BEGIN_LICENSE:LGPL$
9 ** Commercial License Usage
10 ** Licensees holding valid commercial Qt licenses may use this file in
11 ** accordance with the commercial license agreement provided with the
12 ** Software or, alternatively, in accordance with the terms contained in
13 ** a written agreement between you and Digia. For licensing terms and
14 ** conditions see http://qt.digia.com/licensing. For further information
15 ** use the contact form at http://qt.digia.com/contact-us.
16 **
17 ** GNU Lesser General Public License Usage
18 ** Alternatively, this file may be used under the terms of the GNU Lesser
19 ** General Public License version 2.1 as published by the Free Software
20 ** Foundation and appearing in the file LICENSE.LGPL included in the
21 ** packaging of this file. Please review the following information to
22 ** ensure the GNU Lesser General Public License version 2.1 requirements
23 ** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
24 **
25 ** In addition, as a special exception, Digia gives you certain additional
26 ** rights. These rights are described in the Digia Qt LGPL Exception
27 ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
28 **
29 ** GNU General Public License Usage
30 ** Alternatively, this file may be used under the terms of the GNU
31 ** General Public License version 3.0 as published by the Free Software
32 ** Foundation and appearing in the file LICENSE.GPL included in the
33 ** packaging of this file. Please review the following information to
34 ** ensure the GNU General Public License version 3.0 requirements will be
35 ** met: http://www.gnu.org/copyleft/gpl.html.
36 **
37 **
38 ** $QT_END_LICENSE$
39 **
40 ****************************************************************************/
41 
42 #include "qkeymapper_p.h"
43 
44 #include "qdebug.h"
45 #include "qtextcodec.h"
46 #include "qwidget.h"
47 
48 #include "qapplication_p.h"
49 #include "qevent_p.h"
50 #include "qt_x11_p.h"
51 
52 #ifndef QT_NO_XKB
53 # include <X11/XKBlib.h>
54 #endif
55 
56 #define XK_MISCELLANY
57 #define XK_LATIN1
58 #define XK_KOREAN
59 #define XK_XKB_KEYS
60 #include <X11/keysymdef.h>
61 
62 #include <ctype.h>
63 
64 #ifdef QT_LINUXBASE
65 // LSB's IsKeypadKey define is wrong - see
66 // http://bugs.linuxbase.org/show_bug.cgi?id=2521
67 #undef IsKeypadKey
68 #define IsKeypadKey(keysym) \
69  (((KeySym)(keysym) >= XK_KP_Space) && ((KeySym)(keysym) <= XK_KP_Equal))
70 
71 #undef IsPrivateKeypadKey
72 #define IsPrivateKeypadKey(keysym) \
73  (((KeySym)(keysym) >= 0x11000000) && ((KeySym)(keysym) <= 0x1100FFFF))
74 #endif
75 
77 
78 #ifndef QT_NO_XKB
79 
80 // bring in the auto-generated xkbLayoutData
81 #include "qkeymapper_x11_p.cpp"
82 
83 QLocale q_getKeyboardLocale(const QByteArray &layoutName, const QByteArray &variantName)
84 {
85  int i = 0;
86  while (xkbLayoutData[i].layout != 0) {
87  if (layoutName == xkbLayoutData[i].layout && variantName == xkbLayoutData[i].variant)
89  ++i;
90  }
91  return QLocale::c();
92 }
93 #endif // QT_NO_XKB
94 
95 // from qapplication_x11.cpp
96 extern uchar qt_alt_mask;
97 extern uchar qt_meta_mask;
98 extern uchar qt_super_mask;
99 extern uchar qt_hyper_mask;
102 extern bool qt_sendSpontaneousEvent(QObject*, QEvent*);
103 
104 // ### we should really resolve conflicts with other masks by
105 // ### decomposing the Qt::KeyboardModifers in possibleKeys()
106 #define SETMASK(sym, mask) \
107  do { \
108  if (qt_alt_mask == 0 \
109  && qt_meta_mask != mask \
110  && qt_super_mask != mask \
111  && qt_hyper_mask != mask \
112  && (sym == XK_Alt_L || sym == XK_Alt_R)) { \
113  qt_alt_mask = mask; \
114  } \
115  if (qt_meta_mask == 0 \
116  && qt_alt_mask != mask \
117  && qt_super_mask != mask \
118  && qt_hyper_mask != mask \
119  && (sym == XK_Meta_L || sym == XK_Meta_R)) { \
120  qt_meta_mask = mask; \
121  } \
122  if (qt_super_mask == 0 \
123  && qt_alt_mask != mask \
124  && qt_meta_mask != mask \
125  && qt_hyper_mask != mask \
126  && (sym == XK_Super_L || sym == XK_Super_R)) { \
127  qt_super_mask = mask; \
128  } \
129  if (qt_hyper_mask == 0 \
130  && qt_alt_mask != mask \
131  && qt_meta_mask != mask \
132  && qt_super_mask != mask \
133  && (sym == XK_Hyper_L || sym == XK_Hyper_R)) { \
134  qt_hyper_mask = mask; \
135  } \
136  if (qt_mode_switch_mask == 0 \
137  && qt_alt_mask != mask \
138  && qt_meta_mask != mask \
139  && qt_super_mask != mask \
140  && qt_hyper_mask != mask \
141  && sym == XK_Mode_switch) { \
142  qt_mode_switch_mask = mask; \
143  } \
144  if (qt_num_lock_mask == 0 \
145  && sym == XK_Num_Lock) { \
146  qt_num_lock_mask = mask; \
147  } \
148  } while(false)
149 
150 // qt_XTranslateKey() is based on _XTranslateKey() taken from:
151 
152 /* $Xorg: KeyBind.c,v 1.4 2001/02/09 02:03:34 xorgcvs Exp $ */
153 
154 /*
155 
156 Copyright 1985, 1987, 1998 The Open Group
157 
158 Permission to use, copy, modify, distribute, and sell this software and its
159 documentation for any purpose is hereby granted without fee, provided that
160 the above copyright notice appear in all copies and that both that
161 copyright notice and this permission notice appear in supporting
162 documentation.
163 
164 The above copyright notice and this permission notice shall be included in
165 all copies or substantial portions of the Software.
166 
167 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
168 IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
169 FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
170 OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
171 AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
172 CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
173 
174 Except as contained in this notice, the name of The Open Group shall not be
175 used in advertising or otherwise to promote the sale, use or other dealings
176 in this Software without prior written authorization from The Open Group.
177 
178 */
179 static int
180 qt_XTranslateKey(register QXCoreDesc *dpy,
181  KeyCode keycode,
182  register unsigned int modifiers,
183  unsigned int *modifiers_return,
184  KeySym *keysym_return)
185 {
186  int per;
187  register KeySym *syms;
188  KeySym sym, lsym, usym;
189 
190  if (! dpy->keysyms)
191  return 0;
192  *modifiers_return = ((ShiftMask|LockMask)
193  | dpy->mode_switch | dpy->num_lock);
194  if (((int)keycode < dpy->min_keycode) || ((int)keycode > dpy->max_keycode))
195  {
196  *keysym_return = NoSymbol;
197  return 1;
198  }
199  per = dpy->keysyms_per_keycode;
200  syms = &dpy->keysyms[(keycode - dpy->min_keycode) * per];
201  while ((per > 2) && (syms[per - 1] == NoSymbol))
202  per--;
203  if ((per > 2) && (modifiers & dpy->mode_switch)) {
204  syms += 2;
205  per -= 2;
206  }
207  if ((modifiers & dpy->num_lock) &&
208  (per > 1 && (IsKeypadKey(syms[1]) || IsPrivateKeypadKey(syms[1])))) {
209  if ((modifiers & ShiftMask) ||
210  ((modifiers & LockMask) && (dpy->lock_meaning == XK_Shift_Lock)))
211  *keysym_return = syms[0];
212  else
213  *keysym_return = syms[1];
214  } else if (!(modifiers & ShiftMask) &&
215  (!(modifiers & LockMask) || (dpy->lock_meaning == NoSymbol))) {
216  if ((per == 1) || (syms[1] == NoSymbol))
217  XConvertCase(syms[0], keysym_return, &usym);
218  else
219  *keysym_return = syms[0];
220  } else if (!(modifiers & LockMask) ||
221  (dpy->lock_meaning != XK_Caps_Lock)) {
222  if ((per == 1) || ((usym = syms[1]) == NoSymbol))
223  XConvertCase(syms[0], &lsym, &usym);
224  *keysym_return = usym;
225  } else {
226  if ((per == 1) || ((sym = syms[1]) == NoSymbol))
227  sym = syms[0];
228  XConvertCase(sym, &lsym, &usym);
229  if (!(modifiers & ShiftMask) && (sym != syms[0]) &&
230  ((sym != usym) || (lsym == usym)))
231  XConvertCase(syms[0], &lsym, &usym);
232  *keysym_return = usym;
233  }
234  if (*keysym_return == XK_VoidSymbol)
235  *keysym_return = NoSymbol;
236  return 1;
237 }
238 
239 
240 
241 
243  : keyboardInputDirection(Qt::LeftToRight), xkb_currentGroup(0)
244 {
245  memset(&coreDesc, 0, sizeof(coreDesc));
246 
247 #ifndef QT_NO_XKB
248  if (X11->use_xkb) {
249  // get the current group
250  XkbStateRec xkbState;
251  if (XkbGetState(X11->display, XkbUseCoreKbd, &xkbState) == Success)
252  xkb_currentGroup = xkbState.group;
253  }
254 #endif
255 }
256 
258 {
259  if (coreDesc.keysyms)
260  XFree(coreDesc.keysyms);
261 }
262 
264 {
265 #ifndef QT_NO_XKB
266  if (X11->use_xkb)
267  return possibleKeysXKB(event);
268 #endif
269  return possibleKeysCore(event);
270 }
271 
272 enum { MaxBits = sizeof(uint) * 8 };
273 static QString translateKeySym(KeySym keysym, uint xmodifiers,
274  int &code, Qt::KeyboardModifiers &modifiers,
275  QByteArray &chars, int &count);
276 
277 QList<int> QKeyMapperPrivate::possibleKeysXKB(QKeyEvent *event)
278 {
279 #ifndef QT_NO_XKB
280  const int xkeycode = event->nativeScanCode();
281  const uint xmodifiers = event->nativeModifiers();
282 
283  // first, translate key only using lock modifiers (there are no Qt equivalents for these, so we must
284  // always use them when determining the baseKeySym)
285  KeySym baseKeySym;
286  uint consumedModifiers;
287  if (!XkbLookupKeySym(X11->display, xkeycode, (xmodifiers & (LockMask | qt_num_lock_mask)),
288  &consumedModifiers, &baseKeySym))
289  return QList<int>();
290 
291  QList<int> result;
292 
293  // translate sym -> code
294  Qt::KeyboardModifiers baseModifiers = 0;
295  int baseCode = -1;
296  QByteArray chars;
297  int count = 0;
298  QString text = translateKeySym(baseKeySym, xmodifiers, baseCode, baseModifiers, chars, count);
299  if (baseCode == -1) {
300  if (text.isEmpty())
301  return QList<int>();
302  baseCode = text.at(0).unicode();
303  }
304 
305  if (baseCode && baseCode < 0xfffe)
306  baseCode = QChar(baseCode).toUpper().unicode();
307  result += (baseCode | baseModifiers);
308 
309  int pos1Bits[MaxBits];
310  int num1Bits = 0;
311 
312  for (int i = 0; i < MaxBits; ++i) {
313  if (consumedModifiers & (1 << i))
314  pos1Bits[num1Bits++] = i;
315  }
316 
317  const int numPerms = (1 << num1Bits);
318 
319  // translate the key again using each permutation of consumedModifiers
320  for (int i = 1; i < numPerms; ++i) {
321  uint val = 0;
322  for (int j = 0; j < num1Bits; ++j) {
323  if (i & (1 << j))
324  val |= (1 << pos1Bits[j]);
325  }
326 
327  if ((xmodifiers & val) != val)
328  continue;
329 
330  KeySym sym;
331  uint mods;
332  if (!XkbLookupKeySym(X11->display, xkeycode, val, &mods, &sym))
333  continue;
334 
335  // translate sym -> code
336  Qt::KeyboardModifiers modifiers = 0;
337  int code = -1;
338  chars.clear();
339  count = 0;
340  // mask out the modifiers needed to translate keycode
341  text = translateKeySym(sym, xmodifiers & ~val, code, modifiers, chars, count);
342  if (code == -1) {
343  if (text.isEmpty())
344  continue;
345  code = text.at(0).unicode();
346  }
347 
348  if (code && code < 0xfffe)
349  code = QChar(code).toUpper().unicode();
350 
351  if (code == Qt::Key_Tab && (baseModifiers & Qt::ShiftModifier)) {
352  // map shift+tab to shift+backtab
353  code = Qt::Key_Backtab;
354  text = QString();
355  }
356 
357  if (code == baseCode)
358  continue;
359 
360  result += (code | modifiers);
361  }
362 
363 #if 0
364  qDebug() << "possibleKeysXKB()" << hex << result;
365 #endif
366  return result;
367 #else
368  Q_UNUSED(event);
369  return QList<int>();
370 #endif // QT_NO_XKB
371 }
372 
373 QList<int> QKeyMapperPrivate::possibleKeysCore(QKeyEvent *event)
374 {
375  const int xkeycode = event->nativeScanCode();
376  const uint xmodifiers = event->nativeModifiers();
377 
378  // first, translate key only using lock modifiers (there are no Qt equivalents for these, so we must
379  // always use them when determining the baseKeySym)
380  KeySym baseKeySym;
381  uint consumedModifiers;
382  if (!qt_XTranslateKey(&coreDesc, xkeycode, (xmodifiers & (LockMask | qt_num_lock_mask)),
383  &consumedModifiers, &baseKeySym))
384  return QList<int>();
385 
386  QList<int> result;
387 
388  // translate sym -> code
389  Qt::KeyboardModifiers baseModifiers = 0;
390  int baseCode = -1;
391  QByteArray chars;
392  int count = 0;
393  QString text = translateKeySym(baseKeySym, xmodifiers, baseCode, baseModifiers, chars, count);
394  if (baseCode == -1) {
395  if (text.isEmpty())
396  return QList<int>();
397  baseCode = text.at(0).unicode();
398  }
399 
400  if (baseCode && baseCode < 0xfffe)
401  baseCode = QChar(baseCode).toUpper().unicode();
402  result += (baseCode | baseModifiers);
403 
404  int pos1Bits[MaxBits];
405  int num1Bits = 0;
406 
407  for (int i = 0; i < MaxBits; ++i) {
408  if (consumedModifiers & (1 << i))
409  pos1Bits[num1Bits++] = i;
410  }
411 
412  const int numPerms = (1 << num1Bits);
413 
414  // translate the key again using each permutation of consumedModifiers
415  for (int i = 1; i < numPerms; ++i) {
416  uint val = 0;
417  for (int j = 0; j < num1Bits; ++j) {
418  if (i & (1 << j))
419  val |= (1 << pos1Bits[j]);
420  }
421 
422  if ((xmodifiers & val) != val)
423  continue;
424 
425  KeySym sym;
426  uint mods;
427  if (!qt_XTranslateKey(&coreDesc, xkeycode, val, &mods, &sym))
428  continue;
429 
430  // translate sym -> code
431  Qt::KeyboardModifiers modifiers = 0;
432  int code = -1;
433  chars.clear();
434  count = 0;
435  // mask out the modifiers needed to translate keycode
436  text = translateKeySym(sym, xmodifiers & ~val, code, modifiers, chars, count);
437  if (code == -1) {
438  if (text.isEmpty())
439  continue;
440  code = text.at(0).unicode();
441  }
442 
443  if (code && code < 0xfffe)
444  code = QChar(code).toUpper().unicode();
445 
446  if (code == Qt::Key_Tab && (baseModifiers & Qt::ShiftModifier)) {
447  // map shift+tab to shift+backtab
448  code = Qt::Key_Backtab;
449  text = QString();
450  }
451 
452  if (code == baseCode)
453  continue;
454 
455  result += (code | modifiers);
456  }
457 
458 #if 0
459  qDebug() << "possibleKeysCore()" << hex << result;
460 #endif
461  return result;
462 }
463 
464 // for parsing the _XKB_RULES_NAMES property
465 enum {
471 };
472 
474 {
475 #ifndef QT_NO_XKB
476  if (X11->use_xkb) {
477  // try to determine the layout name and input direction by reading the _XKB_RULES_NAMES property off
478  // the root window
479  QByteArray layoutName;
480  QByteArray variantName;
481 
482  Atom type = XNone;
483  int format = 0;
484  ulong nitems = 0;
485  ulong bytesAfter = 0;
486  uchar *data = 0;
487  if (XGetWindowProperty(X11->display, RootWindow(X11->display, 0), ATOM(_XKB_RULES_NAMES), 0, 1024,
488  false, XA_STRING, &type, &format, &nitems, &bytesAfter, &data) == Success
489  && type == XA_STRING && format == 8 && nitems > 2) {
490  /*
491  index 0 == rules file name
492  index 1 == model name
493  index 2 == layout name
494  index 3 == variant name
495  index 4 == options
496  */
497  char *names[5] = { 0, 0, 0, 0, 0 };
498  char *p = reinterpret_cast<char *>(data), *end = p + nitems;
499  int i = 0;
500  do {
501  names[i++] = p;
502  p += qstrlen(p) + 1;
503  } while (p < end);
504 
505  // the layout names and variants are saved in the _XKB_RULES_NAMES property as a comma separated list
506  QList<QByteArray> layoutNames = QByteArray::fromRawData(names[2], qstrlen(names[2])).split(',');
507  if (uint(xkb_currentGroup) < uint(layoutNames.count()))
508  layoutName = layoutNames.at(xkb_currentGroup);
509  QList<QByteArray> variantNames = QByteArray::fromRawData(names[3], qstrlen(names[3])).split(',');
510  if (uint(xkb_currentGroup) < uint(variantNames.count()))
511  variantName = variantNames.at(xkb_currentGroup);
512  }
513 
514  // ### ???
515  // if (keyboardLayoutName.isEmpty())
516  // qWarning("Qt: unable to determine keyboard layout, please talk to qt-bugs@trolltech.com"); ?
517 
518  keyboardInputLocale = q_getKeyboardLocale(layoutName, variantName);
520 
521 #if 0
522  qDebug() << "keyboard input locale ="
524  << "direction ="
526 #endif
527  if (data)
528  XFree(data);
529  } else
530 #endif // QT_NO_XKB
531  {
532  if (coreDesc.keysyms)
533  XFree(coreDesc.keysyms);
534 
535  coreDesc.min_keycode = 8;
536  coreDesc.max_keycode = 255;
537  XDisplayKeycodes(X11->display, &coreDesc.min_keycode, &coreDesc.max_keycode);
538 
539  coreDesc.keysyms_per_keycode = 0;
540  coreDesc.keysyms = XGetKeyboardMapping(X11->display,
541  coreDesc.min_keycode,
542  coreDesc.max_keycode - coreDesc.min_keycode + 1,
543  &coreDesc.keysyms_per_keycode);
544 
545 #if 0
546  qDebug() << "min_keycode =" << coreDesc.min_keycode;
547  qDebug() << "max_keycode =" << coreDesc.max_keycode;
548  qDebug() << "keysyms_per_keycode =" << coreDesc.keysyms_per_keycode;
549  qDebug() << "keysyms =" << coreDesc.keysyms;
550 #endif
551 
552  // ### cannot get/guess the locale with the core protocol
554  // ### could examine group 0 for RTL keys
556  }
557 
558  qt_alt_mask = 0;
559  qt_meta_mask = 0;
560  qt_super_mask = 0;
561  qt_hyper_mask = 0;
563 
564  // look at the modifier mapping, and get the correct masks for alt, meta, super, hyper, and mode_switch
565 #ifndef QT_NO_XKB
566  if (X11->use_xkb) {
567  XkbDescPtr xkbDesc = XkbGetMap(X11->display, XkbAllClientInfoMask, XkbUseCoreKbd);
568  for (int i = xkbDesc->min_key_code; i < xkbDesc->max_key_code; ++i) {
569  const uint mask = xkbDesc->map->modmap ? xkbDesc->map->modmap[i] : 0;
570  if (mask == 0) {
571  // key is not bound to a modifier
572  continue;
573  }
574 
575  for (int j = 0; j < XkbKeyGroupsWidth(xkbDesc, i); ++j) {
576  KeySym keySym = XkbKeySym(xkbDesc, i, j);
577  if (keySym == NoSymbol)
578  continue;
579  SETMASK(keySym, mask);
580  }
581  }
582  XkbFreeKeyboard(xkbDesc, XkbAllComponentsMask, true);
583  } else
584 #endif // QT_NO_XKB
585  {
586  coreDesc.lock_meaning = NoSymbol;
587 
588  XModifierKeymap *map = XGetModifierMapping(X11->display);
589 
590  if (map) {
591  int i, maskIndex = 0, mapIndex = 0;
592  for (maskIndex = 0; maskIndex < 8; maskIndex++) {
593  for (i = 0; i < map->max_keypermod; i++) {
594  if (map->modifiermap[mapIndex]) {
595  KeySym sym;
596  int x = 0;
597  do {
598  sym = XKeycodeToKeysym(X11->display, map->modifiermap[mapIndex], x++);
599  } while (sym == NoSymbol && x < coreDesc.keysyms_per_keycode);
600  const uchar mask = 1 << maskIndex;
601  SETMASK(sym, mask);
602  }
603  mapIndex++;
604  }
605  }
606 
607  // determine the meaning of the Lock modifier
608  for (i = 0; i < map->max_keypermod; ++i) {
609  for (int x = 0; x < coreDesc.keysyms_per_keycode; ++x) {
610  KeySym sym = XKeycodeToKeysym(X11->display, map->modifiermap[LockMapIndex], x);
611  if (sym == XK_Caps_Lock || sym == XK_ISO_Lock) {
612  coreDesc.lock_meaning = XK_Caps_Lock;
613  break;
614  } else if (sym == XK_Shift_Lock) {
615  coreDesc.lock_meaning = XK_Shift_Lock;
616  }
617  }
618  }
619 
620  XFreeModifiermap(map);
621  }
622 
623  // for qt_XTranslateKey()
624  coreDesc.num_lock = qt_num_lock_mask;
625  coreDesc.mode_switch = qt_mode_switch_mask;
626 
627 #if 0
628  qDebug() << "lock_meaning =" << coreDesc.lock_meaning;
629  qDebug() << "num_lock =" << coreDesc.num_lock;
630  qDebug() << "mode_switch =" << coreDesc.mode_switch;
631 #endif
632  }
633 
634  // set default modifier masks if needed
635  if( qt_alt_mask == 0 )
636  qt_alt_mask = Mod1Mask;
637  if( qt_meta_mask == 0 )
638  qt_meta_mask = Mod4Mask;
639 
640  // if we don't have a meta key (or it's hidden behind alt), use super or hyper to generate
641  // Qt::Key_Meta and Qt::MetaModifier, since most newer XFree86/Xorg installations map the Windows
642  // key to Super
643  if (qt_meta_mask == 0 || qt_meta_mask == qt_alt_mask) {
644  // no meta keys... s,meta,super,
646  if (qt_meta_mask == 0 || qt_meta_mask == qt_alt_mask) {
647  // no super keys either? guess we'll use hyper then
649  }
650  }
651 
652 #if 0
653  qDebug() << "qt_alt_mask =" << hex << qt_alt_mask;
654  qDebug() << "qt_meta_mask =" << hex << qt_meta_mask;
655  qDebug() << "qt_super_mask =" << hex << qt_super_mask;
656  qDebug() << "qt_hyper_mask =" << hex << qt_hyper_mask;
657  qDebug() << "qt_mode_switch_mask =" << hex << qt_mode_switch_mask;
658  qDebug() << "qt_num_lock_mask =" << hex << qt_num_lock_mask;
659 #endif
660 }
661 
662 extern bool qt_sm_blockUserInput;
663 
664 //
665 // Keyboard event translation
666 //
667 
668 #ifndef XK_ISO_Left_Tab
669 #define XK_ISO_Left_Tab 0xFE20
670 #endif
671 
672 #ifndef XK_dead_hook
673 #define XK_dead_hook 0xFE61
674 #endif
675 
676 #ifndef XK_dead_horn
677 #define XK_dead_horn 0xFE62
678 #endif
679 
680 #ifndef XK_Codeinput
681 #define XK_Codeinput 0xFF37
682 #endif
683 
684 #ifndef XK_Kanji_Bangou
685 #define XK_Kanji_Bangou 0xFF37 /* same as codeinput */
686 #endif
687 
688 // Fix old X libraries
689 #ifndef XK_KP_Home
690 #define XK_KP_Home 0xFF95
691 #endif
692 #ifndef XK_KP_Left
693 #define XK_KP_Left 0xFF96
694 #endif
695 #ifndef XK_KP_Up
696 #define XK_KP_Up 0xFF97
697 #endif
698 #ifndef XK_KP_Right
699 #define XK_KP_Right 0xFF98
700 #endif
701 #ifndef XK_KP_Down
702 #define XK_KP_Down 0xFF99
703 #endif
704 #ifndef XK_KP_Prior
705 #define XK_KP_Prior 0xFF9A
706 #endif
707 #ifndef XK_KP_Next
708 #define XK_KP_Next 0xFF9B
709 #endif
710 #ifndef XK_KP_End
711 #define XK_KP_End 0xFF9C
712 #endif
713 #ifndef XK_KP_Insert
714 #define XK_KP_Insert 0xFF9E
715 #endif
716 #ifndef XK_KP_Delete
717 #define XK_KP_Delete 0xFF9F
718 #endif
719 
720 // the next lines are taken on 10/2009 from X.org (X11/XF86keysym.h), defining some special
721 // multimedia keys. They are included here as not every system has them.
722 #define XF86XK_MonBrightnessUp 0x1008FF02
723 #define XF86XK_MonBrightnessDown 0x1008FF03
724 #define XF86XK_KbdLightOnOff 0x1008FF04
725 #define XF86XK_KbdBrightnessUp 0x1008FF05
726 #define XF86XK_KbdBrightnessDown 0x1008FF06
727 #define XF86XK_Standby 0x1008FF10
728 #define XF86XK_AudioLowerVolume 0x1008FF11
729 #define XF86XK_AudioMute 0x1008FF12
730 #define XF86XK_AudioRaiseVolume 0x1008FF13
731 #define XF86XK_AudioPlay 0x1008FF14
732 #define XF86XK_AudioStop 0x1008FF15
733 #define XF86XK_AudioPrev 0x1008FF16
734 #define XF86XK_AudioNext 0x1008FF17
735 #define XF86XK_HomePage 0x1008FF18
736 #define XF86XK_Mail 0x1008FF19
737 #define XF86XK_Start 0x1008FF1A
738 #define XF86XK_Search 0x1008FF1B
739 #define XF86XK_AudioRecord 0x1008FF1C
740 #define XF86XK_Calculator 0x1008FF1D
741 #define XF86XK_Memo 0x1008FF1E
742 #define XF86XK_ToDoList 0x1008FF1F
743 #define XF86XK_Calendar 0x1008FF20
744 #define XF86XK_PowerDown 0x1008FF21
745 #define XF86XK_ContrastAdjust 0x1008FF22
746 #define XF86XK_Back 0x1008FF26
747 #define XF86XK_Forward 0x1008FF27
748 #define XF86XK_Stop 0x1008FF28
749 #define XF86XK_Refresh 0x1008FF29
750 #define XF86XK_PowerOff 0x1008FF2A
751 #define XF86XK_WakeUp 0x1008FF2B
752 #define XF86XK_Eject 0x1008FF2C
753 #define XF86XK_ScreenSaver 0x1008FF2D
754 #define XF86XK_WWW 0x1008FF2E
755 #define XF86XK_Sleep 0x1008FF2F
756 #define XF86XK_Favorites 0x1008FF30
757 #define XF86XK_AudioPause 0x1008FF31
758 #define XF86XK_AudioMedia 0x1008FF32
759 #define XF86XK_MyComputer 0x1008FF33
760 #define XF86XK_LightBulb 0x1008FF35
761 #define XF86XK_Shop 0x1008FF36
762 #define XF86XK_History 0x1008FF37
763 #define XF86XK_OpenURL 0x1008FF38
764 #define XF86XK_AddFavorite 0x1008FF39
765 #define XF86XK_HotLinks 0x1008FF3A
766 #define XF86XK_BrightnessAdjust 0x1008FF3B
767 #define XF86XK_Finance 0x1008FF3C
768 #define XF86XK_Community 0x1008FF3D
769 #define XF86XK_AudioRewind 0x1008FF3E
770 #define XF86XK_BackForward 0x1008FF3F
771 #define XF86XK_Launch0 0x1008FF40
772 #define XF86XK_Launch1 0x1008FF41
773 #define XF86XK_Launch2 0x1008FF42
774 #define XF86XK_Launch3 0x1008FF43
775 #define XF86XK_Launch4 0x1008FF44
776 #define XF86XK_Launch5 0x1008FF45
777 #define XF86XK_Launch6 0x1008FF46
778 #define XF86XK_Launch7 0x1008FF47
779 #define XF86XK_Launch8 0x1008FF48
780 #define XF86XK_Launch9 0x1008FF49
781 #define XF86XK_LaunchA 0x1008FF4A
782 #define XF86XK_LaunchB 0x1008FF4B
783 #define XF86XK_LaunchC 0x1008FF4C
784 #define XF86XK_LaunchD 0x1008FF4D
785 #define XF86XK_LaunchE 0x1008FF4E
786 #define XF86XK_LaunchF 0x1008FF4F
787 #define XF86XK_ApplicationLeft 0x1008FF50
788 #define XF86XK_ApplicationRight 0x1008FF51
789 #define XF86XK_Book 0x1008FF52
790 #define XF86XK_CD 0x1008FF53
791 #define XF86XK_Calculater 0x1008FF54
792 #define XF86XK_Clear 0x1008FF55
793 #define XF86XK_ClearGrab 0x1008FE21
794 #define XF86XK_Close 0x1008FF56
795 #define XF86XK_Copy 0x1008FF57
796 #define XF86XK_Cut 0x1008FF58
797 #define XF86XK_Display 0x1008FF59
798 #define XF86XK_DOS 0x1008FF5A
799 #define XF86XK_Documents 0x1008FF5B
800 #define XF86XK_Excel 0x1008FF5C
801 #define XF86XK_Explorer 0x1008FF5D
802 #define XF86XK_Game 0x1008FF5E
803 #define XF86XK_Go 0x1008FF5F
804 #define XF86XK_iTouch 0x1008FF60
805 #define XF86XK_LogOff 0x1008FF61
806 #define XF86XK_Market 0x1008FF62
807 #define XF86XK_Meeting 0x1008FF63
808 #define XF86XK_MenuKB 0x1008FF65
809 #define XF86XK_MenuPB 0x1008FF66
810 #define XF86XK_MySites 0x1008FF67
811 #define XF86XK_News 0x1008FF69
812 #define XF86XK_OfficeHome 0x1008FF6A
813 #define XF86XK_Option 0x1008FF6C
814 #define XF86XK_Paste 0x1008FF6D
815 #define XF86XK_Phone 0x1008FF6E
816 #define XF86XK_Reply 0x1008FF72
817 #define XF86XK_Reload 0x1008FF73
818 #define XF86XK_RotateWindows 0x1008FF74
819 #define XF86XK_RotationPB 0x1008FF75
820 #define XF86XK_RotationKB 0x1008FF76
821 #define XF86XK_Save 0x1008FF77
822 #define XF86XK_Send 0x1008FF7B
823 #define XF86XK_Spell 0x1008FF7C
824 #define XF86XK_SplitScreen 0x1008FF7D
825 #define XF86XK_Support 0x1008FF7E
826 #define XF86XK_TaskPane 0x1008FF7F
827 #define XF86XK_Terminal 0x1008FF80
828 #define XF86XK_Tools 0x1008FF81
829 #define XF86XK_Travel 0x1008FF82
830 #define XF86XK_Video 0x1008FF87
831 #define XF86XK_Word 0x1008FF89
832 #define XF86XK_Xfer 0x1008FF8A
833 #define XF86XK_ZoomIn 0x1008FF8B
834 #define XF86XK_ZoomOut 0x1008FF8C
835 #define XF86XK_Away 0x1008FF8D
836 #define XF86XK_Messenger 0x1008FF8E
837 #define XF86XK_WebCam 0x1008FF8F
838 #define XF86XK_MailForward 0x1008FF90
839 #define XF86XK_Pictures 0x1008FF91
840 #define XF86XK_Music 0x1008FF92
841 #define XF86XK_Battery 0x1008FF93
842 #define XF86XK_Bluetooth 0x1008FF94
843 #define XF86XK_WLAN 0x1008FF95
844 #define XF86XK_UWB 0x1008FF96
845 #define XF86XK_AudioForward 0x1008FF97
846 #define XF86XK_AudioRepeat 0x1008FF98
847 #define XF86XK_AudioRandomPlay 0x1008FF99
848 #define XF86XK_Subtitle 0x1008FF9A
849 #define XF86XK_AudioCycleTrack 0x1008FF9B
850 #define XF86XK_Time 0x1008FF9F
851 #define XF86XK_Select 0x1008FFA0
852 #define XF86XK_View 0x1008FFA1
853 #define XF86XK_TopMenu 0x1008FFA2
854 #define XF86XK_Suspend 0x1008FFA7
855 #define XF86XK_Hibernate 0x1008FFA8
856 
857 
858 // end of XF86keysyms.h
859 
860 // Special keys used by Qtopia, mapped into the X11 private keypad range.
861 #define QTOPIAXK_Select 0x11000601
862 #define QTOPIAXK_Yes 0x11000602
863 #define QTOPIAXK_No 0x11000603
864 #define QTOPIAXK_Cancel 0x11000604
865 #define QTOPIAXK_Printer 0x11000605
866 #define QTOPIAXK_Execute 0x11000606
867 #define QTOPIAXK_Sleep 0x11000607
868 #define QTOPIAXK_Play 0x11000608
869 #define QTOPIAXK_Zoom 0x11000609
870 #define QTOPIAXK_Context1 0x1100060A
871 #define QTOPIAXK_Context2 0x1100060B
872 #define QTOPIAXK_Context3 0x1100060C
873 #define QTOPIAXK_Context4 0x1100060D
874 #define QTOPIAXK_Call 0x1100060E
875 #define QTOPIAXK_Hangup 0x1100060F
876 #define QTOPIAXK_Flip 0x11000610
877 
878 // keyboard mapping table
879 static const unsigned int KeyTbl[] = {
880 
881  // misc keys
882 
883  XK_Escape, Qt::Key_Escape,
884  XK_Tab, Qt::Key_Tab,
886  XK_BackSpace, Qt::Key_Backspace,
887  XK_Return, Qt::Key_Return,
888  XK_Insert, Qt::Key_Insert,
889  XK_Delete, Qt::Key_Delete,
890  XK_Clear, Qt::Key_Delete,
891  XK_Pause, Qt::Key_Pause,
892  XK_Print, Qt::Key_Print,
893  0x1005FF60, Qt::Key_SysReq, // hardcoded Sun SysReq
894  0x1007ff00, Qt::Key_SysReq, // hardcoded X386 SysReq
895 
896  // cursor movement
897 
898  XK_Home, Qt::Key_Home,
899  XK_End, Qt::Key_End,
900  XK_Left, Qt::Key_Left,
901  XK_Up, Qt::Key_Up,
902  XK_Right, Qt::Key_Right,
903  XK_Down, Qt::Key_Down,
904  XK_Prior, Qt::Key_PageUp,
905  XK_Next, Qt::Key_PageDown,
906 
907  // modifiers
908 
909  XK_Shift_L, Qt::Key_Shift,
910  XK_Shift_R, Qt::Key_Shift,
911  XK_Shift_Lock, Qt::Key_Shift,
912  XK_Control_L, Qt::Key_Control,
913  XK_Control_R, Qt::Key_Control,
914  XK_Meta_L, Qt::Key_Meta,
915  XK_Meta_R, Qt::Key_Meta,
916  XK_Alt_L, Qt::Key_Alt,
917  XK_Alt_R, Qt::Key_Alt,
918  XK_Caps_Lock, Qt::Key_CapsLock,
919  XK_Num_Lock, Qt::Key_NumLock,
920  XK_Scroll_Lock, Qt::Key_ScrollLock,
921  XK_Super_L, Qt::Key_Super_L,
922  XK_Super_R, Qt::Key_Super_R,
923  XK_Menu, Qt::Key_Menu,
924  XK_Hyper_L, Qt::Key_Hyper_L,
925  XK_Hyper_R, Qt::Key_Hyper_R,
926  XK_Help, Qt::Key_Help,
927  0x1000FF74, Qt::Key_Backtab, // hardcoded HP backtab
928  0x1005FF10, Qt::Key_F11, // hardcoded Sun F36 (labeled F11)
929  0x1005FF11, Qt::Key_F12, // hardcoded Sun F37 (labeled F12)
930 
931  // numeric and function keypad keys
932 
933  XK_KP_Space, Qt::Key_Space,
934  XK_KP_Tab, Qt::Key_Tab,
935  XK_KP_Enter, Qt::Key_Enter,
936  //XK_KP_F1, Qt::Key_F1,
937  //XK_KP_F2, Qt::Key_F2,
938  //XK_KP_F3, Qt::Key_F3,
939  //XK_KP_F4, Qt::Key_F4,
948  XK_KP_Begin, Qt::Key_Clear,
951  XK_KP_Equal, Qt::Key_Equal,
952  XK_KP_Multiply, Qt::Key_Asterisk,
953  XK_KP_Add, Qt::Key_Plus,
954  XK_KP_Separator, Qt::Key_Comma,
955  XK_KP_Subtract, Qt::Key_Minus,
956  XK_KP_Decimal, Qt::Key_Period,
957  XK_KP_Divide, Qt::Key_Slash,
958 
959  // International input method support keys
960 
961  // International & multi-key character composition
962  XK_ISO_Level3_Shift, Qt::Key_AltGr,
963  XK_Multi_key, Qt::Key_Multi_key,
965  XK_SingleCandidate, Qt::Key_SingleCandidate,
966  XK_MultipleCandidate, Qt::Key_MultipleCandidate,
967  XK_PreviousCandidate, Qt::Key_PreviousCandidate,
968 
969  // Misc Functions
970  XK_Mode_switch, Qt::Key_Mode_switch,
971  XK_script_switch, Qt::Key_Mode_switch,
972 
973  // Japanese keyboard support
974  XK_Kanji, Qt::Key_Kanji,
975  XK_Muhenkan, Qt::Key_Muhenkan,
976  //XK_Henkan_Mode, Qt::Key_Henkan_Mode,
977  XK_Henkan_Mode, Qt::Key_Henkan,
978  XK_Henkan, Qt::Key_Henkan,
979  XK_Romaji, Qt::Key_Romaji,
980  XK_Hiragana, Qt::Key_Hiragana,
981  XK_Katakana, Qt::Key_Katakana,
982  XK_Hiragana_Katakana, Qt::Key_Hiragana_Katakana,
983  XK_Zenkaku, Qt::Key_Zenkaku,
984  XK_Hankaku, Qt::Key_Hankaku,
985  XK_Zenkaku_Hankaku, Qt::Key_Zenkaku_Hankaku,
986  XK_Touroku, Qt::Key_Touroku,
987  XK_Massyo, Qt::Key_Massyo,
988  XK_Kana_Lock, Qt::Key_Kana_Lock,
989  XK_Kana_Shift, Qt::Key_Kana_Shift,
990  XK_Eisu_Shift, Qt::Key_Eisu_Shift,
991  XK_Eisu_toggle, Qt::Key_Eisu_toggle,
992  //XK_Kanji_Bangou, Qt::Key_Kanji_Bangou,
993  //XK_Zen_Koho, Qt::Key_Zen_Koho,
994  //XK_Mae_Koho, Qt::Key_Mae_Koho,
996  XK_Zen_Koho, Qt::Key_MultipleCandidate,
997  XK_Mae_Koho, Qt::Key_PreviousCandidate,
998 
999 #ifdef XK_KOREAN
1000  // Korean keyboard support
1001  XK_Hangul, Qt::Key_Hangul,
1002  XK_Hangul_Start, Qt::Key_Hangul_Start,
1003  XK_Hangul_End, Qt::Key_Hangul_End,
1004  XK_Hangul_Hanja, Qt::Key_Hangul_Hanja,
1005  XK_Hangul_Jamo, Qt::Key_Hangul_Jamo,
1006  XK_Hangul_Romaja, Qt::Key_Hangul_Romaja,
1007  //XK_Hangul_Codeinput, Qt::Key_Hangul_Codeinput,
1008  XK_Hangul_Codeinput, Qt::Key_Codeinput,
1009  XK_Hangul_Jeonja, Qt::Key_Hangul_Jeonja,
1010  XK_Hangul_Banja, Qt::Key_Hangul_Banja,
1011  XK_Hangul_PreHanja, Qt::Key_Hangul_PreHanja,
1012  XK_Hangul_PostHanja, Qt::Key_Hangul_PostHanja,
1013  //XK_Hangul_SingleCandidate,Qt::Key_Hangul_SingleCandidate,
1014  //XK_Hangul_MultipleCandidate,Qt::Key_Hangul_MultipleCandidate,
1015  //XK_Hangul_PreviousCandidate,Qt::Key_Hangul_PreviousCandidate,
1016  XK_Hangul_SingleCandidate, Qt::Key_SingleCandidate,
1017  XK_Hangul_MultipleCandidate,Qt::Key_MultipleCandidate,
1018  XK_Hangul_PreviousCandidate,Qt::Key_PreviousCandidate,
1019  XK_Hangul_Special, Qt::Key_Hangul_Special,
1020  //XK_Hangul_switch, Qt::Key_Hangul_switch,
1021  XK_Hangul_switch, Qt::Key_Mode_switch,
1022 #endif // XK_KOREAN
1023 
1024  // dead keys
1025  XK_dead_grave, Qt::Key_Dead_Grave,
1026  XK_dead_acute, Qt::Key_Dead_Acute,
1027  XK_dead_circumflex, Qt::Key_Dead_Circumflex,
1028  XK_dead_tilde, Qt::Key_Dead_Tilde,
1029  XK_dead_macron, Qt::Key_Dead_Macron,
1030  XK_dead_breve, Qt::Key_Dead_Breve,
1031  XK_dead_abovedot, Qt::Key_Dead_Abovedot,
1032  XK_dead_diaeresis, Qt::Key_Dead_Diaeresis,
1033  XK_dead_abovering, Qt::Key_Dead_Abovering,
1034  XK_dead_doubleacute, Qt::Key_Dead_Doubleacute,
1035  XK_dead_caron, Qt::Key_Dead_Caron,
1036  XK_dead_cedilla, Qt::Key_Dead_Cedilla,
1037  XK_dead_ogonek, Qt::Key_Dead_Ogonek,
1038  XK_dead_iota, Qt::Key_Dead_Iota,
1039  XK_dead_voiced_sound, Qt::Key_Dead_Voiced_Sound,
1040  XK_dead_semivoiced_sound, Qt::Key_Dead_Semivoiced_Sound,
1041  XK_dead_belowdot, Qt::Key_Dead_Belowdot,
1044 
1045  // Special keys from X.org - This include multimedia keys,
1046  // wireless/bluetooth/uwb keys, special launcher keys, etc.
1065  XF86XK_MyComputer, Qt::Key_Launch0, // ### Qt 5: remap properly
1164  XF86XK_Launch0, Qt::Key_Launch2, // ### Qt 5: remap properly
1180 
1181  // Qtopia keys
1198 
1199  0, 0
1200 };
1201 
1203 {
1204  int code = -1;
1205  int i = 0; // any other keys
1206  while (KeyTbl[i]) {
1207  if (key == KeyTbl[i]) {
1208  code = (int)KeyTbl[i+1];
1209  break;
1210  }
1211  i += 2;
1212  }
1213  if (qt_meta_mask) {
1214  // translate Super/Hyper keys to Meta if we're using them as the MetaModifier
1215  if (qt_meta_mask == qt_super_mask && (code == Qt::Key_Super_L || code == Qt::Key_Super_R)) {
1216  code = Qt::Key_Meta;
1217  } else if (qt_meta_mask == qt_hyper_mask && (code == Qt::Key_Hyper_L || code == Qt::Key_Hyper_R)) {
1218  code = Qt::Key_Meta;
1219  }
1220  }
1221  return code;
1222 }
1223 
1224 #if !defined(QT_NO_XIM)
1225 static const unsigned short katakanaKeysymsToUnicode[] = {
1226  0x0000, 0x3002, 0x300C, 0x300D, 0x3001, 0x30FB, 0x30F2, 0x30A1,
1227  0x30A3, 0x30A5, 0x30A7, 0x30A9, 0x30E3, 0x30E5, 0x30E7, 0x30C3,
1228  0x30FC, 0x30A2, 0x30A4, 0x30A6, 0x30A8, 0x30AA, 0x30AB, 0x30AD,
1229  0x30AF, 0x30B1, 0x30B3, 0x30B5, 0x30B7, 0x30B9, 0x30BB, 0x30BD,
1230  0x30BF, 0x30C1, 0x30C4, 0x30C6, 0x30C8, 0x30CA, 0x30CB, 0x30CC,
1231  0x30CD, 0x30CE, 0x30CF, 0x30D2, 0x30D5, 0x30D8, 0x30DB, 0x30DE,
1232  0x30DF, 0x30E0, 0x30E1, 0x30E2, 0x30E4, 0x30E6, 0x30E8, 0x30E9,
1233  0x30EA, 0x30EB, 0x30EC, 0x30ED, 0x30EF, 0x30F3, 0x309B, 0x309C
1234 };
1235 
1236 static const unsigned short cyrillicKeysymsToUnicode[] = {
1237  0x0000, 0x0452, 0x0453, 0x0451, 0x0454, 0x0455, 0x0456, 0x0457,
1238  0x0458, 0x0459, 0x045a, 0x045b, 0x045c, 0x0000, 0x045e, 0x045f,
1239  0x2116, 0x0402, 0x0403, 0x0401, 0x0404, 0x0405, 0x0406, 0x0407,
1240  0x0408, 0x0409, 0x040a, 0x040b, 0x040c, 0x0000, 0x040e, 0x040f,
1241  0x044e, 0x0430, 0x0431, 0x0446, 0x0434, 0x0435, 0x0444, 0x0433,
1242  0x0445, 0x0438, 0x0439, 0x043a, 0x043b, 0x043c, 0x043d, 0x043e,
1243  0x043f, 0x044f, 0x0440, 0x0441, 0x0442, 0x0443, 0x0436, 0x0432,
1244  0x044c, 0x044b, 0x0437, 0x0448, 0x044d, 0x0449, 0x0447, 0x044a,
1245  0x042e, 0x0410, 0x0411, 0x0426, 0x0414, 0x0415, 0x0424, 0x0413,
1246  0x0425, 0x0418, 0x0419, 0x041a, 0x041b, 0x041c, 0x041d, 0x041e,
1247  0x041f, 0x042f, 0x0420, 0x0421, 0x0422, 0x0423, 0x0416, 0x0412,
1248  0x042c, 0x042b, 0x0417, 0x0428, 0x042d, 0x0429, 0x0427, 0x042a
1249 };
1250 
1251 static const unsigned short greekKeysymsToUnicode[] = {
1252  0x0000, 0x0386, 0x0388, 0x0389, 0x038a, 0x03aa, 0x0000, 0x038c,
1253  0x038e, 0x03ab, 0x0000, 0x038f, 0x0000, 0x0000, 0x0385, 0x2015,
1254  0x0000, 0x03ac, 0x03ad, 0x03ae, 0x03af, 0x03ca, 0x0390, 0x03cc,
1255  0x03cd, 0x03cb, 0x03b0, 0x03ce, 0x0000, 0x0000, 0x0000, 0x0000,
1256  0x0000, 0x0391, 0x0392, 0x0393, 0x0394, 0x0395, 0x0396, 0x0397,
1257  0x0398, 0x0399, 0x039a, 0x039b, 0x039c, 0x039d, 0x039e, 0x039f,
1258  0x03a0, 0x03a1, 0x03a3, 0x0000, 0x03a4, 0x03a5, 0x03a6, 0x03a7,
1259  0x03a8, 0x03a9, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
1260  0x0000, 0x03b1, 0x03b2, 0x03b3, 0x03b4, 0x03b5, 0x03b6, 0x03b7,
1261  0x03b8, 0x03b9, 0x03ba, 0x03bb, 0x03bc, 0x03bd, 0x03be, 0x03bf,
1262  0x03c0, 0x03c1, 0x03c3, 0x03c2, 0x03c4, 0x03c5, 0x03c6, 0x03c7,
1263  0x03c8, 0x03c9, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000
1264 };
1265 
1266 static const unsigned short technicalKeysymsToUnicode[] = {
1267  0x0000, 0x23B7, 0x250C, 0x2500, 0x2320, 0x2321, 0x2502, 0x23A1,
1268  0x23A3, 0x23A4, 0x23A6, 0x239B, 0x239D, 0x239E, 0x23A0, 0x23A8,
1269  0x23AC, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
1270  0x0000, 0x0000, 0x0000, 0x0000, 0x2264, 0x2260, 0x2265, 0x222B,
1271  0x2234, 0x221D, 0x221E, 0x0000, 0x0000, 0x2207, 0x0000, 0x0000,
1272  0x223C, 0x2243, 0x0000, 0x0000, 0x0000, 0x21D4, 0x21D2, 0x2261,
1273  0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x221A, 0x0000,
1274  0x0000, 0x0000, 0x2282, 0x2283, 0x2229, 0x222A, 0x2227, 0x2228,
1275  0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
1276  0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x2202,
1277  0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0192, 0x0000,
1278  0x0000, 0x0000, 0x0000, 0x2190, 0x2191, 0x2192, 0x2193, 0x0000
1279 };
1280 
1281 static const unsigned short specialKeysymsToUnicode[] = {
1282  0x25C6, 0x2592, 0x2409, 0x240C, 0x240D, 0x240A, 0x0000, 0x0000,
1283  0x2424, 0x240B, 0x2518, 0x2510, 0x250C, 0x2514, 0x253C, 0x23BA,
1284  0x23BB, 0x2500, 0x23BC, 0x23BD, 0x251C, 0x2524, 0x2534, 0x252C,
1285  0x2502, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000
1286 };
1287 
1288 static const unsigned short publishingKeysymsToUnicode[] = {
1289  0x0000, 0x2003, 0x2002, 0x2004, 0x2005, 0x2007, 0x2008, 0x2009,
1290  0x200a, 0x2014, 0x2013, 0x0000, 0x0000, 0x0000, 0x2026, 0x2025,
1291  0x2153, 0x2154, 0x2155, 0x2156, 0x2157, 0x2158, 0x2159, 0x215a,
1292  0x2105, 0x0000, 0x0000, 0x2012, 0x2329, 0x0000, 0x232a, 0x0000,
1293  0x0000, 0x0000, 0x0000, 0x215b, 0x215c, 0x215d, 0x215e, 0x0000,
1294  0x0000, 0x2122, 0x2613, 0x0000, 0x25c1, 0x25b7, 0x25cb, 0x25af,
1295  0x2018, 0x2019, 0x201c, 0x201d, 0x211e, 0x0000, 0x2032, 0x2033,
1296  0x0000, 0x271d, 0x0000, 0x25ac, 0x25c0, 0x25b6, 0x25cf, 0x25ae,
1297  0x25e6, 0x25ab, 0x25ad, 0x25b3, 0x25bd, 0x2606, 0x2022, 0x25aa,
1298  0x25b2, 0x25bc, 0x261c, 0x261e, 0x2663, 0x2666, 0x2665, 0x0000,
1299  0x2720, 0x2020, 0x2021, 0x2713, 0x2717, 0x266f, 0x266d, 0x2642,
1300  0x2640, 0x260e, 0x2315, 0x2117, 0x2038, 0x201a, 0x201e, 0x0000
1301 };
1302 
1303 static const unsigned short aplKeysymsToUnicode[] = {
1304  0x0000, 0x0000, 0x0000, 0x003c, 0x0000, 0x0000, 0x003e, 0x0000,
1305  0x2228, 0x2227, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
1306  0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
1307  0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
1308  0x00af, 0x0000, 0x22a5, 0x2229, 0x230a, 0x0000, 0x005f, 0x0000,
1309  0x0000, 0x0000, 0x2218, 0x0000, 0x2395, 0x0000, 0x22a4, 0x25cb,
1310  0x0000, 0x0000, 0x0000, 0x2308, 0x0000, 0x0000, 0x222a, 0x0000,
1311  0x2283, 0x0000, 0x2282, 0x0000, 0x22a2, 0x0000, 0x0000, 0x0000,
1312  0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
1313  0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
1314  0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
1315  0x0000, 0x0000, 0x0000, 0x0000, 0x22a3, 0x0000, 0x0000, 0x0000
1316 };
1317 
1318 static const unsigned short koreanKeysymsToUnicode[] = {
1319  0x0000, 0x3131, 0x3132, 0x3133, 0x3134, 0x3135, 0x3136, 0x3137,
1320  0x3138, 0x3139, 0x313a, 0x313b, 0x313c, 0x313d, 0x313e, 0x313f,
1321  0x3140, 0x3141, 0x3142, 0x3143, 0x3144, 0x3145, 0x3146, 0x3147,
1322  0x3148, 0x3149, 0x314a, 0x314b, 0x314c, 0x314d, 0x314e, 0x314f,
1323  0x3150, 0x3151, 0x3152, 0x3153, 0x3154, 0x3155, 0x3156, 0x3157,
1324  0x3158, 0x3159, 0x315a, 0x315b, 0x315c, 0x315d, 0x315e, 0x315f,
1325  0x3160, 0x3161, 0x3162, 0x3163, 0x11a8, 0x11a9, 0x11aa, 0x11ab,
1326  0x11ac, 0x11ad, 0x11ae, 0x11af, 0x11b0, 0x11b1, 0x11b2, 0x11b3,
1327  0x11b4, 0x11b5, 0x11b6, 0x11b7, 0x11b8, 0x11b9, 0x11ba, 0x11bb,
1328  0x11bc, 0x11bd, 0x11be, 0x11bf, 0x11c0, 0x11c1, 0x11c2, 0x316d,
1329  0x3171, 0x3178, 0x317f, 0x3181, 0x3184, 0x3186, 0x318d, 0x318e,
1330  0x11eb, 0x11f0, 0x11f9, 0x0000, 0x0000, 0x0000, 0x0000, 0x20a9
1331 };
1332 
1333 static QChar keysymToUnicode(unsigned char byte3, unsigned char byte4)
1334 {
1335  switch (byte3) {
1336  case 0x04:
1337  // katakana
1338  if (byte4 > 0xa0 && byte4 < 0xe0)
1339  return QChar(katakanaKeysymsToUnicode[byte4 - 0xa0]);
1340  else if (byte4 == 0x7e)
1341  return QChar(0x203e); // Overline
1342  break;
1343  case 0x06:
1344  // russian, use lookup table
1345  if (byte4 > 0xa0)
1346  return QChar(cyrillicKeysymsToUnicode[byte4 - 0xa0]);
1347  break;
1348  case 0x07:
1349  // greek
1350  if (byte4 > 0xa0)
1351  return QChar(greekKeysymsToUnicode[byte4 - 0xa0]);
1352  break;
1353  case 0x08:
1354  // technical
1355  if (byte4 > 0xa0)
1356  return QChar(technicalKeysymsToUnicode[byte4 - 0xa0]);
1357  break;
1358  case 0x09:
1359  // special
1360  if (byte4 >= 0xe0)
1361  return QChar(specialKeysymsToUnicode[byte4 - 0xe0]);
1362  break;
1363  case 0x0a:
1364  // publishing
1365  if (byte4 > 0xa0)
1366  return QChar(publishingKeysymsToUnicode[byte4 - 0xa0]);
1367  break;
1368  case 0x0b:
1369  // APL
1370  if (byte4 > 0xa0)
1371  return QChar(aplKeysymsToUnicode[byte4 - 0xa0]);
1372  break;
1373  case 0x0e:
1374  // Korean
1375  if (byte4 > 0xa0)
1376  return QChar(koreanKeysymsToUnicode[byte4 - 0xa0]);
1377  break;
1378  default:
1379  break;
1380  }
1381  return QChar(0x0);
1382 }
1383 #endif
1384 
1385 static QString translateKeySym(KeySym keysym, uint xmodifiers,
1386  int &code, Qt::KeyboardModifiers &modifiers,
1387  QByteArray &chars, int &count)
1388 {
1389  // all keysyms smaller than 0xff00 are actally keys that can be mapped to unicode chars
1390 
1391  extern QTextCodec *qt_input_mapper; // from qapplication_x11.cpp
1392  QTextCodec *mapper = qt_input_mapper;
1393  QChar converted;
1394 
1395  if (count == 0 && keysym < 0xff00) {
1396  unsigned char byte3 = (unsigned char)(keysym >> 8);
1397  int mib = -1;
1398  switch(byte3) {
1399  case 0: // Latin 1
1400  case 1: // Latin 2
1401  case 2: //latin 3
1402  case 3: // latin4
1403  mib = byte3 + 4; break;
1404  case 5: // arabic
1405  mib = 82; break;
1406  case 12: // Hebrew
1407  mib = 85; break;
1408  case 13: // Thai
1409  mib = 2259; break;
1410  case 4: // kana
1411  case 6: // cyrillic
1412  case 7: // greek
1413  case 8: // technical, no mapping here at the moment
1414  case 9: // Special
1415  case 10: // Publishing
1416  case 11: // APL
1417  case 14: // Korean, no mapping
1418  mib = -1; // manual conversion
1419  mapper = 0;
1420 #if !defined(QT_NO_XIM)
1421  converted = keysymToUnicode(byte3, keysym & 0xff);
1422 #endif
1423  case 0x20:
1424  // currency symbols
1425  if (keysym >= 0x20a0 && keysym <= 0x20ac) {
1426  mib = -1; // manual conversion
1427  mapper = 0;
1428  converted = (uint)keysym;
1429  }
1430  break;
1431  default:
1432  break;
1433  }
1434  if (mib != -1) {
1435  mapper = QTextCodec::codecForMib(mib);
1436  if (chars.isEmpty())
1437  chars.resize(1);
1438  chars[0] = (unsigned char) (keysym & 0xff); // get only the fourth bit for conversion later
1439  count++;
1440  }
1441  } else if (keysym >= 0x1000000 && keysym <= 0x100ffff) {
1442  converted = (ushort) (keysym - 0x1000000);
1443  mapper = 0;
1444  }
1445  if (count < (int)chars.size()-1)
1446  chars[count] = '\0';
1447 
1448  QString text;
1449  if (!mapper && converted.unicode() != 0x0) {
1450  text = converted;
1451  } else if (!chars.isEmpty()) {
1452  // convert chars (8bit) to text (unicode).
1453  if (mapper)
1454  text = mapper->toUnicode(chars.data(), count, 0);
1455  if (text.isEmpty()) {
1456  // no mapper, or codec couldn't convert to unicode (this
1457  // can happen when running in the C locale or with no LANG
1458  // set). try converting from latin-1
1459  text = QString::fromLatin1(chars);
1460  }
1461  }
1462 
1463  modifiers = X11->translateModifiers(xmodifiers);
1464 
1465  // Commentary in X11/keysymdef says that X codes match ASCII, so it
1466  // is safe to use the locale functions to process X codes in ISO8859-1.
1467  //
1468  // This is mainly for compatibility - applications should not use the
1469  // Qt keycodes between 128 and 255, but should rather use the
1470  // QKeyEvent::text().
1471  //
1472  extern QTextCodec *qt_input_mapper; // from qapplication_x11.cpp
1473  if (keysym < 128 || (keysym < 256 && (!qt_input_mapper || qt_input_mapper->mibEnum()==4))) {
1474  // upper-case key, if known
1475  code = isprint((int)keysym) ? toupper((int)keysym) : 0;
1476  } else if (keysym >= XK_F1 && keysym <= XK_F35) {
1477  // function keys
1478  code = Qt::Key_F1 + ((int)keysym - XK_F1);
1479  } else if (keysym >= XK_KP_Space && keysym <= XK_KP_9) {
1480  if (keysym >= XK_KP_0) {
1481  // numeric keypad keys
1482  code = Qt::Key_0 + ((int)keysym - XK_KP_0);
1483  } else {
1484  code = translateKeySym(keysym);
1485  }
1486  modifiers |= Qt::KeypadModifier;
1487  } else if (text.length() == 1 && text.unicode()->unicode() > 0x1f && text.unicode()->unicode() != 0x7f && !(keysym >= XK_dead_grave && keysym <= XK_dead_horn)) {
1488  code = text.unicode()->toUpper().unicode();
1489  } else {
1490  // any other keys
1491  code = translateKeySym(keysym);
1492 
1493  if (code == Qt::Key_Tab && (modifiers & Qt::ShiftModifier)) {
1494  // map shift+tab to shift+backtab, QShortcutMap knows about it
1495  // and will handle it.
1496  code = Qt::Key_Backtab;
1497  text = QString();
1498  }
1499  }
1500 
1501  return text;
1502 }
1503 
1504 extern bool qt_use_rtl_extensions; // from qapplication_x11.cpp
1505 
1507  const XEvent *event,
1508  KeySym &keysym,
1509  int& count,
1510  QString& text,
1511  Qt::KeyboardModifiers &modifiers,
1512  int& code,
1513  QEvent::Type &type,
1514  bool statefulTranslation)
1515 {
1516  XKeyEvent xkeyevent = event->xkey;
1517  int keycode = event->xkey.keycode;
1518  // save the modifier state, we will use the keystate uint later by passing
1519  // it to translateButtonState
1520  uint keystate = event->xkey.state;
1521 
1522  type = (event->type == XKeyPress) ? QEvent::KeyPress : QEvent::KeyRelease;
1523 
1524  static int directionKeyEvent = 0;
1525  static unsigned int lastWinId = 0;
1526 
1527  // translate pending direction change
1528  if (statefulTranslation && qt_use_rtl_extensions && type == QEvent::KeyRelease) {
1529  if (directionKeyEvent == Qt::Key_Direction_R || directionKeyEvent == Qt::Key_Direction_L) {
1531  code = directionKeyEvent;
1532  text = QString();
1533  directionKeyEvent = 0;
1534  lastWinId = 0;
1535  return true;
1536  } else {
1537  directionKeyEvent = 0;
1538  lastWinId = 0;
1539  }
1540  }
1541 
1542  // some XmbLookupString implementations don't return buffer overflow correctly,
1543  // so we increase the input buffer to allow for long strings...
1544  // 256 chars * 2 bytes + 1 null-term == 513 bytes
1545  QByteArray chars;
1546  chars.resize(513);
1547 
1548  count = XLookupString(&xkeyevent, chars.data(), chars.size(), &keysym, 0);
1549  if (count && !keycode) {
1550  extern int qt_ximComposingKeycode; // from qapplication_x11.cpp
1551  keycode = qt_ximComposingKeycode;
1552  qt_ximComposingKeycode = 0;
1553  }
1554 
1555  // translate the keysym + xmodifiers to Qt::Key_* + Qt::KeyboardModifiers
1556  text = translateKeySym(keysym, keystate, code, modifiers, chars, count);
1557 
1558  // Watch for keypresses and if its a key belonging to the Ctrl-Shift
1559  // direction-changing accel, remember it.
1560  // We keep track of those keys instead of using the event's state
1561  // (to figure out whether the Ctrl modifier is held while Shift is pressed,
1562  // or Shift is held while Ctrl is pressed) since the 'state' doesn't tell
1563  // us whether the modifier held is Left or Right.
1564  if (statefulTranslation && qt_use_rtl_extensions && type == QEvent::KeyPress) {
1565  if (keysym == XK_Control_L || keysym == XK_Control_R
1566  || keysym == XK_Shift_L || keysym == XK_Shift_R) {
1567  if (!directionKeyEvent) {
1568  directionKeyEvent = keysym;
1569  // This code exists in order to check that
1570  // the event is occurred in the same widget.
1571  lastWinId = keyWidget->internalWinId();
1572  }
1573  } else {
1574  // this can no longer be a direction-changing accel.
1575  // if any other key was pressed.
1576  directionKeyEvent = Qt::Key_Space;
1577  }
1578 
1579  if (directionKeyEvent && lastWinId == keyWidget->internalWinId()) {
1580  if ((keysym == XK_Shift_L && directionKeyEvent == XK_Control_L)
1581  || (keysym == XK_Control_L && directionKeyEvent == XK_Shift_L)) {
1582  directionKeyEvent = Qt::Key_Direction_L;
1583  } else if ((keysym == XK_Shift_R && directionKeyEvent == XK_Control_R)
1584  || (keysym == XK_Control_R && directionKeyEvent == XK_Shift_R)) {
1585  directionKeyEvent = Qt::Key_Direction_R;
1586  }
1587  } else if (directionKeyEvent == Qt::Key_Direction_L
1588  || directionKeyEvent == Qt::Key_Direction_R) {
1589  directionKeyEvent = Qt::Key_Space; // invalid
1590  }
1591  }
1592 
1593  return true;
1594 }
1595 
1596 
1598 {
1599  // match the window and keycode with timestamp delta of 10 ms
1601  KeyCode keycode;
1603 
1604  // queue scanner state
1605  bool release;
1606  bool error;
1607 };
1608 
1609 #if defined(Q_C_CALLBACKS)
1610 extern "C" {
1611 #endif
1612 
1613 static Bool qt_keypress_scanner(Display *, XEvent *event, XPointer arg)
1614 {
1615  if (event->type != XKeyPress && event->type != XKeyRelease)
1616  return false;
1617 
1619  if (data->error)
1620  return false;
1621 
1622  if (event->xkey.window != data->window ||
1623  event->xkey.keycode != data->keycode) {
1624  // deal breakers: key events in a different window or an event
1625  // with a different key code
1626  data->error = true;
1627  return false;
1628  }
1629 
1630  if (event->type == XKeyPress) {
1631  data->error = (! data->release || event->xkey.time - data->timestamp > 10);
1632  return (! data->error);
1633  }
1634 
1635  // must be XKeyRelease event
1636  if (data->release) {
1637  // found a second release
1638  data->error = true;
1639  return false;
1640  }
1641 
1642  // found a single release
1643  data->release = true;
1644  data->timestamp = event->xkey.time;
1645 
1646  return false;
1647 }
1648 
1649 static Bool qt_keyrelease_scanner(Display *, XEvent *event, XPointer arg)
1650 {
1651  const qt_auto_repeat_data *data = (const qt_auto_repeat_data *) arg;
1652  return (event->type == XKeyRelease &&
1653  event->xkey.window == data->window &&
1654  event->xkey.keycode == data->keycode);
1655 }
1656 
1657 #if defined(Q_C_CALLBACKS)
1658 }
1659 #endif
1660 
1661 bool QKeyMapperPrivate::translateKeyEvent(QWidget *keyWidget, const XEvent *event, bool grab)
1662 {
1663  int code = -1;
1664  int count = 0;
1665  Qt::KeyboardModifiers modifiers;
1666 
1667  if (qt_sm_blockUserInput) // block user interaction during session management
1668  return true;
1669 
1670  Display *dpy = X11->display;
1671 
1672  if (!keyWidget->isEnabled())
1673  return true;
1674 
1676  bool autor = false;
1677  QString text;
1678 
1679  KeySym keysym = 0;
1680  translateKeyEventInternal(keyWidget, event, keysym, count, text, modifiers, code, type);
1681 
1682  // was this the last auto-repeater?
1683  qt_auto_repeat_data auto_repeat_data;
1684  auto_repeat_data.window = event->xkey.window;
1685  auto_repeat_data.keycode = event->xkey.keycode;
1686  auto_repeat_data.timestamp = event->xkey.time;
1687 
1688  static uint curr_autorep = 0;
1689  if (event->type == XKeyPress) {
1690  if (curr_autorep == event->xkey.keycode) {
1691  autor = true;
1692  curr_autorep = 0;
1693  }
1694  } else {
1695  // look ahead for auto-repeat
1696  XEvent nextpress;
1697 
1698  auto_repeat_data.release = true;
1699  auto_repeat_data.error = false;
1700  if (XCheckIfEvent(dpy, &nextpress, &qt_keypress_scanner,
1701  (XPointer) &auto_repeat_data)) {
1702  autor = true;
1703 
1704  // Put it back... we COULD send the event now and not need
1705  // the static curr_autorep variable.
1706  XPutBackEvent(dpy,&nextpress);
1707  }
1708  curr_autorep = autor ? event->xkey.keycode : 0;
1709  }
1710 
1711 #if defined QT3_SUPPORT && !defined(QT_NO_SHORTCUT)
1712  // process accelerators before doing key compression
1713  if (type == QEvent::KeyPress && !grab
1714  && QApplicationPrivate::instance()->use_compat()) {
1715  // send accel events if the keyboard is not grabbed
1716  QKeyEventEx a(type, code, modifiers, text, autor, qMax(qMax(count,1), int(text.length())),
1717  event->xkey.keycode, keysym, event->xkey.state);
1718  if (QApplicationPrivate::instance()->qt_tryAccelEvent(keyWidget, &a))
1719  return true;
1720  }
1721 #endif
1722 
1723 #ifndef QT_NO_IM
1724  QInputContext *qic = keyWidget->inputContext();
1725 #endif
1726 
1727  // compress keys
1728  if (!text.isEmpty() && keyWidget->testAttribute(Qt::WA_KeyCompression) &&
1729 #ifndef QT_NO_IM
1730  // Ordinary input methods require discrete key events to work
1731  // properly, so key compression has to be disabled when input
1732  // context exists.
1733  //
1734  // And further consideration, some complex input method
1735  // require all key press/release events discretely even if
1736  // the input method awares of key compression and compressed
1737  // keys are ordinary alphabets. For example, the uim project
1738  // is planning to implement "combinational shift" feature for
1739  // a Japanese input method, uim-skk. It will work as follows.
1740  //
1741  // 1. press "r"
1742  // 2. press "u"
1743  // 3. release both "r" and "u" in arbitrary order
1744  // 4. above key sequence generates "Ru"
1745  //
1746  // Of course further consideration about other participants
1747  // such as key repeat mechanism is required to implement such
1748  // feature.
1749  !qic &&
1750 #endif // QT_NO_IM
1751  // do not compress keys if the key event we just got above matches
1752  // one of the key ranges used to compute stopCompression
1753  !((code >= Qt::Key_Escape && code <= Qt::Key_SysReq)
1754  || (code >= Qt::Key_Home && code <= Qt::Key_PageDown)
1755  || (code >= Qt::Key_Super_L && code <= Qt::Key_Direction_R)
1756  || (code == 0)
1757  || (text.length() == 1 && text.unicode()->unicode() == '\n'))) {
1758  // the widget wants key compression so it gets it
1759 
1760  // sync the event queue, this makes key compress work better
1761  XSync(dpy, false);
1762 
1763  for (;;) {
1764  XEvent evRelease;
1765  XEvent evPress;
1766  if (!XCheckTypedWindowEvent(dpy,event->xkey.window,
1767  XKeyRelease,&evRelease))
1768  break;
1769  if (!XCheckTypedWindowEvent(dpy,event->xkey.window,
1770  XKeyPress,&evPress)) {
1771  XPutBackEvent(dpy, &evRelease);
1772  break;
1773  }
1774  QString textIntern;
1775  int codeIntern = -1;
1776  int countIntern = 0;
1777  Qt::KeyboardModifiers modifiersIntern;
1778  QEvent::Type t;
1779  KeySym keySymIntern;
1780  translateKeyEventInternal(keyWidget, &evPress, keySymIntern, countIntern, textIntern,
1781  modifiersIntern, codeIntern, t);
1782  // use stopCompression to stop key compression for the following
1783  // key event ranges:
1784  bool stopCompression =
1785  // 1) misc keys
1786  (codeIntern >= Qt::Key_Escape && codeIntern <= Qt::Key_SysReq)
1787  // 2) cursor movement
1788  || (codeIntern >= Qt::Key_Home && codeIntern <= Qt::Key_PageDown)
1789  // 3) extra keys
1790  || (codeIntern >= Qt::Key_Super_L && codeIntern <= Qt::Key_Direction_R)
1791  // 4) something that a) doesn't translate to text or b) translates
1792  // to newline text
1793  || (codeIntern == 0)
1794  || (textIntern.length() == 1 && textIntern.unicode()->unicode() == '\n')
1795  || (codeIntern == Qt::Key_unknown);
1796 
1797  if (modifiersIntern == modifiers && !textIntern.isEmpty() && !stopCompression) {
1798  text += textIntern;
1799  count += countIntern;
1800  } else {
1801  XPutBackEvent(dpy, &evPress);
1802  XPutBackEvent(dpy, &evRelease);
1803  break;
1804  }
1805  }
1806  }
1807 
1808  // autorepeat compression makes sense for all widgets (Windows
1809  // does it automatically ....)
1810  if (event->type == XKeyPress && text.length() <= 1
1811 #ifndef QT_NO_IM
1812  // input methods need discrete key events
1813  && !qic
1814 #endif// QT_NO_IM
1815  ) {
1816  XEvent dummy;
1817 
1818  for (;;) {
1819  auto_repeat_data.release = false;
1820  auto_repeat_data.error = false;
1821  if (! XCheckIfEvent(dpy, &dummy, &qt_keypress_scanner,
1822  (XPointer) &auto_repeat_data))
1823  break;
1824  if (! XCheckIfEvent(dpy, &dummy, &qt_keyrelease_scanner,
1825  (XPointer) &auto_repeat_data))
1826  break;
1827 
1828  count++;
1829  if (!text.isEmpty())
1830  text += text[0];
1831  }
1832  }
1833 
1834  return QKeyMapper::sendKeyEvent(keyWidget, grab, type, code, modifiers, text, autor,
1835  qMax(qMax(count,1), int(text.length())),
1836  event->xkey.keycode, keysym, event->xkey.state);
1837 }
1838 
1839 bool QKeyMapper::sendKeyEvent(QWidget *keyWidget, bool grab,
1840  QEvent::Type type, int code, Qt::KeyboardModifiers modifiers,
1841  const QString &text, bool autorepeat, int count,
1842  quint32 nativeScanCode, quint32 nativeVirtualKey, quint32 nativeModifiers,
1843  bool *)
1844 {
1845  // try the menukey first
1846  if (type == QEvent::KeyPress && code == Qt::Key_Menu) {
1847  QVariant v = keyWidget->inputMethodQuery(Qt::ImMicroFocus);
1848  QPoint globalPos;
1849  QPoint pos;
1850  if (v.isNull()) {
1851  globalPos = QCursor::pos();
1852  pos = keyWidget->mapFromGlobal(globalPos);
1853  } else {
1854  pos = v.toRect().center();
1855  globalPos = keyWidget->mapToGlobal(pos);
1856  }
1858  qt_sendSpontaneousEvent(keyWidget, &e);
1859  if(e.isAccepted())
1860  return true;
1861  }
1862 
1863  Q_UNUSED(grab);
1864  QKeyEventEx e(type, code, modifiers, text, autorepeat, qMax(qMax(count,1), int(text.length())),
1865  nativeScanCode, nativeVirtualKey, nativeModifiers);
1866  return qt_sendSpontaneousEvent(keyWidget, &e);
1867 }
1868 
The QVariant class acts like a union for the most common Qt data types.
Definition: qvariant.h:92
#define QTOPIAXK_Zoom
#define XF86XK_Away
#define XF86XK_Book
#define XF86XK_Option
#define XF86XK_AudioMute
#define XF86XK_ScreenSaver
#define XF86XK_Travel
#define XF86XK_DOS
Qt::LayoutDirection textDirection() const
Returns the text direction of the language.
Definition: qlocale.cpp:2286
#define QTOPIAXK_Context3
#define XF86XK_Launch8
The QKeyEvent class describes a key event.
Definition: qevent.h:224
#define XF86XK_Excel
static const unsigned short katakanaKeysymsToUnicode[]
#define QTOPIAXK_Cancel
int type
Definition: qmetatype.cpp:239
#define XK_Kanji_Bangou
#define XF86XK_Shop
#define XK_KP_Right
#define XF86XK_Reload
#define QT_END_NAMESPACE
This macro expands to.
Definition: qglobal.h:90
#define XF86XK_HotLinks
EventRef event
#define XF86XK_RotateWindows
#define XF86XK_ZoomIn
char * data()
Returns a pointer to the data stored in the byte array.
Definition: qbytearray.h:429
int keycode
#define XK_KP_Home
const QChar at(int i) const
Returns the character at the given index position in the string.
Definition: qstring.h:698
#define XF86XK_Suspend
ushort unicode() const
This is an overloaded member function, provided for convenience. It differs from the above function o...
Definition: qchar.h:251
bool isNull() const
Returns true if this is a NULL variant, false otherwise.
Definition: qvariant.cpp:3102
#define XF86XK_LaunchF
#define XF86XK_LaunchC
The QContextMenuEvent class contains parameters that describe a context menu event.
Definition: qevent.h:396
#define XF86XK_View
#define XF86XK_AudioPlay
#define XF86XK_Launch5
#define XF86XK_WLAN
#define XK_KP_Down
#define XF86XK_RotationKB
uchar qt_num_lock_mask
The QByteArray class provides an array of bytes.
Definition: qbytearray.h:135
uchar qt_hyper_mask
int length() const
Returns the number of characters in this string.
Definition: qstring.h:696
#define XF86XK_TopMenu
static Bool qt_keypress_scanner(Display *, XEvent *event, XPointer arg)
#define XF86XK_AudioPrev
#define XF86XK_AudioMedia
The QWidget class is the base class of all user interface objects.
Definition: qwidget.h:150
#define XK_Codeinput
#define QTOPIAXK_No
#define XF86XK_Search
#define XF86XK_ContrastAdjust
#define XF86XK_Calculator
#define XF86XK_MonBrightnessDown
#define XF86XK_Memo
#define XF86XK_Tools
#define XF86XK_Launch4
static const unsigned short koreanKeysymsToUnicode[]
#define XF86XK_AudioRepeat
static QApplicationPrivate * instance()
long ASN1_INTEGER_get ASN1_INTEGER * a
int count(const T &t) const
Returns the number of occurrences of value in the list.
Definition: qlist.h:891
uchar qt_alt_mask
QLocale keyboardInputLocale
Definition: qkeymapper_p.h:155
QString name() const
Returns the language and country of this locale as a string of the form "language_country", where language is a lowercase, two-letter ISO 639 language code, and country is an uppercase, two- or three-letter ISO 3166 country code.
Definition: qlocale.cpp:963
int keysym
virtual QVariant inputMethodQuery(Qt::InputMethodQuery) const
This method is only relevant for input widgets.
Definition: qwidget.cpp:9683
#define XK_dead_horn
QLocale q_getKeyboardLocale(const QByteArray &layoutName, const QByteArray &variantName)
The QString class provides a Unicode character string.
Definition: qstring.h:83
#define XK_KP_Up
#define QTOPIAXK_Execute
#define XF86XK_Xfer
static const unsigned int KeyTbl[]
#define XF86XK_Select
#define XF86XK_HomePage
The QObject class is the base class of all Qt objects.
Definition: qobject.h:111
#define X11
Definition: qt_x11_p.h:724
#define XF86XK_iTouch
#define XF86XK_Word
#define XF86XK_Subtitle
The QChar class provides a 16-bit Unicode character.
Definition: qchar.h:72
static const unsigned short cyrillicKeysymsToUnicode[]
Q_CORE_EXPORT QTextStream & hex(QTextStream &s)
#define XF86XK_Calendar
#define XF86XK_LaunchA
Q_DECL_CONSTEXPR const T & qMax(const T &a, const T &b)
Definition: qglobal.h:1217
#define XF86XK_Community
#define XF86XK_Video
#define XF86XK_Explorer
#define XF86XK_Terminal
bool qt_sendSpontaneousEvent(QObject *, QEvent *)
union _XEvent XEvent
Definition: qwindowdefs.h:116
#define XF86XK_Copy
#define ATOM(x)
Definition: qt_x11_p.h:723
#define XF86XK_News
#define XF86XK_PowerDown
Q_CORE_EXPORT void qDebug(const char *,...)
#define XF86XK_LaunchD
#define XK_KP_Next
#define XF86XK_Hibernate
unsigned char uchar
Definition: qglobal.h:994
static QString translateKeySym(KeySym keysym, uint xmodifiers, int &code, Qt::KeyboardModifiers &modifiers, QByteArray &chars, int &count)
QList< int > possibleKeys(QKeyEvent *e)
#define XK_ISO_Left_Tab
#define XF86XK_AudioRandomPlay
#define XF86XK_AddFavorite
#define XF86XK_Pictures
QLocale::Language language
#define QT_BEGIN_NAMESPACE
This macro expands to.
Definition: qglobal.h:89
#define XF86XK_BrightnessAdjust
bool isAccepted() const
Definition: qcoreevent.h:307
#define XF86XK_Reply
static const unsigned short aplKeysymsToUnicode[]
#define XF86XK_AudioRaiseVolume
#define XF86XK_ClearGrab
#define XF86XK_Documents
bool testAttribute(Qt::WidgetAttribute) const
Returns true if attribute attribute is set on this widget; otherwise returns false.
Definition: qwidget.h:1041
const QChar * unicode() const
Returns a &#39;\0&#39;-terminated Unicode representation of the string.
Definition: qstring.h:706
#define QTOPIAXK_Context4
bool isEmpty() const
Returns true if the string has no characters; otherwise returns false.
Definition: qstring.h:704
static const unsigned short publishingKeysymsToUnicode[]
#define XF86XK_ZoomOut
#define QTOPIAXK_Yes
QTextCodec * qt_input_mapper
#define XF86XK_Calculater
#define XF86XK_AudioCycleTrack
#define XF86XK_BackForward
const T & at(int i) const
Returns the item at index position i in the list.
Definition: qlist.h:468
const char * layout
static QByteArray fromRawData(const char *, int size)
Constructs a QByteArray that uses the first size bytes of the data array.
#define XF86XK_PowerOff
#define XF86XK_ApplicationLeft
#define XF86XK_Cut
static bool translateKeyEventInternal(EventHandlerCallRef er, EventRef keyEvent, int *qtKey, QChar *outChar, Qt::KeyboardModifiers *outModifiers, bool *outHandled)
#define XK_KP_Left
#define XF86XK_Standby
virtual int mibEnum() const =0
Subclasses of QTextCodec must reimplement this function.
static const char * data(const QByteArray &arr)
#define XF86XK_Launch9
unsigned int uint
Definition: qglobal.h:996
#define XF86XK_KbdBrightnessUp
int mib
bool translateKeyEvent(QWidget *receiver, const MSG &msg, bool grab)
QChar toUpper() const
Returns the uppercase equivalent if the character is lowercase or titlecase; otherwise returns the ch...
Definition: qchar.cpp:1287
#define XF86XK_AudioForward
bool qt_use_rtl_extensions
static QTextCodec * codecForMib(int mib)
Returns the QTextCodec which matches the MIBenum mib.
#define XF86XK_Back
#define QTOPIAXK_Play
#define XK_KP_End
unsigned long ulong
Definition: qglobal.h:997
#define XF86XK_Phone
#define XF86XK_Spell
static const unsigned short technicalKeysymsToUnicode[]
#define XF86XK_MonBrightnessUp
#define XF86XK_Music
#define QTOPIAXK_Select
#define XF86XK_Time
QInputContext * inputContext()
This function returns the QInputContext for this widget.
Definition: qwidget.cpp:474
#define XF86XK_AudioLowerVolume
bool isEnabled() const
Definition: qwidget.h:948
#define XF86XK_LogOff
#define XF86XK_KbdBrightnessDown
#define XF86XK_WWW
char * XPointer
Definition: qt_x11_p.h:180
#define XF86XK_Market
#define XF86XK_LaunchE
QPoint center() const
Returns the center point of the rectangle.
Definition: qrect.h:300
#define XF86XK_Clear
QString toUnicode(const QByteArray &) const
Converts a from the encoding of this codec to Unicode, and returns the result in a QString...
QList< QByteArray > split(char sep) const
Splits the byte array into subarrays wherever sep occurs, and returns the list of those arrays...
#define XF86XK_Paste
#define XF86XK_Meeting
#define QTOPIAXK_Context1
uint qstrlen(const char *str)
Definition: qbytearray.h:79
struct _XDisplay Display
Definition: qwindowdefs.h:115
#define XF86XK_MailForward
#define XF86XK_OfficeHome
static QLocale c()
Returns a QLocale object initialized to the "C" locale.
Definition: qlocale.h:773
static int qt_XTranslateKey(register QXCoreDesc *dpy, KeyCode keycode, register unsigned int modifiers, unsigned int *modifiers_return, KeySym *keysym_return)
static struct @202 xkbLayoutData[]
#define XF86XK_AudioRewind
#define XF86XK_Mail
#define XF86XK_Bluetooth
#define XK_KP_Delete
#define XF86XK_History
#define XF86XK_KbdLightOnOff
bool qt_sm_blockUserInput
uchar qt_super_mask
Type
This enum type defines the valid event types in Qt.
Definition: qcoreevent.h:62
#define XK_dead_hook
#define XF86XK_Launch6
#define XF86XK_Launch1
static Bool qt_keyrelease_scanner(Display *, XEvent *event, XPointer arg)
static QChar keysymToUnicode(unsigned char byte3, unsigned char byte4)
unsigned short ushort
Definition: qglobal.h:995
QRect toRect() const
Returns the variant as a QRect if the variant has type() Rect ; otherwise returns an invalid QRect...
Definition: qvariant.cpp:2416
#define XF86XK_LightBulb
#define XF86XK_WakeUp
#define XF86XK_Launch7
#define XF86XK_CD
static QString fromLatin1(const char *, int size=-1)
Returns a QString initialized with the first size characters of the Latin-1 string str...
Definition: qstring.cpp:4188
#define XF86XK_Forward
#define XF86XK_AudioRecord
#define XF86XK_Launch2
#define XF86XK_Display
#define QTOPIAXK_Hangup
int key
The QPoint class defines a point in the plane using integer precision.
Definition: qpoint.h:53
#define XF86XK_Send
void resize(int size)
Sets the size of the byte array to size bytes.
#define QTOPIAXK_Call
unsigned int quint32
Definition: qglobal.h:938
static const unsigned short greekKeysymsToUnicode[]
#define XF86XK_OpenURL
#define XF86XK_SplitScreen
#define XF86XK_Game
#define XF86XK_Stop
#define XF86XK_ApplicationRight
#define XF86XK_Go
#define XF86XK_Launch0
#define XF86XK_MenuKB
#define XF86XK_AudioStop
#define XF86XK_MySites
#define QTOPIAXK_Printer
WId internalWinId() const
Returns the window system identifier of the widget, or 0 if the widget is not created yet...
Definition: qwidget.h:244
int size() const
Returns the number of bytes in this byte array.
Definition: qbytearray.h:402
#define XF86XK_UWB
QPoint mapFromGlobal(const QPoint &) const
Translates the global screen coordinate pos to widget coordinates.
#define XF86XK_WebCam
#define XF86XK_Close
#define XF86XK_RotationPB
static bool sendKeyEvent(QWidget *widget, bool grab, QEvent::Type type, int code, Qt::KeyboardModifiers modifiers, const QString &text, bool autorepeat, int count, quint32 nativeScanCode, quint32 nativeVirtualKey, quint32 nativeModifiers, bool *unusedExceptForCocoa=0)
#define XF86XK_Favorites
#define XF86XK_Launch3
uchar qt_meta_mask
bool isEmpty() const
Returns true if the byte array has size 0; otherwise returns false.
Definition: qbytearray.h:421
#define XF86XK_TaskPane
#define XF86XK_Save
const char * variant
The QInputContext class abstracts the input method dependent data and composing state.
Definition: qinputcontext.h:83
#define XF86XK_MenuPB
#define XF86XK_Finance
#define XF86XK_ToDoList
#define XF86XK_Eject
The QTextCodec class provides conversions between text encodings.
Definition: qtextcodec.h:62
#define XF86XK_Messenger
static const KeyPair *const end
QLocale::Country country
The QEvent class is the base class of all event classes.
Definition: qcoreevent.h:56
Type type() const
Returns the event type.
Definition: qcoreevent.h:303
Qt::LayoutDirection keyboardInputDirection
Definition: qkeymapper_p.h:156
#define XF86XK_LaunchB
#define Q_UNUSED(x)
Indicates to the compiler that the parameter with the specified name is not used in the body of a fun...
Definition: qglobal.h:1729
#define QTOPIAXK_Sleep
#define SETMASK(sym, mask)
#define XK_KP_Prior
#define XF86XK_Battery
QPoint mapToGlobal(const QPoint &) const
Translates the widget coordinate pos to global screen coordinates.
#define XF86XK_Refresh
#define XF86XK_AudioNext
int qt_ximComposingKeycode
#define XF86XK_MyComputer
void clear()
Clears the contents of the byte array and makes it empty.
static const unsigned short specialKeysymsToUnicode[]
#define XF86XK_Sleep
#define text
Definition: qobjectdefs.h:80
static QPoint pos()
Returns the position of the cursor (hot spot) in global screen coordinates.
Definition: qcursor_mac.mm:310
#define QTOPIAXK_Context2
#define XK_KP_Insert
#define QTOPIAXK_Flip
uchar qt_mode_switch_mask
#define XF86XK_Support