/****************************************************************************
**
** Copyright (C) 2016 The Qt Company Ltd.
** Contact: https://www.qt.io/licensing/
**
** This file is part of the plugins of the Qt Toolkit.
**
** $QT_BEGIN_LICENSE:LGPL$
** Commercial License Usage
** Licensees holding valid commercial Qt licenses may use this file in
** accordance with the commercial license agreement provided with the
** Software or, alternatively, in accordance with the terms contained in
** a written agreement between you and The Qt Company. For licensing terms
** and conditions see https://www.qt.io/terms-conditions. For further
** information use the contact form at https://www.qt.io/contact-us.
**
** GNU Lesser General Public License Usage
** Alternatively, this file may be used under the terms of the GNU Lesser
** General Public License version 3 as published by the Free Software
** Foundation and appearing in the file LICENSE.LGPL3 included in the
** packaging of this file. Please review the following information to
** ensure the GNU Lesser General Public License version 3 requirements
** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
**
** GNU General Public License Usage
** Alternatively, this file may be used under the terms of the GNU
** General Public License version 2.0 or (at your option) the GNU General
** Public license version 3 or any later version approved by the KDE Free
** Qt Foundation. The licenses are as published by the Free Software
** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
** included in the packaging of this file. Please review the following
** information to ensure the GNU General Public License requirements will
** be met: https://www.gnu.org/licenses/gpl-2.0.html and
** https://www.gnu.org/licenses/gpl-3.0.html.
**
** $QT_END_LICENSE$
**
****************************************************************************/
#include "qxcbkeyboard.h"
#include "qxcbwindow.h"
#include "qxcbscreen.h"

#include <qpa/qwindowsysteminterface.h>
#include <qpa/qplatforminputcontext.h>
#include <qpa/qplatformintegration.h>
#include <qpa/qplatformcursor.h>

#include <QtCore/QMetaEnum>

#include <private/qguiapplication_p.h>

#if QT_CONFIG(xkb)
#include <xkbcommon/xkbcommon-x11.h>
#endif

#if QT_CONFIG(xcb_xinput)
#include <xcb/xinput.h>
#endif

QT_BEGIN_NAMESPACE

Qt::KeyboardModifiers QXcbKeyboard::translateModifiers(int s) const
{
    Qt::KeyboardModifiers ret = Qt::NoModifier;
    if (s & XCB_MOD_MASK_SHIFT)
        ret |= Qt::ShiftModifier;
    if (s & XCB_MOD_MASK_CONTROL)
        ret |= Qt::ControlModifier;
    if (s & rmod_masks.alt)
        ret |= Qt::AltModifier;
    if (s & rmod_masks.meta)
        ret |= Qt::MetaModifier;
    if (s & rmod_masks.altgr)
        ret |= Qt::GroupSwitchModifier;
    return ret;
}

/* Look at a pair of unshifted and shifted key symbols.
 * If the 'unshifted' symbol is uppercase and there is no shifted symbol,
 * return the matching lowercase symbol; otherwise return 0.
 * The caller can then use the previously 'unshifted' symbol as the new
 * 'shifted' (uppercase) symbol and the symbol returned by the function
 * as the new 'unshifted' (lowercase) symbol.) */
static xcb_keysym_t getUnshiftedXKey(xcb_keysym_t unshifted, xcb_keysym_t shifted)
{
    if (shifted != XKB_KEY_NoSymbol) // Has a shifted symbol
        return 0;

    xcb_keysym_t xlower;
    xcb_keysym_t xupper;
    QXkbCommon::xkbcommon_XConvertCase(unshifted, &xlower, &xupper);

    if (xlower != xupper          // Check if symbol is cased
        && unshifted == xupper) { // Unshifted must be upper case
        return xlower;
    }

    return 0;
}

static QByteArray symbolsGroupString(const xcb_keysym_t *symbols, int count)
{
    // Don't output trailing NoSymbols
    while (count > 0 && symbols[count - 1] == XKB_KEY_NoSymbol)
        count--;

    QByteArray groupString;
    for (int symIndex = 0; symIndex < count; symIndex++) {
        xcb_keysym_t sym = symbols[symIndex];
        char symString[64];
        if (sym == XKB_KEY_NoSymbol)
            strcpy(symString, "NoSymbol");
        else
            xkb_keysym_get_name(sym, symString, sizeof(symString));

        if (!groupString.isEmpty())
            groupString += ", ";
        groupString += symString;
    }
    return groupString;
}

struct xkb_keymap *QXcbKeyboard::keymapFromCore(const KeysymModifierMap &keysymMods)
{
    /* Construct an XKB keymap string from information queried from
     * the X server */
    QByteArray keymap;
    keymap += "xkb_keymap {\n";

    const xcb_keycode_t minKeycode = connection()->setup()->min_keycode;
    const xcb_keycode_t maxKeycode = connection()->setup()->max_keycode;

    // Generate symbolic names from keycodes
    {
        keymap +=
            "xkb_keycodes \"core\" {\n"
            "\tminimum = " + QByteArray::number(minKeycode) + ";\n"
            "\tmaximum = " + QByteArray::number(maxKeycode) + ";\n";
        for (int code = minKeycode; code <= maxKeycode; code++) {
            auto codeStr = QByteArray::number(code);
            keymap += "<K" + codeStr + "> = " + codeStr + ";\n";
        }
        /* TODO: indicators?
         */
        keymap += "};\n"; // xkb_keycodes
    }

