| /**************************************************************************** |
| ** |
| ** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). |
| ** All rights reserved. |
| ** Contact: Nokia Corporation (qt-info@nokia.com) |
| ** |
| ** This file is part of the QtGui module of the Qt Toolkit. |
| ** |
| ** $QT_BEGIN_LICENSE:LGPL$ |
| ** GNU Lesser General Public License Usage |
| ** This file may be used under the terms of the GNU Lesser General Public |
| ** License version 2.1 as published by the Free Software Foundation and |
| ** appearing in the file LICENSE.LGPL included in the packaging of this |
| ** file. Please review the following information to ensure the GNU Lesser |
| ** General Public License version 2.1 requirements will be met: |
| ** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. |
| ** |
| ** In addition, as a special exception, Nokia gives you certain additional |
| ** rights. These rights are described in the Nokia Qt LGPL Exception |
| ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. |
| ** |
| ** GNU General Public License Usage |
| ** Alternatively, this file may be used under the terms of the GNU General |
| ** Public License version 3.0 as published by the Free Software Foundation |
| ** and appearing in the file LICENSE.GPL included in the packaging of this |
| ** file. Please review the following information to ensure the GNU General |
| ** Public License version 3.0 requirements will be met: |
| ** http://www.gnu.org/copyleft/gpl.html. |
| ** |
| ** Other Usage |
| ** Alternatively, this file may be used in accordance with the terms and |
| ** conditions contained in a signed written agreement between you and Nokia. |
| ** |
| ** |
| ** |
| ** |
| ** |
| ** $QT_END_LICENSE$ |
| ** |
| ****************************************************************************/ |
| |
| #include <private/qt_mac_p.h> |
| #include <qdebug.h> |
| #include <qevent.h> |
| #include <private/qevent_p.h> |
| #include <qtextcodec.h> |
| #include <qapplication.h> |
| #include <qinputcontext.h> |
| #include <private/qkeymapper_p.h> |
| #include <private/qapplication_p.h> |
| #include <private/qmacinputcontext_p.h> |
| |
| QT_BEGIN_NAMESPACE |
| |
| QT_USE_NAMESPACE |
| |
| /***************************************************************************** |
| QKeyMapper debug facilities |
| *****************************************************************************/ |
| //#define DEBUG_KEY_BINDINGS |
| //#define DEBUG_KEY_BINDINGS_MODIFIERS |
| //#define DEBUG_KEY_MAPS |
| |
| /***************************************************************************** |
| Internal variables and functions |
| *****************************************************************************/ |
| bool qt_mac_eat_unicode_key = false; |
| extern bool qt_sendSpontaneousEvent(QObject *obj, QEvent *event); //qapplication_mac.cpp |
| |
| Q_GUI_EXPORT void qt_mac_secure_keyboard(bool b) |
| { |
| static bool secure = false; |
| if (b != secure){ |
| b ? EnableSecureEventInput() : DisableSecureEventInput(); |
| secure = b; |
| } |
| } |
| |
| /* |
| \internal |
| A Mac KeyboardLayoutItem has 8 possible states: |
| 1. Unmodified |
| 2. Shift |
| 3. Control |
| 4. Control + Shift |
| 5. Alt |
| 6. Alt + Shift |
| 7. Alt + Control |
| 8. Alt + Control + Shift |
| 9. Meta |
| 10. Meta + Shift |
| 11. Meta + Control |
| 12. Meta + Control + Shift |
| 13. Meta + Alt |
| 14. Meta + Alt + Shift |
| 15. Meta + Alt + Control |
| 16. Meta + Alt + Control + Shift |
| */ |
| struct KeyboardLayoutItem { |
| bool dirty; |
| quint32 qtKey[16]; // Can by any Qt::Key_<foo>, or unicode character |
| }; |
| |
| // Possible modifier states. |
| // NOTE: The order of these states match the order in QKeyMapperPrivate::updatePossibleKeyCodes()! |
| static const Qt::KeyboardModifiers ModsTbl[] = { |
| Qt::NoModifier, // 0 |
| Qt::ShiftModifier, // 1 |
| Qt::ControlModifier, // 2 |
| Qt::ControlModifier | Qt::ShiftModifier, // 3 |
| Qt::AltModifier, // 4 |
| Qt::AltModifier | Qt::ShiftModifier, // 5 |
| Qt::AltModifier | Qt::ControlModifier, // 6 |
| Qt::AltModifier | Qt::ShiftModifier | Qt::ControlModifier, // 7 |
| Qt::MetaModifier, // 8 |
| Qt::MetaModifier | Qt::ShiftModifier, // 9 |
| Qt::MetaModifier | Qt::ControlModifier, // 10 |
| Qt::MetaModifier | Qt::ControlModifier | Qt::ShiftModifier,// 11 |
| Qt::MetaModifier | Qt::AltModifier, // 12 |
| Qt::MetaModifier | Qt::AltModifier | Qt::ShiftModifier, // 13 |
| Qt::MetaModifier | Qt::AltModifier | Qt::ControlModifier, // 14 |
| Qt::MetaModifier | Qt::AltModifier | Qt::ShiftModifier | Qt::ControlModifier, // 15 |
| }; |
| |
| /* key maps */ |
| struct qt_mac_enum_mapper |
| { |
| int mac_code; |
| int qt_code; |
| #if defined(DEBUG_KEY_BINDINGS) |
| # define QT_MAC_MAP_ENUM(x) x, #x |
| const char *desc; |
| #else |
| # define QT_MAC_MAP_ENUM(x) x |
| #endif |
| }; |
| |
| //modifiers |
| static qt_mac_enum_mapper qt_mac_modifier_symbols[] = { |
| { shiftKey, QT_MAC_MAP_ENUM(Qt::ShiftModifier) }, |
| { rightShiftKey, QT_MAC_MAP_ENUM(Qt::ShiftModifier) }, |
| { controlKey, QT_MAC_MAP_ENUM(Qt::MetaModifier) }, |
| { rightControlKey, QT_MAC_MAP_ENUM(Qt::MetaModifier) }, |
| { cmdKey, QT_MAC_MAP_ENUM(Qt::ControlModifier) }, |
| { optionKey, QT_MAC_MAP_ENUM(Qt::AltModifier) }, |
| { rightOptionKey, QT_MAC_MAP_ENUM(Qt::AltModifier) }, |
| { kEventKeyModifierNumLockMask, QT_MAC_MAP_ENUM(Qt::KeypadModifier) }, |
| { 0, QT_MAC_MAP_ENUM(0) } |
| }; |
| Qt::KeyboardModifiers qt_mac_get_modifiers(int keys) |
| { |
| #ifdef DEBUG_KEY_BINDINGS_MODIFIERS |
| qDebug("Qt: internal: **Mapping modifiers: %d (0x%04x)", keys, keys); |
| #endif |
| Qt::KeyboardModifiers ret = Qt::NoModifier; |
| for (int i = 0; qt_mac_modifier_symbols[i].qt_code; i++) { |
| if (keys & qt_mac_modifier_symbols[i].mac_code) { |
| #ifdef DEBUG_KEY_BINDINGS_MODIFIERS |
| qDebug("Qt: internal: got modifier: %s", qt_mac_modifier_symbols[i].desc); |
| #endif |
| ret |= Qt::KeyboardModifier(qt_mac_modifier_symbols[i].qt_code); |
| } |
| } |
| if (qApp->testAttribute(Qt::AA_MacDontSwapCtrlAndMeta)) { |
| Qt::KeyboardModifiers oldModifiers = ret; |
| ret &= ~(Qt::MetaModifier | Qt::ControlModifier); |
| if (oldModifiers & Qt::ControlModifier) |
| ret |= Qt::MetaModifier; |
| if (oldModifiers & Qt::MetaModifier) |
| ret |= Qt::ControlModifier; |
| } |
| return ret; |
| } |
| static int qt_mac_get_mac_modifiers(Qt::KeyboardModifiers keys) |
| { |
| #ifdef DEBUG_KEY_BINDINGS_MODIFIERS |
| qDebug("Qt: internal: **Mapping modifiers: %d (0x%04x)", (int)keys, (int)keys); |
| #endif |
| int ret = 0; |
| for (int i = 0; qt_mac_modifier_symbols[i].qt_code; i++) { |
| if (keys & qt_mac_modifier_symbols[i].qt_code) { |
| #ifdef DEBUG_KEY_BINDINGS_MODIFIERS |
| qDebug("Qt: internal: got modifier: %s", qt_mac_modifier_symbols[i].desc); |
| #endif |
| ret |= qt_mac_modifier_symbols[i].mac_code; |
| } |
| } |
| |
| if (qApp->testAttribute(Qt::AA_MacDontSwapCtrlAndMeta)) { |
| int oldModifiers = ret; |
| ret &= ~(controlKeyBit | cmdKeyBit); |
| if (oldModifiers & controlKeyBit) |
| ret |= cmdKeyBit; |
| if (oldModifiers & cmdKeyBit) |
| ret |= controlKeyBit; |
| } |
| return ret; |
| } |
| void qt_mac_send_modifiers_changed(quint32 modifiers, QObject *object) |
| { |
| static quint32 cachedModifiers = 0; |
| quint32 lastModifiers = cachedModifiers, |
| changedModifiers = lastModifiers ^ modifiers; |
| cachedModifiers = modifiers; |
| |
| //check the bits |
| static qt_mac_enum_mapper modifier_key_symbols[] = { |
| { shiftKeyBit, QT_MAC_MAP_ENUM(Qt::Key_Shift) }, |
| { rightShiftKeyBit, QT_MAC_MAP_ENUM(Qt::Key_Shift) }, //??? |
| { controlKeyBit, QT_MAC_MAP_ENUM(Qt::Key_Meta) }, |
| { rightControlKeyBit, QT_MAC_MAP_ENUM(Qt::Key_Meta) }, //??? |
| { cmdKeyBit, QT_MAC_MAP_ENUM(Qt::Key_Control) }, |
| { optionKeyBit, QT_MAC_MAP_ENUM(Qt::Key_Alt) }, |
| { rightOptionKeyBit, QT_MAC_MAP_ENUM(Qt::Key_Alt) }, //??? |
| { alphaLockBit, QT_MAC_MAP_ENUM(Qt::Key_CapsLock) }, |
| { kEventKeyModifierNumLockBit, QT_MAC_MAP_ENUM(Qt::Key_NumLock) }, |
| { 0, QT_MAC_MAP_ENUM(0) } }; |
| for (int i = 0; i <= 32; i++) { //just check each bit |
| if (!(changedModifiers & (1 << i))) |
| continue; |
| QEvent::Type etype = QEvent::KeyPress; |
| if (lastModifiers & (1 << i)) |
| etype = QEvent::KeyRelease; |
| int key = 0; |
| for (uint x = 0; modifier_key_symbols[x].mac_code; x++) { |
| if (modifier_key_symbols[x].mac_code == i) { |
| #ifdef DEBUG_KEY_BINDINGS_MODIFIERS |
| qDebug("got modifier changed: %s", modifier_key_symbols[x].desc); |
| #endif |
| key = modifier_key_symbols[x].qt_code; |
| break; |
| } |
| } |
| if (!key) { |
| #ifdef DEBUG_KEY_BINDINGS_MODIFIERS |
| qDebug("could not get modifier changed: %d", i); |
| #endif |
| continue; |
| } |
| #ifdef DEBUG_KEY_BINDINGS_MODIFIERS |
| qDebug("KeyEvent (modif): Sending %s to %s::%s: %d - 0x%08x", |
| etype == QEvent::KeyRelease ? "KeyRelease" : "KeyPress", |
| object ? object->metaObject()->className() : "none", |
| object ? object->objectName().toLatin1().constData() : "", |
| key, (int)modifiers); |
| #endif |
| QKeyEvent ke(etype, key, qt_mac_get_modifiers(modifiers ^ (1 << i)), QLatin1String("")); |
| qt_sendSpontaneousEvent(object, &ke); |
| } |
| } |
| |
| //keyboard keys (non-modifiers) |
| static qt_mac_enum_mapper qt_mac_keyboard_symbols[] = { |
| { kHomeCharCode, QT_MAC_MAP_ENUM(Qt::Key_Home) }, |
| { kEnterCharCode, QT_MAC_MAP_ENUM(Qt::Key_Enter) }, |
| { kEndCharCode, QT_MAC_MAP_ENUM(Qt::Key_End) }, |
| { kBackspaceCharCode, QT_MAC_MAP_ENUM(Qt::Key_Backspace) }, |
| { kTabCharCode, QT_MAC_MAP_ENUM(Qt::Key_Tab) }, |
| { kPageUpCharCode, QT_MAC_MAP_ENUM(Qt::Key_PageUp) }, |
| { kPageDownCharCode, QT_MAC_MAP_ENUM(Qt::Key_PageDown) }, |
| { kReturnCharCode, QT_MAC_MAP_ENUM(Qt::Key_Return) }, |
| { kEscapeCharCode, QT_MAC_MAP_ENUM(Qt::Key_Escape) }, |
| { kLeftArrowCharCode, QT_MAC_MAP_ENUM(Qt::Key_Left) }, |
| { kRightArrowCharCode, QT_MAC_MAP_ENUM(Qt::Key_Right) }, |
| { kUpArrowCharCode, QT_MAC_MAP_ENUM(Qt::Key_Up) }, |
| { kDownArrowCharCode, QT_MAC_MAP_ENUM(Qt::Key_Down) }, |
| { kHelpCharCode, QT_MAC_MAP_ENUM(Qt::Key_Help) }, |
| { kDeleteCharCode, QT_MAC_MAP_ENUM(Qt::Key_Delete) }, |
| //ascii maps, for debug |
| { ':', QT_MAC_MAP_ENUM(Qt::Key_Colon) }, |
| { ';', QT_MAC_MAP_ENUM(Qt::Key_Semicolon) }, |
| { '<', QT_MAC_MAP_ENUM(Qt::Key_Less) }, |
| { '=', QT_MAC_MAP_ENUM(Qt::Key_Equal) }, |
| { '>', QT_MAC_MAP_ENUM(Qt::Key_Greater) }, |
| { '?', QT_MAC_MAP_ENUM(Qt::Key_Question) }, |
| { '@', QT_MAC_MAP_ENUM(Qt::Key_At) }, |
| { ' ', QT_MAC_MAP_ENUM(Qt::Key_Space) }, |
| { '!', QT_MAC_MAP_ENUM(Qt::Key_Exclam) }, |
| { '"', QT_MAC_MAP_ENUM(Qt::Key_QuoteDbl) }, |
| { '#', QT_MAC_MAP_ENUM(Qt::Key_NumberSign) }, |
| { '$', QT_MAC_MAP_ENUM(Qt::Key_Dollar) }, |
| { '%', QT_MAC_MAP_ENUM(Qt::Key_Percent) }, |
| { '&', QT_MAC_MAP_ENUM(Qt::Key_Ampersand) }, |
| { '\'', QT_MAC_MAP_ENUM(Qt::Key_Apostrophe) }, |
| { '(', QT_MAC_MAP_ENUM(Qt::Key_ParenLeft) }, |
| { ')', QT_MAC_MAP_ENUM(Qt::Key_ParenRight) }, |
| { '*', QT_MAC_MAP_ENUM(Qt::Key_Asterisk) }, |
| { '+', QT_MAC_MAP_ENUM(Qt::Key_Plus) }, |
| { ',', QT_MAC_MAP_ENUM(Qt::Key_Comma) }, |
| { '-', QT_MAC_MAP_ENUM(Qt::Key_Minus) }, |
| { '.', QT_MAC_MAP_ENUM(Qt::Key_Period) }, |
| { '/', QT_MAC_MAP_ENUM(Qt::Key_Slash) }, |
| { '[', QT_MAC_MAP_ENUM(Qt::Key_BracketLeft) }, |
| { ']', QT_MAC_MAP_ENUM(Qt::Key_BracketRight) }, |
| { '\\', QT_MAC_MAP_ENUM(Qt::Key_Backslash) }, |
| { '_', QT_MAC_MAP_ENUM(Qt::Key_Underscore) }, |
| { '`', QT_MAC_MAP_ENUM(Qt::Key_QuoteLeft) }, |
| { '{', QT_MAC_MAP_ENUM(Qt::Key_BraceLeft) }, |
| { '}', QT_MAC_MAP_ENUM(Qt::Key_BraceRight) }, |
| { '|', QT_MAC_MAP_ENUM(Qt::Key_Bar) }, |
| { '~', QT_MAC_MAP_ENUM(Qt::Key_AsciiTilde) }, |
| { '^', QT_MAC_MAP_ENUM(Qt::Key_AsciiCircum) }, |
| { 0, QT_MAC_MAP_ENUM(0) } |
| }; |
| |
| static qt_mac_enum_mapper qt_mac_keyvkey_symbols[] = { //real scan codes |
| { 122, QT_MAC_MAP_ENUM(Qt::Key_F1) }, |
| { 120, QT_MAC_MAP_ENUM(Qt::Key_F2) }, |
| { 99, QT_MAC_MAP_ENUM(Qt::Key_F3) }, |
| { 118, QT_MAC_MAP_ENUM(Qt::Key_F4) }, |
| { 96, QT_MAC_MAP_ENUM(Qt::Key_F5) }, |
| { 97, QT_MAC_MAP_ENUM(Qt::Key_F6) }, |
| { 98, QT_MAC_MAP_ENUM(Qt::Key_F7) }, |
| { 100, QT_MAC_MAP_ENUM(Qt::Key_F8) }, |
| { 101, QT_MAC_MAP_ENUM(Qt::Key_F9) }, |
| { 109, QT_MAC_MAP_ENUM(Qt::Key_F10) }, |
| { 103, QT_MAC_MAP_ENUM(Qt::Key_F11) }, |
| { 111, QT_MAC_MAP_ENUM(Qt::Key_F12) }, |
| { 105, QT_MAC_MAP_ENUM(Qt::Key_F13) }, |
| { 107, QT_MAC_MAP_ENUM(Qt::Key_F14) }, |
| { 113, QT_MAC_MAP_ENUM(Qt::Key_F15) }, |
| { 106, QT_MAC_MAP_ENUM(Qt::Key_F16) }, |
| { 0, QT_MAC_MAP_ENUM(0) } |
| }; |
| |
| static qt_mac_enum_mapper qt_mac_private_unicode[] = { |
| { 0xF700, QT_MAC_MAP_ENUM(Qt::Key_Up) }, //NSUpArrowFunctionKey |
| { 0xF701, QT_MAC_MAP_ENUM(Qt::Key_Down) }, //NSDownArrowFunctionKey |
| { 0xF702, QT_MAC_MAP_ENUM(Qt::Key_Left) }, //NSLeftArrowFunctionKey |
| { 0xF703, QT_MAC_MAP_ENUM(Qt::Key_Right) }, //NSRightArrowFunctionKey |
| { 0xF727, QT_MAC_MAP_ENUM(Qt::Key_Insert) }, //NSInsertFunctionKey |
| { 0xF728, QT_MAC_MAP_ENUM(Qt::Key_Delete) }, //NSDeleteFunctionKey |
| { 0xF729, QT_MAC_MAP_ENUM(Qt::Key_Home) }, //NSHomeFunctionKey |
| { 0xF72B, QT_MAC_MAP_ENUM(Qt::Key_End) }, //NSEndFunctionKey |
| { 0xF72C, QT_MAC_MAP_ENUM(Qt::Key_PageUp) }, //NSPageUpFunctionKey |
| { 0xF72D, QT_MAC_MAP_ENUM(Qt::Key_PageDown) }, //NSPageDownFunctionKey |
| { 0xF72F, QT_MAC_MAP_ENUM(Qt::Key_ScrollLock) }, //NSScrollLockFunctionKey |
| { 0xF730, QT_MAC_MAP_ENUM(Qt::Key_Pause) }, //NSPauseFunctionKey |
| { 0xF731, QT_MAC_MAP_ENUM(Qt::Key_SysReq) }, //NSSysReqFunctionKey |
| { 0xF735, QT_MAC_MAP_ENUM(Qt::Key_Menu) }, //NSMenuFunctionKey |
| { 0xF738, QT_MAC_MAP_ENUM(Qt::Key_Print) }, //NSPrintFunctionKey |
| { 0xF73A, QT_MAC_MAP_ENUM(Qt::Key_Clear) }, //NSClearDisplayFunctionKey |
| { 0xF73D, QT_MAC_MAP_ENUM(Qt::Key_Insert) }, //NSInsertCharFunctionKey |
| { 0xF73E, QT_MAC_MAP_ENUM(Qt::Key_Delete) }, //NSDeleteCharFunctionKey |
| { 0xF741, QT_MAC_MAP_ENUM(Qt::Key_Select) }, //NSSelectFunctionKey |
| { 0xF742, QT_MAC_MAP_ENUM(Qt::Key_Execute) }, //NSExecuteFunctionKey |
| { 0xF746, QT_MAC_MAP_ENUM(Qt::Key_Help) }, //NSHelpFunctionKey |
| { 0xF747, QT_MAC_MAP_ENUM(Qt::Key_Mode_switch) }, //NSModeSwitchFunctionKey |
| { 0, QT_MAC_MAP_ENUM(0) } |
| }; |
| |
| static int qt_mac_get_key(int modif, const QChar &key, int virtualKey) |
| { |
| #ifdef DEBUG_KEY_BINDINGS |
| qDebug("**Mapping key: %d (0x%04x) - %d (0x%04x)", key.unicode(), key.unicode(), virtualKey, virtualKey); |
| #endif |
| |
| if (key == kClearCharCode && virtualKey == 0x47) |
| return Qt::Key_Clear; |
| |
| if (key.isDigit()) { |
| #ifdef DEBUG_KEY_BINDINGS |
| qDebug("%d: got key: %d", __LINE__, key.digitValue()); |
| #endif |
| return key.digitValue() + Qt::Key_0; |
| } |
| |
| if (key.isLetter()) { |
| #ifdef DEBUG_KEY_BINDINGS |
| qDebug("%d: got key: %d", __LINE__, (key.toUpper().unicode() - 'A')); |
| #endif |
| return (key.toUpper().unicode() - 'A') + Qt::Key_A; |
| } |
| if (key.isSymbol()) { |
| #ifdef DEBUG_KEY_BINDINGS |
| qDebug("%d: got key: %d", __LINE__, (key.unicode())); |
| #endif |
| return key.unicode(); |
| } |
| |
| for (int i = 0; qt_mac_keyboard_symbols[i].qt_code; i++) { |
| if (qt_mac_keyboard_symbols[i].mac_code == key) { |
| /* To work like Qt for X11 we issue Backtab when Shift + Tab are pressed */ |
| if (qt_mac_keyboard_symbols[i].qt_code == Qt::Key_Tab && (modif & Qt::ShiftModifier)) { |
| #ifdef DEBUG_KEY_BINDINGS |
| qDebug("%d: got key: Qt::Key_Backtab", __LINE__); |
| #endif |
| return Qt::Key_Backtab; |
| } |
| |
| #ifdef DEBUG_KEY_BINDINGS |
| qDebug("%d: got key: %s", __LINE__, qt_mac_keyboard_symbols[i].desc); |
| #endif |
| return qt_mac_keyboard_symbols[i].qt_code; |
| } |
| } |
| |
| //last ditch try to match the scan code |
| for (int i = 0; qt_mac_keyvkey_symbols[i].qt_code; i++) { |
| if (qt_mac_keyvkey_symbols[i].mac_code == virtualKey) { |
| #ifdef DEBUG_KEY_BINDINGS |
| qDebug("%d: got key: %s", __LINE__, qt_mac_keyvkey_symbols[i].desc); |
| #endif |
| return qt_mac_keyvkey_symbols[i].qt_code; |
| } |
| } |
| |
| // check if they belong to key codes in private unicode range |
| if (key >= 0xf700 && key <= 0xf747) { |
| if (key >= 0xf704 && key <= 0xf726) { |
| return Qt::Key_F1 + (key.unicode() - 0xf704) ; |
| } |
| for (int i = 0; qt_mac_private_unicode[i].qt_code; i++) { |
| if (qt_mac_private_unicode[i].mac_code == key) { |
| return qt_mac_private_unicode[i].qt_code; |
| } |
| } |
| |
| } |
| |
| //oh well |
| #ifdef DEBUG_KEY_BINDINGS |
| qDebug("Unknown case.. %s:%d %d[%d] %d", __FILE__, __LINE__, key.unicode(), key.toLatin1(), virtualKey); |
| #endif |
| return Qt::Key_unknown; |
| } |
| |
| static Boolean qt_KeyEventComparatorProc(EventRef inEvent, void *data) |
| { |
| UInt32 ekind = GetEventKind(inEvent), |
| eclass = GetEventClass(inEvent); |
| return (eclass == kEventClassKeyboard && (void *)ekind == data); |
| } |
| |
| static bool translateKeyEventInternal(EventHandlerCallRef er, EventRef keyEvent, int *qtKey, |
| QChar *outChar, Qt::KeyboardModifiers *outModifiers, bool *outHandled) |
| { |
| #if !defined(QT_MAC_USE_COCOA) || defined(Q_OS_MAC64) |
| Q_UNUSED(er); |
| Q_UNUSED(outHandled); |
| #endif |
| const UInt32 ekind = GetEventKind(keyEvent); |
| { |
| UInt32 mac_modifiers = 0; |
| GetEventParameter(keyEvent, kEventParamKeyModifiers, typeUInt32, 0, |
| sizeof(mac_modifiers), 0, &mac_modifiers); |
| #ifdef DEBUG_KEY_BINDINGS_MODIFIERS |
| qDebug("************ Mapping modifiers and key ***********"); |
| #endif |
| *outModifiers = qt_mac_get_modifiers(mac_modifiers); |
| #ifdef DEBUG_KEY_BINDINGS_MODIFIERS |
| qDebug("------------ Mapping modifiers and key -----------"); |
| #endif |
| } |
| |
| //get keycode |
| UInt32 keyCode = 0; |
| GetEventParameter(keyEvent, kEventParamKeyCode, typeUInt32, 0, sizeof(keyCode), 0, &keyCode); |
| |
| //get mac mapping |
| static UInt32 tmp_unused_state = 0L; |
| const UCKeyboardLayout *uchrData = 0; |
| #if defined(Q_OS_MAC32) |
| KeyboardLayoutRef keyLayoutRef = 0; |
| KLGetCurrentKeyboardLayout(&keyLayoutRef); |
| OSStatus err; |
| if (keyLayoutRef != 0) { |
| err = KLGetKeyboardLayoutProperty(keyLayoutRef, kKLuchrData, |
| (reinterpret_cast<const void **>(&uchrData))); |
| if (err != noErr) { |
| qWarning("Qt::internal::unable to get keyboardlayout %ld %s:%d", |
| long(err), __FILE__, __LINE__); |
| } |
| } |
| #else |
| QCFType<TISInputSourceRef> inputSource = TISCopyCurrentKeyboardInputSource(); |
| Q_ASSERT(inputSource != 0); |
| CFDataRef data = static_cast<CFDataRef>(TISGetInputSourceProperty(inputSource, |
| kTISPropertyUnicodeKeyLayoutData)); |
| uchrData = data ? reinterpret_cast<const UCKeyboardLayout *>(CFDataGetBytePtr(data)) : 0; |
| #endif |
| *qtKey = Qt::Key_unknown; |
| if (uchrData) { |
| // The easy stuff; use the unicode stuff! |
| UniChar string[4]; |
| UniCharCount actualLength; |
| UInt32 currentModifiers = GetCurrentEventKeyModifiers(); |
| UInt32 currentModifiersWOAltOrControl = currentModifiers & ~(controlKey | optionKey); |
| int keyAction; |
| switch (ekind) { |
| default: |
| case kEventRawKeyDown: |
| keyAction = kUCKeyActionDown; |
| break; |
| case kEventRawKeyUp: |
| keyAction = kUCKeyActionUp; |
| break; |
| case kEventRawKeyRepeat: |
| keyAction = kUCKeyActionAutoKey; |
| break; |
| } |
| OSStatus err = UCKeyTranslate(uchrData, keyCode, keyAction, |
| ((currentModifiersWOAltOrControl >> 8) & 0xff), LMGetKbdType(), |
| kUCKeyTranslateNoDeadKeysMask, &tmp_unused_state, 4, &actualLength, |
| string); |
| if (err == noErr) { |
| *outChar = QChar(string[0]); |
| *qtKey = qt_mac_get_key(*outModifiers, *outChar, keyCode); |
| if (currentModifiersWOAltOrControl != currentModifiers) { |
| // Now get the real char. |
| err = UCKeyTranslate(uchrData, keyCode, keyAction, |
| ((currentModifiers >> 8) & 0xff), LMGetKbdType(), |
| kUCKeyTranslateNoDeadKeysMask, &tmp_unused_state, 4, &actualLength, |
| string); |
| if (err == noErr) |
| *outChar = QChar(string[0]); |
| } |
| } else { |
| qWarning("Qt::internal::UCKeyTranslate is returnining %ld %s:%d", |
| long(err), __FILE__, __LINE__); |
| } |
| } |
| #ifdef Q_OS_MAC32 |
| else { |
| // The road less travelled; use KeyTranslate |
| const void *keyboard_layout; |
| KeyboardLayoutRef keyLayoutRef = 0; |
| KLGetCurrentKeyboardLayout(&keyLayoutRef); |
| err = KLGetKeyboardLayoutProperty(keyLayoutRef, kKLKCHRData, |
| reinterpret_cast<const void **>(&keyboard_layout)); |
| |
| int translatedChar = KeyTranslate(keyboard_layout, (GetCurrentEventKeyModifiers() & |
| (kEventKeyModifierNumLockMask|shiftKey|cmdKey| |
| rightShiftKey|alphaLock)) | keyCode, |
| &tmp_unused_state); |
| if (!translatedChar) { |
| #ifdef QT_MAC_USE_COCOA |
| if (outHandled) { |
| qt_mac_eat_unicode_key = false; |
| if (er) |
| CallNextEventHandler(er, keyEvent); |
| *outHandled = qt_mac_eat_unicode_key; |
| } |
| #endif |
| return false; |
| } |
| |
| //map it into qt keys |
| *qtKey = qt_mac_get_key(*outModifiers, QChar(translatedChar), keyCode); |
| if (*outModifiers & (Qt::AltModifier | Qt::ControlModifier)) { |
| if (translatedChar & (1 << 7)) //high ascii |
| translatedChar = 0; |
| } else { //now get the real ascii value |
| UInt32 tmp_mod = 0L; |
| static UInt32 tmp_state = 0L; |
| if (*outModifiers & Qt::ShiftModifier) |
| tmp_mod |= shiftKey; |
| if (*outModifiers & Qt::MetaModifier) |
| tmp_mod |= controlKey; |
| if (*outModifiers & Qt::ControlModifier) |
| tmp_mod |= cmdKey; |
| if (GetCurrentEventKeyModifiers() & alphaLock) //no Qt mapper |
| tmp_mod |= alphaLock; |
| if (*outModifiers & Qt::AltModifier) |
| tmp_mod |= optionKey; |
| if (*outModifiers & Qt::KeypadModifier) |
| tmp_mod |= kEventKeyModifierNumLockMask; |
| translatedChar = KeyTranslate(keyboard_layout, tmp_mod | keyCode, &tmp_state); |
| } |
| { |
| ByteCount unilen = 0; |
| if (GetEventParameter(keyEvent, kEventParamKeyUnicodes, typeUnicodeText, 0, 0, &unilen, 0) |
| == noErr && unilen == 2) { |
| GetEventParameter(keyEvent, kEventParamKeyUnicodes, typeUnicodeText, 0, unilen, 0, outChar); |
| } else if (translatedChar) { |
| static QTextCodec *c = 0; |
| if (!c) |
| c = QTextCodec::codecForName("Apple Roman"); |
| char tmpChar = (char)translatedChar; // **sigh** |
| *outChar = c->toUnicode(&tmpChar, 1).at(0); |
| } else { |
| *qtKey = qt_mac_get_key(*outModifiers, QChar(translatedChar), keyCode); |
| } |
| } |
| } |
| #endif |
| if (*qtKey == Qt::Key_unknown) |
| *qtKey = qt_mac_get_key(*outModifiers, *outChar, keyCode); |
| return true; |
| } |
| |
| QKeyMapperPrivate::QKeyMapperPrivate() |
| { |
| memset(keyLayout, 0, sizeof(keyLayout)); |
| keyboard_layout_format.unicode = 0; |
| #ifdef Q_OS_MAC32 |
| keyboard_mode = NullMode; |
| #else |
| currentInputSource = 0; |
| #endif |
| } |
| |
| QKeyMapperPrivate::~QKeyMapperPrivate() |
| { |
| deleteLayouts(); |
| } |
| |
| bool |
| QKeyMapperPrivate::updateKeyboard() |
| { |
| const UCKeyboardLayout *uchrData = 0; |
| #ifdef Q_OS_MAC32 |
| KeyboardLayoutRef keyLayoutRef = 0; |
| KLGetCurrentKeyboardLayout(&keyLayoutRef); |
| |
| if (keyboard_mode != NullMode && currentKeyboardLayout == keyLayoutRef) |
| return false; |
| |
| OSStatus err; |
| if (keyLayoutRef != 0) { |
| err = KLGetKeyboardLayoutProperty(keyLayoutRef, kKLuchrData, |
| const_cast<const void **>(reinterpret_cast<const void **>(&uchrData))); |
| if (err != noErr) { |
| qWarning("Qt::internal::unable to get unicode keyboardlayout %ld %s:%d", |
| long(err), __FILE__, __LINE__); |
| } |
| } |
| #else |
| QCFType<TISInputSourceRef> source = TISCopyCurrentKeyboardInputSource(); |
| if (keyboard_mode != NullMode && source == currentInputSource) { |
| return false; |
| } |
| Q_ASSERT(source != 0); |
| CFDataRef data = static_cast<CFDataRef>(TISGetInputSourceProperty(source, |
| kTISPropertyUnicodeKeyLayoutData)); |
| uchrData = data ? reinterpret_cast<const UCKeyboardLayout *>(CFDataGetBytePtr(data)) : 0; |
| #endif |
| |
| keyboard_kind = LMGetKbdType(); |
| if (uchrData) { |
| keyboard_layout_format.unicode = uchrData; |
| keyboard_mode = UnicodeMode; |
| } |
| #ifdef Q_OS_MAC32 |
| else { |
| void *happy; |
| err = KLGetKeyboardLayoutProperty(keyLayoutRef, kKLKCHRData, |
| const_cast<const void **>(reinterpret_cast<void **>(&happy))); |
| if (err != noErr) { |
| qFatal("Qt::internal::unable to get non-unicode layout, cannot procede %ld %s:%d", |
| long(err), __FILE__, __LINE__); |
| } |
| keyboard_layout_format.other = happy; |
| keyboard_mode = OtherMode; |
| } |
| |
| currentKeyboardLayout = keyLayoutRef; |
| #else |
| currentInputSource = source; |
| #endif |
| keyboard_dead = 0; |
| CFStringRef iso639Code; |
| #ifdef Q_OS_MAC32 |
| # ifndef kKLLanguageCode |
| # define kKLLanguageCode 9 |
| # endif |
| KLGetKeyboardLayoutProperty(currentKeyboardLayout, kKLLanguageCode, |
| reinterpret_cast<const void **>(&iso639Code)); |
| #else |
| CFArrayRef array = static_cast<CFArrayRef>(TISGetInputSourceProperty(currentInputSource, kTISPropertyInputSourceLanguages)); |
| iso639Code = static_cast<CFStringRef>(CFArrayGetValueAtIndex(array, 0)); // Actually a RFC3066bis, but it's close enough |
| #endif |
| if (iso639Code) { |
| keyboardInputLocale = QLocale(QCFString::toQString(iso639Code)); |
| keyboardInputDirection = keyboardInputLocale.textDirection(); |
| } else { |
| keyboardInputLocale = QLocale::c(); |
| keyboardInputDirection = Qt::LeftToRight; |
| } |
| return true; |
| } |
| |
| void |
| QKeyMapperPrivate::deleteLayouts() |
| { |
| keyboard_mode = NullMode; |
| for (int i = 0; i < 255; ++i) { |
| if (keyLayout[i]) { |
| delete keyLayout[i]; |
| keyLayout[i] = 0; |
| } |
| } |
| } |
| |
| void |
| QKeyMapperPrivate::clearMappings() |
| { |
| deleteLayouts(); |
| updateKeyboard(); |
| } |
| |
| QList<int> |
| QKeyMapperPrivate::possibleKeys(QKeyEvent *e) |
| { |
| QList<int> ret; |
| |
| KeyboardLayoutItem *kbItem = keyLayout[e->nativeVirtualKey()]; |
| if (!kbItem) // Key is not in any keyboard layout (e.g. eisu-key on Japanese keyboard) |
| return ret; |
| |
| int baseKey = kbItem->qtKey[0]; |
| Qt::KeyboardModifiers keyMods = e->modifiers(); |
| ret << int(baseKey + keyMods); // The base key is _always_ valid, of course |
| |
| for (int i = 1; i < 8; ++i) { |
| Qt::KeyboardModifiers neededMods = ModsTbl[i]; |
| int key = kbItem->qtKey[i]; |
| if (key && key != baseKey && ((keyMods & neededMods) == neededMods)) |
| ret << int(key + (keyMods & ~neededMods)); |
| } |
| |
| return ret; |
| } |
| |
| bool QKeyMapperPrivate::translateKeyEvent(QWidget *widget, EventHandlerCallRef er, EventRef event, |
| void *info, bool grab) |
| { |
| Q_ASSERT(GetEventClass(event) == kEventClassKeyboard); |
| bool handled_event=true; |
| UInt32 ekind = GetEventKind(event); |
| |
| // unfortunately modifiers changed event looks quite different, so I have a separate |
| // code path |
| if (ekind == kEventRawKeyModifiersChanged) { |
| //figure out changed modifiers, wish Apple would just send a delta |
| UInt32 modifiers = 0; |
| GetEventParameter(event, kEventParamKeyModifiers, typeUInt32, 0, |
| sizeof(modifiers), 0, &modifiers); |
| qt_mac_send_modifiers_changed(modifiers, widget); |
| return true; |
| } |
| |
| QInputContext *currentContext = qApp->inputContext(); |
| if (currentContext && currentContext->isComposing()) { |
| if (ekind == kEventRawKeyDown) { |
| QMacInputContext *context = qobject_cast<QMacInputContext*>(currentContext); |
| if (context) |
| context->setLastKeydownEvent(event); |
| } |
| return false; |
| } |
| // Once we process the key down , we don't need to send the saved event again from |
| // kEventTextInputUnicodeForKeyEvent, so clear it. |
| if (currentContext && ekind == kEventRawKeyDown) { |
| QMacInputContext *context = qobject_cast<QMacInputContext*>(currentContext); |
| if (context) |
| context->setLastKeydownEvent(0); |
| } |
| |
| //get modifiers |
| Qt::KeyboardModifiers modifiers; |
| int qtKey; |
| QChar ourChar; |
| if (translateKeyEventInternal(er, event, &qtKey, &ourChar, &modifiers, |
| &handled_event) == false) |
| return handled_event; |
| QString text(ourChar); |
| /* This is actually wrong - but unfortunately it is the best that can be |
| done for now because of the Control/Meta mapping problems */ |
| if (modifiers & (Qt::ControlModifier | Qt::MetaModifier) |
| && !qApp->testAttribute(Qt::AA_MacDontSwapCtrlAndMeta)) { |
| text = QString(); |
| } |
| |
| |
| if (widget) { |
| #ifndef QT_MAC_USE_COCOA |
| Q_UNUSED(info); |
| // Try not to call "other" event handlers if we have a popup, |
| // However, if the key has text |
| // then we should pass it along because otherwise then people |
| // can use input method stuff. |
| if (!qApp->activePopupWidget() |
| || (qApp->activePopupWidget() && !text.isEmpty())) { |
| //Find out if someone else wants the event, namely |
| //is it of use to text services? If so we won't bother |
| //with a QKeyEvent. |
| qt_mac_eat_unicode_key = false; |
| if (er) |
| CallNextEventHandler(er, event); |
| extern bool qt_mac_menubar_is_open(); |
| if (qt_mac_eat_unicode_key || qt_mac_menubar_is_open()) { |
| return true; |
| } |
| } |
| #endif |
| // Try to compress key events. |
| if (!text.isEmpty() && widget->testAttribute(Qt::WA_KeyCompression)) { |
| EventTime lastTime = GetEventTime(event); |
| for (;;) { |
| EventRef releaseEvent = FindSpecificEventInQueue(GetMainEventQueue(), |
| qt_KeyEventComparatorProc, |
| (void*)kEventRawKeyUp); |
| if (!releaseEvent) |
| break; |
| const EventTime releaseTime = GetEventTime(releaseEvent); |
| if (releaseTime < lastTime) |
| break; |
| lastTime = releaseTime; |
| |
| EventRef pressEvent = FindSpecificEventInQueue(GetMainEventQueue(), |
| qt_KeyEventComparatorProc, |
| (void*)kEventRawKeyDown); |
| if (!pressEvent) |
| break; |
| const EventTime pressTime = GetEventTime(pressEvent); |
| if (pressTime < lastTime) |
| break; |
| lastTime = pressTime; |
| |
| Qt::KeyboardModifiers compressMod; |
| int compressQtKey = 0; |
| QChar compressChar; |
| if (translateKeyEventInternal(er, pressEvent, |
| &compressQtKey, &compressChar, &compressMod, 0) |
| == false) { |
| break; |
| } |
| // Copied from qapplication_x11.cpp (change both). |
| |
| bool stopCompression = |
| // 1) misc keys |
| (compressQtKey >= Qt::Key_Escape && compressQtKey <= Qt::Key_SysReq) |
| // 2) cursor movement |
| || (compressQtKey >= Qt::Key_Home && compressQtKey <= Qt::Key_PageDown) |
| // 3) extra keys |
| || (compressQtKey >= Qt::Key_Super_L && compressQtKey <= Qt::Key_Direction_R) |
| // 4) something that a) doesn't translate to text or b) translates |
| // to newline text |
| || (compressQtKey == 0) |
| || (compressChar == QLatin1Char('\n')) |
| || (compressQtKey == Qt::Key_unknown); |
| |
| if (compressMod == modifiers && !compressChar.isNull() && !stopCompression) { |
| #ifdef DEBUG_KEY_BINDINGS |
| qDebug("compressing away %c", compressChar.toLatin1()); |
| #endif |
| text += compressChar; |
| // Clean up |
| RemoveEventFromQueue(GetMainEventQueue(), releaseEvent); |
| RemoveEventFromQueue(GetMainEventQueue(), pressEvent); |
| } else { |
| #ifdef DEBUG_KEY_BINDINGS |
| qDebug("stoping compression.."); |
| #endif |
| break; |
| } |
| } |
| } |
| |
| // There is no way to get the scan code from carbon. But we cannot use the value 0, since |
| // it indicates that the event originates from somewhere else than the keyboard |
| UInt32 macScanCode = 1; |
| UInt32 macVirtualKey = 0; |
| GetEventParameter(event, kEventParamKeyCode, typeUInt32, 0, sizeof(macVirtualKey), 0, &macVirtualKey); |
| UInt32 macModifiers = 0; |
| GetEventParameter(event, kEventParamKeyModifiers, typeUInt32, 0, |
| sizeof(macModifiers), 0, &macModifiers); |
| #ifdef QT_MAC_USE_COCOA |
| // The unicode characters in the range 0xF700-0xF747 are reserved |
| // by Mac OS X for transient use as keyboard function keys. We |
| // wont send 'text' for such key events. This is done to match |
| // behavior on other platforms. |
| unsigned int *unicodeKey = (unsigned int*)info; |
| if (*unicodeKey >= 0xf700 && *unicodeKey <= 0xf747) |
| text = QString(); |
| bool isAccepted; |
| #endif |
| handled_event = QKeyMapper::sendKeyEvent(widget, grab, |
| (ekind == kEventRawKeyUp) ? QEvent::KeyRelease : QEvent::KeyPress, |
| qtKey, modifiers, text, ekind == kEventRawKeyRepeat, 0, |
| macScanCode, macVirtualKey, macModifiers |
| #ifdef QT_MAC_USE_COCOA |
| ,&isAccepted |
| #endif |
| ); |
| #ifdef QT_MAC_USE_COCOA |
| *unicodeKey = (unsigned int)isAccepted; |
| #endif |
| } |
| return handled_event; |
| } |
| |
| void |
| QKeyMapperPrivate::updateKeyMap(EventHandlerCallRef, EventRef event, void * |
| #if defined(QT_MAC_USE_COCOA) |
| unicodeKey // unicode character from NSEvent (modifiers applied) |
| #endif |
| ) |
| { |
| UInt32 macVirtualKey = 0; |
| GetEventParameter(event, kEventParamKeyCode, typeUInt32, 0, sizeof(macVirtualKey), 0, &macVirtualKey); |
| if (updateKeyboard()) |
| QKeyMapper::changeKeyboard(); |
| else if (keyLayout[macVirtualKey]) |
| return; |
| |
| UniCharCount buffer_size = 10; |
| UniChar buffer[buffer_size]; |
| keyLayout[macVirtualKey] = new KeyboardLayoutItem; |
| for (int i = 0; i < 16; ++i) { |
| UniCharCount out_buffer_size = 0; |
| keyLayout[macVirtualKey]->qtKey[i] = 0; |
| #ifdef Q_WS_MAC32 |
| if (keyboard_mode == UnicodeMode) { |
| #endif |
| const UInt32 keyModifier = ((qt_mac_get_mac_modifiers(ModsTbl[i]) >> 8) & 0xFF); |
| OSStatus err = UCKeyTranslate(keyboard_layout_format.unicode, macVirtualKey, kUCKeyActionDown, keyModifier, |
| keyboard_kind, 0, &keyboard_dead, buffer_size, &out_buffer_size, buffer); |
| if (err == noErr && out_buffer_size) { |
| const QChar unicode(buffer[0]); |
| int qtkey = qt_mac_get_key(keyModifier, unicode, macVirtualKey); |
| if (qtkey == Qt::Key_unknown) |
| qtkey = unicode.unicode(); |
| keyLayout[macVirtualKey]->qtKey[i] = qtkey; |
| } |
| #ifndef Q_WS_MAC32 |
| else { |
| const QChar unicode(*((UniChar *)unicodeKey)); |
| int qtkey = qt_mac_get_key(keyModifier, unicode, macVirtualKey); |
| if (qtkey == Qt::Key_unknown) |
| qtkey = unicode.unicode(); |
| keyLayout[macVirtualKey]->qtKey[i] = qtkey; |
| } |
| #endif |
| #ifdef Q_WS_MAC32 |
| } else { |
| const UInt32 keyModifier = (qt_mac_get_mac_modifiers(ModsTbl[i])); |
| |
| uchar translatedChar = KeyTranslate(keyboard_layout_format.other, keyModifier | macVirtualKey, &keyboard_dead); |
| if (translatedChar) { |
| static QTextCodec *c = 0; |
| if (!c) |
| c = QTextCodec::codecForName("Apple Roman"); |
| const QChar unicode(c->toUnicode((const char *)&translatedChar, 1).at(0)); |
| int qtkey = qt_mac_get_key(keyModifier, unicode, macVirtualKey); |
| if (qtkey == Qt::Key_unknown) |
| qtkey = unicode.unicode(); |
| keyLayout[macVirtualKey]->qtKey[i] = qtkey; |
| } |
| } |
| #endif |
| } |
| #ifdef DEBUG_KEY_MAPS |
| qDebug("updateKeyMap for virtual key = 0x%02x!", (uint)macVirtualKey); |
| for (int i = 0; i < 16; ++i) { |
| qDebug(" [%d] (%d,0x%02x,'%c')", i, |
| keyLayout[macVirtualKey]->qtKey[i], |
| keyLayout[macVirtualKey]->qtKey[i], |
| keyLayout[macVirtualKey]->qtKey[i]); |
| } |
| #endif |
| } |
| |
| bool |
| QKeyMapper::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 *isAccepted) |
| { |
| Q_UNUSED(count); |
| if (widget && widget->isEnabled()) { |
| bool key_event = true; |
| #if defined(QT3_SUPPORT) && !defined(QT_NO_SHORTCUT) |
| if (type == QEvent::KeyPress && !grab |
| && QApplicationPrivate::instance()->use_compat()) { |
| QKeyEventEx accel_ev(type, code, modifiers, |
| text, autorepeat, qMax(1, int(text.length())), |
| nativeScanCode, nativeVirtualKey, nativeModifiers); |
| if (QApplicationPrivate::instance()->qt_tryAccelEvent(widget, &accel_ev)) { |
| #if defined(DEBUG_KEY_BINDINGS) || defined(DEBUG_KEY_BINDINGS_MODIFIERS) |
| qDebug("KeyEvent: %s::%s consumed Accel: %s", |
| widget ? widget->metaObject()->className() : "none", |
| widget ? widget->objectName().toLatin1().constData() : "", |
| text.toLatin1().constData()); |
| #endif |
| key_event = false; |
| } else { |
| if (accel_ev.isAccepted()) { |
| #if defined(DEBUG_KEY_BINDINGS) || defined(DEBUG_KEY_BINDINGS_MODIFIERS) |
| qDebug("KeyEvent: %s::%s overrode Accel: %s", |
| widget ? widget->metaObject()->className() : "none", |
| widget ? widget->objectName().toLatin1().constData() : "", |
| text.toLatin1().constData()); |
| #endif |
| } |
| } |
| } |
| #else |
| Q_UNUSED(grab); |
| #endif // QT3_SUPPORT && !QT_NO_SHORTCUT |
| if (key_event) { |
| #if defined(DEBUG_KEY_BINDINGS) || defined(DEBUG_KEY_BINDINGS_MODIFIERS) |
| qDebug("KeyEvent: Sending %s to %s::%s: %s 0x%08x%s", |
| type == QEvent::KeyRelease ? "KeyRelease" : "KeyPress", |
| widget ? widget->metaObject()->className() : "none", |
| widget ? widget->objectName().toLatin1().constData() : "", |
| text.toLatin1().constData(), int(modifiers), |
| autorepeat ? " Repeat" : ""); |
| #endif |
| QKeyEventEx ke(type, code, modifiers, text, autorepeat, qMax(1, text.length()), |
| nativeScanCode, nativeVirtualKey, nativeModifiers); |
| bool retMe = qt_sendSpontaneousEvent(widget,&ke); |
| if (isAccepted) |
| *isAccepted = ke.isAccepted(); |
| return retMe; |
| } |
| } |
| return false; |
| } |
| |
| QT_END_NAMESPACE |