/****************************************************************************
**
** 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 "qwindowsinputcontext.h"
#include "qwindowscontext.h"
#include "qwindowswindow.h"
#include "qwindowsintegration.h"
#include "qwindowsmousehandler.h"

#include <QtCore/qdebug.h>
#include <QtCore/qobject.h>
#include <QtCore/qrect.h>
#include <QtCore/qtextboundaryfinder.h>
#include <QtCore/qoperatingsystemversion.h>

#include <QtGui/qevent.h>
#include <QtGui/qtextformat.h>
#include <QtGui/qpalette.h>
#include <QtGui/qguiapplication.h>

#include <private/qhighdpiscaling_p.h>

#include <algorithm>

QT_BEGIN_NAMESPACE

static inline QByteArray debugComposition(int lParam)
{
    QByteArray str;
    if (lParam & GCS_RESULTSTR)
        str += "RESULTSTR ";
    if (lParam & GCS_COMPSTR)
        str += "COMPSTR ";
    if (lParam & GCS_COMPATTR)
        str += "COMPATTR ";
    if (lParam & GCS_CURSORPOS)
        str += "CURSORPOS ";
    if (lParam & GCS_COMPCLAUSE)
        str += "COMPCLAUSE ";
    if (lParam & CS_INSERTCHAR)
        str += "INSERTCHAR ";
    if (lParam & CS_NOMOVECARET)
        str += "NOMOVECARET ";
    return str;
}

// Cancel current IME composition.
static inline void imeNotifyCancelComposition(HWND hwnd)
{
    if (!hwnd) {
        qWarning() << __FUNCTION__ << "called with" << hwnd;
        return;
    }
    const HIMC himc = ImmGetContext(hwnd);
    ImmNotifyIME(himc, NI_COMPOSITIONSTR, CPS_CANCEL, 0);
    ImmReleaseContext(hwnd, himc);
}

static inline LCID languageIdFromLocaleId(LCID localeId)
{
    return localeId & 0xFFFF;
}

static inline LCID currentInputLanguageId()
{
    return languageIdFromLocaleId(reinterpret_cast<quintptr>(GetKeyboardLayout(0)));
}

Q_CORE_EXPORT QLocale qt_localeFromLCID(LCID id); // from qlocale_win.cpp

/*!
    \class QWindowsInputContext
    \brief Windows Input context implementation

    Handles input of foreign characters (particularly East Asian)
    languages.

    \section1 Testing

    \list
    \li Install the East Asian language support and choose Japanese (say).
    \li Compile the \a mainwindows/mdi example and open a text window.
    \li In the language bar, switch to Japanese and choose the
       Input method 'Hiragana'.
    \li In a text editor control, type the syllable \a 'la'.
       Underlined characters show up, indicating that there is completion
       available. Press the Space key two times. A completion popup occurs
       which shows the options.
    \endlist

    Reconversion: Input texts can be 'converted' into different
    input modes or more completion suggestions can be made based on
    context to correct errors. This is bound to the 'Conversion key'
    (F13-key in Japanese, which can be changed in the
    configuration). After writing text, pressing the key selects text
    and triggers a conversion popup, which shows the alternatives for
    the word.

    \section1 Interaction

    When the user activates input methods,  Windows sends
    WM_IME_STARTCOMPOSITION, WM_IME_COMPOSITION,
    WM_IME_ENDCOMPOSITION messages that trigger startComposition(),
    composition(), endComposition(), respectively. No key events are sent.

    composition() determines the markup of the pre-edit or selected
    text and/or the final text and sends that to the focus object.

    In between startComposition(), endComposition(), multiple
    compositions may happen (isComposing).

    update() is called to synchronize the position of the candidate
    window with the microfocus rectangle of the focus object.
    Also, a hidden caret is moved along with that position,
    which is important for some Chinese input methods.

    reset() is called to cancel a composition if the mouse is
    moved outside or for example some Undo/Redo operation is
    invoked.

    \note Mouse interaction of popups with
    QtWindows::InputMethodOpenCandidateWindowEvent and
    QtWindows::InputMethodCloseCandidateWindowEvent
    needs to be checked (mouse grab might interfere with candidate window).

    \internal
    \ingroup qt-lighthouse-win
*/


