https://git.reactos.org/?p=reactos.git;a=commitdiff;h=3401a99e0f2bedb195f6978671063f9b2a3341e3

commit 3401a99e0f2bedb195f6978671063f9b2a3341e3
Author:     Katayama Hirofumi MZ <katayama.hirofumi...@gmail.com>
AuthorDate: Thu Dec 21 12:02:21 2023 +0900
Commit:     Katayama Hirofumi MZ <katayama.hirofumi...@gmail.com>
CommitDate: Thu Dec 21 12:02:21 2023 +0900

    [MSCTFIME] Half-implement CicBridge::ActivateIMMX/DeactivateIMMX
    
    CORE-19360
---
 dll/ime/msctfime/msctfime.cpp | 172 +++++++++++++++++++++++++++++++++++++++++-
 1 file changed, 168 insertions(+), 4 deletions(-)

diff --git a/dll/ime/msctfime/msctfime.cpp b/dll/ime/msctfime/msctfime.cpp
index c63aab280f3..047dbfe3ccd 100644
--- a/dll/ime/msctfime/msctfime.cpp
+++ b/dll/ime/msctfime/msctfime.cpp
@@ -15,6 +15,8 @@ DWORD g_dwOSInfo = 0;
 BOOL gfTFInitLib = FALSE;
 CRITICAL_SECTION g_csLock;
 
+DEFINE_GUID(GUID_COMPARTMENT_CTFIME_DIMFLAGS, 0xA94C5FD2, 0xC471, 0x4031, 
0x95, 0x46, 0x70, 0x9C, 0x17, 0x30, 0x0C, 0xB9);
+
 UINT WM_MSIME_SERVICE = 0;
 UINT WM_MSIME_UIREADY = 0;
 UINT WM_MSIME_RECONVERTREQUEST = 0;
@@ -944,13 +946,52 @@ HRESULT CThreadMgrEventSink::_Unadvise()
     return hr;
 }
 
+/* FIXME */
+class CFunctionProvider : public IUnknown
+{
+public:
+    CFunctionProvider(TfClientId clientId)
+    {
+    }
+
+    // IUnknown interface
+    STDMETHODIMP QueryInterface(REFIID riid, LPVOID* ppvObj) override;
+    STDMETHODIMP_(ULONG) AddRef() override;
+    STDMETHODIMP_(ULONG) Release() override;
+};
+
+/**
+ * @unimplemented
+ */
+STDMETHODIMP CFunctionProvider::QueryInterface(REFIID riid, LPVOID* ppvObj)
+{
+    return E_NOTIMPL;
+}
+
+/**
+ * @unimplemented
+ */
+STDMETHODIMP_(ULONG) CFunctionProvider::AddRef()
+{
+    return 1;
+}
+
+/**
+ * @unimplemented
+ */
+STDMETHODIMP_(ULONG) CFunctionProvider::Release()
+{
+    return 0;
+}
+
 /* FIXME */
 class CicBridge : public ITfSysHookSink
 {
 protected:
     LONG m_cRefs;
     DWORD m_dwImmxInit;
-    DWORD m_dw[3];
+    DWORD m_dw[2];
+    DWORD m_cActivateLocks;
     ITfKeystrokeMgr *m_pKeystrokeMgr;
     ITfDocumentMgr *m_pDocMgr;
     CThreadMgrEventSink *m_pThreadMgrEventSink;
@@ -958,6 +999,9 @@ protected:
     LIBTHREAD m_LibThread;
     DWORD m_dw21;
 
+    static BOOL CALLBACK EnumCreateInputContextCallback(HIMC hIMC, LPARAM 
lParam);
+    static BOOL CALLBACK EnumDestroyInputContextCallback(HIMC hIMC, LPARAM 
lParam);
+
 public:
     CicBridge();
     virtual ~CicBridge();
@@ -976,6 +1020,8 @@ public:
     BOOL UnInitIMMX(TLS *pTLS);
     HRESULT ActivateIMMX(TLS *pTLS, ITfThreadMgr *pThreadMgr);
     HRESULT DeactivateIMMX(TLS *pTLS, ITfThreadMgr *pThreadMgr);
+
+    HRESULT CreateInputContext(TLS *pTLS, HIMC hIMC);
     HRESULT DestroyInputContext(TLS *pTLS, HIMC hIMC);
 
     void PostTransMsg(HWND hWnd, INT cTransMsgs, LPTRANSMSG pTransMsgs);
@@ -1335,7 +1381,9 @@ public:
     CicBridge *m_pBridge;
     CicProfile *m_pProfile;
     ITfThreadMgr *m_pThreadMgr;
-    DWORD m_dwUnknown2[4];
+    DWORD m_dwFlags1;
+    DWORD m_dwFlags2;
+    DWORD m_dwUnknown2[2];
     DWORD m_dwNowOpening;
     DWORD m_NonEAComposition;
     DWORD m_cWnds;
@@ -1532,6 +1580,14 @@ CicBridge::~CicBridge()
         UnInitIMMX(pTLS);
 }
 