    /* Set up default types (xkbcommon automatically assigns these to
     * symbols, but doesn't have shift info) */
    keymap +=
        "xkb_types \"core\" {\n"
        "virtual_modifiers NumLock,Alt,LevelThree;\n"
        "type \"ONE_LEVEL\" {\n"
            "modifiers= none;\n"
            "level_name[Level1] = \"Any\";\n"
        "};\n"
        "type \"TWO_LEVEL\" {\n"
            "modifiers= Shift;\n"
            "map[Shift]= Level2;\n"
            "level_name[Level1] = \"Base\";\n"
            "level_name[Level2] = \"Shift\";\n"
        "};\n"
        "type \"ALPHABETIC\" {\n"
            "modifiers= Shift+Lock;\n"
            "map[Shift]= Level2;\n"
            "map[Lock]= Level2;\n"
            "level_name[Level1] = \"Base\";\n"
            "level_name[Level2] = \"Caps\";\n"
        "};\n"
        "type \"KEYPAD\" {\n"
            "modifiers= Shift+NumLock;\n"
            "map[Shift]= Level2;\n"
            "map[NumLock]= Level2;\n"
            "level_name[Level1] = \"Base\";\n"
            "level_name[Level2] = \"Number\";\n"
        "};\n"
        "type \"FOUR_LEVEL\" {\n"
            "modifiers= Shift+LevelThree;\n"
            "map[Shift]= Level2;\n"
            "map[LevelThree]= Level3;\n"
            "map[Shift+LevelThree]= Level4;\n"
            "level_name[Level1] = \"Base\";\n"
            "level_name[Level2] = \"Shift\";\n"
            "level_name[Level3] = \"Alt Base\";\n"
            "level_name[Level4] = \"Shift Alt\";\n"
        "};\n"
        "type \"FOUR_LEVEL_ALPHABETIC\" {\n"
            "modifiers= Shift+Lock+LevelThree;\n"
            "map[Shift]= Level2;\n"
            "map[Lock]= Level2;\n"
            "map[LevelThree]= Level3;\n"
            "map[Shift+LevelThree]= Level4;\n"
            "map[Lock+LevelThree]= Level4;\n"
            "map[Shift+Lock+LevelThree]= Level3;\n"
            "level_name[Level1] = \"Base\";\n"
            "level_name[Level2] = \"Shift\";\n"
            "level_name[Level3] = \"Alt Base\";\n"
            "level_name[Level4] = \"Shift Alt\";\n"
        "};\n"
        "type \"FOUR_LEVEL_SEMIALPHABETIC\" {\n"
            "modifiers= Shift+Lock+LevelThree;\n"
            "map[Shift]= Level2;\n"
            "map[Lock]= Level2;\n"
            "map[LevelThree]= Level3;\n"
            "map[Shift+LevelThree]= Level4;\n"
            "map[Lock+LevelThree]= Level3;\n"
            "preserve[Lock+LevelThree]= Lock;\n"
            "map[Shift+Lock+LevelThree]= Level4;\n"
            "preserve[Shift+Lock+LevelThree]= Lock;\n"
            "level_name[Level1] = \"Base\";\n"
            "level_name[Level2] = \"Shift\";\n"
            "level_name[Level3] = \"Alt Base\";\n"
            "level_name[Level4] = \"Shift Alt\";\n"
        "};\n"
        "type \"FOUR_LEVEL_KEYPAD\" {\n"
            "modifiers= Shift+NumLock+LevelThree;\n"
            "map[Shift]= Level2;\n"
            "map[NumLock]= Level2;\n"
            "map[LevelThree]= Level3;\n"
            "map[Shift+LevelThree]= Level4;\n"
            "map[NumLock+LevelThree]= Level4;\n"
            "map[Shift+NumLock+LevelThree]= Level3;\n"
            "level_name[Level1] = \"Base\";\n"
            "level_name[Level2] = \"Number\";\n"
            "level_name[Level3] = \"Alt Base\";\n"
            "level_name[Level4] = \"Alt Number\";\n"
        "};\n"
        "};\n"; // xkb_types

