https://git.reactos.org/?p=reactos.git;a=commitdiff;h=980ebf0694960551201fdd132e0ec2475a9433fd
commit 980ebf0694960551201fdd132e0ec2475a9433fd Author: Katayama Hirofumi MZ <katayama.hirofumi...@gmail.com> AuthorDate: Fri Feb 23 17:43:13 2024 +0900 Commit: GitHub <nore...@github.com> CommitDate: Fri Feb 23 17:43:13 2024 +0900 [MSCTFIME] Implement CtfImeSetActiveContextAlways (#6522) Supporting TIPs... JIRA issue: CORE-19360 - Move code of functions.cpp into misc.cpp and delete functions.cpp. - Add implementation to CicBridge::GetDocumentManager, CicBridge::CreateInputContext, and CicBridge::SetActiveContextAlways methods. - Implement NotifyIME, CtfImeSetActiveContextAlways, and CtfImeCreateInputContext functions. --- dll/ime/msctfime/CMakeLists.txt | 4 - dll/ime/msctfime/bridge.cpp | 153 ++++++++++---- dll/ime/msctfime/bridge.h | 21 +- dll/ime/msctfime/functions.cpp | 261 ------------------------ dll/ime/msctfime/functions.h | 63 ------ dll/ime/msctfime/misc.cpp | 438 ++++++++++++++++++++++++++++++++++++++-- dll/ime/msctfime/misc.h | 68 ++++++- dll/ime/msctfime/msctfime.cpp | 211 ++++++------------- dll/ime/msctfime/msctfime.h | 16 +- dll/ime/msctfime/tls.cpp | 32 +++ dll/ime/msctfime/tls.h | 44 +--- dll/ime/msctfime/ui.cpp | 2 +- dll/ime/msctfime/ui.h | 2 - 13 files changed, 725 insertions(+), 590 deletions(-) diff --git a/dll/ime/msctfime/CMakeLists.txt b/dll/ime/msctfime/CMakeLists.txt index 0e5acc805b0..717e879e119 100644 --- a/dll/ime/msctfime/CMakeLists.txt +++ b/dll/ime/msctfime/CMakeLists.txt @@ -1,12 +1,8 @@ -include_directories( - ${REACTOS_SOURCE_DIR}/win32ss/include) - spec2def(msctfime.ime msctfime.spec) list(APPEND SOURCE bridge.cpp - functions.cpp inputcontext.cpp misc.cpp msctfime.cpp diff --git a/dll/ime/msctfime/bridge.cpp b/dll/ime/msctfime/bridge.cpp index 50ac6622614..cd966083264 100644 --- a/dll/ime/msctfime/bridge.cpp +++ b/dll/ime/msctfime/bridge.cpp @@ -1,7 +1,7 @@ /* * PROJECT: ReactOS msctfime.ime * LICENSE: LGPL-2.1-or-later (https://spdx.org/licenses/LGPL-2.1-or-later) - * PURPOSE: Bridge + * PURPOSE: The bridge of msctfime.ime * COPYRIGHT: Copyright 2024 Katayama Hirofumi MZ <katayama.hirofumi...@gmail.com> */ @@ -65,22 +65,19 @@ CicBridge::~CicBridge() UnInitIMMX(pTLS); } -void CicBridge::GetDocumentManager(_Inout_ CicIMCCLock<CTFIMECONTEXT>& imeContext) +/// @implemented +ITfDocumentMgr* +CicBridge::GetDocumentManager(_Inout_ CicIMCCLock<CTFIMECONTEXT>& imeContext) { CicInputContext *pCicIC = imeContext.get().m_pCicIC; - if (pCicIC) - { - m_pDocMgr = pCicIC->m_pDocumentMgr; - m_pDocMgr->AddRef(); - } - else - { - m_pDocMgr->Release(); - m_pDocMgr = NULL; - } + if (!pCicIC) + return NULL; + + pCicIC->m_pDocumentMgr->AddRef(); + return pCicIC->m_pDocumentMgr; } -/// @unimplemented +/// @implemented HRESULT CicBridge::CreateInputContext( _Inout_ TLS *pTLS, @@ -100,45 +97,49 @@ CicBridge::CreateInputContext( CicIMCCLock<CTFIMECONTEXT> imeContext(imcLock.get().hCtfImeContext); CicInputContext *pCicIC = imeContext.get().m_pCicIC; + if (pCicIC) + return S_OK; + + pCicIC = new(cicNoThrow) CicInputContext(m_cliendId, &m_LibThread, hIMC); if (!pCicIC) { - pCicIC = new(cicNoThrow) CicInputContext(m_cliendId, &m_LibThread, hIMC); - if (!pCicIC) - { - imeContext.unlock(); - imcLock.unlock(); - DestroyInputContext(pTLS, hIMC); - return E_OUTOFMEMORY; - } - - if (!pTLS->m_pThreadMgr) - { - pCicIC->Release(); - imeContext.unlock(); - imcLock.unlock(); - DestroyInputContext(pTLS, hIMC); - return E_NOINTERFACE; - } + imeContext.unlock(); + imcLock.unlock(); + DestroyInputContext(pTLS, hIMC); + return E_OUTOFMEMORY; + } - imeContext.get().m_pCicIC = pCicIC; + if (!pTLS->m_pThreadMgr) + { + pCicIC->Release(); + imeContext.unlock(); + imcLock.unlock(); + DestroyInputContext(pTLS, hIMC); + return E_NOINTERFACE; } + imeContext.get().m_pCicIC = pCicIC; + HRESULT hr = pCicIC->CreateInputContext(pTLS->m_pThreadMgr, imcLock); if (FAILED(hr)) { pCicIC->Release(); imeContext.get().m_pCicIC = NULL; + return hr; } - else + + HWND hWnd = imcLock.get().hWnd; + if (hWnd && hWnd == ::GetFocus()) { - if (imcLock.get().hWnd && imcLock.get().hWnd == ::GetFocus()) + ITfDocumentMgr *pDocMgr = GetDocumentManager(imeContext); + if (pDocMgr) { - GetDocumentManager(imeContext); - //FIXME + SetAssociate(pTLS, hWnd, hIMC, pTLS->m_pThreadMgr, pDocMgr); + pDocMgr->Release(); } } - return E_NOTIMPL; + return hr; } /// @implemented @@ -608,3 +609,83 @@ CicBridge::ConfigureRegisterWord( pFunction->Release(); return hr; } + +/// @unimplemented +void CicBridge::SetAssociate( + TLS *pTLS, + HWND hWnd, + HIMC hIMC, + ITfThreadMgr_P *pThreadMgr, + ITfDocumentMgr *pDocMgr) +{ + //FIXME +} + +HRESULT +CicBridge::SetActiveContextAlways(TLS *pTLS, HIMC hIMC, BOOL fActive, HWND hWnd, HKL hKL) +{ + auto pThreadMgr = pTLS->m_pThreadMgr; + if (!pThreadMgr) + return E_OUTOFMEMORY; + + if (fActive) + { + if (!hIMC) + { + SetAssociate(pTLS, hWnd, hIMC, pThreadMgr, m_pDocMgr); + return S_OK; + } + + CicIMCLock imcLock(hIMC); + if (FAILED(imcLock.m_hr)) + return imcLock.m_hr; + + CicIMCCLock<CTFIMECONTEXT> imeContext(imcLock.get().hCtfImeContext); + if (FAILED(imeContext.m_hr)) + return imeContext.m_hr; + + if (hIMC == ::ImmGetContext(hWnd)) + { + ITfDocumentMgr *pDocMgr = GetDocumentManager(imeContext); + if (pDocMgr) + { + SetAssociate(pTLS, imcLock.get().hWnd, hIMC, pThreadMgr, pDocMgr); + pDocMgr->Release(); + } + } + + return S_OK; + } + + if (hIMC && !IsEALang(LOWORD(hKL))) + { + CicIMCLock imcLock(hIMC); + if (FAILED(imcLock.m_hr)) + return imcLock.m_hr; + + CicIMCCLock<CTFIMECONTEXT> imeContext(imcLock.get().hCtfImeContext); + if (FAILED(imeContext.m_hr)) + return imeContext.m_hr; + + CicInputContext *pCicIC = imeContext.get().m_pCicIC; + if (!pCicIC->m_dwUnknown6_5[2] && !pCicIC->m_dwUnknown6_5[3]) + ::ImmNotifyIME(hIMC, NI_COMPOSITIONSTR, CPS_COMPLETE, 0); + } + + if (!hIMC || (::GetFocus() != hWnd) || (hIMC != ::ImmGetContext(hWnd))) + SetAssociate(pTLS, hWnd, hIMC, pThreadMgr, m_pDocMgr); + + return S_OK; +} + +/// @unimplemented +HRESULT CicBridge::Notify( + TLS *pTLS, + ITfThreadMgr *pThreadMgr, + HIMC hIMC, + DWORD dwAction, + DWORD dwIndex, + DWORD_PTR dwValue) +{ + return E_NOTIMPL; // FIXME +} diff --git a/dll/ime/msctfime/bridge.h b/dll/ime/msctfime/bridge.h index c8b8441203d..fa3919f6953 100644 --- a/dll/ime/msctfime/bridge.h +++ b/dll/ime/msctfime/bridge.h @@ -1,7 +1,7 @@ /* * PROJECT: ReactOS msctfime.ime * LICENSE: LGPL-2.1-or-later (https://spdx.org/licenses/LGPL-2.1-or-later) - * PURPOSE: Bridge + * PURPOSE: The bridge of msctfime.ime * COPYRIGHT: Copyright 2024 Katayama Hirofumi MZ <katayama.hirofumi...@gmail.com> */ @@ -64,7 +64,7 @@ public: CicInputContext *pCicIC); void PostTransMsg(_In_ HWND hWnd, _In_ INT cTransMsgs, _In_ const TRANSMSG *pTransMsgs); - void GetDocumentManager(_Inout_ CicIMCCLock<CTFIMECONTEXT>& imeContext); + ITfDocumentMgr* GetDocumentManager(_Inout_ CicIMCCLock<CTFIMECONTEXT>& imeContext); HRESULT ConfigureGeneral(_Inout_ TLS* pTLS, @@ -77,4 +77,21 @@ public: _In_ HKL hKL, _In_ HWND hWnd, _Inout_opt_ LPVOID lpData); + + HRESULT SetActiveContextAlways(TLS *pTLS, HIMC hIMC, BOOL fActive, HWND hWnd, HKL hKL); + + void SetAssociate( + TLS *pTLS, + HWND hWnd, + HIMC hIMC, + ITfThreadMgr_P *pThreadMgr, + ITfDocumentMgr *pDocMgr); + + HRESULT Notify( + TLS *pTLS, + ITfThreadMgr *pThreadMgr, + HIMC hIMC, + DWORD dwAction, + DWORD dwIndex, + DWORD_PTR dwValue); }; diff --git a/dll/ime/msctfime/functions.cpp b/dll/ime/msctfime/functions.cpp deleted file mode 100644 index e3133022023..00000000000 --- a/dll/ime/msctfime/functions.cpp +++ /dev/null @@ -1,261 +0,0 @@ -/* - * PROJECT: ReactOS msctfime.ime - * LICENSE: LGPL-2.1-or-later (https://spdx.org/licenses/LGPL-2.1-or-later) - * PURPOSE: The functionalities of msctfime.ime - * COPYRIGHT: Copyright 2024 Katayama Hirofumi MZ <katayama.hirofumi...@gmail.com> - */ - -#include "msctfime.h" - -WINE_DEFAULT_DEBUG_CHANNEL(msctfime); - -/// @implemented -CFunctionProviderBase::CFunctionProviderBase(_In_ TfClientId clientId) -{ - m_clientId = clientId; - m_guid = GUID_NULL; - m_bstr = NULL; - m_cRefs = 1; -} - -/// @implemented -CFunctionProviderBase::~CFunctionProviderBase() -{ - if (!DllShutdownInProgress()) - ::SysFreeString(m_bstr); -} - -/// @implemented -BOOL -CFunctionProviderBase::Init( - _In_ REFGUID rguid, - _In_ LPCWSTR psz) -{ - m_bstr = ::SysAllocString(psz); - m_guid = rguid; - return (m_bstr != NULL); -} - -/// @implemented -STDMETHODIMP -CFunctionProviderBase::QueryInterface( - _In_ REFIID riid, - _Out_ LPVOID* ppvObj) -{ - if (IsEqualIID(riid, IID_IUnknown) || IsEqualIID(riid, IID_ITfFunctionProvider)) - { - *ppvObj = this; - AddRef(); - return S_OK; - } - return E_NOINTERFACE; -} - -/// @implemented -STDMETHODIMP_(ULONG) CFunctionProviderBase::AddRef() -{ - return ::InterlockedIncrement(&m_cRefs); -} - -/// @implemented -STDMETHODIMP_(ULONG) CFunctionProviderBase::Release() -{ - if (::InterlockedDecrement(&m_cRefs) == 0) - { - delete this; - return 0; - } - return m_cRefs; -} - -/// @implemented -STDMETHODIMP CFunctionProviderBase::GetType(_Out_ GUID *guid) -{ - *guid = m_guid; - return S_OK; -} - -/// @implemented -STDMETHODIMP CFunctionProviderBase::GetDescription(_Out_ BSTR *desc) -{ - *desc = ::SysAllocString(m_bstr); - return (*desc ? S_OK : E_OUTOFMEMORY); -} - -/***********************************************************************/ - -/// @implemented -CFunctionProvider::CFunctionProvider(_In_ TfClientId clientId) : CFunctionProviderBase(clientId) -{ - Init(CLSID_CAImmLayer, L"MSCTFIME::Function Provider"); -} - -/// @implemented -STDMETHODIMP -CFunctionProvider::GetFunction( - _In_ REFGUID guid, - _In_ REFIID riid, - _Out_ IUnknown **func) -{ - *func = NULL; - - if (IsEqualGUID(guid, GUID_NULL) && - IsEqualIID(riid, IID_IAImmFnDocFeed)) - { - *func = new(cicNoThrow) CFnDocFeed(); - if (*func) - return S_OK; - } - - return E_NOINTERFACE; -} - -/***********************************************************************/ - -CFnDocFeed::CFnDocFeed() -{ - m_cRefs = 1; -} - -CFnDocFeed::~CFnDocFeed() -{ -} - -/// @implemented -STDMETHODIMP CFnDocFeed::QueryInterface(_In_ REFIID riid, _Out_ LPVOID* ppvObj) -{ - if (IsEqualIID(riid, IID_IUnknown) || IsEqualIID(riid, IID_IAImmFnDocFeed)) - { - *ppvObj = this; - AddRef(); - return S_OK; - } - return E_NOINTERFACE; -} - -/// @implemented -STDMETHODIMP_(ULONG) CFnDocFeed::AddRef() -{ - return ::InterlockedIncrement(&m_cRefs); -} - -/// @implemented -STDMETHODIMP_(ULONG) CFnDocFeed::Release() -{ - if (::InterlockedDecrement(&m_cRefs) == 0) - { - delete this; - return 0; - } - return m_cRefs; -} - -/// @implemented -STDMETHODIMP CFnDocFeed::DocFeed() -{ - TLS *pTLS = TLS::GetTLS(); - if (!pTLS) - return E_OUTOFMEMORY; - - HIMC hIMC = GetActiveContext(); - CicIMCLock imcLock(hIMC); - if (FAILED(imcLock.m_hr)) - return imcLock.m_hr; - - CicIMCCLock<CTFIMECONTEXT> imeContext(imcLock.get().hCtfImeContext); - if (FAILED(imeContext.m_hr)) - return imeContext.m_hr; - CicInputContext *pCicIC = imeContext.get().m_pCicIC; - if (!pCicIC) - return E_FAIL; - - UINT uCodePage = CP_ACP; - pTLS->m_pProfile->GetCodePageA(&uCodePage); - pCicIC->SetupDocFeedString(imcLock, uCodePage); - return S_OK; -} - -/// @implemented -STDMETHODIMP CFnDocFeed::ClearDocFeedBuffer() -{ - if (!TLS::GetTLS()) - return E_OUTOFMEMORY; - - HIMC hIMC = GetActiveContext(); - CicIMCLock imcLock(hIMC); - if (FAILED(imcLock.m_hr)) - return imcLock.m_hr; - - CicIMCCLock<CTFIMECONTEXT> imeContext(imcLock.get().hCtfImeContext); - if (FAILED(imeContext.m_hr)) - return imeContext.m_hr; - - CicInputContext *pCicIC = imeContext.get().m_pCicIC; - if (!pCicIC) - return E_FAIL; - - pCicIC->EscbClearDocFeedBuffer(imcLock, TRUE); - return S_OK; -} - -/// @unimplemented -STDMETHODIMP CFnDocFeed::StartReconvert() -{ - TLS *pTLS = TLS::GetTLS(); - if (!pTLS) - return E_OUTOFMEMORY; - auto *pThreadMgr = pTLS->m_pThreadMgr; - if (!pThreadMgr) - return E_OUTOFMEMORY; - - HIMC hIMC = GetActiveContext(); - CicIMCLock imcLock(hIMC); - if (FAILED(imcLock.m_hr)) - return imcLock.m_hr; - - CicIMCCLock<CTFIMECONTEXT> imeContext(imcLock.get().hCtfImeContext); - if (FAILED(imeContext.m_hr)) - return imeContext.m_hr; - CicInputContext *pCicIC = imeContext.get().m_pCicIC; - if (!pCicIC) - return E_FAIL; - - UINT uCodePage = CP_ACP; - pTLS->m_pProfile->GetCodePageA(&uCodePage); - - pCicIC->m_bReconverting = TRUE; - pCicIC->SetupReconvertString(imcLock, pThreadMgr, uCodePage, 0, 0); - pCicIC->EndReconvertString(imcLock); - pCicIC->m_bReconverting = FALSE; - return S_OK; -} - -/// @implemented -STDMETHODIMP CFnDocFeed::StartUndoCompositionString() -{ - TLS *pTLS = TLS::GetTLS(); - if (!pTLS) - return E_OUTOFMEMORY; - auto *pThreadMgr = pTLS->m_pThreadMgr; - if (!pThreadMgr) - return E_OUTOFMEMORY; - - HIMC hIMC = GetActiveContext(); - CicIMCLock imcLock(hIMC); - if (FAILED(imcLock.m_hr)) - return imcLock.m_hr; - - CicIMCCLock<CTFIMECONTEXT> imeContext(imcLock.get().hCtfImeContext); - if (FAILED(imeContext.m_hr)) - return imeContext.m_hr; - CicInputContext *pCicIC = imeContext.get().m_pCicIC; - if (!pCicIC) - return E_FAIL; - - UINT uCodePage = CP_ACP; - pTLS->m_pProfile->GetCodePageA(&uCodePage); - - pCicIC->SetupReconvertString(imcLock, pThreadMgr, uCodePage, 0, TRUE); - pCicIC->EndReconvertString(imcLock); - return S_OK; -} diff --git a/dll/ime/msctfime/functions.h b/dll/ime/msctfime/functions.h deleted file mode 100644 index d0b7d8c2ebe..00000000000 --- a/dll/ime/msctfime/functions.h +++ /dev/null @@ -1,63 +0,0 @@ -/* - * PROJECT: ReactOS msctfime.ime - * LICENSE: LGPL-2.1-or-later (https://spdx.org/licenses/LGPL-2.1-or-later) - * PURPOSE: The functionalities of msctfime.ime - * COPYRIGHT: Copyright 2024 Katayama Hirofumi MZ <katayama.hirofumi...@gmail.com> - */ - -class CFunctionProviderBase : public ITfFunctionProvider -{ -protected: - TfClientId m_clientId; - GUID m_guid; - BSTR m_bstr; - LONG m_cRefs; - -public: - CFunctionProviderBase(_In_ TfClientId clientId); - virtual ~CFunctionProviderBase(); - - // IUnknown interface - STDMETHODIMP QueryInterface(_In_ REFIID riid, _Out_ LPVOID* ppvObj) override; - STDMETHODIMP_(ULONG) AddRef() override; - STDMETHODIMP_(ULONG) Release() override; - - // ITfFunctionProvider interface - STDMETHODIMP GetType(_Out_ GUID *guid) override; - STDMETHODIMP GetDescription(_Out_ BSTR *desc) override; - //STDMETHODIMP GetFunction(_In_ REFGUID guid, _In_ REFIID riid, _Out_ IUnknown **func) = 0; - - BOOL Init(_In_ REFGUID rguid, _In_ LPCWSTR psz); -}; - -/***********************************************************************/ - -class CFunctionProvider : public CFunctionProviderBase -{ -public: - CFunctionProvider(_In_ TfClientId clientId); - - STDMETHODIMP GetFunction(_In_ REFGUID guid, _In_ REFIID riid, _Out_ IUnknown **func) override; -}; - -/***********************************************************************/ - -class CFnDocFeed : public IAImmFnDocFeed -{ - LONG m_cRefs; - -public: - CFnDocFeed(); - virtual ~CFnDocFeed(); - - // IUnknown interface - STDMETHODIMP QueryInterface(_In_ REFIID riid, _Out_ LPVOID* ppvObj) override; - STDMETHODIMP_(ULONG) AddRef() override; - STDMETHODIMP_(ULONG) Release() override; - - // IAImmFnDocFeed interface - STDMETHODIMP DocFeed() override; - STDMETHODIMP ClearDocFeedBuffer() override; - STDMETHODIMP StartReconvert() override; - STDMETHODIMP StartUndoCompositionString() override; -}; diff --git a/dll/ime/msctfime/misc.cpp b/dll/ime/msctfime/misc.cpp index 7cf38ad15b2..5b899c2ccfc 100644 --- a/dll/ime/msctfime/misc.cpp +++ b/dll/ime/msctfime/misc.cpp @@ -9,6 +9,185 @@ WINE_DEFAULT_DEBUG_CHANNEL(msctfime); +/// East-Asian language? +/// @implemented +BOOL IsEALang(LANGID LangID) +{ + if (LangID == 0) + { + TLS *pTLS = TLS::GetTLS(); + if (!pTLS || !pTLS->m_pProfile) + return FALSE; + + pTLS->m_pProfile->GetLangId(&LangID); + } + + switch (PRIMARYLANGID(LangID)) + { + case LANG_CHINESE: + case LANG_JAPANESE: + case LANG_KOREAN: + return TRUE; + + default: + return FALSE; + } +} + +typedef BOOLEAN (WINAPI *FN_DllShutdownInProgress)(VOID); + +/// This function calls ntdll!RtlDllShutdownInProgress. +/// It can detect the system is shutting down or not. +/// @implemented +BOOLEAN DllShutdownInProgress(VOID) +{ + HMODULE hNTDLL; + static FN_DllShutdownInProgress s_fnDllShutdownInProgress = NULL; + + if (s_fnDllShutdownInProgress) + return s_fnDllShutdownInProgress(); + + hNTDLL = cicGetSystemModuleHandle(L"ntdll.dll", FALSE); + s_fnDllShutdownInProgress = + (FN_DllShutdownInProgress)GetProcAddress(hNTDLL, "RtlDllShutdownInProgress"); + if (!s_fnDllShutdownInProgress) + return FALSE; + + return s_fnDllShutdownInProgress(); +} + +/// This function checks if the current user logon session is interactive. +/// @implemented +BOOL IsInteractiveUserLogon(VOID) +{ + BOOL bOK, IsMember = FALSE; + PSID pSid; + SID_IDENTIFIER_AUTHORITY IdentAuth = { SECURITY_NT_AUTHORITY }; + + if (!AllocateAndInitializeSid(&IdentAuth, 1, SECURITY_INTERACTIVE_RID, + 0, 0, 0, 0, 0, 0, 0, &pSid)) + { + ERR("Error: %ld\n", GetLastError()); + return FALSE; + } + + bOK = CheckTokenMembership(NULL, pSid, &IsMember); + + if (pSid) + FreeSid(pSid); + + return bOK && IsMember; +} + +/// Gets the charset from a language ID. +/// @implemented +BYTE GetCharsetFromLangId(_In_ DWORD dwValue) +{ + CHARSETINFO info; + if (!::TranslateCharsetInfo((DWORD*)(DWORD_PTR)dwValue, &info, TCI_SRCLOCALE)) + return 0; + return info.ciCharset; +} + +/// Get the active input context. +/// @implemented +HIMC GetActiveContext(VOID) +{ + HWND hwndFocus = ::GetFocus(); + if (!hwndFocus) + hwndFocus = ::GetActiveWindow(); + return ::ImmGetContext(hwndFocus); +} + +/// @implemented +ITfCategoryMgr *GetUIMCat(PCIC_LIBTHREAD pLibThread) +{ + if (!pLibThread) + return NULL; + + if (pLibThread->m_pCategoryMgr) + return pLibThread->m_pCategoryMgr; + + if (FAILED(cicCoCreateInstance(CLSID_TF_CategoryMgr, NULL, CLSCTX_INPROC_SERVER, + IID_ITfCategoryMgr, (void **)&pLibThread->m_pCategoryMgr))) + { + return NULL; + } + return pLibThread->m_pCategoryMgr; +} + +/// @implemented +static HRESULT +LibEnumItemsInCategory(PCIC_LIBTHREAD pLibThread, REFGUID rguid, IEnumGUID **ppEnum) +{ + ITfCategoryMgr *pCat = GetUIMCat(pLibThread); + if (!pCat) + return E_FAIL; + return pCat->EnumItemsInCategory(rguid, ppEnum); +} + +/// @implemented +HRESULT InitDisplayAttrbuteLib(PCIC_LIBTHREAD pLibThread) +{ + if (!pLibThread) + return E_FAIL; + + if (pLibThread->m_pDisplayAttrMgr) + { + pLibThread->m_pDisplayAttrMgr->Release(); + pLibThread->m_pDisplayAttrMgr = NULL; + } + + if (FAILED(cicCoCreateInstance(CLSID_TF_DisplayAttributeMgr, NULL, CLSCTX_INPROC_SERVER, + IID_ITfDisplayAttributeMgr, + (void **)&pLibThread->m_pDisplayAttrMgr))) + { + return E_FAIL; + } + + IEnumGUID *pEnumGuid; + LibEnumItemsInCategory(pLibThread, GUID_TFCAT_DISPLAYATTRIBUTEPROPERTY, &pEnumGuid); + + HRESULT hr = E_OUTOFMEMORY; + + ::EnterCriticalSection(&g_csLock); + if (pEnumGuid && !g_pPropCache) + { + g_pPropCache = new(cicNoThrow) CDispAttrPropCache(); + if (g_pPropCache) + { + g_pPropCache->Add(GUID_PROP_ATTRIBUTE); + GUID guid; + while (pEnumGuid->Next(1, &guid, NULL) == S_OK) + { + if (!IsEqualGUID(guid, GUID_PROP_ATTRIBUTE)) + g_pPropCache->Add(guid); + } + hr = S_OK; + } + } + ::LeaveCriticalSection(&g_csLock); + + return hr; +} + +/// @implemented +HRESULT UninitDisplayAttrbuteLib(PCIC_LIBTHREAD pLibThread) +{ + if (!pLibThread) + return E_FAIL; + + if (pLibThread->m_pDisplayAttrMgr) + { + pLibThread->m_pDisplayAttrMgr->Release(); + pLibThread->m_pDisplayAttrMgr = NULL; + } + + return S_OK; +} + +/***********************************************************************/ + /// @implemented HRESULT GetCompartment( @@ -179,11 +358,13 @@ static const MODEBIAS g_ModeBiasMap[] = { GUID_MODEBIAS_NONE, 0x00000000 }, }; +/// @implemented void CModeBias::SetModeBias(REFGUID rguid) { m_guid = rguid; } +/// @implemented GUID CModeBias::ConvertModeBias(LONG bias) { const GUID *pguid = &GUID_NULL; @@ -199,6 +380,7 @@ GUID CModeBias::ConvertModeBias(LONG bias) return *pguid; } +/// @implemented LONG CModeBias::ConvertModeBias(REFGUID guid) { for (auto& item : g_ModeBiasMap) @@ -211,25 +393,253 @@ LONG CModeBias::ConvertModeBias(REFGUID guid) /***********************************************************************/ -/// East-Asian language? /// @implemented -BOOL IsEALang(VOID) +CFunctionProviderBase::CFunctionProviderBase(_In_ TfClientId clientId) { - TLS *pTLS = TLS::GetTLS(); - if (!pTLS || !pTLS->m_pProfile) - return FALSE; + m_clientId = clientId; + m_guid = GUID_NULL; + m_bstr = NULL; + m_cRefs = 1; +} - LANGID LangID; - pTLS->m_pProfile->GetLangId(&LangID); +/// @implemented +CFunctionProviderBase::~CFunctionProviderBase() +{ + if (!DllShutdownInProgress()) + ::SysFreeString(m_bstr); +} - switch (PRIMARYLANGID(LangID)) +/// @implemented +BOOL +CFunctionProviderBase::Init( + _In_ REFGUID rguid, + _In_ LPCWSTR psz) +{ + m_bstr = ::SysAllocString(psz); + m_guid = rguid; + return (m_bstr != NULL); +} + +/// @implemented +STDMETHODIMP +CFunctionProviderBase::QueryInterface( + _In_ REFIID riid, + _Out_ LPVOID* ppvObj) +{ + if (IsEqualIID(riid, IID_IUnknown) || IsEqualIID(riid, IID_ITfFunctionProvider)) { - case LANG_CHINESE: - case LANG_JAPANESE: - case LANG_KOREAN: - return TRUE; + *ppvObj = this; + AddRef(); + return S_OK; + } + return E_NOINTERFACE; +} - default: - return FALSE; +/// @implemented +STDMETHODIMP_(ULONG) CFunctionProviderBase::AddRef() +{ + return ::InterlockedIncrement(&m_cRefs); +} + +/// @implemented +STDMETHODIMP_(ULONG) CFunctionProviderBase::Release() +{ + if (::InterlockedDecrement(&m_cRefs) == 0) + { + delete this; + return 0; + } + return m_cRefs; +} + +/// @implemented +STDMETHODIMP CFunctionProviderBase::GetType(_Out_ GUID *guid) +{ + *guid = m_guid; + return S_OK; +} + +/// @implemented +STDMETHODIMP CFunctionProviderBase::GetDescription(_Out_ BSTR *desc) +{ + *desc = ::SysAllocString(m_bstr); + return (*desc ? S_OK : E_OUTOFMEMORY); +} + +/***********************************************************************/ + +/// @implemented +CFunctionProvider::CFunctionProvider(_In_ TfClientId clientId) : CFunctionProviderBase(clientId) +{ + Init(CLSID_CAImmLayer, L"MSCTFIME::Function Provider"); +} + +/// @implemented +STDMETHODIMP +CFunctionProvider::GetFunction( + _In_ REFGUID guid, + _In_ REFIID riid, + _Out_ IUnknown **func) +{ + *func = NULL; + + if (IsEqualGUID(guid, GUID_NULL) && + IsEqualIID(riid, IID_IAImmFnDocFeed)) + { + *func = new(cicNoThrow) CFnDocFeed(); + if (*func) + return S_OK; } + + return E_NOINTERFACE; +} + +/***********************************************************************/ + +CFnDocFeed::CFnDocFeed() +{ + m_cRefs = 1; +} + +CFnDocFeed::~CFnDocFeed() +{ +} + +/// @implemented +STDMETHODIMP CFnDocFeed::QueryInterface(_In_ REFIID riid, _Out_ LPVOID* ppvObj) +{ + if (IsEqualIID(riid, IID_IUnknown) || IsEqualIID(riid, IID_IAImmFnDocFeed)) + { + *ppvObj = this; + AddRef(); + return S_OK; + } + return E_NOINTERFACE; +} + +/// @implemented +STDMETHODIMP_(ULONG) CFnDocFeed::AddRef() +{ + return ::InterlockedIncrement(&m_cRefs); +} + +/// @implemented +STDMETHODIMP_(ULONG) CFnDocFeed::Release() +{ + if (::InterlockedDecrement(&m_cRefs) == 0) + { + delete this; + return 0; + } + return m_cRefs; +} + +/// @implemented +STDMETHODIMP CFnDocFeed::DocFeed() +{ + TLS *pTLS = TLS::GetTLS(); + if (!pTLS) + return E_OUTOFMEMORY; + + HIMC hIMC = GetActiveContext(); + CicIMCLock imcLock(hIMC); + if (FAILED(imcLock.m_hr)) + return imcLock.m_hr; + + CicIMCCLock<CTFIMECONTEXT> imeContext(imcLock.get().hCtfImeContext); + if (FAILED(imeContext.m_hr)) + return imeContext.m_hr; + CicInputContext *pCicIC = imeContext.get().m_pCicIC; + if (!pCicIC) + return E_FAIL; + + UINT uCodePage = CP_ACP; + pTLS->m_pProfile->GetCodePageA(&uCodePage); + pCicIC->SetupDocFeedString(imcLock, uCodePage); + return S_OK; +} + +/// @implemented +STDMETHODIMP CFnDocFeed::ClearDocFeedBuffer() +{ + if (!TLS::GetTLS()) + return E_OUTOFMEMORY; + + HIMC hIMC = GetActiveContext(); + CicIMCLock imcLock(hIMC); + if (FAILED(imcLock.m_hr)) + return imcLock.m_hr; + + CicIMCCLock<CTFIMECONTEXT> imeContext(imcLock.get().hCtfImeContext); + if (FAILED(imeContext.m_hr)) + return imeContext.m_hr; + + CicInputContext *pCicIC = imeContext.get().m_pCicIC; + if (!pCicIC) + return E_FAIL; + + pCicIC->EscbClearDocFeedBuffer(imcLock, TRUE); + return S_OK; +} + +/// @unimplemented +STDMETHODIMP CFnDocFeed::StartReconvert() +{ + TLS *pTLS = TLS::GetTLS(); + if (!pTLS) + return E_OUTOFMEMORY; + auto *pThreadMgr = pTLS->m_pThreadMgr; + if (!pThreadMgr) + return E_OUTOFMEMORY; + + HIMC hIMC = GetActiveContext(); + CicIMCLock imcLock(hIMC); + if (FAILED(imcLock.m_hr)) + return imcLock.m_hr; + + CicIMCCLock<CTFIMECONTEXT> imeContext(imcLock.get().hCtfImeContext); + if (FAILED(imeContext.m_hr)) + return imeContext.m_hr; + CicInputContext *pCicIC = imeContext.get().m_pCicIC; + if (!pCicIC) + return E_FAIL; + + UINT uCodePage = CP_ACP; + pTLS->m_pProfile->GetCodePageA(&uCodePage); + + pCicIC->m_bReconverting = TRUE; + pCicIC->SetupReconvertString(imcLock, pThreadMgr, uCodePage, 0, 0); + pCicIC->EndReconvertString(imcLock); + pCicIC->m_bReconverting = FALSE; + return S_OK; +} + +/// @implemented +STDMETHODIMP CFnDocFeed::StartUndoCompositionString() +{ + TLS *pTLS = TLS::GetTLS(); + if (!pTLS) + return E_OUTOFMEMORY; + auto *pThreadMgr = pTLS->m_pThreadMgr; + if (!pThreadMgr) + return E_OUTOFMEMORY; + + HIMC hIMC = GetActiveContext(); + CicIMCLock imcLock(hIMC); + if (FAILED(imcLock.m_hr)) + return imcLock.m_hr; + + CicIMCCLock<CTFIMECONTEXT> imeContext(imcLock.get().hCtfImeContext); + if (FAILED(imeContext.m_hr)) + return imeContext.m_hr; + CicInputContext *pCicIC = imeContext.get().m_pCicIC; + if (!pCicIC) + return E_FAIL; + + UINT uCodePage = CP_ACP; + pTLS->m_pProfile->GetCodePageA(&uCodePage); + + pCicIC->SetupReconvertString(imcLock, pThreadMgr, uCodePage, 0, TRUE); + pCicIC->EndReconvertString(imcLock); + return S_OK; } diff --git a/dll/ime/msctfime/misc.h b/dll/ime/msctfime/misc.h index 49cca38c0cc..d5d17f15f53 100644 --- a/dll/ime/msctfime/misc.h +++ b/dll/ime/msctfime/misc.h @@ -7,6 +7,17 @@ #pragma once +BOOLEAN DllShutdownInProgress(VOID); +BOOL IsEALang(LANGID LangID); +BOOL IsInteractiveUserLogon(VOID); +BYTE GetCharsetFromLangId(_In_ DWORD dwValue); +HIMC GetActiveContext(VOID); +ITfCategoryMgr *GetUIMCat(PCIC_LIBTHREAD pLibThread); +HRESULT InitDisplayAttrbuteLib(PCIC_LIBTHREAD pLibThread); +HRESULT UninitDisplayAttrbuteLib(PCIC_LIBTHREAD pLibThread); + +/***********************************************************************/ + HRESULT GetCompartment( IUnknown *pUnknown, @@ -59,4 +70,59 @@ public: /***********************************************************************/ -BOOL IsEALang(VOID); +class CFunctionProviderBase : public ITfFunctionProvider +{ +protected: + TfClientId m_clientId; + GUID m_guid; + BSTR m_bstr; + LONG m_cRefs; + +public: + CFunctionProviderBase(_In_ TfClientId clientId); + virtual ~CFunctionProviderBase(); + + // IUnknown interface + STDMETHODIMP QueryInterface(_In_ REFIID riid, _Out_ LPVOID* ppvObj) override; + STDMETHODIMP_(ULONG) AddRef() override; + STDMETHODIMP_(ULONG) Release() override; + + // ITfFunctionProvider interface + STDMETHODIMP GetType(_Out_ GUID *guid) override; + STDMETHODIMP GetDescription(_Out_ BSTR *desc) override; + //STDMETHODIMP GetFunction(_In_ REFGUID guid, _In_ REFIID riid, _Out_ IUnknown **func) = 0; + + BOOL Init(_In_ REFGUID rguid, _In_ LPCWSTR psz); +}; + +/***********************************************************************/ + +class CFunctionProvider : public CFunctionProviderBase +{ +public: + CFunctionProvider(_In_ TfClientId clientId); + + STDMETHODIMP GetFunction(_In_ REFGUID guid, _In_ REFIID riid, _Out_ IUnknown **func) override; +}; + +/***********************************************************************/ + +class CFnDocFeed : public IAImmFnDocFeed +{ + LONG m_cRefs; + +public: + CFnDocFeed(); + virtual ~CFnDocFeed(); + + // IUnknown interface + STDMETHODIMP QueryInterface(_In_ REFIID riid, _Out_ LPVOID* ppvObj) override; + STDMETHODIMP_(ULONG) AddRef() override; + STDMETHODIMP_(ULONG) Release() override; + + // IAImmFnDocFeed interface + STDMETHODIMP DocFeed() override; + STDMETHODIMP ClearDocFeedBuffer() override; + STDMETHODIMP StartReconvert() override; + STDMETHODIMP StartUndoCompositionString() override; +}; diff --git a/dll/ime/msctfime/msctfime.cpp b/dll/ime/msctfime/msctfime.cpp index 87ca208819c..cd4b4af212c 100644 --- a/dll/ime/msctfime/msctfime.cpp +++ b/dll/ime/msctfime/msctfime.cpp @@ -6,12 +6,9 @@ */ #include "msctfime.h" -#include <ndk/ldrfuncs.h> /* for RtlDllShutdownInProgress */ WINE_DEFAULT_DEBUG_CHANNEL(msctfime); -typedef CicArray<GUID> CDispAttrPropCache; - HINSTANCE g_hInst = NULL; /* The instance of this module */ BOOL g_bWinLogon = FALSE; UINT g_uACP = CP_ACP; @@ -25,148 +22,6 @@ EXTERN_C void __cxa_pure_virtual(void) ERR("__cxa_pure_virtual\n"); } -typedef BOOLEAN (WINAPI *FN_DllShutdownInProgress)(VOID); - -/// This function calls ntdll!RtlDllShutdownInProgress. -/// It can detect the system is shutting down or not. -/// @implemented -EXTERN_C BOOLEAN WINAPI DllShutdownInProgress(VOID) -{ - HMODULE hNTDLL; - static FN_DllShutdownInProgress s_fnDllShutdownInProgress = NULL; - - if (s_fnDllShutdownInProgress) - return s_fnDllShutdownInProgress(); - - hNTDLL = cicGetSystemModuleHandle(L"ntdll.dll", FALSE); - s_fnDllShutdownInProgress = - (FN_DllShutdownInProgress)GetProcAddress(hNTDLL, "RtlDllShutdownInProgress"); - if (!s_fnDllShutdownInProgress) - return FALSE; - - return s_fnDllShutdownInProgress(); -} - -/// This function checks if the current user logon session is interactive. -/// @implemented -static BOOL -IsInteractiveUserLogon(VOID) -{ - BOOL bOK, IsMember = FALSE; - PSID pSid; - SID_IDENTIFIER_AUTHORITY IdentAuth = { SECURITY_NT_AUTHORITY }; - - if (!AllocateAndInitializeSid(&IdentAuth, 1, SECURITY_INTERACTIVE_RID, - 0, 0, 0, 0, 0, 0, 0, &pSid)) - { - ERR("Error: %ld\n", GetLastError()); - return FALSE; - } - - bOK = CheckTokenMembership(NULL, pSid, &IsMember); - - if (pSid) - FreeSid(pSid); - - return bOK && IsMember; -} - -/// @implemented -ITfCategoryMgr *GetUIMCat(PCIC_LIBTHREAD pLibThread) -{ - if (!pLibThread) - return NULL; - - if (pLibThread->m_pCategoryMgr) - return pLibThread->m_pCategoryMgr; - - if (FAILED(cicCoCreateInstance(CLSID_TF_CategoryMgr, NULL, CLSCTX_INPROC_SERVER, - IID_ITfCategoryMgr, (void **)&pLibThread->m_pCategoryMgr))) - { - return NULL; - } - return pLibThread->m_pCategoryMgr; -} - -/// @implemented -HRESULT LibEnumItemsInCategory(PCIC_LIBTHREAD pLibThread, REFGUID rguid, IEnumGUID **ppEnum) -{ - ITfCategoryMgr *pCat = GetUIMCat(pLibThread); - if (!pCat) - return E_FAIL; - return pCat->EnumItemsInCategory(rguid, ppEnum); -} - -/// @implemented -HRESULT InitDisplayAttrbuteLib(PCIC_LIBTHREAD pLibThread) -{ - if (!pLibThread) - return E_FAIL; - - if (pLibThread->m_pDisplayAttrMgr) - { - pLibThread->m_pDisplayAttrMgr->Release(); - pLibThread->m_pDisplayAttrMgr = NULL; - } - - if (FAILED(cicCoCreateInstance(CLSID_TF_DisplayAttributeMgr, NULL, CLSCTX_INPROC_SERVER, - IID_ITfDisplayAttributeMgr, - (void **)&pLibThread->m_pDisplayAttrMgr))) - { - return E_FAIL; - } - - IEnumGUID *pEnumGuid; - LibEnumItemsInCategory(pLibThread, GUID_TFCAT_DISPLAYATTRIBUTEPROPERTY, &pEnumGuid); - - HRESULT hr = E_OUTOFMEMORY; - - ::EnterCriticalSection(&g_csLock); - if (pEnumGuid && !g_pPropCache) - { - g_pPropCache = new(cicNoThrow) CDispAttrPropCache(); - if (g_pPropCache) - { - g_pPropCache->Add(GUID_PROP_ATTRIBUTE); - GUID guid; - while (pEnumGuid->Next(1, &guid, NULL) == S_OK) - { - if (!IsEqualGUID(guid, GUID_PROP_ATTRIBUTE)) - g_pPropCache->Add(guid); - } - hr = S_OK; - } - } - ::LeaveCriticalSection(&g_csLock); - - return hr; -} - -/// @implemented -HRESULT UninitDisplayAttrbuteLib(PCIC_LIBTHREAD pLibThread) -{ - if (!pLibThread) - return E_FAIL; - - if (pLibThread->m_pDisplayAttrMgr) - { - pLibThread->m_pDisplayAttrMgr->Release(); - pLibThread->m_pDisplayAttrMgr = NULL; - } - - return S_OK; -} - -/// Gets the charset from a language ID. -/// @implemented -BYTE GetCharsetFromLangId(_In_ DWORD dwValue) -{ - CHARSETINFO info; - if (!::TranslateCharsetInfo((DWORD*)(DWORD_PTR)dwValue, &info, TCI_SRCLOCALE)) - return 0; - return info.ciCharset; -} - /// Selects or unselects the input context. /// @implemented HRESULT @@ -236,8 +91,6 @@ InternalSelectEx( return imcLock.m_hr; } -class TLS; - /*********************************************************************** * ImeInquire (MSCTFIME.@) * @@ -245,6 +98,7 @@ class TLS; * * @implemented * @see CtfImeInquireExW + * @see https://katahiromz.web.fc2.com/colony3rd/imehackerz/en/ImeInquire.html */ EXTERN_C BOOL WINAPI @@ -264,6 +118,7 @@ ImeInquire( * * @implemented * @see ImmGetConversionListW + * @see https://katahiromz.web.fc2.com/colony3rd/imehackerz/en/ImeConversionList.html */ EXTERN_C DWORD WINAPI ImeConversionList( @@ -284,6 +139,7 @@ ImeConversionList( * * @implemented * @see ImeUnregisterWord + * @see https://katahiromz.web.fc2.com/colony3rd/imehackerz/en/ImeRegisterWord.html */ EXTERN_C BOOL WINAPI ImeRegisterWord( @@ -302,6 +158,7 @@ ImeRegisterWord( * * @implemented * @see ImeRegisterWord + * @see https://katahiromz.web.fc2.com/colony3rd/imehackerz/en/ImeUnregisterWord.html */ EXTERN_C BOOL WINAPI ImeUnregisterWord( @@ -320,6 +177,7 @@ ImeUnregisterWord( * * @implemented * @see ImeRegisterWord + * @see https://katahiromz.web.fc2.com/colony3rd/imehackerz/en/ImeGetRegisterWordStyle.html */ EXTERN_C UINT WINAPI ImeGetRegisterWordStyle( @@ -337,6 +195,7 @@ ImeGetRegisterWordStyle( * * @implemented * @see ImeRegisterWord + * @see https://katahiromz.web.fc2.com/colony3rd/imehackerz/en/ImeEnumRegisterWord.html */ EXTERN_C UINT WINAPI ImeEnumRegisterWord( @@ -351,6 +210,12 @@ ImeEnumRegisterWord( return 0; } +/*********************************************************************** + * ImeConfigure (MSCTFIME.@) + * + * @implemented + * @see https://katahiromz.web.fc2.com/colony3rd/imehackerz/en/ImeConfigure.html + */ EXTERN_C BOOL WINAPI ImeConfigure( _In_ HKL hKL, @@ -380,6 +245,7 @@ ImeConfigure( * ImeDestroy (MSCTFIME.@) * * @implemented + * @see https://katahiromz.web.fc2.com/colony3rd/imehackerz/en/ImeDestroy.html */ EXTERN_C BOOL WINAPI ImeDestroy( @@ -410,6 +276,7 @@ ImeDestroy( * * @implemented * @see CtfImeEscapeEx + * @see https://katahiromz.web.fc2.com/colony3rd/imehackerz/en/ImeEscape.html */ EXTERN_C LRESULT WINAPI ImeEscape( @@ -439,6 +306,7 @@ ImeProcessKey( * * @implemented * @see CtfImeSelectEx + * @see https://katahiromz.web.fc2.com/colony3rd/imehackerz/en/ImeSelect.html */ EXTERN_C BOOL WINAPI ImeSelect( @@ -456,6 +324,7 @@ ImeSelect( * * @implemented * @see CtfImeSetActiveContextAlways + * @see https://katahiromz.web.fc2.com/colony3rd/imehackerz/en/ImeSetActiveContext.html */ EXTERN_C BOOL WINAPI ImeSetActiveContext( @@ -480,6 +349,12 @@ ImeToAsciiEx( return 0; } +/*********************************************************************** + * NotifyIME (MSCTFIME.@) + * + * @implemented + * @see https://katahiromz.web.fc2.com/colony3rd/imehackerz/en/NotifyIME.html + */ EXTERN_C BOOL WINAPI NotifyIME( _In_ HIMC hIMC, @@ -487,8 +362,19 @@ NotifyIME( _In_ DWORD dwIndex, _In_ DWORD_PTR dwValue) { - FIXME("stub:(%p, 0x%lX, 0x%lX, %p)\n", hIMC, dwAction, dwIndex, dwValue); - return FALSE; + TRACE("(%p, 0x%lX, 0x%lX, %p)\n", hIMC, dwAction, dwIndex, dwValue); + + TLS *pTLS = TLS::GetTLS(); + if (!pTLS) + return FALSE; + + auto pBridge = pTLS->m_pBridge; + auto pThreadMgr = pTLS->m_pThreadMgr; + if (!pBridge || !pThreadMgr) + return FALSE; + + HRESULT hr = pBridge->Notify(pTLS, pThreadMgr, hIMC, dwAction, dwIndex, dwValue); + return (hr == S_OK); } EXTERN_C BOOL WINAPI @@ -704,11 +590,22 @@ CtfImeDestroyThreadMgr(VOID) return hr; } +/*********************************************************************** + * CtfImeCreateInputContext (MSCTFIME.@) + * + * @implemented + */ EXTERN_C HRESULT WINAPI CtfImeCreateInputContext( _In_ HIMC hIMC) { - return E_NOTIMPL; + TRACE("(%p)\n", hIMC); + + TLS *pTLS = TLS::GetTLS(); + if (!pTLS || !pTLS->m_pBridge) + return E_OUTOFMEMORY; + + return pTLS->m_pBridge->CreateInputContext(pTLS, hIMC); } /*********************************************************************** @@ -729,6 +626,11 @@ CtfImeDestroyInputContext( return pTLS->m_pBridge->DestroyInputContext(pTLS, hIMC); } +/*********************************************************************** + * CtfImeSetActiveContextAlways (MSCTFIME.@) + * + * @implemented + */ EXTERN_C HRESULT WINAPI CtfImeSetActiveContextAlways( _In_ HIMC hIMC, @@ -736,10 +638,13 @@ CtfImeSetActiveContextAlways( _In_ HWND hWnd, _In_ HKL hKL) { - FIXME("stub:(%p, %d, %p, %p)\n", hIMC, fActive, hWnd, hKL); - return E_NOTIMPL; -} + TRACE("(%p, %d, %p, %p)\n", hIMC, fActive, hWnd, hKL); + TLS *pTLS = TLS::GetTLS(); + if (!pTLS || !pTLS->m_pBridge) + return E_OUTOFMEMORY; + return pTLS->m_pBridge->SetActiveContextAlways(pTLS, hIMC, fActive, hWnd, hKL); +} /*********************************************************************** * CtfImeProcessCicHotkey (MSCTFIME.@) diff --git a/dll/ime/msctfime/msctfime.h b/dll/ime/msctfime/msctfime.h index 59a89d537f2..48b184940df 100644 --- a/dll/ime/msctfime/msctfime.h +++ b/dll/ime/msctfime/msctfime.h @@ -35,18 +35,10 @@ #include <wine/debug.h> -EXTERN_C BOOLEAN WINAPI DllShutdownInProgress(VOID); +extern CRITICAL_SECTION g_csLock; -HRESULT InitDisplayAttrbuteLib(PCIC_LIBTHREAD pLibThread); -HRESULT UninitDisplayAttrbuteLib(PCIC_LIBTHREAD pLibThread); - -static inline HIMC GetActiveContext(VOID) -{ - HWND hwndFocus = ::GetFocus(); - if (!hwndFocus) - hwndFocus = ::GetActiveWindow(); - return ::ImmGetContext(hwndFocus); -} +typedef CicArray<GUID> CDispAttrPropCache; +extern CDispAttrPropCache *g_pPropCache; DEFINE_GUID(GUID_COMPARTMENT_CTFIME_DIMFLAGS, 0xA94C5FD2, 0xC471, 0x4031, 0x95, 0x46, 0x70, 0x9C, 0x17, 0x30, 0x0C, 0xB9); DEFINE_GUID(GUID_COMPARTMENT_CTFIME_CICINPUTCONTEXT, 0x85A688F7, 0x6DC8, 0x4F17, 0xA8, 0x3A, 0xB1, 0x1C, 0x09, 0xCD, 0xD7, 0xBF); @@ -55,13 +47,11 @@ DEFINE_GUID(GUID_MODEBIAS_NUMERIC, 0x4021766C, 0xE872, 0x48FD, DEFINE_GUID(GUID_MODEBIAS_URLHISTORY, 0x8B0E54D9, 0x63F2, 0x4C68, 0x84, 0xD4, 0x79, 0xAE, 0xE7, 0xA5, 0x9F, 0x09); DEFINE_GUID(GUID_MODEBIAS_DEFAULT, 0xF3DA8BD4, 0x0786, 0x49C2, 0x8C, 0x09, 0x68, 0x39, 0xD8, 0xB8, 0x4F, 0x58); DEFINE_GUID(GUID_PROP_MODEBIAS, 0x372E0716, 0x974F, 0x40AC, 0xA0, 0x88, 0x08, 0xCD, 0xC9, 0x2E, 0xBF, 0xBC); - #define GUID_MODEBIAS_NONE GUID_NULL #include "resource.h" #include "bridge.h" -#include "functions.h" #include "inputcontext.h" #include "misc.h" #include "profile.h" diff --git a/dll/ime/msctfime/tls.cpp b/dll/ime/msctfime/tls.cpp index c6db21cc61e..392106e96ed 100644 --- a/dll/ime/msctfime/tls.cpp +++ b/dll/ime/msctfime/tls.cpp @@ -11,6 +11,38 @@ WINE_DEFAULT_DEBUG_CHANNEL(msctfime); DWORD TLS::s_dwTlsIndex = (DWORD)-1; +/// @implemented +BOOL TLS::Initialize() +{ + s_dwTlsIndex = ::TlsAlloc(); + return s_dwTlsIndex != (DWORD)-1; +} + +/// @implemented +VOID TLS::Uninitialize() +{ + if (s_dwTlsIndex != (DWORD)-1) + { + ::TlsFree(s_dwTlsIndex); + s_dwTlsIndex = (DWORD)-1; + } +} + +/// @implemented +TLS* TLS::GetTLS() +{ + if (s_dwTlsIndex == (DWORD)-1) + return NULL; + + return InternalAllocateTLS(); +} + +/// @implemented +TLS* TLS::PeekTLS() +{ + return (TLS*)::TlsGetValue(TLS::s_dwTlsIndex); +} + /// @implemented TLS* TLS::InternalAllocateTLS() { diff --git a/dll/ime/msctfime/tls.h b/dll/ime/msctfime/tls.h index 2d2c882a67e..87788650d46 100644 --- a/dll/ime/msctfime/tls.h +++ b/dll/ime/msctfime/tls.h @@ -7,8 +7,6 @@ #pragma once -class TLS; - class CicBridge; class CicProfile; @@ -29,45 +27,11 @@ public: DWORD m_NonEAComposition; DWORD m_cWnds; - /** - * @implemented - */ - static BOOL Initialize() - { - s_dwTlsIndex = ::TlsAlloc(); - return s_dwTlsIndex != (DWORD)-1; - } - - /** - * @implemented - */ - static VOID Uninitialize() - { - if (s_dwTlsIndex != (DWORD)-1) - { - ::TlsFree(s_dwTlsIndex); - s_dwTlsIndex = (DWORD)-1; - } - } - - /** - * @implemented - */ - static TLS* GetTLS() - { - if (s_dwTlsIndex == (DWORD)-1) - return NULL; - - return InternalAllocateTLS(); - } + static BOOL Initialize(); + static VOID Uninitialize(); - /** - * @implemented - */ - static TLS* PeekTLS() - { - return (TLS*)::TlsGetValue(TLS::s_dwTlsIndex); - } + static TLS* GetTLS(); + static TLS* PeekTLS(); static TLS* InternalAllocateTLS(); static BOOL InternalDestroyTLS(); diff --git a/dll/ime/msctfime/ui.cpp b/dll/ime/msctfime/ui.cpp index 7b6b5b2a2fc..650c88171fc 100644 --- a/dll/ime/msctfime/ui.cpp +++ b/dll/ime/msctfime/ui.cpp @@ -529,7 +529,7 @@ HRESULT UIComposition::CreateCompButtonWnd(HWND hwndParent, HIMC hIMC) if (!pTLS || !pTLS->NonEACompositionEnabled()) return S_OK; - if (IsEALang()) + if (IsEALang(0)) { if (m_pCompButtonFrameWindow) { diff --git a/dll/ime/msctfime/ui.h b/dll/ime/msctfime/ui.h index 72dd14c7761..3d9c822755a 100644 --- a/dll/ime/msctfime/ui.h +++ b/dll/ime/msctfime/ui.h @@ -44,8 +44,6 @@ public: /***********************************************************************/ -class CCompFrameWindow; - class CCompFinalizeButton : public CUIFToolbarButton { public: