https://git.reactos.org/?p=reactos.git;a=commitdiff;h=814cb188c6470b3188e8294cc1216ea80f847762
commit 814cb188c6470b3188e8294cc1216ea80f847762 Author: Katayama Hirofumi MZ <katayama.hirofumi...@gmail.com> AuthorDate: Thu Dec 21 16:23:23 2023 +0900 Commit: GitHub <nore...@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()