    // Generate mapping between symbolic names and keysyms
    {
        QVector<xcb_keysym_t> xkeymap;
        int keysymsPerKeycode = 0;
        {
            int keycodeCount = maxKeycode - minKeycode + 1;
            if (auto keymapReply = Q_XCB_REPLY(xcb_get_keyboard_mapping, xcb_connection(),
                                               minKeycode, keycodeCount)) {
                keysymsPerKeycode = keymapReply->keysyms_per_keycode;
                int numSyms = keycodeCount * keysymsPerKeycode;
                auto keymapPtr = xcb_get_keyboard_mapping_keysyms(keymapReply.get());
                xkeymap.resize(numSyms);
                for (int i = 0; i < numSyms; i++)
                    xkeymap[i] = keymapPtr[i];
            }
        }
        if (xkeymap.isEmpty())
            return nullptr;

        static const char *const builtinModifiers[] =
        { "Shift", "Lock", "Control", "Mod1", "Mod2", "Mod3", "Mod4", "Mod5" };

        /* Level 3 symbols (e.g. AltGr+something) seem to come in two flavors:
         * - as a proper level 3 in group 1, at least on recent X.org versions
         * - 'disguised' as group 2, on 'legacy' X servers
         * In the 2nd case, remap group 2 to level 3, that seems to work better
         * in practice */
        bool mapGroup2ToLevel3 = keysymsPerKeycode < 5;

        keymap += "xkb_symbols \"core\" {\n";
        for (int code = minKeycode; code <= maxKeycode; code++) {
            auto codeMap = xkeymap.constData() + (code - minKeycode) * keysymsPerKeycode;

            const int maxGroup1 = 4; // We only support 4 shift states anyway
            const int maxGroup2 = 2; // Only 3rd and 4th keysym are group 2
            xcb_keysym_t symbolsGroup1[maxGroup1];
            xcb_keysym_t symbolsGroup2[maxGroup2];
            for (int i = 0; i < maxGroup1 + maxGroup2; i++) {
                xcb_keysym_t sym = i < keysymsPerKeycode ? codeMap[i] : XKB_KEY_NoSymbol;
                if (mapGroup2ToLevel3) {
                    // Merge into single group
                    if (i < maxGroup1)
                        symbolsGroup1[i] = sym;
                } else {
                    // Preserve groups
                    if (i < 2)
                        symbolsGroup1[i] = sym;
                    else if (i < 4)
                        symbolsGroup2[i - 2] = sym;
                    else
                        symbolsGroup1[i - 2] = sym;
                }
            }

            /* Fix symbols so the unshifted and shifted symbols have
             * lower resp. upper case */
            if (auto lowered = getUnshiftedXKey(symbolsGroup1[0], symbolsGroup1[1])) {
                symbolsGroup1[1] = symbolsGroup1[0];
                symbolsGroup1[0] = lowered;
            }
            if (auto lowered = getUnshiftedXKey(symbolsGroup2[0], symbolsGroup2[1])) {
                symbolsGroup2[1] = symbolsGroup2[0];
                symbolsGroup2[0] = lowered;
            }

            QByteArray groupStr1 = symbolsGroupString(symbolsGroup1, maxGroup1);
            if (groupStr1.isEmpty())
                continue;

            keymap += "key <K" + QByteArray::number(code) + "> { ";
            keymap += "symbols[Group1] = [ " + groupStr1 + " ]";
            QByteArray groupStr2 = symbolsGroupString(symbolsGroup2, maxGroup2);
            if (!groupStr2.isEmpty())
                keymap += ", symbols[Group2] = [ " + groupStr2 + " ]";

            // See if this key code is for a modifier
            xcb_keysym_t modifierSym = XKB_KEY_NoSymbol;
            for (int symIndex = 0; symIndex < keysymsPerKeycode; symIndex++) {
                xcb_keysym_t sym = codeMap[symIndex];

                if (sym == XKB_KEY_Alt_L
                    || sym == XKB_KEY_Meta_L
                    || sym == XKB_KEY_Mode_switch
                    || sym == XKB_KEY_Super_L
                    || sym == XKB_KEY_Super_R
                    || sym == XKB_KEY_Hyper_L
                    || sym == XKB_KEY_Hyper_R) {
                    modifierSym = sym;
                    break;
                }
            }

            // AltGr
            if (modifierSym == XKB_KEY_Mode_switch)
                keymap += ", virtualMods=LevelThree";
            keymap += " };\n"; // key

            // Generate modifier mappings
            int modNum = keysymMods.value(modifierSym, -1);
            if (modNum != -1) {
                // Here modNum is always < 8 (see keysymsToModifiers())
                keymap += QByteArray("modifier_map ") + builtinModifiers[modNum]
                    + " { <K" + QByteArray::number(code) + "> };\n";
            }
        }
        // TODO: indicators?
        keymap += "};\n"; // xkb_symbols
    }

    // We need an "Alt" modifier, provide via the xkb_compatibility section
    keymap +=
        "xkb_compatibility \"core\" {\n"
        "virtual_modifiers NumLock,Alt,LevelThree;\n"
        "interpret Alt_L+AnyOf(all) {\n"
            "virtualModifier= Alt;\n"
            "action= SetMods(modifiers=modMapMods,clearLocks);\n"
        "};\n"
        "interpret Alt_R+AnyOf(all) {\n"
            "virtualModifier= Alt;\n"
            "action= SetMods(modifiers=modMapMods,clearLocks);\n"
        "};\n"
        "};\n";

    /* TODO: There is an issue with modifier state not being handled
     * correctly if using Xming with XKEYBOARD disabled. */

    keymap += "};\n"; // xkb_keymap

    return xkb_keymap_new_from_buffer(m_xkbContext.get(),
                                      keymap.constData(),
                                      keymap.size(),
                                      XKB_KEYMAP_FORMAT_TEXT_V1,
                                      XKB_KEYMAP_COMPILE_NO_FLAGS);
}

void QXcbKeyboard::updateKeymap(xcb_mapping_notify_event_t *event)
{
    if (connection()->hasXKB() || event->request == XCB_MAPPING_POINTER)
        return;

    xcb_refresh_keyboard_mapping(m_key_symbols, event);
    updateKeymap();
}

