/****************************************************************************
**
** 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