QWindowsInputContext::QWindowsInputContext() :
    m_WM_MSIME_MOUSE(RegisterWindowMessage(L"MSIMEMouseOperation")),
    m_languageId(currentInputLanguageId()),
    m_locale(qt_localeFromLCID(m_languageId))
{
    const quint32 bmpData = 0;
    m_transparentBitmap = CreateBitmap(2, 2, 1, 1, &bmpData);

    connect(QGuiApplication::inputMethod(), &QInputMethod::cursorRectangleChanged,
            this, &QWindowsInputContext::cursorRectChanged);
}

QWindowsInputContext::~QWindowsInputContext()
{
    if (m_transparentBitmap)
        DeleteObject(m_transparentBitmap);
}

bool QWindowsInputContext::hasCapability(Capability capability) const
{
    switch (capability) {
    case QPlatformInputContext::HiddenTextCapability:
        return false; // QTBUG-40691, do not show IME on desktop for password entry fields.
    default:
        break;
    }
    return true;
}

/*!
    \brief Cancels a composition.
*/

void QWindowsInputContext::reset()
{
    QPlatformInputContext::reset();
    if (!m_compositionContext.hwnd)
        return;
    qCDebug(lcQpaInputMethods) << __FUNCTION__;
    if (m_compositionContext.isComposing && !m_compositionContext.focusObject.isNull()) {
        QInputMethodEvent event;
        if (!m_compositionContext.composition.isEmpty())
            event.setCommitString(m_compositionContext.composition);
        QCoreApplication::sendEvent(m_compositionContext.focusObject, &event);
        endContextComposition();
    }
    imeNotifyCancelComposition(m_compositionContext.hwnd);
    doneContext();
}

void QWindowsInputContext::setFocusObject(QObject *)
{
    // ### fixme: On Windows 8.1, it has been observed that the Input context
    // remains active when this happens resulting in a lock-up. Consecutive
    // key events still have VK_PROCESSKEY set and are thus ignored.
    if (m_compositionContext.isComposing)
        reset();
    updateEnabled();
}

HWND QWindowsInputContext::getVirtualKeyboardWindowHandle() const
{
    return ::FindWindowA("IPTip_Main_Window", nullptr);
}

QRectF QWindowsInputContext::keyboardRect() const
{
    if (HWND hwnd = getVirtualKeyboardWindowHandle()) {
        RECT rect;
        if (::GetWindowRect(hwnd, &rect)) {
            return QRectF(rect.left, rect.top, rect.right - rect.left, rect.bottom - rect.top);
        }
    }
    return QRectF();
}

bool QWindowsInputContext::isInputPanelVisible() const
{
    HWND hwnd = getVirtualKeyboardWindowHandle();
    if (hwnd && ::IsWindowEnabled(hwnd) && ::IsWindowVisible(hwnd))
        return true;
    // check if the Input Method Editor is open
    if (inputMethodAccepted()) {
        if (QWindow *window = QGuiApplication::focusWindow()) {
            if (QWindowsWindow *platformWindow = QWindowsWindow::windowsWindowOf(window)) {
                if (HIMC himc = ImmGetContext(platformWindow->handle()))
                    return ImmGetOpenStatus(himc);
            }
        }
    }
    return false;
}

void QWindowsInputContext::showInputPanel()
{
    if (!inputMethodAccepted())
        return;

    QWindow *window = QGuiApplication::focusWindow();
    if (!window)
        return;

    QWindowsWindow *platformWindow = QWindowsWindow::windowsWindowOf(window);
    if (!platformWindow)
        return;

    // Create an invisible 2x2 caret, which will be kept at the microfocus position.
    // It is important for triggering the on-screen keyboard in touch-screen devices,
    // for some Chinese input methods, and for Magnifier's "follow keyboard" feature.
    if (!m_caretCreated && m_transparentBitmap)
        m_caretCreated = CreateCaret(platformWindow->handle(), m_transparentBitmap, 0, 0);

    // For some reason, the on-screen keyboard is only triggered on the Surface
    // with Windows 10 if the Windows IME is (re)enabled _after_ the caret is shown.
    if (m_caretCreated) {
        cursorRectChanged();
        // We only call ShowCaret() on Windows 10 after 1703 as in earlier versions
        // the caret would actually be visible (QTBUG-74492) and the workaround for
        // the Surface seems unnecessary there anyway. But leave it hidden for IME.
        // Only trigger the native OSK if the Qt OSK is not in use.
        static bool imModuleEmpty = qEnvironmentVariableIsEmpty("QT_IM_MODULE");
        if (imModuleEmpty
                && QOperatingSystemVersion::current()
                    >= QOperatingSystemVersion(QOperatingSystemVersion::Windows, 10, 0, 16299)) {
            ShowCaret(platformWindow->handle());
        } else {
            HideCaret(platformWindow->handle());
        }
        setWindowsImeEnabled(platformWindow, false);
        setWindowsImeEnabled(platformWindow, true);
    }
}