void QXcbKeyboard::updateKeymap()
{
    KeysymModifierMap keysymMods;
    if (!connection()->hasXKB())
        keysymMods = keysymsToModifiers();
    updateModifiers(keysymMods);

    m_config = true;

    if (!m_xkbContext) {
        m_xkbContext.reset(xkb_context_new(XKB_CONTEXT_NO_DEFAULT_INCLUDES));
        if (!m_xkbContext) {
            qCWarning(lcQpaKeyboard, "failed to create XKB context");
            m_config = false;
            return;
        }
        xkb_log_level logLevel = lcQpaKeyboard().isDebugEnabled() ?
                                 XKB_LOG_LEVEL_DEBUG : XKB_LOG_LEVEL_CRITICAL;
        xkb_context_set_log_level(m_xkbContext.get(), logLevel);
    }

#if QT_CONFIG(xkb)
    if (connection()->hasXKB()) {
        m_xkbKeymap.reset(xkb_x11_keymap_new_from_device(m_xkbContext.get(), xcb_connection(),
                                                         core_device_id, XKB_KEYMAP_COMPILE_NO_FLAGS));
        if (m_xkbKeymap)
            m_xkbState.reset(xkb_x11_state_new_from_device(m_xkbKeymap.get(), xcb_connection(), core_device_id));
    } else {
#endif
        m_xkbKeymap.reset(keymapFromCore(keysymMods));
        if (m_xkbKeymap)
            m_xkbState.reset(xkb_state_new(m_xkbKeymap.get()));
#if QT_CONFIG(xkb)
    }
#endif

    if (!m_xkbKeymap) {
        qCWarning(lcQpaKeyboard, "failed to compile a keymap");
        m_config = false;
        return;
    }
    if (!m_xkbState) {
        qCWarning(lcQpaKeyboard, "failed to create XKB state");
        m_config = false;
        return;
    }

    updateXKBMods();

    QXkbCommon::verifyHasLatinLayout(m_xkbKeymap.get());
}

QList<int> QXcbKeyboard::possibleKeys(const QKeyEvent *event) const
{
    return QXkbCommon::possibleKeys(m_xkbState.get(), event, m_superAsMeta, m_hyperAsMeta);
}

#if QT_CONFIG(xkb)
void QXcbKeyboard::updateXKBState(xcb_xkb_state_notify_event_t *state)
{
    if (m_config && connection()->hasXKB()) {
        const xkb_state_component changedComponents
                = xkb_state_update_mask(m_xkbState.get(),
                                  state->baseMods,
                                  state->latchedMods,
                                  state->lockedMods,
                                  state->baseGroup,
                                  state->latchedGroup,
                                  state->lockedGroup);

        handleStateChanges(changedComponents);
    }
}
#endif

static xkb_layout_index_t lockedGroup(quint16 state)
{
    return (state >> 13) & 3; // bits 13 and 14 report the state keyboard group
}

void QXcbKeyboard::updateXKBStateFromCore(quint16 state)
{
    if (m_config && !connection()->hasXKB()) {
        struct xkb_state *xkbState = m_xkbState.get();
        xkb_mod_mask_t modsDepressed = xkb_state_serialize_mods(xkbState, XKB_STATE_MODS_DEPRESSED);
        xkb_mod_mask_t modsLatched = xkb_state_serialize_mods(xkbState, XKB_STATE_MODS_LATCHED);
        xkb_mod_mask_t modsLocked = xkb_state_serialize_mods(xkbState, XKB_STATE_MODS_LOCKED);
        xkb_mod_mask_t xkbMask = xkbModMask(state);

        xkb_mod_mask_t latched = modsLatched & xkbMask;
        xkb_mod_mask_t locked = modsLocked & xkbMask;
        xkb_mod_mask_t depressed = modsDepressed & xkbMask;
        // set modifiers in depressed if they don't appear in any of the final masks
        depressed |= ~(depressed | latched | locked) & xkbMask;

        xkb_state_component changedComponents = xkb_state_update_mask(
                    xkbState, depressed, latched, locked, 0, 0, lockedGroup(state));

        handleStateChanges(changedComponents);
    }
}

#if QT_CONFIG(xcb_xinput)
void QXcbKeyboard::updateXKBStateFromXI(void *modInfo, void *groupInfo)
{
    if (m_config && !connection()->hasXKB()) {
        auto *mods = static_cast<xcb_input_modifier_info_t *>(modInfo);
        auto *group = static_cast<xcb_input_group_info_t *>(groupInfo);
        const xkb_state_component changedComponents
                = xkb_state_update_mask(m_xkbState.get(),
                                        mods->base,
                                        mods->latched,
                                        mods->locked,
                                        group->base,
                                        group->latched,
                                        group->locked);

        handleStateChanges(changedComponents);
    }
}
#endif

void QXcbKeyboard::handleStateChanges(xkb_state_component changedComponents)
{
    // Note: Ubuntu (with Unity) always creates a new keymap when layout is changed
    // via system settings, which means that the layout change would not be detected
    // by this code. That can be solved by emitting KeyboardLayoutChange also from updateKeymap().
    if ((changedComponents & XKB_STATE_LAYOUT_EFFECTIVE) == XKB_STATE_LAYOUT_EFFECTIVE)
        qCDebug(lcQpaKeyboard, "TODO: Support KeyboardLayoutChange on QPA (QTBUG-27681)");
}

