https://git.reactos.org/?p=reactos.git;a=commitdiff;h=0d8e6e781c43be1770eba8a762a6b0a3cfcbc9be
commit 0d8e6e781c43be1770eba8a762a6b0a3cfcbc9be Author: Katayama Hirofumi MZ <katayama.hirofumi...@gmail.com> AuthorDate: Wed Dec 20 16:12:57 2023 +0900 Commit: GitHub <nore...@github.com> CommitDate: Wed Dec 20 16:12:57 2023 +0900 [MSCTFIME] Implemenet CicBridge::InitIMMX/UnInitIMMX (#6201) - Define LIBTHREAD structure. - Add InitDisplayAttrbuteLib and UninitDisplayAttrbuteLib helper functions. - Define CThreadMgrEventSink class. - Strengthen CicBridge class. CORE-19360 --- dll/ime/msctfime/msctfime.cpp | 416 +++++++++++++++++++++++++++++++++++++----- 1 file changed, 372 insertions(+), 44 deletions(-) diff --git a/dll/ime/msctfime/msctfime.cpp b/dll/ime/msctfime/msctfime.cpp index b2a0b979bbb..db9c0fe352b 100644 --- a/dll/ime/msctfime/msctfime.cpp +++ b/dll/ime/msctfime/msctfime.cpp @@ -26,6 +26,9 @@ UINT WM_MSIME_SHOWIMEPAD = 0; UINT WM_MSIME_MOUSE = 0; UINT WM_MSIME_KEYMAP = 0; +/** + * @implemented + */ BOOL IsMsImeMessage(UINT uMsg) { return (uMsg == WM_MSIME_SERVICE || @@ -40,6 +43,33 @@ BOOL IsMsImeMessage(UINT uMsg) uMsg == WM_MSIME_KEYMAP); } +/** + * @implemented + */ +BOOL RegisterMSIMEMessage(VOID) +{ + WM_MSIME_SERVICE = RegisterWindowMessageW(L"MSIMEService"); + WM_MSIME_UIREADY = RegisterWindowMessageW(L"MSIMEUIReady"); + WM_MSIME_RECONVERTREQUEST = RegisterWindowMessageW(L"MSIMEReconvertRequest"); + WM_MSIME_RECONVERT = RegisterWindowMessageW(L"MSIMEReconvert"); + WM_MSIME_DOCUMENTFEED = RegisterWindowMessageW(L"MSIMEDocumentFeed"); + WM_MSIME_QUERYPOSITION = RegisterWindowMessageW(L"MSIMEQueryPosition"); + WM_MSIME_MODEBIAS = RegisterWindowMessageW(L"MSIMEModeBias"); + WM_MSIME_SHOWIMEPAD = RegisterWindowMessageW(L"MSIMEShowImePad"); + WM_MSIME_MOUSE = RegisterWindowMessageW(L"MSIMEMouseOperation"); + WM_MSIME_KEYMAP = RegisterWindowMessageW(L"MSIMEKeyMap"); + return (WM_MSIME_SERVICE && + WM_MSIME_UIREADY && + WM_MSIME_RECONVERTREQUEST && + WM_MSIME_RECONVERT && + WM_MSIME_DOCUMENTFEED && + WM_MSIME_QUERYPOSITION && + WM_MSIME_MODEBIAS && + WM_MSIME_SHOWIMEPAD && + WM_MSIME_MOUSE && + WM_MSIME_KEYMAP); +} + typedef BOOLEAN (WINAPI *FN_DllShutDownInProgress)(VOID); EXTERN_C BOOLEAN WINAPI @@ -82,6 +112,58 @@ IsInteractiveUserLogon(VOID) return bOK && IsMember; } +typedef struct LIBTHREAD +{ + IUnknown *m_pUnknown1; + ITfDisplayAttributeMgr *m_pDisplayAttrMgr; +} LIBTHREAD, *PLIBTHREAD; + +HRESULT InitDisplayAttrbuteLib(PLIBTHREAD pLibThread) +{ + if (!pLibThread) + return E_FAIL; + + if (pLibThread->m_pDisplayAttrMgr) + { + pLibThread->m_pDisplayAttrMgr->Release(); + pLibThread->m_pDisplayAttrMgr = NULL; + } + + //FIXME + return E_NOTIMPL; +} + +HRESULT UninitDisplayAttrbuteLib(PLIBTHREAD pLibThread) +{ + if (!pLibThread) + return E_FAIL; + + if (pLibThread->m_pDisplayAttrMgr) + { + pLibThread->m_pDisplayAttrMgr->Release(); + pLibThread->m_pDisplayAttrMgr = NULL; + } + + return S_OK; +} + +void TFUninitLib_Thread(PLIBTHREAD pLibThread) +{ + if (!pLibThread) + return; + + if (pLibThread->m_pUnknown1) + { + pLibThread->m_pUnknown1->Release(); + pLibThread->m_pUnknown1 = NULL; + } + if (pLibThread->m_pDisplayAttrMgr) + { + pLibThread->m_pDisplayAttrMgr->Release(); + pLibThread->m_pDisplayAttrMgr = NULL; + } +} + /* FIXME */ class CicInputContext : public ITfContextOwnerCompositionSink { @@ -305,21 +387,222 @@ struct ITfSysHookSink : IUnknown class TLS; +typedef INT (CALLBACK *FN_INITDOCMGR)(UINT, ITfDocumentMgr *, ITfDocumentMgr *, LPVOID); +typedef INT (CALLBACK *FN_PUSHPOP)(UINT, ITfContext *, LPVOID); + +class CThreadMgrEventSink : public ITfThreadMgrEventSink +{ +protected: + ITfThreadMgr *m_pThreadMgr; + DWORD m_dwCookie; + FN_INITDOCMGR m_fnInit; + FN_PUSHPOP m_fnPushPop; + DWORD m_dw; + LPVOID m_pCallbackPV; + LONG m_cRefs; + +public: + CThreadMgrEventSink( + FN_INITDOCMGR fnInit, + FN_PUSHPOP fnPushPop = NULL, + LPVOID pvCallbackPV = NULL); + virtual ~CThreadMgrEventSink() { } + + void SetCallbackPV(LPVOID pv); + HRESULT _Advise(ITfThreadMgr *pThreadMgr); + HRESULT _Unadvise(); + + // IUnknown interface + STDMETHODIMP QueryInterface(REFIID riid, LPVOID* ppvObj) override; + STDMETHODIMP_(ULONG) AddRef() override; + STDMETHODIMP_(ULONG) Release() override; + + // ITfThreadMgrEventSink interface + STDMETHODIMP OnInitDocumentMgr(ITfDocumentMgr *pdim) override; + STDMETHODIMP OnUninitDocumentMgr(ITfDocumentMgr *pdim) override; + STDMETHODIMP OnSetFocus(ITfDocumentMgr *pdimFocus, ITfDocumentMgr *pdimPrevFocus) override; + STDMETHODIMP OnPushContext(ITfContext *pic) override; + STDMETHODIMP OnPopContext(ITfContext *pic) override; + + static INT CALLBACK DIMCallback( + UINT nCode, + ITfDocumentMgr *pDocMgr1, + ITfDocumentMgr *pDocMgr2, + LPVOID pUserData); +}; + +/** + * @implemented + */ +CThreadMgrEventSink::CThreadMgrEventSink( + FN_INITDOCMGR fnInit, + FN_PUSHPOP fnPushPop, + LPVOID pvCallbackPV) +{ + m_fnInit = fnInit; + m_fnPushPop = fnPushPop; + m_pCallbackPV = pvCallbackPV; + m_cRefs = 1; +} + +/** + * @implemented + */ +STDMETHODIMP CThreadMgrEventSink::QueryInterface(REFIID riid, LPVOID* ppvObj) +{ + if (IsEqualIID(riid, IID_IUnknown) || IsEqualIID(riid, IID_ITfThreadMgrEventSink)) + { + *ppvObj = this; + AddRef(); + return S_OK; + } + *ppvObj = NULL; + return E_NOINTERFACE; +} + +/** + * @implemented + */ +STDMETHODIMP_(ULONG) CThreadMgrEventSink::AddRef() +{ + return ::InterlockedIncrement(&m_cRefs); +} + +/** + * @implemented + */ +STDMETHODIMP_(ULONG) CThreadMgrEventSink::Release() +{ + if (::InterlockedDecrement(&m_cRefs) == 0) + { + delete this; + return 0; + } + return m_cRefs; +} + +INT CALLBACK +CThreadMgrEventSink::DIMCallback( + UINT nCode, + ITfDocumentMgr *pDocMgr1, + ITfDocumentMgr *pDocMgr2, + LPVOID pUserData) +{ + return E_NOTIMPL; +} + +STDMETHODIMP CThreadMgrEventSink::OnInitDocumentMgr(ITfDocumentMgr *pdim) +{ + if (!m_fnInit) + return S_OK; + return m_fnInit(0, pdim, NULL, m_pCallbackPV); +} + +STDMETHODIMP CThreadMgrEventSink::OnUninitDocumentMgr(ITfDocumentMgr *pdim) +{ + if (!m_fnInit) + return S_OK; + return m_fnInit(1, pdim, NULL, m_pCallbackPV); +} + +STDMETHODIMP +CThreadMgrEventSink::OnSetFocus(ITfDocumentMgr *pdimFocus, ITfDocumentMgr *pdimPrevFocus) +{ + if (!m_fnInit) + return S_OK; + return m_fnInit(2, pdimFocus, pdimPrevFocus, m_pCallbackPV); +} + +STDMETHODIMP CThreadMgrEventSink::OnPushContext(ITfContext *pic) +{ + if (!m_fnPushPop) + return S_OK; + return m_fnPushPop(3, pic, m_pCallbackPV); +} + +STDMETHODIMP CThreadMgrEventSink::OnPopContext(ITfContext *pic) +{ + if (!m_fnPushPop) + return S_OK; + return m_fnPushPop(4, pic, m_pCallbackPV); +} + +void CThreadMgrEventSink::SetCallbackPV(LPVOID pv) +{ + if (!m_pCallbackPV) + m_pCallbackPV = pv; +} + +HRESULT CThreadMgrEventSink::_Advise(ITfThreadMgr *pThreadMgr) +{ + m_pThreadMgr = NULL; + + HRESULT hr = E_FAIL; + ITfSource *pSource = NULL; + if (pThreadMgr->QueryInterface(IID_ITfSource, (void **)&pSource) == S_OK && + pSource->AdviseSink(IID_ITfThreadMgrEventSink, this, &m_dwCookie) == S_OK) + { + m_pThreadMgr = pThreadMgr; + pThreadMgr->AddRef(); + hr = S_OK; + } + + if (pSource) + pSource->Release(); + + return hr; +} + +HRESULT CThreadMgrEventSink::_Unadvise() +{ + HRESULT hr = E_FAIL; + ITfSource *pSource = NULL; + + if (m_pThreadMgr) + { + if (m_pThreadMgr->QueryInterface(IID_ITfSource, (void **)&pSource) == S_OK && + pSource->UnadviseSink(m_dwCookie) == S_OK) + { + hr = S_OK; + } + + if (pSource) + pSource->Release(); + } + + if (m_pThreadMgr) + { + m_pThreadMgr->Release(); + m_pThreadMgr = NULL; + } + + return hr; +} + /* FIXME */ class CicBridge : public ITfSysHookSink { protected: LONG m_cRefs; DWORD m_dwImmxInit; - DWORD m_dwUnknown[10]; + DWORD m_dw[3]; + ITfKeystrokeMgr *m_pKeystrokeMgr; + ITfDocumentMgr *m_pDocMgr; + CThreadMgrEventSink *m_pThreadMgrEventSink; + TfClientId m_cliendId; + LIBTHREAD m_LibThread; + DWORD m_dw21; public: CicBridge(); virtual ~CicBridge(); + // IUnknown interface STDMETHODIMP QueryInterface(REFIID riid, LPVOID* ppvObj) override; STDMETHODIMP_(ULONG) AddRef() override; STDMETHODIMP_(ULONG) Release() override; + + // ITfSysHookSink interface STDMETHODIMP OnPreFocusDIM(HWND hwnd) override; STDMETHODIMP OnSysKeyboardProc(UINT, LONG) override; STDMETHODIMP OnSysShellProc(INT, UINT, LONG) override; @@ -822,13 +1105,13 @@ CicProfile::InitProfileInstance(TLS *pTLS) CicBridge::CicBridge() { m_dwImmxInit &= ~1; - m_dwUnknown[0] &= ~1; - m_dwUnknown[1] &= ~1; - m_dwUnknown[9] &= ~1; - m_dwUnknown[3] = 0; - m_dwUnknown[4] = 0; - m_dwUnknown[5] = 0; - m_dwUnknown[6] = 0; + m_dw[0] &= ~1; + m_dw[1] &= ~1; + m_dw21 &= ~1; + m_pKeystrokeMgr = NULL; + m_pDocMgr = NULL; + m_pThreadMgrEventSink = NULL; + m_cliendId = 0; m_cRefs = 1; } @@ -926,7 +1209,7 @@ HRESULT CicBridge::DestroyInputContext(TLS *pTLS, HIMC hIMC) /** * @unimplemented */ -HRESULT CicBridge::InitIMMX(TLS *pTLS) +HRESULT CicBridge::ActivateIMMX(TLS *pTLS, ITfThreadMgr *pThreadMgr) { return E_NOTIMPL; } @@ -934,25 +1217,93 @@ HRESULT CicBridge::InitIMMX(TLS *pTLS) /** * @unimplemented */ -HRESULT CicBridge::ActivateIMMX(TLS *pTLS, ITfThreadMgr *pThreadMgr) +HRESULT CicBridge::DeactivateIMMX(TLS *pTLS, ITfThreadMgr *pThreadMgr) { return E_NOTIMPL; } /** - * @unimplemented + * @implemented */ -HRESULT CicBridge::DeactivateIMMX(TLS *pTLS, ITfThreadMgr *pThreadMgr) +HRESULT CicBridge::InitIMMX(TLS *pTLS) { - return E_NOTIMPL; + if (m_dwImmxInit & 1) + return S_OK; + + HRESULT hr; + if (!pTLS->m_pThreadMgr) + { + hr = TF_CreateThreadMgr(&pTLS->m_pThreadMgr); + if (FAILED(hr)) + return E_FAIL; + + hr = pTLS->m_pThreadMgr->QueryInterface(IID_ITfThreadMgr, (void **)&pTLS->m_pThreadMgr); + if (FAILED(hr)) + { + pTLS->m_pThreadMgr->Release(); + pTLS->m_pThreadMgr = NULL; + return E_FAIL; + } + } + + if (!m_pThreadMgrEventSink) + { + m_pThreadMgrEventSink = + new CThreadMgrEventSink(CThreadMgrEventSink::DIMCallback, NULL, NULL); + if (!m_pThreadMgrEventSink) + { + UnInitIMMX(pTLS); + return E_FAIL; + } + } + + m_pThreadMgrEventSink->SetCallbackPV(m_pThreadMgrEventSink); + m_pThreadMgrEventSink->_Advise(pTLS->m_pThreadMgr); + + if (!pTLS->m_pProfile) + { + pTLS->m_pProfile = new CicProfile(); + if (!pTLS->m_pProfile) + return E_OUTOFMEMORY; + hr = pTLS->m_pProfile->InitProfileInstance(pTLS); + if (FAILED(hr)) + { + UnInitIMMX(pTLS); + return E_FAIL; + } + } + + hr = pTLS->m_pThreadMgr->QueryInterface(IID_ITfKeystrokeMgr, (void **)&m_pKeystrokeMgr); + if (FAILED(hr)) + { + UnInitIMMX(pTLS); + return E_FAIL; + } + + hr = InitDisplayAttrbuteLib(&m_LibThread); + if (FAILED(hr)) + { + UnInitIMMX(pTLS); + return E_FAIL; + } + + m_dwImmxInit |= 1; + return S_OK; } /** - * @unimplemented + * @implemented */ BOOL CicBridge::UnInitIMMX(TLS *pTLS) { - //FIXME + UninitDisplayAttrbuteLib(&m_LibThread); + TFUninitLib_Thread(&m_LibThread); + + if (m_pKeystrokeMgr) + { + m_pKeystrokeMgr->Release(); + m_pKeystrokeMgr = NULL; + } if (pTLS->m_pProfile) { @@ -960,7 +1311,12 @@ BOOL CicBridge::UnInitIMMX(TLS *pTLS) pTLS->m_pProfile = NULL; } - //FIXME + if (m_pThreadMgrEventSink) + { + m_pThreadMgrEventSink->_Unadvise(); + m_pThreadMgrEventSink->Release(); + m_pThreadMgrEventSink = NULL; + } if (pTLS->m_pThreadMgr) { @@ -969,7 +1325,6 @@ BOOL CicBridge::UnInitIMMX(TLS *pTLS) } m_dwImmxInit &= ~1; - return TRUE; } @@ -1746,33 +2101,6 @@ VOID UnregisterImeClass(VOID) DestroyIcon(wcx.hIconSm); } -/** - * @implemented - */ -BOOL RegisterMSIMEMessage(VOID) -{ - WM_MSIME_SERVICE = RegisterWindowMessageW(L"MSIMEService"); - WM_MSIME_UIREADY = RegisterWindowMessageW(L"MSIMEUIReady"); - WM_MSIME_RECONVERTREQUEST = RegisterWindowMessageW(L"MSIMEReconvertRequest"); - WM_MSIME_RECONVERT = RegisterWindowMessageW(L"MSIMEReconvert"); - WM_MSIME_DOCUMENTFEED = RegisterWindowMessageW(L"MSIMEDocumentFeed"); - WM_MSIME_QUERYPOSITION = RegisterWindowMessageW(L"MSIMEQueryPosition"); - WM_MSIME_MODEBIAS = RegisterWindowMessageW(L"MSIMEModeBias"); - WM_MSIME_SHOWIMEPAD = RegisterWindowMessageW(L"MSIMEShowImePad"); - WM_MSIME_MOUSE = RegisterWindowMessageW(L"MSIMEMouseOperation"); - WM_MSIME_KEYMAP = RegisterWindowMessageW(L"MSIMEKeyMap"); - return (WM_MSIME_SERVICE && - WM_MSIME_UIREADY && - WM_MSIME_RECONVERTREQUEST && - WM_MSIME_RECONVERT && - WM_MSIME_DOCUMENTFEED && - WM_MSIME_QUERYPOSITION && - WM_MSIME_MODEBIAS && - WM_MSIME_SHOWIMEPAD && - WM_MSIME_MOUSE && - WM_MSIME_KEYMAP); -} - /** * @implemented */