void QWindowsInputContext::hideInputPanel()
{
    if (m_caretCreated) {
        DestroyCaret();
        m_caretCreated = false;
    }
}

void QWindowsInputContext::updateEnabled()
{
    if (!QGuiApplication::focusObject())
        return;
    if (QWindowsWindow *platformWindow = QWindowsWindow::windowsWindowOf(QGuiApplication::focusWindow())) {
        const bool accepted = inputMethodAccepted();
        if (QWindowsContext::verbose > 1)
            qCDebug(lcQpaInputMethods) << __FUNCTION__ << platformWindow->window() << "accepted=" << accepted;
        QWindowsInputContext::setWindowsImeEnabled(platformWindow, accepted);
    }
}

void QWindowsInputContext::setWindowsImeEnabled(QWindowsWindow *platformWindow, bool enabled)
{
    if (!platformWindow)
        return;
    if (enabled) {
        // Re-enable Windows IME by associating default context.
        ImmAssociateContextEx(platformWindow->handle(), nullptr, IACE_DEFAULT);
    } else {
        // Disable Windows IME by associating 0 context.
        ImmAssociateContext(platformWindow->handle(), nullptr);
    }
}

/*!
    \brief Moves the candidate window along with microfocus of the focus object.
*/

void QWindowsInputContext::update(Qt::InputMethodQueries queries)
{
    if (queries & Qt::ImEnabled)
        updateEnabled();
    QPlatformInputContext::update(queries);
}

void QWindowsInputContext::cursorRectChanged()
{
    QWindow *window = QGuiApplication::focusWindow();
    if (!window)
        return;

    qreal factor = QHighDpiScaling::factor(window);

    const QInputMethod *inputMethod = QGuiApplication::inputMethod();
    const QRectF cursorRectangleF = inputMethod->cursorRectangle();
    if (!cursorRectangleF.isValid())
        return;

    const QRect cursorRectangle =
        QRectF(cursorRectangleF.topLeft() * factor, cursorRectangleF.size() * factor).toRect();

    if (m_caretCreated)
        SetCaretPos(cursorRectangle.x(), cursorRectangle.y());

    if (!m_compositionContext.hwnd)
        return;

    qCDebug(lcQpaInputMethods) << __FUNCTION__<< cursorRectangle;

    const HIMC himc = ImmGetContext(m_compositionContext.hwnd);
    if (!himc)
        return;
    // Move candidate list window to the microfocus position.
    COMPOSITIONFORM cf;
    // ### need X-like inputStyle config settings
    cf.dwStyle = CFS_FORCE_POSITION;
    cf.ptCurrentPos.x = cursorRectangle.x();
    cf.ptCurrentPos.y = cursorRectangle.y();

    CANDIDATEFORM candf;
    candf.dwIndex = 0;
    candf.dwStyle = CFS_EXCLUDE;
    candf.ptCurrentPos.x = cursorRectangle.x();
    candf.ptCurrentPos.y = cursorRectangle.y() + cursorRectangle.height();
    candf.rcArea.left = cursorRectangle.x();
    candf.rcArea.top = cursorRectangle.y();
    candf.rcArea.right = cursorRectangle.x() + cursorRectangle.width();
    candf.rcArea.bottom = cursorRectangle.y() + cursorRectangle.height();

    ImmSetCompositionWindow(himc, &cf);
    ImmSetCandidateWindow(himc, &candf);
    ImmReleaseContext(m_compositionContext.hwnd, himc);
}

void QWindowsInputContext::invokeAction(QInputMethod::Action action, int cursorPosition)
{
    if (action != QInputMethod::Click || !m_compositionContext.hwnd) {
        QPlatformInputContext::invokeAction(action, cursorPosition);
        return;
    }

    qCDebug(lcQpaInputMethods) << __FUNCTION__ << cursorPosition << action;
    if (cursorPosition < 0 || cursorPosition > m_compositionContext.composition.size())
        reset();

    // Magic code that notifies Japanese IME about the cursor
    // position.
    const HIMC himc = ImmGetContext(m_compositionContext.hwnd);
    const HWND imeWindow = ImmGetDefaultIMEWnd(m_compositionContext.hwnd);
    const WPARAM mouseOperationCode =
        MAKELONG(MAKEWORD(MK_LBUTTON, cursorPosition == 0 ? 2 : 1), cursorPosition);
    SendMessage(imeWindow, m_WM_MSIME_MOUSE, mouseOperationCode, LPARAM(himc));
    ImmReleaseContext(m_compositionContext.hwnd, himc);
}