xkb_mod_mask_t QXcbKeyboard::xkbModMask(quint16 state)
{
    xkb_mod_mask_t xkb_mask = 0;

    if ((state & XCB_MOD_MASK_SHIFT) && xkb_mods.shift != XKB_MOD_INVALID)
        xkb_mask |= (1 << xkb_mods.shift);
    if ((state & XCB_MOD_MASK_LOCK) && xkb_mods.lock != XKB_MOD_INVALID)
        xkb_mask |= (1 << xkb_mods.lock);
    if ((state & XCB_MOD_MASK_CONTROL) && xkb_mods.control != XKB_MOD_INVALID)
        xkb_mask |= (1 << xkb_mods.control);
    if ((state & XCB_MOD_MASK_1) && xkb_mods.mod1 != XKB_MOD_INVALID)
        xkb_mask |= (1 << xkb_mods.mod1);
    if ((state & XCB_MOD_MASK_2) && xkb_mods.mod2 != XKB_MOD_INVALID)
        xkb_mask |= (1 << xkb_mods.mod2);
    if ((state & XCB_MOD_MASK_3) && xkb_mods.mod3 != XKB_MOD_INVALID)
        xkb_mask |= (1 << xkb_mods.mod3);
    if ((state & XCB_MOD_MASK_4) && xkb_mods.mod4 != XKB_MOD_INVALID)
        xkb_mask |= (1 << xkb_mods.mod4);
    if ((state & XCB_MOD_MASK_5) && xkb_mods.mod5 != XKB_MOD_INVALID)
        xkb_mask |= (1 << xkb_mods.mod5);

    return xkb_mask;
}

void QXcbKeyboard::updateXKBMods()
{
    xkb_mods.shift = xkb_keymap_mod_get_index(m_xkbKeymap.get(), XKB_MOD_NAME_SHIFT);
    xkb_mods.lock = xkb_keymap_mod_get_index(m_xkbKeymap.get(), XKB_MOD_NAME_CAPS);
    xkb_mods.control = xkb_keymap_mod_get_index(m_xkbKeymap.get(), XKB_MOD_NAME_CTRL);
    xkb_mods.mod1 = xkb_keymap_mod_get_index(m_xkbKeymap.get(), "Mod1");
    xkb_mods.mod2 = xkb_keymap_mod_get_index(m_xkbKeymap.get(), "Mod2");
    xkb_mods.mod3 = xkb_keymap_mod_get_index(m_xkbKeymap.get(), "Mod3");
    xkb_mods.mod4 = xkb_keymap_mod_get_index(m_xkbKeymap.get(), "Mod4");
    xkb_mods.mod5 = xkb_keymap_mod_get_index(m_xkbKeymap.get(), "Mod5");
}

QXcbKeyboard::QXcbKeyboard(QXcbConnection *connection)
    : QXcbObject(connection)
{
#if QT_CONFIG(xkb)
    core_device_id = 0;
    if (connection->hasXKB()) {
        selectEvents();
        core_device_id = xkb_x11_get_core_keyboard_device_id(xcb_connection());
        if (core_device_id == -1) {
            qCWarning(lcQpaXcb, "failed to get core keyboard device info");
            return;
        }
    } else {
#endif
        m_key_symbols = xcb_key_symbols_alloc(xcb_connection());
#if QT_CONFIG(xkb)
    }
#endif
    updateKeymap();
}

QXcbKeyboard::~QXcbKeyboard()
{
    if (m_key_symbols)
        xcb_key_symbols_free(m_key_symbols);
}

void QXcbKeyboard::initialize()
{
    auto inputContext = QGuiApplicationPrivate::platformIntegration()->inputContext();
    QXkbCommon::setXkbContext(inputContext, m_xkbContext.get());
}

void QXcbKeyboard::selectEvents()
{
#if QT_CONFIG(xkb)
    const uint16_t required_map_parts = (XCB_XKB_MAP_PART_KEY_TYPES |
        XCB_XKB_MAP_PART_KEY_SYMS |
        XCB_XKB_MAP_PART_MODIFIER_MAP |
        XCB_XKB_MAP_PART_EXPLICIT_COMPONENTS |
        XCB_XKB_MAP_PART_KEY_ACTIONS |
        XCB_XKB_MAP_PART_KEY_BEHAVIORS |
        XCB_XKB_MAP_PART_VIRTUAL_MODS |
        XCB_XKB_MAP_PART_VIRTUAL_MOD_MAP);

    const uint16_t required_events = (XCB_XKB_EVENT_TYPE_NEW_KEYBOARD_NOTIFY |
        XCB_XKB_EVENT_TYPE_MAP_NOTIFY |
        XCB_XKB_EVENT_TYPE_STATE_NOTIFY);

    // XKB events are reported to all interested clients without regard
    // to the current keyboard input focus or grab state
    xcb_void_cookie_t select = xcb_xkb_select_events_checked(
                xcb_connection(),
                XCB_XKB_ID_USE_CORE_KBD,
                required_events,
                0,
                required_events,
                required_map_parts,
                required_map_parts,
                0);

    xcb_generic_error_t *error = xcb_request_check(xcb_connection(), select);
    if (error) {
        free(error);
        qCWarning(lcQpaXcb, "failed to select notify events from XKB");
    }
#endif
}

