https://git.reactos.org/?p=reactos.git;a=commitdiff;h=814cb188c6470b3188e82…
commit 814cb188c6470b3188e8294cc1216ea80f847762
Author: Katayama Hirofumi MZ <katayama.hirofumi.mz(a)gmail.com>
AuthorDate: Thu Dec 21 16:23:23 2023 +0900
Commit: GitHub <noreply(a)github.com>
CommitDate: Thu Dec 21 16:23:23 2023 +0900
[MSCTFIME][SDK] Implement CicInputContext::OnCleanupContext (#6213)
- Strengthen CicInputContext class.
- Modify <cicero/imclock.h>.
- add __cxa_pure_virtual function.
CORE-19360
---
dll/ime/msctfime/msctfime.cpp | 174 ++++++++++++++++++++++++++++++++++-
sdk/include/reactos/cicero/imclock.h | 17 ++++
2 files changed, 186 insertions(+), 5 deletions(-)
diff --git a/dll/ime/msctfime/msctfime.cpp b/dll/ime/msctfime/msctfime.cpp
index 047dbfe3ccd..86a7ddc325a 100644
--- a/dll/ime/msctfime/msctfime.cpp
+++ b/dll/ime/msctfime/msctfime.cpp
@@ -17,6 +17,11 @@ CRITICAL_SECTION g_csLock;
DEFINE_GUID(GUID_COMPARTMENT_CTFIME_DIMFLAGS, 0xA94C5FD2, 0xC471, 0x4031, 0x95, 0x46,
0x70, 0x9C, 0x17, 0x30, 0x0C, 0xB9);
+EXTERN_C void __cxa_pure_virtual(void)
+{
+ ERR("__cxa_pure_virtual\n");
+}
+
UINT WM_MSIME_SERVICE = 0;
UINT WM_MSIME_UIREADY = 0;
UINT WM_MSIME_RECONVERTREQUEST = 0;
@@ -508,8 +513,12 @@ HRESULT CCompartmentEventSink::_Unadvise()
class CInputContextOwnerCallBack;
/* FIXME */
-class CicInputContext : public ITfContextOwnerCompositionSink
+class CicInputContext
+ : public ITfCleanupContextSink
+ , public ITfContextOwnerCompositionSink
+ , public ITfCompositionSink
{
+public:
DWORD m_dw[2];
LONG m_cRefs;
HIMC m_hIMC;
@@ -532,10 +541,7 @@ class CicInputContext : public ITfContextOwnerCompositionSink
DWORD m_dw3[19];
public:
- CicInputContext()
- {
- m_cRefs = 1;
- }
+ CicInputContext(TfClientId cliendId, LIBTHREAD *pLibThread, HIMC hIMC);
virtual ~CicInputContext()
{
}
@@ -545,20 +551,38 @@ public:
STDMETHODIMP_(ULONG) AddRef() override;
STDMETHODIMP_(ULONG) Release() override;
+ // ITfCleanupContextSink interface
+ STDMETHODIMP OnCleanupContext(TfEditCookie ecWrite, ITfContext *pic) override;
+
// ITfContextOwnerCompositionSink interface
STDMETHODIMP OnStartComposition(ITfCompositionView *pComposition, BOOL *pfOk)
override;
STDMETHODIMP OnUpdateComposition(ITfCompositionView *pComposition, ITfRange
*pRangeNew) override;
STDMETHODIMP OnEndComposition(ITfCompositionView *pComposition) override;
+ // ITfCompositionSink interface
+ STDMETHODIMP OnCompositionTerminated(TfEditCookie ecWrite, ITfComposition
*pComposition) override;
+
HRESULT
GetGuidAtom(
_Inout_ IMCLock& imcLock,
_In_ BYTE iAtom,
_Out_opt_ LPDWORD pdwGuidAtom);
+ HRESULT CreateInputContext(ITfThreadMgr *pThreadMgr, IMCLock& imcLock);
HRESULT DestroyInputContext();
};
+/**
+ * @unimplemented
+ */
+CicInputContext::CicInputContext(TfClientId cliendId, LIBTHREAD *pLibThread, HIMC hIMC)
+{
+ m_hIMC = hIMC;
+ m_guid = GUID_NULL;
+ m_dwQueryPos = 0;
+ m_cRefs = 1;
+}
+
/**
* @unimplemented
*/
@@ -661,6 +685,16 @@ CicInputContext::GetGuidAtom(
return hr;
}
+/**
+ * @unimplemented
+ */
+HRESULT
+CicInputContext::CreateInputContext(ITfThreadMgr *pThreadMgr, IMCLock& imcLock)
+{
+ //FIXME
+ return E_NOTIMPL;
+}
+
/**
* @unimplemented
*/
@@ -671,6 +705,15 @@ CicInputContext::DestroyInputContext()
return E_NOTIMPL;
}
+/**
+ * @implemented
+ */
+STDMETHODIMP
+CicInputContext::OnCompositionTerminated(TfEditCookie ecWrite, ITfComposition
*pComposition)
+{
+ return S_OK;
+}
+
/**
* @implemented
*/
@@ -1025,6 +1068,7 @@ public:
HRESULT DestroyInputContext(TLS *pTLS, HIMC hIMC);
void PostTransMsg(HWND hWnd, INT cTransMsgs, LPTRANSMSG pTransMsgs);
+ void GetDocumentManager(IMCCLock<CTFIMECONTEXT>& imeContext);
HRESULT ConfigureGeneral(TLS* pTLS, ITfThreadMgr *pThreadMgr, HKL hKL, HWND hWnd);
HRESULT ConfigureRegisterWord(TLS* pTLS, ITfThreadMgr *pThreadMgr, HKL hKL, HWND
hWnd, LPVOID lpData);
@@ -1513,6 +1557,56 @@ CicProfile::InitProfileInstance(TLS *pTLS)
return hr;
}
+/**
+ * @implemented
+ */
+STDMETHODIMP CicInputContext::OnCleanupContext(TfEditCookie ecWrite, ITfContext *pic)
+{
+ TLS *pTLS = TLS::PeekTLS();
+ if (!pTLS || !pTLS->m_pProfile)
+ return E_OUTOFMEMORY;
+
+ LANGID LangID;
+ pTLS->m_pProfile->GetLangId(&LangID);
+
+ IMEINFO IMEInfo;
+ WCHAR szPath[MAX_PATH];
+ if (Inquire(&IMEInfo, szPath, 0, (HKL)UlongToHandle(LangID)) != S_OK)
+ return E_FAIL;
+
+ ITfProperty *pProp = NULL;
+ if (!(IMEInfo.fdwProperty & IME_PROP_COMPLETE_ON_UNSELECT))
+ return S_OK;
+
+ HRESULT hr = pic->GetProperty(GUID_PROP_COMPOSING, &pProp);
+ if (FAILED(hr))
+ return S_OK;
+
+ IEnumTfRanges *pRanges = NULL;
+ hr = pProp->EnumRanges(ecWrite, &pRanges, NULL);
+ if (SUCCEEDED(hr))
+ {
+ ITfRange *pRange = NULL;
+ while (pRanges->Next(1, &pRange, 0) == S_OK)
+ {
+ VARIANT vari;
+ V_VT(&vari) = VT_EMPTY;
+ pProp->GetValue(ecWrite, pRange, &vari);
+ if (V_VT(&vari) == VT_I4)
+ {
+ if (V_I4(&vari))
+ pProp->Clear(ecWrite, pRange);
+ }
+ pRange->Release();
+ pRange = NULL;
+ }
+ pRanges->Release();
+ }
+ pProp->Release();
+
+ return S_OK;
+}
+
/***********************************************************************
* CicBridge
*/
@@ -1580,11 +1674,81 @@ CicBridge::~CicBridge()
UnInitIMMX(pTLS);
}
+void CicBridge::GetDocumentManager(IMCCLock<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;
+ }
+}
+
/**
* @unimplemented
*/
HRESULT CicBridge::CreateInputContext(TLS *pTLS, HIMC hIMC)
{
+ IMCLock imcLock(hIMC);
+ HRESULT hr = imcLock.m_hr;
+ if (!imcLock)
+ hr = E_FAIL;
+ if (FAILED(hr))
+ return hr;
+
+ if (!imcLock.get().hCtfImeContext)
+ {
+ HIMCC hCtfImeContext = ImmCreateIMCC(sizeof(CTFIMECONTEXT));
+ if (!hCtfImeContext)
+ return E_OUTOFMEMORY;
+ imcLock.get().hCtfImeContext = hCtfImeContext;
+ }
+
+ IMCCLock<CTFIMECONTEXT> imeContext(imcLock.get().hCtfImeContext);
+ CicInputContext *pCicIC = imeContext.get().m_pCicIC;
+ if (!pCicIC)
+ {
+ pCicIC = new 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.get().m_pCicIC = pCicIC;
+ }
+
+ hr = pCicIC->CreateInputContext(pTLS->m_pThreadMgr, imcLock);
+ if (FAILED(hr))
+ {
+ pCicIC->Release();
+ imeContext.get().m_pCicIC = NULL;
+ }
+ else
+ {
+ if (imcLock.get().hWnd && imcLock.get().hWnd == ::GetFocus())
+ {
+ GetDocumentManager(imeContext);
+ //FIXME
+ }
+ }
+
return E_NOTIMPL;
}
diff --git a/sdk/include/reactos/cicero/imclock.h b/sdk/include/reactos/cicero/imclock.h
index 3392c9a1107..81a642ec067 100644
--- a/sdk/include/reactos/cicero/imclock.h
+++ b/sdk/include/reactos/cicero/imclock.h
@@ -40,10 +40,19 @@ public:
_LockIMCC(this->m_hIMCC, &this->m_pIMCC);
}
~IMCCLock()
+ {
+ unlock();
+ }
+
+ void unlock()
{
if (this->m_pIMCC)
+ {
_UnlockIMCC(this->m_hIMCC);
+ this->m_pIMCC = NULL;
+ }
}
+
operator T_DATA*() const
{
return this->m_pIMCC;
@@ -101,9 +110,17 @@ public:
m_hr = _LockIMC(hIMC, &m_pIC);
}
~IMCLock()
+ {
+ unlock();
+ }
+
+ void unlock()
{
if (m_pIC)
+ {
_UnlockIMC(m_hIMC);
+ m_pIC = NULL;
+ }
}
void InitContext()