static inline QString getCompositionString(HIMC himc, DWORD dwIndex)
{
    enum { bufferSize = 256 };
    wchar_t buffer[bufferSize];
    const int length = ImmGetCompositionString(himc, dwIndex, buffer, bufferSize * sizeof(wchar_t));
    return QString::fromWCharArray(buffer,  size_t(length) / sizeof(wchar_t));
}

// Determine the converted string range as pair of start/length to be selected.
static inline void getCompositionStringConvertedRange(HIMC himc, int *selStart, int *selLength)
{
    enum { bufferSize = 256 };
    // Find the range of bytes with ATTR_TARGET_CONVERTED set.
    char attrBuffer[bufferSize];
    *selStart = *selLength = 0;
    if (const int attrLength = ImmGetCompositionString(himc, GCS_COMPATTR, attrBuffer, bufferSize)) {
        int start = 0;
        while (start < attrLength && !(attrBuffer[start] & ATTR_TARGET_CONVERTED))
            start++;
        if (start < attrLength) {
            int end = start + 1;
            while (end < attrLength && (attrBuffer[end] & ATTR_TARGET_CONVERTED))
                end++;
            *selStart = start;
            *selLength = end - start;
        }
    }
}

enum StandardFormat {
    PreeditFormat,
    SelectionFormat
};

static inline QTextFormat standardFormat(StandardFormat format)
{
    QTextCharFormat result;
    switch (format) {
    case PreeditFormat:
        result.setUnderlineStyle(QTextCharFormat::DashUnderline);
        break;
    case SelectionFormat: {
        // TODO: Should be that of the widget?
        const QPalette palette = QGuiApplication::palette();
        const QColor background = palette.text().color();
        result.setBackground(QBrush(background));
        result.setForeground(palette.window());
        break;
    }
    }
    return result;
}

bool QWindowsInputContext::startComposition(HWND hwnd)
{
    QObject *fo = QGuiApplication::focusObject();
    if (!fo)
        return false;
    // This should always match the object.
    QWindow *window = QGuiApplication::focusWindow();
    if (!window)
        return false;
    qCDebug(lcQpaInputMethods) << __FUNCTION__ << fo << window << "language=" << m_languageId;
    if (!fo || QWindowsWindow::handleOf(window) != hwnd)
        return false;
    initContext(hwnd, fo);
    startContextComposition();
    return true;
}

void QWindowsInputContext::startContextComposition()
{
    if (m_compositionContext.isComposing) {
        qWarning("%s: Called out of sequence.", __FUNCTION__);
        return;
    }
    m_compositionContext.isComposing = true;
    m_compositionContext.composition.clear();
    m_compositionContext.position = 0;
    cursorRectChanged(); // position cursor initially.
    update(Qt::ImQueryAll);
}

void QWindowsInputContext::endContextComposition()
{
    if (!m_compositionContext.isComposing) {
        qWarning("%s: Called out of sequence.", __FUNCTION__);
        return;
    }
    m_compositionContext.composition.clear();
    m_compositionContext.position = 0;
    m_compositionContext.isComposing = false;
}

// Create a list of markup attributes for QInputMethodEvent
// to display the selected part of the intermediate composition
// result differently.
static inline QList<QInputMethodEvent::Attribute>
    intermediateMarkup(int position, int compositionLength,
                       int selStart, int selLength)
{
    QList<QInputMethodEvent::Attribute> attributes;
    if (selStart > 0)
        attributes << QInputMethodEvent::Attribute(QInputMethodEvent::TextFormat, 0, selStart,
                                                   standardFormat(PreeditFormat));
    if (selLength)
        attributes << QInputMethodEvent::Attribute(QInputMethodEvent::TextFormat, selStart, selLength,
                                                   standardFormat(SelectionFormat));
    if (selStart + selLength < compositionLength)
        attributes << QInputMethodEvent::Attribute(QInputMethodEvent::TextFormat, selStart + selLength,
                                                   compositionLength - selStart - selLength,
                                                   standardFormat(PreeditFormat));
    if (position >= 0)
        attributes << QInputMethodEvent::Attribute(QInputMethodEvent::Cursor, position, selLength ? 0 : 1, QVariant());
    return attributes;
}