+/**
+ * @unimplemented
+ */
+HRESULT CicBridge::CreateInputContext(TLS *pTLS, HIMC hIMC)
+{
+    return E_NOTIMPL;
+}
+
 /**
  * @implemented
  */
@@ -1573,12 +1629,83 @@ HRESULT CicBridge::DestroyInputContext(TLS *pTLS, HIMC 
hIMC)
     return hr;
 }
 
+typedef struct ENUM_CREATE_DESTROY_IC
+{
+    TLS *m_pTLS;
+    CicBridge *m_pBridge;
+} ENUM_CREATE_DESTROY_IC, *PENUM_CREATE_DESTROY_IC;
+
+BOOL CALLBACK CicBridge::EnumCreateInputContextCallback(HIMC hIMC, LPARAM 
lParam)
+{
+    PENUM_CREATE_DESTROY_IC pData = (PENUM_CREATE_DESTROY_IC)lParam;
+    pData->m_pBridge->CreateInputContext(pData->m_pTLS, hIMC);
+    return TRUE;
+}
+
+BOOL CALLBACK CicBridge::EnumDestroyInputContextCallback(HIMC hIMC, LPARAM 
lParam)
+{
+    PENUM_CREATE_DESTROY_IC pData = (PENUM_CREATE_DESTROY_IC)lParam;
+    pData->m_pBridge->DestroyInputContext(pData->m_pTLS, hIMC);
+    return TRUE;
+}
+
 /**
  * @unimplemented
  */
 HRESULT CicBridge::ActivateIMMX(TLS *pTLS, ITfThreadMgr *pThreadMgr)
 {
-    return E_NOTIMPL;
+    //FIXME
+
+    if (m_cActivateLocks++ != 0)
+        return S_OK;
+
+    ITfSourceSingle *pSource = NULL;
+    HRESULT hr = pThreadMgr->QueryInterface(IID_ITfSourceSingle, 
(void**)&pSource);
+    if (FAILED(hr))
+    {
+        DeactivateIMMX(pTLS, pThreadMgr);
+        return hr;
+    }
+
+    CFunctionProvider *pProvider = new CFunctionProvider(m_cliendId);
+    if (!pProvider)
+    {
+        hr = E_FAIL;
+        goto Finish;
+    }
+
+    pSource->AdviseSingleSink(m_cliendId, IID_ITfFunctionProvider, pProvider);
+    pProvider->Release();
+
+    if (!m_pDocMgr)
+    {
+        hr = pThreadMgr->CreateDocumentMgr(&m_pDocMgr);
+        if (FAILED(hr))
+        {
+            hr = E_FAIL;
+            goto Finish;
+        }
+
+        SetCompartmentDWORD(m_cliendId, m_pDocMgr, 
GUID_COMPARTMENT_CTFIME_DIMFLAGS, TRUE, FALSE);
+    }
+
+    //FIXME
+
+    hr = S_OK;
+    if (pTLS->m_dwUnknown2[1] & 1)
+    {
+        ENUM_CREATE_DESTROY_IC Data = { pTLS, this };
+        ImmEnumInputContext(0, CicBridge::EnumCreateInputContextCallback, 
(LPARAM)&Data);
+    }
+
+Finish:
+    if (FAILED(hr))
+        DeactivateIMMX(pTLS, pThreadMgr);
+
+    if (pSource)
+        pSource->Release();
+
+    return hr;
 }
 
 /**
@@ -1586,7 +1713,44 @@ HRESULT CicBridge::ActivateIMMX(TLS *pTLS, ITfThreadMgr 
*pThreadMgr)
  */
 HRESULT CicBridge::DeactivateIMMX(TLS *pTLS, ITfThreadMgr *pThreadMgr)
 {
-    return E_NOTIMPL;
+    if (m_dw[1] & 1)
+        return TRUE;
+
+    m_dw[1] |= 1;
+
+    if (m_cliendId)
+    {
+        ENUM_CREATE_DESTROY_IC Data = { pTLS, this };
+        ImmEnumInputContext(0, CicBridge::EnumDestroyInputContextCallback, 
(LPARAM)&Data);
+        pTLS->m_dwUnknown2[1] |= 1u;
+
+        ITfSourceSingle *pSource = NULL;
+        if (pThreadMgr->QueryInterface(IID_ITfSourceSingle, (void **)&pSource) 
== S_OK)
+            pSource->UnadviseSingleSink(m_cliendId, IID_ITfFunctionProvider);
+
+        m_cliendId = 0;
+
+        while (m_cActivateLocks > 0)
+        {
+            --m_cActivateLocks;
+            pThreadMgr->Deactivate();
+        }
+
+        if (pSource)
+            pSource->Release();
+    }
+
+    if (m_pDocMgr)
+    {
+        m_pDocMgr->Release();
+        m_pDocMgr = NULL;
+    }
+
+    //FIXME
+
+    m_dw[1] &= ~1;
+
+    return S_OK;
 }
 
 /**

Reply via email to