Qt 4.8
qkeymapper_mac.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 <private/qt_mac_p.h>
43 #include <qdebug.h>
44 #include <qevent.h>
45 #include <private/qevent_p.h>
46 #include <qtextcodec.h>
47 #include <qapplication.h>
48 #include <qinputcontext.h>
49 #include <private/qkeymapper_p.h>
50 #include <private/qapplication_p.h>
51 #include <private/qmacinputcontext_p.h>
52 
54 
56 
57 /*****************************************************************************
58  QKeyMapper debug facilities
59  *****************************************************************************/
60 //#define DEBUG_KEY_BINDINGS
61 //#define DEBUG_KEY_BINDINGS_MODIFIERS
62 //#define DEBUG_KEY_MAPS
63 
64 /*****************************************************************************
65  Internal variables and functions
66  *****************************************************************************/
68 extern bool qt_sendSpontaneousEvent(QObject *obj, QEvent *event); //qapplication_mac.cpp
69 
71 {
72  static bool secure = false;
73  if (b != secure){
74  b ? EnableSecureEventInput() : DisableSecureEventInput();
75  secure = b;
76  }
77 }
78 
79 /*
80  \internal
81  A Mac KeyboardLayoutItem has 8 possible states:
82  1. Unmodified
83  2. Shift
84  3. Control
85  4. Control + Shift
86  5. Alt
87  6. Alt + Shift
88  7. Alt + Control
89  8. Alt + Control + Shift
90  9. Meta
91  10. Meta + Shift
92  11. Meta + Control
93  12. Meta + Control + Shift
94  13. Meta + Alt
95  14. Meta + Alt + Shift
96  15. Meta + Alt + Control
97  16. Meta + Alt + Control + Shift
98 */
100  bool dirty;
101  quint32 qtKey[16]; // Can by any Qt::Key_<foo>, or unicode character
102 };
103 
104 // Possible modifier states.
105 // NOTE: The order of these states match the order in QKeyMapperPrivate::updatePossibleKeyCodes()!
106 static const Qt::KeyboardModifiers ModsTbl[] = {
107  Qt::NoModifier, // 0
108  Qt::ShiftModifier, // 1
109  Qt::ControlModifier, // 2
110  Qt::ControlModifier | Qt::ShiftModifier, // 3
111  Qt::AltModifier, // 4
112  Qt::AltModifier | Qt::ShiftModifier, // 5
113  Qt::AltModifier | Qt::ControlModifier, // 6
114  Qt::AltModifier | Qt::ShiftModifier | Qt::ControlModifier, // 7
115  Qt::MetaModifier, // 8
116  Qt::MetaModifier | Qt::ShiftModifier, // 9
117  Qt::MetaModifier | Qt::ControlModifier, // 10
118  Qt::MetaModifier | Qt::ControlModifier | Qt::ShiftModifier,// 11
119  Qt::MetaModifier | Qt::AltModifier, // 12
120  Qt::MetaModifier | Qt::AltModifier | Qt::ShiftModifier, // 13
121  Qt::MetaModifier | Qt::AltModifier | Qt::ControlModifier, // 14
122  Qt::MetaModifier | Qt::AltModifier | Qt::ShiftModifier | Qt::ControlModifier, // 15
123 };
124 
125 /* key maps */
127 {
128  int mac_code;
129  int qt_code;
130 #if defined(DEBUG_KEY_BINDINGS)
131 # define QT_MAC_MAP_ENUM(x) x, #x
132  const char *desc;
133 #else
134 # define QT_MAC_MAP_ENUM(x) x
135 #endif
136 };
137 
138 //modifiers
140  { shiftKey, QT_MAC_MAP_ENUM(Qt::ShiftModifier) },
141  { rightShiftKey, QT_MAC_MAP_ENUM(Qt::ShiftModifier) },
142  { controlKey, QT_MAC_MAP_ENUM(Qt::MetaModifier) },
143  { rightControlKey, QT_MAC_MAP_ENUM(Qt::MetaModifier) },
145  { optionKey, QT_MAC_MAP_ENUM(Qt::AltModifier) },
146  { rightOptionKey, QT_MAC_MAP_ENUM(Qt::AltModifier) },
147  { kEventKeyModifierNumLockMask, QT_MAC_MAP_ENUM(Qt::KeypadModifier) },
148  { 0, QT_MAC_MAP_ENUM(0) }
149 };
150 Qt::KeyboardModifiers qt_mac_get_modifiers(int keys)
151 {
152 #ifdef DEBUG_KEY_BINDINGS_MODIFIERS
153  qDebug("Qt: internal: **Mapping modifiers: %d (0x%04x)", keys, keys);
154 #endif
155  Qt::KeyboardModifiers ret = Qt::NoModifier;
156  for (int i = 0; qt_mac_modifier_symbols[i].qt_code; i++) {
157  if (keys & qt_mac_modifier_symbols[i].mac_code) {
158 #ifdef DEBUG_KEY_BINDINGS_MODIFIERS
159  qDebug("Qt: internal: got modifier: %s", qt_mac_modifier_symbols[i].desc);
160 #endif
161  ret |= Qt::KeyboardModifier(qt_mac_modifier_symbols[i].qt_code);
162  }
163  }
164  if (qApp->testAttribute(Qt::AA_MacDontSwapCtrlAndMeta)) {
165  Qt::KeyboardModifiers oldModifiers = ret;
167  if (oldModifiers & Qt::ControlModifier)
168  ret |= Qt::MetaModifier;
169  if (oldModifiers & Qt::MetaModifier)
170  ret |= Qt::ControlModifier;
171  }
172  return ret;
173 }
174 static int qt_mac_get_mac_modifiers(Qt::KeyboardModifiers keys)
175 {
176 #ifdef DEBUG_KEY_BINDINGS_MODIFIERS
177  qDebug("Qt: internal: **Mapping modifiers: %d (0x%04x)", (int)keys, (int)keys);
178 #endif
179  int ret = 0;
180  for (int i = 0; qt_mac_modifier_symbols[i].qt_code; i++) {
181  if (keys & qt_mac_modifier_symbols[i].qt_code) {
182 #ifdef DEBUG_KEY_BINDINGS_MODIFIERS
183  qDebug("Qt: internal: got modifier: %s", qt_mac_modifier_symbols[i].desc);
184 #endif
185  ret |= qt_mac_modifier_symbols[i].mac_code;
186  }
187  }
188 
189  if (qApp->testAttribute(Qt::AA_MacDontSwapCtrlAndMeta)) {
190  int oldModifiers = ret;
191  ret &= ~(controlKeyBit | cmdKeyBit);
192  if (oldModifiers & controlKeyBit)
193  ret |= cmdKeyBit;
194  if (oldModifiers & cmdKeyBit)
195  ret |= controlKeyBit;
196  }
197  return ret;
198 }
200 {
201  static quint32 cachedModifiers = 0;
202  quint32 lastModifiers = cachedModifiers,
203  changedModifiers = lastModifiers ^ modifiers;
204  cachedModifiers = modifiers;
205 
206  //check the bits
207  static qt_mac_enum_mapper modifier_key_symbols[] = {
208  { shiftKeyBit, QT_MAC_MAP_ENUM(Qt::Key_Shift) },
209  { rightShiftKeyBit, QT_MAC_MAP_ENUM(Qt::Key_Shift) }, //???
210  { controlKeyBit, QT_MAC_MAP_ENUM(Qt::Key_Meta) },
211  { rightControlKeyBit, QT_MAC_MAP_ENUM(Qt::Key_Meta) }, //???
212  { cmdKeyBit, QT_MAC_MAP_ENUM(Qt::Key_Control) },
213  { optionKeyBit, QT_MAC_MAP_ENUM(Qt::Key_Alt) },
214  { rightOptionKeyBit, QT_MAC_MAP_ENUM(Qt::Key_Alt) }, //???
215  { alphaLockBit, QT_MAC_MAP_ENUM(Qt::Key_CapsLock) },
216  { kEventKeyModifierNumLockBit, QT_MAC_MAP_ENUM(Qt::Key_NumLock) },
217  { 0, QT_MAC_MAP_ENUM(0) } };
218  for (int i = 0; i <= 32; i++) { //just check each bit
219  if (!(changedModifiers & (1 << i)))
220  continue;
222  if (lastModifiers & (1 << i))
223  etype = QEvent::KeyRelease;
224  int key = 0;
225  for (uint x = 0; modifier_key_symbols[x].mac_code; x++) {
226  if (modifier_key_symbols[x].mac_code == i) {
227 #ifdef DEBUG_KEY_BINDINGS_MODIFIERS
228  qDebug("got modifier changed: %s", modifier_key_symbols[x].desc);
229 #endif
230  key = modifier_key_symbols[x].qt_code;
231  break;
232  }
233  }
234  if (!key) {
235 #ifdef DEBUG_KEY_BINDINGS_MODIFIERS
236  qDebug("could not get modifier changed: %d", i);
237 #endif
238  continue;
239  }
240 #ifdef DEBUG_KEY_BINDINGS_MODIFIERS
241  qDebug("KeyEvent (modif): Sending %s to %s::%s: %d - 0x%08x",
242  etype == QEvent::KeyRelease ? "KeyRelease" : "KeyPress",
243  object ? object->metaObject()->className() : "none",
244  object ? object->objectName().toLatin1().constData() : "",
245  key, (int)modifiers);
246 #endif
247  QKeyEvent ke(etype, key, qt_mac_get_modifiers(modifiers ^ (1 << i)), QLatin1String(""));
248  qt_sendSpontaneousEvent(object, &ke);
249  }
250 }
251 
252 //keyboard keys (non-modifiers)
254  { kHomeCharCode, QT_MAC_MAP_ENUM(Qt::Key_Home) },
255  { kEnterCharCode, QT_MAC_MAP_ENUM(Qt::Key_Enter) },
256  { kEndCharCode, QT_MAC_MAP_ENUM(Qt::Key_End) },
257  { kBackspaceCharCode, QT_MAC_MAP_ENUM(Qt::Key_Backspace) },
258  { kTabCharCode, QT_MAC_MAP_ENUM(Qt::Key_Tab) },
259  { kPageUpCharCode, QT_MAC_MAP_ENUM(Qt::Key_PageUp) },
260  { kPageDownCharCode, QT_MAC_MAP_ENUM(Qt::Key_PageDown) },
261  { kReturnCharCode, QT_MAC_MAP_ENUM(Qt::Key_Return) },
262  { kEscapeCharCode, QT_MAC_MAP_ENUM(Qt::Key_Escape) },
263  { kLeftArrowCharCode, QT_MAC_MAP_ENUM(Qt::Key_Left) },
264  { kRightArrowCharCode, QT_MAC_MAP_ENUM(Qt::Key_Right) },
265  { kUpArrowCharCode, QT_MAC_MAP_ENUM(Qt::Key_Up) },
266  { kDownArrowCharCode, QT_MAC_MAP_ENUM(Qt::Key_Down) },
267  { kHelpCharCode, QT_MAC_MAP_ENUM(Qt::Key_Help) },
268  { kDeleteCharCode, QT_MAC_MAP_ENUM(Qt::Key_Delete) },
269 //ascii maps, for debug
270  { ':', QT_MAC_MAP_ENUM(Qt::Key_Colon) },
272  { '<', QT_MAC_MAP_ENUM(Qt::Key_Less) },
273  { '=', QT_MAC_MAP_ENUM(Qt::Key_Equal) },
276  { '@', QT_MAC_MAP_ENUM(Qt::Key_At) },
277  { ' ', QT_MAC_MAP_ENUM(Qt::Key_Space) },
288  { '+', QT_MAC_MAP_ENUM(Qt::Key_Plus) },
289  { ',', QT_MAC_MAP_ENUM(Qt::Key_Comma) },
290  { '-', QT_MAC_MAP_ENUM(Qt::Key_Minus) },
292  { '/', QT_MAC_MAP_ENUM(Qt::Key_Slash) },
300  { '|', QT_MAC_MAP_ENUM(Qt::Key_Bar) },
303  { 0, QT_MAC_MAP_ENUM(0) }
304 };
305 
306 static qt_mac_enum_mapper qt_mac_keyvkey_symbols[] = { //real scan codes
307  { 122, QT_MAC_MAP_ENUM(Qt::Key_F1) },
308  { 120, QT_MAC_MAP_ENUM(Qt::Key_F2) },
309  { 99, QT_MAC_MAP_ENUM(Qt::Key_F3) },
310  { 118, QT_MAC_MAP_ENUM(Qt::Key_F4) },
311  { 96, QT_MAC_MAP_ENUM(Qt::Key_F5) },
312  { 97, QT_MAC_MAP_ENUM(Qt::Key_F6) },
313  { 98, QT_MAC_MAP_ENUM(Qt::Key_F7) },
314  { 100, QT_MAC_MAP_ENUM(Qt::Key_F8) },
315  { 101, QT_MAC_MAP_ENUM(Qt::Key_F9) },
316  { 109, QT_MAC_MAP_ENUM(Qt::Key_F10) },
317  { 103, QT_MAC_MAP_ENUM(Qt::Key_F11) },
318  { 111, QT_MAC_MAP_ENUM(Qt::Key_F12) },
319  { 105, QT_MAC_MAP_ENUM(Qt::Key_F13) },
320  { 107, QT_MAC_MAP_ENUM(Qt::Key_F14) },
321  { 113, QT_MAC_MAP_ENUM(Qt::Key_F15) },
322  { 106, QT_MAC_MAP_ENUM(Qt::Key_F16) },
323  { 0, QT_MAC_MAP_ENUM(0) }
324 };
325 
327  { 0xF700, QT_MAC_MAP_ENUM(Qt::Key_Up) }, //NSUpArrowFunctionKey
328  { 0xF701, QT_MAC_MAP_ENUM(Qt::Key_Down) }, //NSDownArrowFunctionKey
329  { 0xF702, QT_MAC_MAP_ENUM(Qt::Key_Left) }, //NSLeftArrowFunctionKey
330  { 0xF703, QT_MAC_MAP_ENUM(Qt::Key_Right) }, //NSRightArrowFunctionKey
331  { 0xF727, QT_MAC_MAP_ENUM(Qt::Key_Insert) }, //NSInsertFunctionKey
332  { 0xF728, QT_MAC_MAP_ENUM(Qt::Key_Delete) }, //NSDeleteFunctionKey
333  { 0xF729, QT_MAC_MAP_ENUM(Qt::Key_Home) }, //NSHomeFunctionKey
334  { 0xF72B, QT_MAC_MAP_ENUM(Qt::Key_End) }, //NSEndFunctionKey
335  { 0xF72C, QT_MAC_MAP_ENUM(Qt::Key_PageUp) }, //NSPageUpFunctionKey
336  { 0xF72D, QT_MAC_MAP_ENUM(Qt::Key_PageDown) }, //NSPageDownFunctionKey
337  { 0xF72F, QT_MAC_MAP_ENUM(Qt::Key_ScrollLock) }, //NSScrollLockFunctionKey
338  { 0xF730, QT_MAC_MAP_ENUM(Qt::Key_Pause) }, //NSPauseFunctionKey
339  { 0xF731, QT_MAC_MAP_ENUM(Qt::Key_SysReq) }, //NSSysReqFunctionKey
340  { 0xF735, QT_MAC_MAP_ENUM(Qt::Key_Menu) }, //NSMenuFunctionKey
341  { 0xF738, QT_MAC_MAP_ENUM(Qt::Key_Print) }, //NSPrintFunctionKey
342  { 0xF73A, QT_MAC_MAP_ENUM(Qt::Key_Clear) }, //NSClearDisplayFunctionKey
343  { 0xF73D, QT_MAC_MAP_ENUM(Qt::Key_Insert) }, //NSInsertCharFunctionKey
344  { 0xF73E, QT_MAC_MAP_ENUM(Qt::Key_Delete) }, //NSDeleteCharFunctionKey
345  { 0xF741, QT_MAC_MAP_ENUM(Qt::Key_Select) }, //NSSelectFunctionKey
346  { 0xF742, QT_MAC_MAP_ENUM(Qt::Key_Execute) }, //NSExecuteFunctionKey
347  { 0xF746, QT_MAC_MAP_ENUM(Qt::Key_Help) }, //NSHelpFunctionKey
348  { 0xF747, QT_MAC_MAP_ENUM(Qt::Key_Mode_switch) }, //NSModeSwitchFunctionKey
349  { 0, QT_MAC_MAP_ENUM(0) }
350 };
351 
352 static int qt_mac_get_key(int modif, const QChar &key, int virtualKey)
353 {
354 #ifdef DEBUG_KEY_BINDINGS
355  qDebug("**Mapping key: %d (0x%04x) - %d (0x%04x)", key.unicode(), key.unicode(), virtualKey, virtualKey);
356 #endif
357 
358  if (key == kClearCharCode && virtualKey == 0x47)
359  return Qt::Key_Clear;
360 
361  if (key.isDigit()) {
362 #ifdef DEBUG_KEY_BINDINGS
363  qDebug("%d: got key: %d", __LINE__, key.digitValue());
364 #endif
365  return key.digitValue() + Qt::Key_0;
366  }
367 
368  if (key.isLetter()) {
369 #ifdef DEBUG_KEY_BINDINGS
370  qDebug("%d: got key: %d", __LINE__, (key.toUpper().unicode() - 'A'));
371 #endif
372  return (key.toUpper().unicode() - 'A') + Qt::Key_A;
373  }
374  if (key.isSymbol()) {
375 #ifdef DEBUG_KEY_BINDINGS
376  qDebug("%d: got key: %d", __LINE__, (key.unicode()));
377 #endif
378  return key.unicode();
379  }
380 
381  for (int i = 0; qt_mac_keyboard_symbols[i].qt_code; i++) {
382  if (qt_mac_keyboard_symbols[i].mac_code == key) {
383  /* To work like Qt for X11 we issue Backtab when Shift + Tab are pressed */
384  if (qt_mac_keyboard_symbols[i].qt_code == Qt::Key_Tab && (modif & Qt::ShiftModifier)) {
385 #ifdef DEBUG_KEY_BINDINGS
386  qDebug("%d: got key: Qt::Key_Backtab", __LINE__);
387 #endif
388  return Qt::Key_Backtab;
389  }
390 
391 #ifdef DEBUG_KEY_BINDINGS
392  qDebug("%d: got key: %s", __LINE__, qt_mac_keyboard_symbols[i].desc);
393 #endif
394  return qt_mac_keyboard_symbols[i].qt_code;
395  }
396  }
397 
398  //last ditch try to match the scan code
399  for (int i = 0; qt_mac_keyvkey_symbols[i].qt_code; i++) {
400  if (qt_mac_keyvkey_symbols[i].mac_code == virtualKey) {
401 #ifdef DEBUG_KEY_BINDINGS
402  qDebug("%d: got key: %s", __LINE__, qt_mac_keyvkey_symbols[i].desc);
403 #endif
404  return qt_mac_keyvkey_symbols[i].qt_code;
405  }
406  }
407 
408  // check if they belong to key codes in private unicode range
409  if (key >= 0xf700 && key <= 0xf747) {
410  if (key >= 0xf704 && key <= 0xf726) {
411  return Qt::Key_F1 + (key.unicode() - 0xf704) ;
412  }
413  for (int i = 0; qt_mac_private_unicode[i].qt_code; i++) {
414  if (qt_mac_private_unicode[i].mac_code == key) {
415  return qt_mac_private_unicode[i].qt_code;
416  }
417  }
418 
419  }
420 
421  //oh well
422 #ifdef DEBUG_KEY_BINDINGS
423  qDebug("Unknown case.. %s:%d %d[%d] %d", __FILE__, __LINE__, key.unicode(), key.toLatin1(), virtualKey);
424 #endif
425  return Qt::Key_unknown;
426 }
427 
429 {
430  UInt32 ekind = GetEventKind(inEvent),
431  eclass = GetEventClass(inEvent);
432  return (eclass == kEventClassKeyboard && (void *)ekind == data);
433 }
434 
436  QChar *outChar, Qt::KeyboardModifiers *outModifiers, bool *outHandled)
437 {
438 #if !defined(QT_MAC_USE_COCOA) || defined(Q_OS_MAC64)
439  Q_UNUSED(er);
440  Q_UNUSED(outHandled);
441 #endif
442  const UInt32 ekind = GetEventKind(keyEvent);
443  {
444  UInt32 mac_modifiers = 0;
445  GetEventParameter(keyEvent, kEventParamKeyModifiers, typeUInt32, 0,
446  sizeof(mac_modifiers), 0, &mac_modifiers);
447 #ifdef DEBUG_KEY_BINDINGS_MODIFIERS
448  qDebug("************ Mapping modifiers and key ***********");
449 #endif
450  *outModifiers = qt_mac_get_modifiers(mac_modifiers);
451 #ifdef DEBUG_KEY_BINDINGS_MODIFIERS
452  qDebug("------------ Mapping modifiers and key -----------");
453 #endif
454  }
455 
456  //get keycode
457  UInt32 keyCode = 0;
458  GetEventParameter(keyEvent, kEventParamKeyCode, typeUInt32, 0, sizeof(keyCode), 0, &keyCode);
459 
460  //get mac mapping
461  static UInt32 tmp_unused_state = 0L;
462  const UCKeyboardLayout *uchrData = 0;
463 #if defined(Q_OS_MAC32)
464  KeyboardLayoutRef keyLayoutRef = 0;
465  KLGetCurrentKeyboardLayout(&keyLayoutRef);
466  OSStatus err;
467  if (keyLayoutRef != 0) {
468  err = KLGetKeyboardLayoutProperty(keyLayoutRef, kKLuchrData,
469  (reinterpret_cast<const void **>(&uchrData)));
470  if (err != noErr) {
471  qWarning("Qt::internal::unable to get keyboardlayout %ld %s:%d",
472  long(err), __FILE__, __LINE__);
473  }
474  }
475 #else
476  QCFType<TISInputSourceRef> inputSource = TISCopyCurrentKeyboardInputSource();
477  Q_ASSERT(inputSource != 0);
478  CFDataRef data = static_cast<CFDataRef>(TISGetInputSourceProperty(inputSource,
479  kTISPropertyUnicodeKeyLayoutData));
480  uchrData = data ? reinterpret_cast<const UCKeyboardLayout *>(CFDataGetBytePtr(data)) : 0;
481 #endif
482  *qtKey = Qt::Key_unknown;
483  if (uchrData) {
484  // The easy stuff; use the unicode stuff!
485  UniChar string[4];
486  UniCharCount actualLength;
487  UInt32 currentModifiers = GetCurrentEventKeyModifiers();
488  UInt32 currentModifiersWOAltOrControl = currentModifiers & ~(controlKey | optionKey);
489  int keyAction;
490  switch (ekind) {
491  default:
492  case kEventRawKeyDown:
493  keyAction = kUCKeyActionDown;
494  break;
495  case kEventRawKeyUp:
496  keyAction = kUCKeyActionUp;
497  break;
498  case kEventRawKeyRepeat:
499  keyAction = kUCKeyActionAutoKey;
500  break;
501  }
502  OSStatus err = UCKeyTranslate(uchrData, keyCode, keyAction,
503  ((currentModifiersWOAltOrControl >> 8) & 0xff), LMGetKbdType(),
504  kUCKeyTranslateNoDeadKeysMask, &tmp_unused_state, 4, &actualLength,
505  string);
506  if (err == noErr) {
507  *outChar = QChar(string[0]);
508  *qtKey = qt_mac_get_key(*outModifiers, *outChar, keyCode);
509  if (currentModifiersWOAltOrControl != currentModifiers) {
510  // Now get the real char.
511  err = UCKeyTranslate(uchrData, keyCode, keyAction,
512  ((currentModifiers >> 8) & 0xff), LMGetKbdType(),
513  kUCKeyTranslateNoDeadKeysMask, &tmp_unused_state, 4, &actualLength,
514  string);
515  if (err == noErr)
516  *outChar = QChar(string[0]);
517  }
518  } else {
519  qWarning("Qt::internal::UCKeyTranslate is returnining %ld %s:%d",
520  long(err), __FILE__, __LINE__);
521  }
522  }
523 #ifdef Q_OS_MAC32
524  else {
525  // The road less travelled; use KeyTranslate
526  const void *keyboard_layout;
527  KeyboardLayoutRef keyLayoutRef = 0;
528  KLGetCurrentKeyboardLayout(&keyLayoutRef);
529  err = KLGetKeyboardLayoutProperty(keyLayoutRef, kKLKCHRData,
530  reinterpret_cast<const void **>(&keyboard_layout));
531 
532  int translatedChar = KeyTranslate(keyboard_layout, (GetCurrentEventKeyModifiers() &
533  (kEventKeyModifierNumLockMask|shiftKey|cmdKey|
534  rightShiftKey|alphaLock)) | keyCode,
535  &tmp_unused_state);
536  if (!translatedChar) {
537 #ifdef QT_MAC_USE_COCOA
538  if (outHandled) {
539  qt_mac_eat_unicode_key = false;
540  if (er)
541  CallNextEventHandler(er, keyEvent);
542  *outHandled = qt_mac_eat_unicode_key;
543  }
544 #endif
545  return false;
546  }
547 
548  //map it into qt keys
549  *qtKey = qt_mac_get_key(*outModifiers, QChar(translatedChar), keyCode);
550  if (*outModifiers & (Qt::AltModifier | Qt::ControlModifier)) {
551  if (translatedChar & (1 << 7)) //high ascii
552  translatedChar = 0;
553  } else { //now get the real ascii value
554  UInt32 tmp_mod = 0L;
555  static UInt32 tmp_state = 0L;
556  if (*outModifiers & Qt::ShiftModifier)
557  tmp_mod |= shiftKey;
558  if (*outModifiers & Qt::MetaModifier)
559  tmp_mod |= controlKey;
560  if (*outModifiers & Qt::ControlModifier)
561  tmp_mod |= cmdKey;
562  if (GetCurrentEventKeyModifiers() & alphaLock) //no Qt mapper
563  tmp_mod |= alphaLock;
564  if (*outModifiers & Qt::AltModifier)
565  tmp_mod |= optionKey;
566  if (*outModifiers & Qt::KeypadModifier)
567  tmp_mod |= kEventKeyModifierNumLockMask;
568  translatedChar = KeyTranslate(keyboard_layout, tmp_mod | keyCode, &tmp_state);
569  }
570  {
571  ByteCount unilen = 0;
572  if (GetEventParameter(keyEvent, kEventParamKeyUnicodes, typeUnicodeText, 0, 0, &unilen, 0)
573  == noErr && unilen == 2) {
574  GetEventParameter(keyEvent, kEventParamKeyUnicodes, typeUnicodeText, 0, unilen, 0, outChar);
575  } else if (translatedChar) {
576  static QTextCodec *c = 0;
577  if (!c)
578  c = QTextCodec::codecForName("Apple Roman");
579  char tmpChar = (char)translatedChar; // **sigh**
580  *outChar = c->toUnicode(&tmpChar, 1).at(0);
581  } else {
582  *qtKey = qt_mac_get_key(*outModifiers, QChar(translatedChar), keyCode);
583  }
584  }
585  }
586 #endif
587  if (*qtKey == Qt::Key_unknown)
588  *qtKey = qt_mac_get_key(*outModifiers, *outChar, keyCode);
589  return true;
590 }
591 
593 {
594  memset(keyLayout, 0, sizeof(keyLayout));
595  keyboard_layout_format.unicode = 0;
596 #ifdef Q_OS_MAC32
597  keyboard_mode = NullMode;
598 #else
599  currentInputSource = 0;
600 #endif
601 }
602 
604 {
605  deleteLayouts();
606 }
607 
608 bool
609 QKeyMapperPrivate::updateKeyboard()
610 {
611  const UCKeyboardLayout *uchrData = 0;
612 #ifdef Q_OS_MAC32
613  KeyboardLayoutRef keyLayoutRef = 0;
614  KLGetCurrentKeyboardLayout(&keyLayoutRef);
615 
616  if (keyboard_mode != NullMode && currentKeyboardLayout == keyLayoutRef)
617  return false;
618 
619  OSStatus err;
620  if (keyLayoutRef != 0) {
621  err = KLGetKeyboardLayoutProperty(keyLayoutRef, kKLuchrData,
622  const_cast<const void **>(reinterpret_cast<const void **>(&uchrData)));
623  if (err != noErr) {
624  qWarning("Qt::internal::unable to get unicode keyboardlayout %ld %s:%d",
625  long(err), __FILE__, __LINE__);
626  }
627  }
628 #else
629  QCFType<TISInputSourceRef> source = TISCopyCurrentKeyboardInputSource();
630  if (keyboard_mode != NullMode && source == currentInputSource) {
631  return false;
632  }
633  Q_ASSERT(source != 0);
634  CFDataRef data = static_cast<CFDataRef>(TISGetInputSourceProperty(source,
635  kTISPropertyUnicodeKeyLayoutData));
636  uchrData = data ? reinterpret_cast<const UCKeyboardLayout *>(CFDataGetBytePtr(data)) : 0;
637 #endif
638 
639  keyboard_kind = LMGetKbdType();
640  if (uchrData) {
641  keyboard_layout_format.unicode = uchrData;
642  keyboard_mode = UnicodeMode;
643  }
644 #ifdef Q_OS_MAC32
645  else {
646  void *happy;
647  err = KLGetKeyboardLayoutProperty(keyLayoutRef, kKLKCHRData,
648  const_cast<const void **>(reinterpret_cast<void **>(&happy)));
649  if (err != noErr) {
650  qFatal("Qt::internal::unable to get non-unicode layout, cannot procede %ld %s:%d",
651  long(err), __FILE__, __LINE__);
652  }
653  keyboard_layout_format.other = happy;
654  keyboard_mode = OtherMode;
655  }
656 
657  currentKeyboardLayout = keyLayoutRef;
658 #else
659  currentInputSource = source;
660 #endif
661  keyboard_dead = 0;
662  CFStringRef iso639Code;
663 #ifdef Q_OS_MAC32
664 # ifndef kKLLanguageCode
665 # define kKLLanguageCode 9
666 # endif
667  KLGetKeyboardLayoutProperty(currentKeyboardLayout, kKLLanguageCode,
668  reinterpret_cast<const void **>(&iso639Code));
669 #else
670  CFArrayRef array = static_cast<CFArrayRef>(TISGetInputSourceProperty(currentInputSource, kTISPropertyInputSourceLanguages));
671  iso639Code = static_cast<CFStringRef>(CFArrayGetValueAtIndex(array, 0)); // Actually a RFC3066bis, but it's close enough
672 #endif
673  if (iso639Code) {
674  keyboardInputLocale = QLocale(QCFString::toQString(iso639Code));
675  keyboardInputDirection = keyboardInputLocale.textDirection();
676  } else {
677  keyboardInputLocale = QLocale::c();
678  keyboardInputDirection = Qt::LeftToRight;
679  }
680  return true;
681 }
682 
683 void
685 {
686  keyboard_mode = NullMode;
687  for (int i = 0; i < 255; ++i) {
688  if (keyLayout[i]) {
689  delete keyLayout[i];
690  keyLayout[i] = 0;
691  }
692  }
693 }
694 
695 void
697 {
698  deleteLayouts();
699  updateKeyboard();
700 }
701 
704 {
705  QList<int> ret;
706 
707  KeyboardLayoutItem *kbItem = keyLayout[e->nativeVirtualKey()];
708  if (!kbItem) // Key is not in any keyboard layout (e.g. eisu-key on Japanese keyboard)
709  return ret;
710 
711  int baseKey = kbItem->qtKey[0];
712  Qt::KeyboardModifiers keyMods = e->modifiers();
713  ret << int(baseKey + keyMods); // The base key is _always_ valid, of course
714 
715  for (int i = 1; i < 8; ++i) {
716  Qt::KeyboardModifiers neededMods = ModsTbl[i];
717  int key = kbItem->qtKey[i];
718  if (key && key != baseKey && ((keyMods & neededMods) == neededMods))
719  ret << int(key + (keyMods & ~neededMods));
720  }
721 
722  return ret;
723 }
724 
726  void *info, bool grab)
727 {
728  Q_ASSERT(GetEventClass(event) == kEventClassKeyboard);
729  bool handled_event=true;
730  UInt32 ekind = GetEventKind(event);
731 
732  // unfortunately modifiers changed event looks quite different, so I have a separate
733  // code path
734  if (ekind == kEventRawKeyModifiersChanged) {
735  //figure out changed modifiers, wish Apple would just send a delta
736  UInt32 modifiers = 0;
737  GetEventParameter(event, kEventParamKeyModifiers, typeUInt32, 0,
738  sizeof(modifiers), 0, &modifiers);
739  qt_mac_send_modifiers_changed(modifiers, widget);
740  return true;
741  }
742 #ifndef QT_NO_IM
743  QInputContext *currentContext = qApp->inputContext();
744  if (currentContext && currentContext->isComposing()) {
745  if (ekind == kEventRawKeyDown) {
746  QMacInputContext *context = qobject_cast<QMacInputContext*>(currentContext);
747  if (context)
748  context->setLastKeydownEvent(event);
749  }
750  return false;
751  }
752  // Once we process the key down , we don't need to send the saved event again from
753  // kEventTextInputUnicodeForKeyEvent, so clear it.
754  if (currentContext && ekind == kEventRawKeyDown) {
755  QMacInputContext *context = qobject_cast<QMacInputContext*>(currentContext);
756  if (context)
757  context->setLastKeydownEvent(0);
758  }
759 #endif
760  //get modifiers
761  Qt::KeyboardModifiers modifiers;
762  int qtKey;
763  QChar ourChar;
764  if (translateKeyEventInternal(er, event, &qtKey, &ourChar, &modifiers,
765  &handled_event) == false)
766  return handled_event;
767  QString text(ourChar);
768  /* This is actually wrong - but unfortunately it is the best that can be
769  done for now because of the Control/Meta mapping problems */
770  if (modifiers & (Qt::ControlModifier | Qt::MetaModifier)
771  && !qApp->testAttribute(Qt::AA_MacDontSwapCtrlAndMeta)) {
772  text = QString();
773  }
774 
775 
776  if (widget) {
777 #ifndef QT_MAC_USE_COCOA
778  Q_UNUSED(info);
779  // Try not to call "other" event handlers if we have a popup,
780  // However, if the key has text
781  // then we should pass it along because otherwise then people
782  // can use input method stuff.
783  if (!qApp->activePopupWidget()
784  || (qApp->activePopupWidget() && !text.isEmpty())) {
785  //Find out if someone else wants the event, namely
786  //is it of use to text services? If so we won't bother
787  //with a QKeyEvent.
788  qt_mac_eat_unicode_key = false;
789  if (er)
790  CallNextEventHandler(er, event);
791  extern bool qt_mac_menubar_is_open();
793  return true;
794  }
795  }
796 #endif
797  // Try to compress key events.
798  if (!text.isEmpty() && widget->testAttribute(Qt::WA_KeyCompression)) {
799  EventTime lastTime = GetEventTime(event);
800  for (;;) {
801  EventRef releaseEvent = FindSpecificEventInQueue(GetMainEventQueue(),
803  (void*)kEventRawKeyUp);
804  if (!releaseEvent)
805  break;
806  const EventTime releaseTime = GetEventTime(releaseEvent);
807  if (releaseTime < lastTime)
808  break;
809  lastTime = releaseTime;
810 
811  EventRef pressEvent = FindSpecificEventInQueue(GetMainEventQueue(),
813  (void*)kEventRawKeyDown);
814  if (!pressEvent)
815  break;
816  const EventTime pressTime = GetEventTime(pressEvent);
817  if (pressTime < lastTime)
818  break;
819  lastTime = pressTime;
820 
821  Qt::KeyboardModifiers compressMod;
822  int compressQtKey = 0;
823  QChar compressChar;
824  if (translateKeyEventInternal(er, pressEvent,
825  &compressQtKey, &compressChar, &compressMod, 0)
826  == false) {
827  break;
828  }
829  // Copied from qapplication_x11.cpp (change both).
830 
831  bool stopCompression =
832  // 1) misc keys
833  (compressQtKey >= Qt::Key_Escape && compressQtKey <= Qt::Key_SysReq)
834  // 2) cursor movement
835  || (compressQtKey >= Qt::Key_Home && compressQtKey <= Qt::Key_PageDown)
836  // 3) extra keys
837  || (compressQtKey >= Qt::Key_Super_L && compressQtKey <= Qt::Key_Direction_R)
838  // 4) something that a) doesn't translate to text or b) translates
839  // to newline text
840  || (compressQtKey == 0)
841  || (compressChar == QLatin1Char('\n'))
842  || (compressQtKey == Qt::Key_unknown);
843 
844  if (compressMod == modifiers && !compressChar.isNull() && !stopCompression) {
845 #ifdef DEBUG_KEY_BINDINGS
846  qDebug("compressing away %c", compressChar.toLatin1());
847 #endif
848  text += compressChar;
849  // Clean up
850  RemoveEventFromQueue(GetMainEventQueue(), releaseEvent);
851  RemoveEventFromQueue(GetMainEventQueue(), pressEvent);
852  } else {
853 #ifdef DEBUG_KEY_BINDINGS
854  qDebug("stoping compression..");
855 #endif
856  break;
857  }
858  }
859  }
860 
861  // There is no way to get the scan code from carbon. But we cannot use the value 0, since
862  // it indicates that the event originates from somewhere else than the keyboard
863  UInt32 macScanCode = 1;
864  UInt32 macVirtualKey = 0;
865  GetEventParameter(event, kEventParamKeyCode, typeUInt32, 0, sizeof(macVirtualKey), 0, &macVirtualKey);
866  UInt32 macModifiers = 0;
867  GetEventParameter(event, kEventParamKeyModifiers, typeUInt32, 0,
868  sizeof(macModifiers), 0, &macModifiers);
869 #ifdef QT_MAC_USE_COCOA
870  // The unicode characters in the range 0xF700-0xF747 are reserved
871  // by Mac OS X for transient use as keyboard function keys. We
872  // wont send 'text' for such key events. This is done to match
873  // behavior on other platforms.
874  unsigned int *unicodeKey = (unsigned int*)info;
875  if (*unicodeKey >= 0xf700 && *unicodeKey <= 0xf747)
876  text = QString();
877  bool isAccepted;
878 #endif
879  handled_event = QKeyMapper::sendKeyEvent(widget, grab,
880  (ekind == kEventRawKeyUp) ? QEvent::KeyRelease : QEvent::KeyPress,
881  qtKey, modifiers, text, ekind == kEventRawKeyRepeat, 0,
882  macScanCode, macVirtualKey, macModifiers
883 #ifdef QT_MAC_USE_COCOA
884  ,&isAccepted
885 #endif
886  );
887 #ifdef QT_MAC_USE_COCOA
888  *unicodeKey = (unsigned int)isAccepted;
889 #endif
890  }
891  return handled_event;
892 }
893 
894 void
896 #if defined(QT_MAC_USE_COCOA)
897  unicodeKey // unicode character from NSEvent (modifiers applied)
898 #endif
899  )
900 {
901  UInt32 macVirtualKey = 0;
902  GetEventParameter(event, kEventParamKeyCode, typeUInt32, 0, sizeof(macVirtualKey), 0, &macVirtualKey);
903  if (updateKeyboard())
905  else if (keyLayout[macVirtualKey])
906  return;
907 
908  UniCharCount buffer_size = 10;
909  UniChar buffer[buffer_size];
910  keyLayout[macVirtualKey] = new KeyboardLayoutItem;
911  for (int i = 0; i < 16; ++i) {
912  UniCharCount out_buffer_size = 0;
913  keyLayout[macVirtualKey]->qtKey[i] = 0;
914 #ifdef Q_WS_MAC32
915  if (keyboard_mode == UnicodeMode) {
916 #endif
917  const UInt32 keyModifier = ((qt_mac_get_mac_modifiers(ModsTbl[i]) >> 8) & 0xFF);
918  OSStatus err = UCKeyTranslate(keyboard_layout_format.unicode, macVirtualKey, kUCKeyActionDown, keyModifier,
919  keyboard_kind, 0, &keyboard_dead, buffer_size, &out_buffer_size, buffer);
920  if (err == noErr && out_buffer_size) {
921  const QChar unicode(buffer[0]);
922  int qtkey = qt_mac_get_key(keyModifier, unicode, macVirtualKey);
923  if (qtkey == Qt::Key_unknown)
924  qtkey = unicode.unicode();
925  keyLayout[macVirtualKey]->qtKey[i] = qtkey;
926  }
927 #ifndef Q_WS_MAC32
928  else {
929  const QChar unicode(*((UniChar *)unicodeKey));
930  int qtkey = qt_mac_get_key(keyModifier, unicode, macVirtualKey);
931  if (qtkey == Qt::Key_unknown)
932  qtkey = unicode.unicode();
933  keyLayout[macVirtualKey]->qtKey[i] = qtkey;
934  }
935 #endif
936 #ifdef Q_WS_MAC32
937  } else {
938  const UInt32 keyModifier = (qt_mac_get_mac_modifiers(ModsTbl[i]));
939 
940  uchar translatedChar = KeyTranslate(keyboard_layout_format.other, keyModifier | macVirtualKey, &keyboard_dead);
941  if (translatedChar) {
942  static QTextCodec *c = 0;
943  if (!c)
944  c = QTextCodec::codecForName("Apple Roman");
945  const QChar unicode(c->toUnicode((const char *)&translatedChar, 1).at(0));
946  int qtkey = qt_mac_get_key(keyModifier, unicode, macVirtualKey);
947  if (qtkey == Qt::Key_unknown)
948  qtkey = unicode.unicode();
949  keyLayout[macVirtualKey]->qtKey[i] = qtkey;
950  }
951  }
952 #endif
953  }
954 #ifdef DEBUG_KEY_MAPS
955  qDebug("updateKeyMap for virtual key = 0x%02x!", (uint)macVirtualKey);
956  for (int i = 0; i < 16; ++i) {
957  qDebug(" [%d] (%d,0x%02x,'%c')", i,
958  keyLayout[macVirtualKey]->qtKey[i],
959  keyLayout[macVirtualKey]->qtKey[i],
960  keyLayout[macVirtualKey]->qtKey[i]);
961  }
962 #endif
963 }
964 
965 bool
967  QEvent::Type type, int code, Qt::KeyboardModifiers modifiers,
968  const QString &text, bool autorepeat, int count,
969  quint32 nativeScanCode, quint32 nativeVirtualKey,
970  quint32 nativeModifiers, bool *isAccepted)
971 {
972  Q_UNUSED(count);
973  if (widget && widget->isEnabled()) {
974  bool key_event = true;
975 #if defined(QT3_SUPPORT) && !defined(QT_NO_SHORTCUT)
976  if (type == QEvent::KeyPress && !grab
977  && QApplicationPrivate::instance()->use_compat()) {
978  QKeyEventEx accel_ev(type, code, modifiers,
979  text, autorepeat, qMax(1, int(text.length())),
980  nativeScanCode, nativeVirtualKey, nativeModifiers);
981  if (QApplicationPrivate::instance()->qt_tryAccelEvent(widget, &accel_ev)) {
982 #if defined(DEBUG_KEY_BINDINGS) || defined(DEBUG_KEY_BINDINGS_MODIFIERS)
983  qDebug("KeyEvent: %s::%s consumed Accel: %s",
984  widget ? widget->metaObject()->className() : "none",
985  widget ? widget->objectName().toLatin1().constData() : "",
986  text.toLatin1().constData());
987 #endif
988  key_event = false;
989  } else {
990  if (accel_ev.isAccepted()) {
991 #if defined(DEBUG_KEY_BINDINGS) || defined(DEBUG_KEY_BINDINGS_MODIFIERS)
992  qDebug("KeyEvent: %s::%s overrode Accel: %s",
993  widget ? widget->metaObject()->className() : "none",
994  widget ? widget->objectName().toLatin1().constData() : "",
995  text.toLatin1().constData());
996 #endif
997  }
998  }
999  }
1000 #else
1001 Q_UNUSED(grab);
1002 #endif // QT3_SUPPORT && !QT_NO_SHORTCUT
1003  if (key_event) {
1004 #if defined(DEBUG_KEY_BINDINGS) || defined(DEBUG_KEY_BINDINGS_MODIFIERS)
1005  qDebug("KeyEvent: Sending %s to %s::%s: %s 0x%08x%s",
1006  type == QEvent::KeyRelease ? "KeyRelease" : "KeyPress",
1007  widget ? widget->metaObject()->className() : "none",
1008  widget ? widget->objectName().toLatin1().constData() : "",
1009  text.toLatin1().constData(), int(modifiers),
1010  autorepeat ? " Repeat" : "");
1011 #endif
1012  QKeyEventEx ke(type, code, modifiers, text, autorepeat, qMax(1, text.length()),
1013  nativeScanCode, nativeVirtualKey, nativeModifiers);
1014  bool retMe = qt_sendSpontaneousEvent(widget,&ke);
1015  if (isAccepted)
1016  *isAccepted = ke.isAccepted();
1017  return retMe;
1018  }
1019  }
1020  return false;
1021 }
1022 
T qobject_cast(QObject *object)
Definition: qobject.h:375
static int qt_mac_get_mac_modifiers(Qt::KeyboardModifiers keys)
const struct __CFString * CFStringRef
The QKeyEvent class describes a key event.
Definition: qevent.h:224
int type
Definition: qmetatype.cpp:239
bool isLetter() const
Returns true if the character is a letter (Letter_* categories); otherwise returns false...
Definition: qchar.cpp:653
static mach_timebase_info_data_t info
unsigned char c[8]
Definition: qnumeric_p.h:62
#define QT_END_NAMESPACE
This macro expands to.
Definition: qglobal.h:90
EventRef event
QPointer< QWidget > widget
int digitValue() const
Returns the numeric value of the digit, or -1 if the character is not a digit.
Definition: qchar.cpp:817
const QChar at(int i) const
Returns the character at the given index position in the string.
Definition: qstring.h:698
static void keyEvent(KeyAction action, QWidget *widget, char ascii, Qt::KeyboardModifiers modifier=Qt::NoModifier, int delay=-1)
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 the character is the Unicode character 0x0000 (&#39;\0&#39;); otherwise returns false...
Definition: qchar.h:262
#define Q_GUI_EXPORT
Definition: qglobal.h:1450
int length() const
Returns the number of characters in this string.
Definition: qstring.h:696
The QWidget class is the base class of all user interface objects.
Definition: qwidget.h:150
Qt::KeyboardModifiers qt_mac_get_modifiers(int keys)
virtual bool isComposing() const =0
This function indicates whether InputMethodStart event had been sent to the current focus widget...
static QString toQString(CFStringRef cfstr)
Definition: qcore_mac.cpp:47
QLatin1String(DBUS_INTERFACE_DBUS))) Q_GLOBAL_STATIC_WITH_ARGS(QString
static QApplicationPrivate * instance()
KeyboardModifier
Definition: qnamespace.h:127
The QString class provides a Unicode character string.
Definition: qstring.h:83
void updateKeyMap(const MSG &msg)
bool isSymbol() const
Returns true if the character is a symbol (Symbol_* categories); otherwise returns false...
Definition: qchar.cpp:709
#define Q_ASSERT(cond)
Definition: qglobal.h:1823
The QObject class is the base class of all Qt objects.
Definition: qobject.h:111
bool qt_sendSpontaneousEvent(QObject *obj, QEvent *event)
static qt_mac_enum_mapper qt_mac_keyboard_symbols[]
The QChar class provides a 16-bit Unicode character.
Definition: qchar.h:72
QStringList keys
bool qt_mac_eat_unicode_key
static qt_mac_enum_mapper qt_mac_keyvkey_symbols[]
Q_DECL_CONSTEXPR const T & qMax(const T &a, const T &b)
Definition: qglobal.h:1217
Q_CORE_EXPORT void qDebug(const char *,...)
Qt::KeyboardModifiers modifiers() const
Returns the keyboard modifier flags that existed immediately after the event occurred.
Definition: qevent.cpp:999
unsigned char uchar
Definition: qglobal.h:994
QList< int > possibleKeys(QKeyEvent *e)
#define QT_BEGIN_NAMESPACE
This macro expands to.
Definition: qglobal.h:89
bool testAttribute(Qt::WidgetAttribute) const
Returns true if attribute attribute is set on this widget; otherwise returns false.
Definition: qwidget.h:1041
bool isEmpty() const
Returns true if the string has no characters; otherwise returns false.
Definition: qstring.h:704
#define qApp
Q_CORE_EXPORT void qWarning(const char *,...)
static bool translateKeyEventInternal(EventHandlerCallRef er, EventRef keyEvent, int *qtKey, QChar *outChar, Qt::KeyboardModifiers *outModifiers, bool *outHandled)
static const char * data(const QByteArray &arr)
unsigned int uint
Definition: qglobal.h:996
void setLastKeydownEvent(EventRef)
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
bool qt_mac_menubar_is_open()
Definition: qmenu_mac.mm:750
QByteArray toLatin1() const Q_REQUIRED_RESULT
Returns a Latin-1 representation of the string as a QByteArray.
Definition: qstring.cpp:3993
signed long OSStatus
static int qt_mac_get_key(int modif, const QChar &key, int virtualKey)
struct OpaqueEventRef * EventRef
bool isEnabled() const
Definition: qwidget.h:948
static qt_mac_enum_mapper qt_mac_private_unicode[]
const char * constData() const
Returns a pointer to the data stored in the byte array.
Definition: qbytearray.h:433
QString toUnicode(const QByteArray &) const
Converts a from the encoding of this codec to Unicode, and returns the result in a QString...
Q_CORE_EXPORT void qFatal(const char *,...)
static QLocale c()
Returns a QLocale object initialized to the "C" locale.
Definition: qlocale.h:773
Type
This enum type defines the valid event types in Qt.
Definition: qcoreevent.h:62
static void changeKeyboard()
Definition: qkeymapper.cpp:90
Q_GUI_EXPORT void qt_mac_secure_keyboard(bool b)
int key
unsigned int quint32
Definition: qglobal.h:938
const char * className() const
Returns the class name.
Definition: qobjectdefs.h:491
void qt_mac_send_modifiers_changed(quint32 modifiers, QObject *object)
QString objectName() const
static QTextCodec * codecForName(const QByteArray &name)
Searches all installed QTextCodec objects and returns the one which best matches name; the match is c...
static const int buffer_size
Definition: qdrawhelper.cpp:80
char toLatin1() const
Returns the Latin-1 character equivalent to the QChar, or 0.
Definition: qchar.h:376
#define QT_USE_NAMESPACE
This macro expands to using QT_NAMESPACE if QT_NAMESPACE is defined and nothing otherwise.
Definition: qglobal.h:88
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)
struct OpaqueEventHandlerCallRef * EventHandlerCallRef
static qt_mac_enum_mapper qt_mac_modifier_symbols[]
The QInputContext class abstracts the input method dependent data and composing state.
Definition: qinputcontext.h:83
The QTextCodec class provides conversions between text encodings.
Definition: qtextcodec.h:62
static const Qt::KeyboardModifiers ModsTbl[]
const struct __CFArray * CFArrayRef
The QEvent class is the base class of all event classes.
Definition: qcoreevent.h:56
#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
The QLatin1Char class provides an 8-bit ASCII/Latin-1 character.
Definition: qchar.h:55
quint32 nativeVirtualKey() const
Returns the native virtual key, or key sym of the key event.
Definition: qevent.cpp:889
bool isDigit() const
Returns true if the character is a decimal digit (Number_DecimalDigit); otherwise returns false...
Definition: qchar.cpp:699
static Boolean qt_KeyEventComparatorProc(EventRef inEvent, void *data)
virtual const QMetaObject * metaObject() const
Returns a pointer to the meta-object of this object.
#define QT_MAC_MAP_ENUM(x)
#define text
Definition: qobjectdefs.h:80