/*!
    \brief Notify focus object about markup or final text.
*/

bool QWindowsInputContext::composition(HWND hwnd, LPARAM lParamIn)
{
    const int lParam = int(lParamIn);
    qCDebug(lcQpaInputMethods) << '>' << __FUNCTION__ << m_compositionContext.focusObject
        << debugComposition(lParam) << " composing=" << m_compositionContext.isComposing;
    if (m_compositionContext.focusObject.isNull() || m_compositionContext.hwnd != hwnd || !lParam)
        return false;
    const HIMC himc = ImmGetContext(m_compositionContext.hwnd);
    if (!himc)
        return false;

    QScopedPointer<QInputMethodEvent> event;
    if (lParam & (GCS_COMPSTR | GCS_COMPATTR | GCS_CURSORPOS)) {
        if (!m_compositionContext.isComposing)
            startContextComposition();
        // Some intermediate composition result. Parametrize event with
        // attribute sequence specifying the formatting of the converted part.
        int selStart, selLength;
        m_compositionContext.composition = getCompositionString(himc, GCS_COMPSTR);
        m_compositionContext.position = ImmGetCompositionString(himc, GCS_CURSORPOS, nullptr, 0);
        getCompositionStringConvertedRange(himc, &selStart, &selLength);
        if ((lParam & CS_INSERTCHAR) && (lParam & CS_NOMOVECARET)) {
            // make Korean work correctly. Hope this is correct for all IMEs
            selStart = 0;
            selLength = m_compositionContext.composition.size();
        }
        if (!selLength)
            selStart = 0;

        event.reset(new QInputMethodEvent(m_compositionContext.composition,
                                          intermediateMarkup(m_compositionContext.position,
                                                             m_compositionContext.composition.size(),
                                                             selStart, selLength)));
    }
    if (event.isNull())
        event.reset(new QInputMethodEvent);

    if (lParam & GCS_RESULTSTR) {
        // A fixed result, return the converted string
        event->setCommitString(getCompositionString(himc, GCS_RESULTSTR));
        if (!(lParam & GCS_DELTASTART))
            endContextComposition();
    }
    const bool result = QCoreApplication::sendEvent(m_compositionContext.focusObject, event.data());
    qCDebug(lcQpaInputMethods) << '<' << __FUNCTION__ << "sending markup="
        << event->attributes().size() << " commit=" << event->commitString()
        << " to " << m_compositionContext.focusObject << " returns " << result;
    update(Qt::ImQueryAll);
    ImmReleaseContext(m_compositionContext.hwnd, himc);
    return result;
}

bool QWindowsInputContext::endComposition(HWND hwnd)
{
    qCDebug(lcQpaInputMethods) << __FUNCTION__ << m_endCompositionRecursionGuard << hwnd;
    // Googles Pinyin Input Method likes to call endComposition again
    // when we call notifyIME with CPS_CANCEL, so protect ourselves
    // against that.
    if (m_endCompositionRecursionGuard || m_compositionContext.hwnd != hwnd)
        return false;
    if (m_compositionContext.focusObject.isNull())
        return false;

    // QTBUG-58300: Ignore WM_IME_ENDCOMPOSITION when CTRL is pressed to prevent
    // for example the text being cleared when pressing CTRL+A
    if (m_locale.language() == QLocale::Korean
        && QGuiApplication::queryKeyboardModifiers().testFlag(Qt::ControlModifier)) {
        reset();
        return true;
    }

    m_endCompositionRecursionGuard = true;

    imeNotifyCancelComposition(m_compositionContext.hwnd);
    if (m_compositionContext.isComposing) {
        QInputMethodEvent event;
        QCoreApplication::sendEvent(m_compositionContext.focusObject, &event);
    }
    doneContext();

    m_endCompositionRecursionGuard = false;
    return true;
}

void QWindowsInputContext::initContext(HWND hwnd, QObject *focusObject)
{
    if (m_compositionContext.hwnd)
        doneContext();
    m_compositionContext.hwnd = hwnd;
    m_compositionContext.focusObject = focusObject;

    update(Qt::ImQueryAll);
    m_compositionContext.isComposing = false;
    m_compositionContext.position = 0;
}

void QWindowsInputContext::doneContext()
{
    if (!m_compositionContext.hwnd)
        return;
    m_compositionContext.hwnd = nullptr;
    m_compositionContext.composition.clear();
    m_compositionContext.position = 0;
    m_compositionContext.isComposing = false;
    m_compositionContext.focusObject = nullptr;
}

bool QWindowsInputContext::handleIME_Request(WPARAM wParam,
                                             LPARAM lParam,
                                             LRESULT *result)
{
    switch (int(wParam)) {
    case IMR_RECONVERTSTRING: {
        const int size = reconvertString(reinterpret_cast<RECONVERTSTRING *>(lParam));
        if (size < 0)
            return false;
        *result = size;
    }
        return true;
    case IMR_CONFIRMRECONVERTSTRING:
        return true;
    default:
        break;
    }
    return false;
}

void QWindowsInputContext::handleInputLanguageChanged(WPARAM wparam, LPARAM lparam)
{
    const LCID newLanguageId = languageIdFromLocaleId(WORD(lparam));
    if (newLanguageId == m_languageId)
        return;
    const LCID oldLanguageId = m_languageId;
    m_languageId = newLanguageId;
    m_locale = qt_localeFromLCID(m_languageId);
    emitLocaleChanged();

    qCDebug(lcQpaInputMethods) << __FUNCTION__ << Qt::hex << Qt::showbase
        << oldLanguageId  << "->" << newLanguageId << "Character set:"
        << DWORD(wparam) << Qt::dec << Qt::noshowbase << m_locale;
}

/*!
    \brief Determines the string for reconversion with selection.

    This is triggered twice by WM_IME_REQUEST, first with reconv=0
    to determine the length and later with a reconv struct to obtain
    the string with the position of the selection to be reconverted.

    Obtains the text from the focus object and marks the word
    for selection (might not be entirely correct for Japanese).
*/

int QWindowsInputContext::reconvertString(RECONVERTSTRING *reconv)
{
    QObject *fo = QGuiApplication::focusObject();
    if (!fo)
        return false;

    const QVariant surroundingTextV = QInputMethod::queryFocusObject(Qt::ImSurroundingText, QVariant());
    if (!surroundingTextV.isValid())
        return -1;
    const QString surroundingText = surroundingTextV.toString();
    const int memSize = int(sizeof(RECONVERTSTRING))
        + (surroundingText.length() + 1) * int(sizeof(ushort));
    qCDebug(lcQpaInputMethods) << __FUNCTION__ << " reconv=" << reconv
        << " surroundingText=" << surroundingText << " size=" << memSize;
    // If memory is not allocated, return the required size.
    if (!reconv)
        return surroundingText.isEmpty() ? -1 : memSize;

    const QVariant posV = QInputMethod::queryFocusObject(Qt::ImCursorPosition, QVariant());
    const int pos = posV.isValid() ? posV.toInt() : 0;
    // Find the word in the surrounding text.
    QTextBoundaryFinder bounds(QTextBoundaryFinder::Word, surroundingText);
    bounds.setPosition(pos);
    if (bounds.position() > 0 && !(bounds.boundaryReasons() & QTextBoundaryFinder::StartOfItem))
        bounds.toPreviousBoundary();
    const int startPos = bounds.position();
    bounds.toNextBoundary();
    const int endPos = bounds.position();
    qCDebug(lcQpaInputMethods) << __FUNCTION__ << " boundary=" << startPos << endPos;
    // Select the text, this will be overwritten by following IME events.
    QList<QInputMethodEvent::Attribute> attributes;
    attributes << QInputMethodEvent::Attribute(QInputMethodEvent::Selection, startPos, endPos-startPos, QVariant());
    QInputMethodEvent selectEvent(QString(), attributes);
    QCoreApplication::sendEvent(fo, &selectEvent);

    reconv->dwSize = DWORD(memSize);
    reconv->dwVersion = 0;

    reconv->dwStrLen = DWORD(surroundingText.size());
    reconv->dwStrOffset = sizeof(RECONVERTSTRING);
    reconv->dwCompStrLen = DWORD(endPos - startPos); // TCHAR count.
    reconv->dwCompStrOffset = DWORD(startPos) * sizeof(ushort); // byte count.
    reconv->dwTargetStrLen = reconv->dwCompStrLen;
    reconv->dwTargetStrOffset = reconv->dwCompStrOffset;
    auto *pastReconv = reinterpret_cast<ushort *>(reconv + 1);
    std::copy(surroundingText.utf16(), surroundingText.utf16() + surroundingText.size(),
              QT_MAKE_UNCHECKED_ARRAY_ITERATOR(pastReconv));
    return memSize;
}

QT_END_NAMESPACE