void QXcbKeyboard::updateVModMapping()
{
#if QT_CONFIG(xkb)
    xcb_xkb_get_names_value_list_t names_list;

    memset(&vmod_masks, 0, sizeof(vmod_masks));

    auto name_reply = Q_XCB_REPLY(xcb_xkb_get_names, xcb_connection(),
                                  XCB_XKB_ID_USE_CORE_KBD,
                                  XCB_XKB_NAME_DETAIL_VIRTUAL_MOD_NAMES);
    if (!name_reply) {
        qWarning("Qt: failed to retrieve the virtual modifier names from XKB");
        return;
    }

    const void *buffer = xcb_xkb_get_names_value_list(name_reply.get());
    xcb_xkb_get_names_value_list_unpack(buffer,
                                        name_reply->nTypes,
                                        name_reply->indicators,
                                        name_reply->virtualMods,
                                        name_reply->groupNames,
                                        name_reply->nKeys,
                                        name_reply->nKeyAliases,
                                        name_reply->nRadioGroups,
                                        name_reply->which,
                                        &names_list);

    int count = 0;
    uint vmod_mask, bit;
    char *vmod_name;
    vmod_mask = name_reply->virtualMods;
    // find the virtual modifiers for which names are defined.
    for (bit = 1; vmod_mask; bit <<= 1) {
        vmod_name = 0;

        if (!(vmod_mask & bit))
            continue;

        vmod_mask &= ~bit;
        // virtualModNames - the list of virtual modifier atoms beginning with the lowest-numbered
        // virtual modifier for which a name is defined and proceeding to the highest.
        QByteArray atomName = connection()->atomName(names_list.virtualModNames[count]);
        vmod_name = atomName.data();
        count++;

        if (!vmod_name)
            continue;

        // similarly we could retrieve NumLock, Super, Hyper modifiers if needed.
        if (qstrcmp(vmod_name, "Alt") == 0)
            vmod_masks.alt = bit;
        else if (qstrcmp(vmod_name, "Meta") == 0)
            vmod_masks.meta = bit;
        else if (qstrcmp(vmod_name, "AltGr") == 0)
            vmod_masks.altgr = bit;
        else if (qstrcmp(vmod_name, "Super") == 0)
            vmod_masks.super = bit;
        else if (qstrcmp(vmod_name, "Hyper") == 0)
            vmod_masks.hyper = bit;
    }
#endif
}

void QXcbKeyboard::updateVModToRModMapping()
{
#if QT_CONFIG(xkb)
    xcb_xkb_get_map_map_t map;

    memset(&rmod_masks, 0, sizeof(rmod_masks));

    auto map_reply = Q_XCB_REPLY(xcb_xkb_get_map,
                                 xcb_connection(),
                                 XCB_XKB_ID_USE_CORE_KBD,
                                 XCB_XKB_MAP_PART_VIRTUAL_MODS,
                                 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0);
    if (!map_reply) {
        qWarning("Qt: failed to retrieve the virtual modifier map from XKB");
        return;
    }

    const void *buffer = xcb_xkb_get_map_map(map_reply.get());
    xcb_xkb_get_map_map_unpack(buffer,
                               map_reply->nTypes,
                               map_reply->nKeySyms,
                               map_reply->nKeyActions,
                               map_reply->totalActions,
                               map_reply->totalKeyBehaviors,
                               map_reply->nVModMapKeys,
                               map_reply->totalKeyExplicit,
                               map_reply->totalModMapKeys,
                               map_reply->totalVModMapKeys,
                               map_reply->present,
                               &map);

    uint vmod_mask, bit;
    // the virtual modifiers mask for which a set of corresponding
    // real modifiers is to be returned
    vmod_mask = map_reply->virtualMods;
    int count = 0;

    for (bit = 1; vmod_mask; bit <<= 1) {
        uint modmap;

        if (!(vmod_mask & bit))
            continue;

        vmod_mask &= ~bit;
        // real modifier bindings for the specified virtual modifiers
        modmap = map.vmods_rtrn[count];
        count++;

        if (vmod_masks.alt == bit)
            rmod_masks.alt = modmap;
        else if (vmod_masks.meta == bit)
            rmod_masks.meta = modmap;
        else if (vmod_masks.altgr == bit)
            rmod_masks.altgr = modmap;
        else if (vmod_masks.super == bit)
            rmod_masks.super = modmap;
        else if (vmod_masks.hyper == bit)
            rmod_masks.hyper = modmap;
    }
#endif
}

// Small helper: set modifier bit, if modifier position is valid
static inline void applyModifier(uint *mask, int modifierBit)
{
    if (modifierBit >= 0 && modifierBit < 8)
        *mask |= 1 << modifierBit;
}

void QXcbKeyboard::updateModifiers(const KeysymModifierMap &keysymMods)
{
    if (connection()->hasXKB()) {
        updateVModMapping();
        updateVModToRModMapping();
    } else {
        memset(&rmod_masks, 0, sizeof(rmod_masks));
        // Compute X modifier bits for Qt modifiers
        applyModifier(&rmod_masks.alt,   keysymMods.value(XKB_KEY_Alt_L,       -1));
        applyModifier(&rmod_masks.alt,   keysymMods.value(XKB_KEY_Alt_R,       -1));
        applyModifier(&rmod_masks.meta,  keysymMods.value(XKB_KEY_Meta_L,      -1));
        applyModifier(&rmod_masks.meta,  keysymMods.value(XKB_KEY_Meta_R,      -1));
        applyModifier(&rmod_masks.altgr, keysymMods.value(XKB_KEY_Mode_switch, -1));
        applyModifier(&rmod_masks.super, keysymMods.value(XKB_KEY_Super_L,     -1));
        applyModifier(&rmod_masks.super, keysymMods.value(XKB_KEY_Super_R,     -1));
        applyModifier(&rmod_masks.hyper, keysymMods.value(XKB_KEY_Hyper_L,     -1));
        applyModifier(&rmod_masks.hyper, keysymMods.value(XKB_KEY_Hyper_R,     -1));
    }

    resolveMaskConflicts();
}

