https://git.reactos.org/?p=reactos.git;a=commitdiff;h=980ebf0694960551201fd…
commit 980ebf0694960551201fdd132e0ec2475a9433fd
Author: Katayama Hirofumi MZ <katayama.hirofumi.mz(a)gmail.com>
AuthorDate: Fri Feb 23 17:43:13 2024 +0900
Commit: GitHub <noreply(a)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.mz(a)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.mz(a)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.mz(a)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.mz(a)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.ht…
*/
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.ht…
*/
EXTERN_C BOOL WINAPI
ImeUnregisterWord(
@@ -320,6 +177,7 @@ ImeUnregisterWord(
*
* @implemented
* @see ImeRegisterWord
+ * @see
https://katahiromz.web.fc2.com/colony3rd/imehackerz/en/ImeGetRegisterWordSt…
*/
EXTERN_C UINT WINAPI
ImeGetRegisterWordStyle(
@@ -337,6 +195,7 @@ ImeGetRegisterWordStyle(
*
* @implemented
* @see ImeRegisterWord
+ * @see
https://katahiromz.web.fc2.com/colony3rd/imehackerz/en/ImeEnumRegisterWord.…
*/
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.…
*/
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: