From f67b8df3ebdba2d398b9cce686b7c644adffff08 Mon Sep 17 00:00:00 2001 From: Lars Knoll Date: Sat, 7 May 2011 00:02:01 +0200 Subject: library split --- src/gui/inputmethod/qwininputcontext_win.cpp | 847 --------------------------- 1 file changed, 847 deletions(-) delete mode 100644 src/gui/inputmethod/qwininputcontext_win.cpp (limited to 'src/gui/inputmethod/qwininputcontext_win.cpp') diff --git a/src/gui/inputmethod/qwininputcontext_win.cpp b/src/gui/inputmethod/qwininputcontext_win.cpp deleted file mode 100644 index 4289cf4191..0000000000 --- a/src/gui/inputmethod/qwininputcontext_win.cpp +++ /dev/null @@ -1,847 +0,0 @@ -/**************************************************************************** -** -** 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$ -** No Commercial Usage -** This file contains pre-release code and may not be distributed. -** You may use this file in accordance with the terms and conditions -** contained in the Technology Preview License Agreement accompanying -** this package. -** -** GNU Lesser General Public License Usage -** Alternatively, 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. -** -** If you have questions regarding the use of this file, please contact -** Nokia at qt-info@nokia.com. -** -** -** -** -** -** -** -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include "qwininputcontext_p.h" -#include "qinputcontext_p.h" - -#include "qfont.h" -#include "qwidget.h" -#include "qapplication.h" -#include "qevent.h" -#include "qtextformat.h" -#include "qtextboundaryfinder.h" - -//#define Q_IME_DEBUG - -#ifdef Q_IME_DEBUG -#include "qdebug.h" -#endif - -#if defined(Q_WS_WINCE) -extern void qt_wince_show_SIP(bool show); // defined in qguifunctions_wince.cpp -#endif - -QT_BEGIN_NAMESPACE - -extern bool qt_sendSpontaneousEvent(QObject*, QEvent*); - - -DEFINE_GUID(IID_IActiveIMMApp, -0x08c0e040, 0x62d1, 0x11d1, 0x93, 0x26, 0x0, 0x60, 0xb0, 0x67, 0xb8, 0x6e); - - - -DEFINE_GUID(CLSID_CActiveIMM, -0x4955DD33, 0xB159, 0x11d0, 0x8F, 0xCF, 0x0, 0xAA, 0x00, 0x6B, 0xCC, 0x59); - - - -DEFINE_GUID(IID_IActiveIMMMessagePumpOwner, -0xb5cf2cfa, 0x8aeb, 0x11d1, 0x93, 0x64, 0x0, 0x60, 0xb0, 0x67, 0xb8, 0x6e); - - - -interface IEnumRegisterWordW; -interface IEnumInputContext; - - -bool qt_sendSpontaneousEvent(QObject*, QEvent*); - - -#define IFMETHOD HRESULT STDMETHODCALLTYPE - -interface IActiveIMMApp : public IUnknown -{ -public: - virtual IFMETHOD AssociateContext(HWND hWnd, HIMC hIME, HIMC __RPC_FAR *phPrev) = 0; - virtual IFMETHOD dummy_ConfigureIMEA() = 0; - virtual IFMETHOD ConfigureIMEW(HKL hKL, HWND hWnd, DWORD dwMode, REGISTERWORDW __RPC_FAR *pData) = 0; - virtual IFMETHOD CreateContext(HIMC __RPC_FAR *phIMC) = 0; - virtual IFMETHOD DestroyContext(HIMC hIME) = 0; - virtual IFMETHOD dummy_EnumRegisterWordA() = 0; - virtual IFMETHOD EnumRegisterWordW(HKL hKL, LPWSTR szReading, DWORD dwStyle, LPWSTR szRegister, LPVOID pData, - IEnumRegisterWordW __RPC_FAR *__RPC_FAR *pEnum) = 0; - virtual IFMETHOD dummy_EscapeA() = 0; - virtual IFMETHOD EscapeW(HKL hKL, HIMC hIMC, UINT uEscape, LPVOID pData, LRESULT __RPC_FAR *plResult) = 0; - virtual IFMETHOD dummy_GetCandidateListA() = 0; - virtual IFMETHOD GetCandidateListW(HIMC hIMC, DWORD dwIndex, UINT uBufLen, CANDIDATELIST __RPC_FAR *pCandList, - UINT __RPC_FAR *puCopied) = 0; - virtual IFMETHOD dummy_GetCandidateListCountA() = 0; - virtual IFMETHOD GetCandidateListCountW(HIMC hIMC, DWORD __RPC_FAR *pdwListSize, DWORD __RPC_FAR *pdwBufLen) = 0; - virtual IFMETHOD GetCandidateWindow(HIMC hIMC, DWORD dwIndex, CANDIDATEFORM __RPC_FAR *pCandidate) = 0; - virtual IFMETHOD dummy_GetCompositionFontA() = 0; - virtual IFMETHOD GetCompositionFontW(HIMC hIMC, LOGFONTW __RPC_FAR *plf) = 0; - virtual IFMETHOD dummy_GetCompositionStringA() = 0; - virtual IFMETHOD GetCompositionStringW(HIMC hIMC, DWORD dwIndex, DWORD dwBufLen, LONG __RPC_FAR *plCopied, LPVOID pBuf) = 0; - virtual IFMETHOD GetCompositionWindow(HIMC hIMC, COMPOSITIONFORM __RPC_FAR *pCompForm) = 0; - virtual IFMETHOD GetContext(HWND hWnd, HIMC __RPC_FAR *phIMC) = 0; - virtual IFMETHOD dummy_GetConversionListA() = 0; - virtual IFMETHOD GetConversionListW(HKL hKL, HIMC hIMC, LPWSTR pSrc, UINT uBufLen, UINT uFlag, - CANDIDATELIST __RPC_FAR *pDst, UINT __RPC_FAR *puCopied) = 0; - virtual IFMETHOD GetConversionStatus(HIMC hIMC, DWORD __RPC_FAR *pfdwConversion, DWORD __RPC_FAR *pfdwSentence) = 0; - virtual IFMETHOD GetDefaultIMEWnd(HWND hWnd, HWND __RPC_FAR *phDefWnd) = 0; - virtual IFMETHOD dummy_GetDescriptionA() = 0; - virtual IFMETHOD GetDescriptionW(HKL hKL, UINT uBufLen, LPWSTR szDescription, UINT __RPC_FAR *puCopied) = 0; - virtual IFMETHOD dummy_GetGuideLineA() = 0; - virtual IFMETHOD GetGuideLineW(HIMC hIMC, DWORD dwIndex, DWORD dwBufLen, LPWSTR pBuf, DWORD __RPC_FAR *pdwResult) = 0; - virtual IFMETHOD dummy_GetIMEFileNameA() = 0; - virtual IFMETHOD GetIMEFileNameW(HKL hKL, UINT uBufLen, LPWSTR szFileName, UINT __RPC_FAR *puCopied) = 0; - virtual IFMETHOD GetOpenStatus(HIMC hIMC) = 0; - virtual IFMETHOD GetProperty(HKL hKL, DWORD fdwIndex, DWORD __RPC_FAR *pdwProperty) = 0; - virtual IFMETHOD dummy_GetRegisterWordStyleA() = 0; - virtual IFMETHOD GetRegisterWordStyleW(HKL hKL, UINT nItem, STYLEBUFW __RPC_FAR *pStyleBuf, UINT __RPC_FAR *puCopied) = 0; - virtual IFMETHOD GetStatusWindowPos(HIMC hIMC, POINT __RPC_FAR *pptPos) = 0; - virtual IFMETHOD GetVirtualKey(HWND hWnd, UINT __RPC_FAR *puVirtualKey) = 0; - virtual IFMETHOD dummy_InstallIMEA() = 0; - virtual IFMETHOD InstallIMEW(LPWSTR szIMEFileName, LPWSTR szLayoutText, HKL __RPC_FAR *phKL) = 0; - virtual IFMETHOD IsIME(HKL hKL) = 0; - virtual IFMETHOD dummy_IsUIMessageA() = 0; - virtual IFMETHOD IsUIMessageW(HWND hWndIME, UINT msg, WPARAM wParam, LPARAM lParam) = 0; - virtual IFMETHOD NotifyIME(HIMC hIMC, DWORD dwAction, DWORD dwIndex, DWORD dwValue) = 0; - virtual IFMETHOD dummy_RegisterWordA() = 0; - virtual IFMETHOD RegisterWordW(HKL hKL, LPWSTR szReading, DWORD dwStyle, LPWSTR szRegister) = 0; - virtual IFMETHOD ReleaseContext(HWND hWnd, HIMC hIMC) = 0; - virtual IFMETHOD SetCandidateWindow(HIMC hIMC, CANDIDATEFORM __RPC_FAR *pCandidate) = 0; - virtual IFMETHOD SetCompositionFontA(HIMC hIMC, LOGFONTA __RPC_FAR *plf) = 0; - virtual IFMETHOD SetCompositionFontW(HIMC hIMC, LOGFONTW __RPC_FAR *plf) = 0; - virtual IFMETHOD dummy_SetCompositionStringA() = 0; - virtual IFMETHOD SetCompositionStringW(HIMC hIMC, DWORD dwIndex, LPVOID pComp, DWORD dwCompLen, - LPVOID pRead, DWORD dwReadLen) = 0; - virtual IFMETHOD SetCompositionWindow(HIMC hIMC, COMPOSITIONFORM __RPC_FAR *pCompForm) = 0; - virtual IFMETHOD SetConversionStatus(HIMC hIMC, DWORD fdwConversion, DWORD fdwSentence) = 0; - virtual IFMETHOD SetOpenStatus(HIMC hIMC, BOOL fOpen) = 0; - virtual IFMETHOD SetStatusWindowPos(HIMC hIMC, POINT __RPC_FAR *pptPos) = 0; - virtual IFMETHOD SimulateHotKey(HWND hWnd, DWORD dwHotKeyID) = 0; - virtual IFMETHOD dummy_UnregisterWordA() = 0; - virtual IFMETHOD UnregisterWordW(HKL hKL, LPWSTR szReading, DWORD dwStyle, LPWSTR szUnregister) = 0; - virtual IFMETHOD Activate(BOOL fRestoreLayout) = 0; - virtual IFMETHOD Deactivate(void) = 0; - virtual IFMETHOD OnDefWindowProc(HWND hWnd, UINT Msg, WPARAM wParam, LPARAM lParam, LRESULT __RPC_FAR *plResult) = 0; - virtual IFMETHOD FilterClientWindows(ATOM __RPC_FAR *aaClassList, UINT uSize) = 0; - virtual IFMETHOD dummy_GetCodePageA() = 0; - virtual IFMETHOD GetLangId(HKL hKL, LANGID __RPC_FAR *plid) = 0; - virtual IFMETHOD AssociateContextEx(HWND hWnd, HIMC hIMC, DWORD dwFlags) = 0; - virtual IFMETHOD DisableIME(DWORD idThread) = 0; - virtual IFMETHOD dummy_GetImeMenuItemsA() = 0; - virtual IFMETHOD GetImeMenuItemsW(HIMC hIMC, DWORD dwFlags, DWORD dwType, /*IMEMENUITEMINFOW*/ void __RPC_FAR *pImeParentMenu, - /*IMEMENUITEMINFOW*/ void __RPC_FAR *pImeMenu, DWORD dwSize, DWORD __RPC_FAR *pdwResult) = 0; - virtual IFMETHOD EnumInputContext(DWORD idThread, IEnumInputContext __RPC_FAR *__RPC_FAR *ppEnum) = 0; -}; - -interface IActiveIMMMessagePumpOwner : public IUnknown -{ -public: - virtual IFMETHOD Start(void) = 0; - virtual IFMETHOD End(void) = 0; - virtual IFMETHOD OnTranslateMessage(const MSG __RPC_FAR *pMsg) = 0; - virtual IFMETHOD Pause(DWORD __RPC_FAR *pdwCookie) = 0; - virtual IFMETHOD Resume(DWORD dwCookie) = 0; -}; - - -static IActiveIMMApp *aimm = 0; -static IActiveIMMMessagePumpOwner *aimmpump = 0; -static QString *imeComposition = 0; -static int imePosition = -1; -bool qt_use_rtl_extensions = false; -static bool haveCaret = false; - -#ifndef LGRPID_INSTALLED -#define LGRPID_INSTALLED 0x00000001 // installed language group ids -#define LGRPID_SUPPORTED 0x00000002 // supported language group ids -#endif - -#ifndef LGRPID_ARABIC -#define LGRPID_WESTERN_EUROPE 0x0001 // Western Europe & U.S. -#define LGRPID_CENTRAL_EUROPE 0x0002 // Central Europe -#define LGRPID_BALTIC 0x0003 // Baltic -#define LGRPID_GREEK 0x0004 // Greek -#define LGRPID_CYRILLIC 0x0005 // Cyrillic -#define LGRPID_TURKISH 0x0006 // Turkish -#define LGRPID_JAPANESE 0x0007 // Japanese -#define LGRPID_KOREAN 0x0008 // Korean -#define LGRPID_TRADITIONAL_CHINESE 0x0009 // Traditional Chinese -#define LGRPID_SIMPLIFIED_CHINESE 0x000a // Simplified Chinese -#define LGRPID_THAI 0x000b // Thai -#define LGRPID_HEBREW 0x000c // Hebrew -#define LGRPID_ARABIC 0x000d // Arabic -#define LGRPID_VIETNAMESE 0x000e // Vietnamese -#define LGRPID_INDIC 0x000f // Indic -#define LGRPID_GEORGIAN 0x0010 // Georgian -#define LGRPID_ARMENIAN 0x0011 // Armenian -#endif - -static DWORD WM_MSIME_MOUSE = 0; - -QWinInputContext::QWinInputContext(QObject *parent) - : QInputContext(parent), recursionGuard(false) -{ -#ifndef Q_WS_WINCE - QSysInfo::WinVersion ver = QSysInfo::windowsVersion(); - if (ver & QSysInfo::WV_NT_based && ver >= QSysInfo::WV_VISTA) { - // Since the IsValidLanguageGroup/IsValidLocale functions always return true on - // Vista, check the Keyboard Layouts for enabling RTL. - UINT nLayouts = GetKeyboardLayoutList(0, 0); - if (nLayouts) { - HKL *lpList = new HKL[nLayouts]; - GetKeyboardLayoutList(nLayouts, lpList); - for (int i = 0; i<(int)nLayouts; i++) { - WORD plangid = PRIMARYLANGID((quintptr)lpList[i]); - if (plangid == LANG_ARABIC - || plangid == LANG_HEBREW - || plangid == LANG_FARSI -#ifdef LANG_SYRIAC - || plangid == LANG_SYRIAC -#endif - ) { - qt_use_rtl_extensions = true; - break; - } - } - delete []lpList; - } - } else { - // figure out whether a RTL language is installed - qt_use_rtl_extensions = IsValidLanguageGroup(LGRPID_ARABIC, LGRPID_INSTALLED) - || IsValidLanguageGroup(LGRPID_HEBREW, LGRPID_INSTALLED) - || IsValidLocale(MAKELCID(MAKELANGID(LANG_ARABIC, SUBLANG_DEFAULT), SORT_DEFAULT), LCID_INSTALLED) - || IsValidLocale(MAKELCID(MAKELANGID(LANG_HEBREW, SUBLANG_DEFAULT), SORT_DEFAULT), LCID_INSTALLED) -#ifdef LANG_SYRIAC - || IsValidLocale(MAKELCID(MAKELANGID(LANG_SYRIAC, SUBLANG_DEFAULT), SORT_DEFAULT), LCID_INSTALLED) -#endif - || IsValidLocale(MAKELCID(MAKELANGID(LANG_FARSI, SUBLANG_DEFAULT), SORT_DEFAULT), LCID_INSTALLED); - } -#else - qt_use_rtl_extensions = false; -#endif - - WM_MSIME_MOUSE = RegisterWindowMessage(L"MSIMEMouseOperation"); -} - -QWinInputContext::~QWinInputContext() -{ - // release active input method if we have one - if (aimm) { - aimmpump->End(); - aimmpump->Release(); - aimm->Deactivate(); - aimm->Release(); - aimm = 0; - aimmpump = 0; - } - delete imeComposition; - imeComposition = 0; -} - -static HWND getDefaultIMEWnd(HWND wnd) -{ - HWND ime_wnd; - if(aimm) - aimm->GetDefaultIMEWnd(wnd, &ime_wnd); - else - ime_wnd = ImmGetDefaultIMEWnd(wnd); - return ime_wnd; -} - -static HIMC getContext(HWND wnd) -{ - HIMC imc; - if (aimm) - aimm->GetContext(wnd, &imc); - else - imc = ImmGetContext(wnd); - - return imc; -} - -static void releaseContext(HWND wnd, HIMC imc) -{ - if (aimm) - aimm->ReleaseContext(wnd, imc); - else - ImmReleaseContext(wnd, imc); -} - -static void notifyIME(HIMC imc, DWORD dwAction, DWORD dwIndex, DWORD dwValue) -{ - if (!imc) - return; - if (aimm) - aimm->NotifyIME(imc, dwAction, dwIndex, dwValue); - else - ImmNotifyIME(imc, dwAction, dwIndex, dwValue); -} - -static LONG getCompositionString(HIMC himc, DWORD dwIndex, LPVOID lpbuf, DWORD dBufLen) -{ - LONG len = 0; - if (aimm) - aimm->GetCompositionStringW(himc, dwIndex, dBufLen, &len, lpbuf); - else - len = ImmGetCompositionString(himc, dwIndex, lpbuf, dBufLen); - return len; -} - -static int getCursorPosition(HIMC himc) -{ - return getCompositionString(himc, GCS_CURSORPOS, 0, 0); -} - -static QString getString(HIMC himc, DWORD dwindex, int *selStart = 0, int *selLength = 0) -{ - const int bufferSize = 256; - wchar_t buffer[bufferSize]; - int len = getCompositionString(himc, dwindex, buffer, bufferSize * sizeof(wchar_t)); - - if (selStart) { - char attrbuffer[bufferSize]; - int attrlen = getCompositionString(himc, GCS_COMPATTR, attrbuffer, bufferSize); - *selStart = attrlen+1; - *selLength = -1; - for (int i = 0; i < attrlen; i++) { - if (attrbuffer[i] & ATTR_TARGET_CONVERTED) { - *selStart = qMin(*selStart, i); - *selLength = qMax(*selLength, i); - } - } - *selLength = qMax(0, *selLength - *selStart + 1); - } - - if (len <= 0) - return QString(); - - return QString((QChar*)buffer, len / sizeof(QChar)); -} - -void QWinInputContext::TranslateMessage(const MSG *msg) -{ - if (!aimmpump || aimmpump->OnTranslateMessage(msg) != S_OK) - ::TranslateMessage(msg); -} - -LRESULT QWinInputContext::DefWindowProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam) -{ - LRESULT retval; - if (!aimm || aimm->OnDefWindowProc(hwnd, msg, wParam, lParam, &retval) != S_OK) - { - retval = ::DefWindowProc(hwnd, msg, wParam, lParam); - } - return retval; -} - - -void QWinInputContext::update() -{ - QWidget *w = focusWidget(); - if(!w) - return; - - Q_ASSERT(w->testAttribute(Qt::WA_WState_Created)); - HIMC imc = getContext(w->effectiveWinId()); - - if (!imc) - return; - - QFont f = qvariant_cast(w->inputMethodQuery(Qt::ImFont)); - HFONT hf; - hf = f.handle(); - - LOGFONT lf; - if (GetObject(hf, sizeof(lf), &lf)) { - if (aimm) - aimm->SetCompositionFontW(imc, &lf); - else - ImmSetCompositionFont(imc, &lf); - } - - QRect r = w->inputMethodQuery(Qt::ImMicroFocus).toRect(); - - // The ime window positions are based on the WinId with active focus. - QWidget *imeWnd = QWidget::find(::GetFocus()); - if (imeWnd && !aimm) { - QPoint pt (r.topLeft()); - pt = w->mapToGlobal(pt); - pt = imeWnd->mapFromGlobal(pt); - r.moveTo(pt); - } - - COMPOSITIONFORM cf; - // ### need X-like inputStyle config settings - cf.dwStyle = CFS_FORCE_POSITION; - cf.ptCurrentPos.x = r.x(); - cf.ptCurrentPos.y = r.y(); - - CANDIDATEFORM candf; - candf.dwIndex = 0; - candf.dwStyle = CFS_EXCLUDE; - candf.ptCurrentPos.x = r.x(); - candf.ptCurrentPos.y = r.y() + r.height(); - candf.rcArea.left = r.x(); - candf.rcArea.top = r.y(); - candf.rcArea.right = r.x() + r.width(); - candf.rcArea.bottom = r.y() + r.height(); - - if(haveCaret) - SetCaretPos(r.x(), r.y()); - - if (aimm) { - aimm->SetCompositionWindow(imc, &cf); - aimm->SetCandidateWindow(imc, &candf); - } else { - ImmSetCompositionWindow(imc, &cf); - ImmSetCandidateWindow(imc, &candf); - } - - releaseContext(w->effectiveWinId(), imc); -} - - -bool QWinInputContext::endComposition() -{ - QWidget *fw = focusWidget(); -#ifdef Q_IME_DEBUG - qDebug("endComposition! fw = %s", fw ? fw->className() : "(null)"); -#endif - bool result = true; - if(imePosition == -1 || recursionGuard) - return result; - - // Googles Pinyin Input Method likes to call endComposition again - // when we call notifyIME with CPS_CANCEL, so protect ourselves - // against that. - recursionGuard = true; - - if (fw) { - Q_ASSERT(fw->testAttribute(Qt::WA_WState_Created)); - HIMC imc = getContext(fw->effectiveWinId()); - notifyIME(imc, NI_COMPOSITIONSTR, CPS_CANCEL, 0); - releaseContext(fw->effectiveWinId(), imc); - if(haveCaret) { - DestroyCaret(); - haveCaret = false; - } - } - - if (!fw) - fw = QApplication::focusWidget(); - - if (fw) { - QInputMethodEvent e; - result = qt_sendSpontaneousEvent(fw, &e); - } - - if (imeComposition) - imeComposition->clear(); - imePosition = -1; - - recursionGuard = false; - - return result; -} - -void QWinInputContext::reset() -{ - QWidget *fw = focusWidget(); - -#ifdef Q_IME_DEBUG - qDebug("sending accept to focus widget %s", fw ? fw->className() : "(null)"); -#endif - - if (fw && imePosition != -1) { - QInputMethodEvent e; - if (imeComposition) - e.setCommitString(*imeComposition); - imePosition = -1; - qt_sendSpontaneousEvent(fw, &e); - } - - if (imeComposition) - imeComposition->clear(); - imePosition = -1; - - if (fw) { - Q_ASSERT(fw->testAttribute(Qt::WA_WState_Created)); - HIMC imc = getContext(fw->effectiveWinId()); - notifyIME(imc, NI_COMPOSITIONSTR, CPS_CANCEL, 0); - releaseContext(fw->effectiveWinId(), imc); - } - -} - - -bool QWinInputContext::startComposition() -{ -#ifdef Q_IME_DEBUG - qDebug("startComposition"); -#endif - - if (!imeComposition) - imeComposition = new QString(); - - QWidget *fw = focusWidget(); - if (fw) { - Q_ASSERT(fw->testAttribute(Qt::WA_WState_Created)); - imePosition = 0; - haveCaret = CreateCaret(fw->effectiveWinId(), 0, 1, 1); - HideCaret(fw->effectiveWinId()); - update(); - } - return fw != 0; -} - -enum StandardFormat { - PreeditFormat, - SelectionFormat -}; - -bool QWinInputContext::composition(LPARAM lParam) -{ -#ifdef Q_IME_DEBUG - QString 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 "; - qDebug("composition, lParam=(%x) %s imePosition=%d", lParam, str.latin1(), imePosition); -#endif - - bool result = true; - - if(!lParam) - // bogus event - return true; - - QWidget *fw = QApplication::focusWidget(); - if (fw) { - Q_ASSERT(fw->testAttribute(Qt::WA_WState_Created)); - HIMC imc = getContext(fw->effectiveWinId()); - QInputMethodEvent e; - if (lParam & (GCS_COMPSTR | GCS_COMPATTR | GCS_CURSORPOS)) { - if (imePosition == -1) - // need to send a start event - startComposition(); - - // some intermediate composition result - int selStart, selLength; - *imeComposition = getString(imc, GCS_COMPSTR, &selStart, &selLength); - imePosition = getCursorPosition(imc); - if (lParam & CS_INSERTCHAR && lParam & CS_NOMOVECARET) { - // make korean work correctly. Hope this is correct for all IMEs - selStart = 0; - selLength = imeComposition->length(); - } - if(selLength == 0) - selStart = 0; - - QList attrs; - if (selStart > 0) - attrs << QInputMethodEvent::Attribute(QInputMethodEvent::TextFormat, 0, selStart, - standardFormat(PreeditFormat)); - if (selLength) - attrs << QInputMethodEvent::Attribute(QInputMethodEvent::TextFormat, selStart, selLength, - standardFormat(SelectionFormat)); - if (selStart + selLength < imeComposition->length()) - attrs << QInputMethodEvent::Attribute(QInputMethodEvent::TextFormat, selStart + selLength, - imeComposition->length() - selStart - selLength, - standardFormat(PreeditFormat)); - if(imePosition >= 0) - attrs << QInputMethodEvent::Attribute(QInputMethodEvent::Cursor, imePosition, selLength ? 0 : 1, QVariant()); - - e = QInputMethodEvent(*imeComposition, attrs); - } - if (lParam & GCS_RESULTSTR) { - if(imePosition == -1) - startComposition(); - // a fixed result, return the converted string - *imeComposition = getString(imc, GCS_RESULTSTR); - imePosition = -1; - e.setCommitString(*imeComposition); - imeComposition->clear(); - } - result = qt_sendSpontaneousEvent(fw, &e); - update(); - releaseContext(fw->effectiveWinId(), imc); - } -#ifdef Q_IME_DEBUG - qDebug("imecomposition: cursor pos at %d, str=%x", imePosition, str[0].unicode()); -#endif - return result; -} - -static HIMC defaultContext = 0; - -// checks whether widget is a popup -inline bool isPopup(QWidget *w) -{ - if (w && (w->windowFlags() & Qt::Popup) == Qt::Popup) - return true; - else - return false; -} -// checks whether widget is in a popup -inline bool isInPopup(QWidget *w) -{ - if (w && (isPopup(w) || isPopup(w->window()))) - return true; - else - return false; -} - -// find the parent widget, which is a non popup toplevel -// this is valid only if the widget is/in a popup -inline QWidget *findParentforPopup(QWidget *w) -{ - QWidget *e = QWidget::find(w->effectiveWinId()); - // check if this or its parent is a popup - while (isInPopup(e)) { - e = e->window()->parentWidget(); - if (!e) - break; - e = QWidget::find(e->effectiveWinId()); - } - if (e) - return e->window(); - else - return 0; -} - -// enables or disables the ime -inline void enableIme(QWidget *w, bool value) -{ - if (value) { - // enable ime - if (defaultContext) - ImmAssociateContext(w->effectiveWinId(), defaultContext); -#ifdef Q_WS_WINCE - if (qApp->autoSipEnabled()) - qt_wince_show_SIP(true); -#endif - } else { - // disable ime - HIMC oldimc = ImmAssociateContext(w->effectiveWinId(), 0); - if (!defaultContext) - defaultContext = oldimc; -#ifdef Q_WS_WINCE - if (qApp->autoSipEnabled()) - qt_wince_show_SIP(false); -#endif - } -} - - -void QWinInputContext::updateImeStatus(QWidget *w, bool hasFocus) -{ - if (!w) - return; - // It's always the proxy that carries the hints. - QWidget *focusProxyWidget = w->focusProxy(); - if (!focusProxyWidget) - focusProxyWidget = w; - bool e = w->testAttribute(Qt::WA_InputMethodEnabled) && w->isEnabled() - && !(focusProxyWidget->inputMethodHints() & (Qt::ImhExclusiveInputMask | Qt::ImhHiddenText)); - bool hasIme = e && hasFocus; -#ifdef Q_IME_DEBUG - qDebug("%s HasFocus = %d hasIme = %d e = %d ", w->className(), hasFocus, hasIme, e); -#endif - if (hasFocus || e) { - if (isInPopup(w)) - QWinInputContext::enablePopupChild(w, hasIme); - else - QWinInputContext::enable(w, hasIme); - } -} - -void QWinInputContext::enablePopupChild(QWidget *w, bool e) -{ - if (aimm) { - enable(w, e); - return; - } - - if (!w || !isInPopup(w)) - return; -#ifdef Q_IME_DEBUG - qDebug("enablePopupChild: w=%s, enable = %s", w ? w->className() : "(null)" , e ? "true" : "false"); -#endif - QWidget *parent = findParentforPopup(w); - if (parent) { - // update ime status of the normal toplevel parent of the popup - enableIme(parent, e); - } - QWidget *toplevel = w->window(); - if (toplevel) { - // update ime status of the toplevel popup - enableIme(toplevel, e); - } -} - -void QWinInputContext::enable(QWidget *w, bool e) -{ - if(w) { -#ifdef Q_IME_DEBUG - qDebug("enable: w=%s, enable = %s", w ? w->className() : "(null)" , e ? "true" : "false"); -#endif - if (!w->testAttribute(Qt::WA_WState_Created)) - return; - if(aimm) { - HIMC oldimc; - if (!e) { - aimm->AssociateContext(w->effectiveWinId(), 0, &oldimc); - if (!defaultContext) - defaultContext = oldimc; - } else if (defaultContext) { - aimm->AssociateContext(w->effectiveWinId(), defaultContext, &oldimc); - } - } else { - // update ime status on the widget - QWidget *p = QWidget::find(w->effectiveWinId()); - if (p) - enableIme(p, e); - } - } -} - -void QWinInputContext::setFocusWidget(QWidget *w) -{ - QWidget *oldFocus = focusWidget(); - if (oldFocus == w) - return; - if (w) { - QWinInputContext::updateImeStatus(w, true); - } else { - if (oldFocus) - QWinInputContext::updateImeStatus(oldFocus , false); - } - QInputContext::setFocusWidget(w); - update(); -} - -bool QWinInputContext::isComposing() const -{ - return imeComposition && !imeComposition->isEmpty(); -} - -void QWinInputContext::mouseHandler(int pos, QMouseEvent *e) -{ - if(e->type() != QEvent::MouseButtonPress) - return; - - if (pos < 0 || pos > imeComposition->length()) - reset(); - - // Probably should pass the correct button, but it seems to work fine like this. - DWORD button = MK_LBUTTON; - - QWidget *fw = focusWidget(); - if (fw) { - Q_ASSERT(fw->testAttribute(Qt::WA_WState_Created)); - HIMC himc = getContext(fw->effectiveWinId()); - HWND ime_wnd = getDefaultIMEWnd(fw->effectiveWinId()); - SendMessage(ime_wnd, WM_MSIME_MOUSE, MAKELONG(MAKEWORD(button, pos == 0 ? 2 : 1), pos), (LPARAM)himc); - releaseContext(fw->effectiveWinId(), himc); - } - //qDebug("mouseHandler: got value %d pos=%d", ret,pos); -} - -QString QWinInputContext::language() -{ - return QString(); -} - -int QWinInputContext::reconvertString(RECONVERTSTRING *reconv) -{ - QWidget *w = focusWidget(); - if(!w) - return -1; - - Q_ASSERT(w->testAttribute(Qt::WA_WState_Created)); - QString surroundingText = qvariant_cast(w->inputMethodQuery(Qt::ImSurroundingText)); - int memSize = sizeof(RECONVERTSTRING)+(surroundingText.length()+1)*sizeof(ushort); - // If memory is not allocated, return the required size. - if (!reconv) { - if (surroundingText.isEmpty()) - return -1; - else - return memSize; - } - int pos = qvariant_cast(w->inputMethodQuery(Qt::ImCursorPosition)); - // find the word in the surrounding text. - QTextBoundaryFinder bounds(QTextBoundaryFinder::Word, surroundingText); - bounds.setPosition(pos); - if (bounds.isAtBoundary()) { - if (QTextBoundaryFinder::EndWord == bounds.boundaryReasons()) - bounds.toPreviousBoundary(); - } else { - bounds.toPreviousBoundary(); - } - int startPos = bounds.position(); - bounds.toNextBoundary(); - int endPos = bounds.position(); - // select the text, this will be overwritten by following ime events. - QList attrs; - attrs << QInputMethodEvent::Attribute(QInputMethodEvent::Selection, startPos, endPos-startPos, QVariant()); - QInputMethodEvent e(QString(), attrs); - qt_sendSpontaneousEvent(w, &e); - - reconv->dwSize = memSize; - reconv->dwVersion = 0; - - reconv->dwStrLen = surroundingText.length(); - reconv->dwStrOffset = sizeof(RECONVERTSTRING); - reconv->dwCompStrLen = endPos-startPos; - reconv->dwCompStrOffset = startPos*sizeof(ushort); - reconv->dwTargetStrLen = reconv->dwCompStrLen; - reconv->dwTargetStrOffset = reconv->dwCompStrOffset; - memcpy((char*)(reconv+1), surroundingText.utf16(), surroundingText.length()*sizeof(ushort)); - return memSize; -} - -QT_END_NAMESPACE -- cgit v1.2.3