// Small helper: check if an array of xcb_keycode_t contains a certain code
static inline bool keycodes_contains(xcb_keycode_t *codes, xcb_keycode_t which)
{
    while (*codes != XCB_NO_SYMBOL) {
        if (*codes == which) return true;
        codes++;
    }
    return false;
}

QXcbKeyboard::KeysymModifierMap QXcbKeyboard::keysymsToModifiers()
{
    // The core protocol does not provide a convenient way to determine the mapping
    // of modifier bits. Clients must retrieve and search the modifier map to determine
    // the keycodes bound to each modifier, and then retrieve and search the keyboard
    // mapping to determine the keysyms bound to the keycodes. They must repeat this
    // process for all modifiers whenever any part of the modifier mapping is changed.

    KeysymModifierMap map;

    auto modMapReply = Q_XCB_REPLY(xcb_get_modifier_mapping, xcb_connection());
    if (!modMapReply) {
        qWarning("Qt: failed to get modifier mapping");
        return map;
    }

    // for Alt and Meta L and R are the same
    static const xcb_keysym_t symbols[] = {
        XKB_KEY_Alt_L, XKB_KEY_Meta_L, XKB_KEY_Mode_switch, XKB_KEY_Super_L, XKB_KEY_Super_R,
        XKB_KEY_Hyper_L, XKB_KEY_Hyper_R
    };
    static const size_t numSymbols = sizeof symbols / sizeof *symbols;

    // Figure out the modifier mapping, ICCCM 6.6
    xcb_keycode_t* modKeyCodes[numSymbols];
    for (size_t i = 0; i < numSymbols; ++i)
        modKeyCodes[i] = xcb_key_symbols_get_keycode(m_key_symbols, symbols[i]);

    xcb_keycode_t *modMap = xcb_get_modifier_mapping_keycodes(modMapReply.get());
    const int modMapLength = xcb_get_modifier_mapping_keycodes_length(modMapReply.get());
    /* For each modifier of "Shift, Lock, Control, Mod1, Mod2, Mod3,
     * Mod4, and Mod5" the modifier map contains keycodes_per_modifier
     * key codes that are associated with a modifier.
     *
     * As an example, take this 'xmodmap' output:
     *   xmodmap: up to 4 keys per modifier, (keycodes in parentheses):
     *
     *   shift       Shift_L (0x32),  Shift_R (0x3e)
     *   lock        Caps_Lock (0x42)
     *   control     Control_L (0x25),  Control_R (0x69)
     *   mod1        Alt_L (0x40),  Alt_R (0x6c),  Meta_L (0xcd)
     *   mod2        Num_Lock (0x4d)
     *   mod3
     *   mod4        Super_L (0x85),  Super_R (0x86),  Super_L (0xce),  Hyper_L (0xcf)
     *   mod5        ISO_Level3_Shift (0x5c),  Mode_switch (0xcb)
     *
     * The corresponding raw modifier map would contain keycodes for:
     *   Shift_L (0x32), Shift_R (0x3e), 0, 0,
     *   Caps_Lock (0x42), 0, 0, 0,
     *   Control_L (0x25), Control_R (0x69), 0, 0,
     *   Alt_L (0x40), Alt_R (0x6c), Meta_L (0xcd), 0,
     *   Num_Lock (0x4d), 0, 0, 0,
     *   0,0,0,0,
     *   Super_L (0x85),  Super_R (0x86),  Super_L (0xce),  Hyper_L (0xcf),
     *   ISO_Level3_Shift (0x5c),  Mode_switch (0xcb), 0, 0
     */

    /* Create a map between a modifier keysym (as per the symbols array)
     * and the modifier bit it's associated with (if any).
     * As modMap contains key codes, search modKeyCodes for a match;
     * if one is found we can look up the associated keysym.
     * Together with the modifier index this will be used
     * to compute a mapping between X modifier bits and Qt's
     * modifiers (Alt, Ctrl etc). */
    for (int i = 0; i < modMapLength; i++) {
        if (modMap[i] == XCB_NO_SYMBOL)
            continue;
        // Get key symbol for key code
        for (size_t k = 0; k < numSymbols; k++) {
            if (modKeyCodes[k] && keycodes_contains(modKeyCodes[k], modMap[i])) {
                // Key code is for modifier. Record mapping
                xcb_keysym_t sym = symbols[k];
                /* As per modMap layout explanation above, dividing
                 * by keycodes_per_modifier gives the 'row' in the
                 * modifier map, which in turn is the modifier bit. */
                map[sym] = i / modMapReply->keycodes_per_modifier;
                break;
            }
        }
    }

    for (size_t i = 0; i < numSymbols; ++i)
        free(modKeyCodes[i]);

    return map;
}

void QXcbKeyboard::resolveMaskConflicts()
{
    // if we don't have a meta key (or it's hidden behind alt), use super or hyper to generate
    // Qt::Key_Meta and Qt::MetaModifier, since most newer XFree86/Xorg installations map the Windows
    // key to Super
    if (rmod_masks.alt == rmod_masks.meta)
        rmod_masks.meta = 0;

    if (rmod_masks.meta == 0) {
        // no meta keys... s/meta/super,
        rmod_masks.meta = rmod_masks.super;
        if (rmod_masks.meta == 0) {
            // no super keys either? guess we'll use hyper then
            rmod_masks.meta = rmod_masks.hyper;
        }
    }

    // translate Super/Hyper keys to Meta if we're using them as the MetaModifier
    if (rmod_masks.meta && rmod_masks.meta == rmod_masks.super)
        m_superAsMeta = true;
    if (rmod_masks.meta && rmod_masks.meta == rmod_masks.hyper)
        m_hyperAsMeta = true;
}

void QXcbKeyboard::handleKeyEvent(xcb_window_t sourceWindow, QEvent::Type type, xcb_keycode_t code,
                                  quint16 state, xcb_timestamp_t time, bool fromSendEvent)
{
    if (!m_config)
        return;

    QXcbWindow *source = connection()->platformWindowFromId(sourceWindow);
    QXcbWindow *targetWindow = connection()->focusWindow() ? connection()->focusWindow() : source;
    if (!targetWindow || !source)
        return;
    if (type == QEvent::KeyPress)
        targetWindow->updateNetWmUserTime(time);

    QXkbCommon::ScopedXKBState sendEventState;
    if (fromSendEvent) {
        // Have a temporary keyboard state filled in from state
        // this way we allow for synthetic events to have different state
        // from the current state i.e. you can have Alt+Ctrl pressed
        // and receive a synthetic key event that has neither Alt nor Ctrl pressed
        sendEventState.reset(xkb_state_new(m_xkbKeymap.get()));
        if (!sendEventState)
            return;

        xkb_mod_mask_t depressed = xkbModMask(state);
        xkb_state_update_mask(sendEventState.get(), depressed, 0, 0, 0, 0, lockedGroup(state));
    }

    struct xkb_state *xkbState = fromSendEvent ? sendEventState.get() : m_xkbState.get();

    xcb_keysym_t sym = xkb_state_key_get_one_sym(xkbState, code);
    QString text = QXkbCommon::lookupString(xkbState, code);

    Qt::KeyboardModifiers modifiers = translateModifiers(state);
    if (QXkbCommon::isKeypad(sym))
        modifiers |= Qt::KeypadModifier;

    int qtcode = QXkbCommon::keysymToQtKey(sym, modifiers, xkbState, code, m_superAsMeta, m_hyperAsMeta);

    if (type == QEvent::KeyPress) {
        if (m_isAutoRepeat && m_autoRepeatCode != code)
            // Some other key was pressed while we are auto-repeating on a different key.
            m_isAutoRepeat = false;
    } else {
        m_isAutoRepeat = false;
        // Look at the next event in the queue to see if we are auto-repeating.
        connection()->eventQueue()->peek(QXcbEventQueue::PeekRetainMatch,
                                         [this, time, code](xcb_generic_event_t *event, int type) {
            if (type == XCB_KEY_PRESS) {
                auto keyPress = reinterpret_cast<xcb_key_press_event_t *>(event);
                m_isAutoRepeat = keyPress->time == time && keyPress->detail == code;
                if (m_isAutoRepeat)
                    m_autoRepeatCode = code;
            }
            return true;
        });
    }

    bool filtered = false;
    if (auto inputContext = QGuiApplicationPrivate::platformIntegration()->inputContext()) {
        QKeyEvent event(type, qtcode, modifiers, code, sym, state, text, m_isAutoRepeat, text.size());
        event.setTimestamp(time);
        filtered = inputContext->filterEvent(&event);
    }

    if (!filtered) {
        QWindow *window = targetWindow->window();
#ifndef QT_NO_CONTEXTMENU
        if (type == QEvent::KeyPress && qtcode == Qt::Key_Menu) {
            const QPoint globalPos = window->screen()->handle()->cursor()->pos();
            const QPoint pos = window->mapFromGlobal(globalPos);
            QWindowSystemInterface::handleContextMenuEvent(window, false, pos, globalPos, modifiers);
        }
#endif
        QWindowSystemInterface::handleExtendedKeyEvent(window, time, type, qtcode, modifiers,
                                                       code, sym, state, text, m_isAutoRepeat);
    }
}

static bool fromSendEvent(const void *event)
{
    // From X11 protocol: Every event contains an 8-bit type code. The most
    // significant bit in this code is set if the event was generated from
    // a SendEvent request.
    const xcb_generic_event_t *e = reinterpret_cast<const xcb_generic_event_t *>(event);
    return (e->response_type & 0x80) != 0;
}

void QXcbKeyboard::handleKeyPressEvent(const xcb_key_press_event_t *e)
{
    handleKeyEvent(e->event, QEvent::KeyPress, e->detail, e->state, e->time, fromSendEvent(e));
}

void QXcbKeyboard::handleKeyReleaseEvent(const xcb_key_release_event_t *e)
{
    handleKeyEvent(e->event, QEvent::KeyRelease, e->detail, e->state, e->time, fromSendEvent(e));
}

QT_END_NAMESPACE
