[PATCH 3/3] msctf: Add ITextStoreACP2 support for ITfDocumentMgr::CreateContext().

Jactry Zeng jzeng at codeweavers.com
Wed Sep 25 10:14:43 CDT 2019


Signed-off-by: Jactry Zeng <jzeng at codeweavers.com>
---
 dlls/msctf/context.c              | 67 +++++++++++++++++--------------
 dlls/msctf/msctf_internal.h       |  3 +-
 dlls/msctf/range.c                |  9 +++--
 dlls/msctf/tests/inputprocessor.c | 31 +++++++++++++-
 4 files changed, 75 insertions(+), 35 deletions(-)

diff --git a/dlls/msctf/context.c b/dlls/msctf/context.c
index 63f2bf5455..6c82088f58 100644
--- a/dlls/msctf/context.c
+++ b/dlls/msctf/context.c
@@ -60,7 +60,8 @@ typedef struct tagContext {
     TS_STATUS documentStatus;
     ITfDocumentMgr *manager;
 
-    ITextStoreACP   *pITextStoreACP;
+    ITextStoreACP2 *textstore;
+    UINT textstore_ver;
     ITfContextOwnerCompositionSink *pITfContextOwnerCompositionSink;
 
     ITfEditSession* currentEditSession;
@@ -119,8 +120,8 @@ static void Context_Destructor(Context *This)
     EditCookie *cookie;
     TRACE("destroying %p\n", This);
 
-    if (This->pITextStoreACP)
-        ITextStoreACP_Release(This->pITextStoreACP);
+    if (This->textstore)
+        ITextStoreACP2_Release(This->textstore);
 
     if (This->pITfContextOwnerCompositionSink)
         ITfContextOwnerCompositionSink_Release(This->pITfContextOwnerCompositionSink);
@@ -218,7 +219,7 @@ static HRESULT WINAPI Context_RequestEditSession (ITfContext *iface,
         return E_INVALIDARG;
     }
 
-    if (!This->pITextStoreACP)
+    if (!This->textstore)
     {
         FIXME("No ITextStoreACP available\n");
         *phrSession = E_FAIL;
@@ -234,7 +235,7 @@ static HRESULT WINAPI Context_RequestEditSession (ITfContext *iface,
         dwLockFlags |= TS_LF_READ;
 
     if (!This->documentStatus.dwDynamicFlags)
-        ITextStoreACP_GetStatus(This->pITextStoreACP, &This->documentStatus);
+        ITextStoreACP2_GetStatus(This->textstore, &This->documentStatus);
 
     if (((dwFlags & TF_ES_READWRITE) == TF_ES_READWRITE) && (This->documentStatus.dwDynamicFlags & TS_SD_READONLY))
     {
@@ -248,7 +249,7 @@ static HRESULT WINAPI Context_RequestEditSession (ITfContext *iface,
         return E_INVALIDARG;
     }
 
-    hr = ITextStoreACP_RequestLock(This->pITextStoreACP, dwLockFlags, phrSession);
+    hr = ITextStoreACP2_RequestLock(This->textstore, dwLockFlags, phrSession);
 
     return hr;
 }
@@ -283,7 +284,7 @@ static HRESULT WINAPI Context_GetSelection (ITfContext *iface,
     if (get_Cookie_magic(ec)!=COOKIE_MAGIC_EDITCOOKIE)
         return TF_E_NOLOCK;
 
-    if (!This->pITextStoreACP)
+    if (!This->textstore)
     {
         FIXME("Context does not have a ITextStoreACP\n");
         return E_NOTIMPL;
@@ -301,8 +302,7 @@ static HRESULT WINAPI Context_GetSelection (ITfContext *iface,
         DWORD fetched;
         TS_SELECTION_ACP acps;
 
-        hr = ITextStoreACP_GetSelection(This->pITextStoreACP, ulIndex + i,
-                1, &acps, &fetched);
+        hr = ITextStoreACP2_GetSelection(This->textstore, ulIndex + i, 1, &acps, &fetched);
 
         if (hr == TS_E_NOLOCK)
             return TF_E_NOLOCK;
@@ -310,7 +310,8 @@ static HRESULT WINAPI Context_GetSelection (ITfContext *iface,
         {
             pSelection[totalFetched].style.ase = acps.style.ase;
             pSelection[totalFetched].style.fInterimChar = acps.style.fInterimChar;
-            Range_Constructor(iface, This->pITextStoreACP, cookie->lockType, acps.acpStart, acps.acpEnd, &pSelection[totalFetched].range);
+            Range_Constructor(iface, This->textstore, This->textstore_ver, cookie->lockType, acps.acpStart,
+                              acps.acpEnd, &pSelection[totalFetched].range);
             totalFetched ++;
         }
         else
@@ -332,7 +333,7 @@ static HRESULT WINAPI Context_SetSelection (ITfContext *iface,
 
     TRACE("(%p) %i %i %p\n",This,ec,ulCount,pSelection);
 
-    if (!This->pITextStoreACP)
+    if (!This->textstore)
     {
         FIXME("Context does not have a ITextStoreACP\n");
         return E_NOTIMPL;
@@ -353,7 +354,7 @@ static HRESULT WINAPI Context_SetSelection (ITfContext *iface,
             return E_FAIL;
         }
 
-    hr = ITextStoreACP_SetSelection(This->pITextStoreACP, ulCount, acp);
+    hr = ITextStoreACP2_SetSelection(This->textstore, ulCount, acp);
 
     HeapFree(GetProcessHeap(), 0, acp);
 
@@ -379,7 +380,7 @@ static HRESULT WINAPI Context_GetStart (ITfContext *iface,
         return TF_E_NOLOCK;
 
     cookie = get_Cookie_data(ec);
-    return Range_Constructor(iface, This->pITextStoreACP, cookie->lockType, 0, 0, ppStart);
+    return Range_Constructor(iface, This->textstore, This->textstore_ver, cookie->lockType, 0, 0, ppStart);
 }
 
 static HRESULT WINAPI Context_GetEnd (ITfContext *iface,
@@ -401,16 +402,16 @@ static HRESULT WINAPI Context_GetEnd (ITfContext *iface,
     if (get_Cookie_magic(ec)!=COOKIE_MAGIC_EDITCOOKIE)
         return TF_E_NOLOCK;
 
-    if (!This->pITextStoreACP)
+    if (!This->textstore)
     {
         FIXME("Context does not have a ITextStoreACP\n");
         return E_NOTIMPL;
     }
 
     cookie = get_Cookie_data(ec);
-    ITextStoreACP_GetEndACP(This->pITextStoreACP,&end);
+    ITextStoreACP2_GetEndACP(This->textstore,&end);
 
-    return Range_Constructor(iface, This->pITextStoreACP, cookie->lockType, end, end, ppEnd);
+    return Range_Constructor(iface, This->textstore, This->textstore_ver, cookie->lockType, end, end, ppEnd);
 }
 
 static HRESULT WINAPI Context_GetActiveView (ITfContext *iface,
@@ -441,13 +442,13 @@ static HRESULT WINAPI Context_GetStatus (ITfContext *iface,
     if (!pdcs)
         return E_INVALIDARG;
 
-    if (!This->pITextStoreACP)
+    if (!This->textstore)
     {
         FIXME("Context does not have a ITextStoreACP\n");
         return E_NOTIMPL;
     }
 
-    ITextStoreACP_GetStatus(This->pITextStoreACP, &This->documentStatus);
+    ITextStoreACP2_GetStatus(This->textstore, &This->documentStatus);
 
     *pdcs = This->documentStatus;
 
@@ -712,15 +713,16 @@ static HRESULT WINAPI InsertAtSelection_InsertTextAtSelection(
     if ((cookie->lockType & TS_LF_READWRITE) != TS_LF_READWRITE )
         return TS_E_READONLY;
 
-    if (!This->pITextStoreACP)
+    if (!This->textstore)
     {
         FIXME("Context does not have a ITextStoreACP\n");
         return E_NOTIMPL;
     }
 
-    hr = ITextStoreACP_InsertTextAtSelection(This->pITextStoreACP, dwFlags, pchText, cch, &acpStart, &acpEnd, &change);
+    hr = ITextStoreACP2_InsertTextAtSelection(This->textstore, dwFlags, pchText, cch, &acpStart, &acpEnd, &change);
     if (SUCCEEDED(hr))
-        Range_Constructor(&This->ITfContext_iface, This->pITextStoreACP, cookie->lockType, change.acpStart, change.acpNewEnd, ppRange);
+        Range_Constructor(&This->ITfContext_iface, This->textstore, This->textstore_ver, cookie->lockType,
+                          change.acpStart, change.acpNewEnd, ppRange);
 
     return hr;
 }
@@ -863,13 +865,13 @@ static HRESULT WINAPI TextStoreACPSink_OnStatusChange(ITextStoreACPSink *iface,
 
     TRACE("(%p) %x\n",This, dwFlags);
 
-    if (!This->pITextStoreACP)
+    if (!This->textstore)
     {
         FIXME("Context does not have a ITextStoreACP\n");
         return E_NOTIMPL;
     }
 
-    hr = ITextStoreACP_RequestLock(This->pITextStoreACP, TS_LF_READ, &hrSession);
+    hr = ITextStoreACP2_RequestLock(This->textstore, TS_LF_READ, &hrSession);
 
     if(SUCCEEDED(hr) && SUCCEEDED(hrSession))
         This->documentStatus.dwDynamicFlags = dwFlags;
@@ -1081,13 +1083,18 @@ HRESULT Context_Constructor(TfClientId tidOwner, IUnknown *punk, ITfDocumentMgr
 
     if (punk)
     {
-        IUnknown_QueryInterface(punk, &IID_ITextStoreACP,
-                          (LPVOID*)&This->pITextStoreACP);
+        This->textstore_ver = 1;
+        IUnknown_QueryInterface(punk, &IID_ITextStoreACP, (void **)&This->textstore);
+        if (!This->textstore)
+        {
+            IUnknown_QueryInterface(punk, &IID_ITextStoreACP2, (void **)&This->textstore);
+            This->textstore_ver = 2;
+        }
 
         IUnknown_QueryInterface(punk, &IID_ITfContextOwnerCompositionSink,
                                 (LPVOID*)&This->pITfContextOwnerCompositionSink);
 
-        if (!This->pITextStoreACP && !This->pITfContextOwnerCompositionSink)
+        if (!This->textstore && !This->pITfContextOwnerCompositionSink)
             FIXME("Unhandled pUnk\n");
     }
 
@@ -1110,8 +1117,8 @@ HRESULT Context_Initialize(ITfContext *iface, ITfDocumentMgr *manager)
 {
     Context *This = impl_from_ITfContext(iface);
 
-    if (This->pITextStoreACP)
-        ITextStoreACP_AdviseSink(This->pITextStoreACP, &IID_ITextStoreACPSink,
+    if (This->textstore)
+        ITextStoreACP2_AdviseSink(This->textstore, &IID_ITextStoreACPSink,
             (IUnknown*)&This->ITextStoreACPSink_iface, TS_AS_ALL_SINKS);
     This->connected = TRUE;
     This->manager = manager;
@@ -1122,8 +1129,8 @@ HRESULT Context_Uninitialize(ITfContext *iface)
 {
     Context *This = impl_from_ITfContext(iface);
 
-    if (This->pITextStoreACP)
-        ITextStoreACP_UnadviseSink(This->pITextStoreACP, (IUnknown*)&This->ITextStoreACPSink_iface);
+    if (This->textstore)
+        ITextStoreACP2_UnadviseSink(This->textstore, (IUnknown*)&This->ITextStoreACPSink_iface);
     This->connected = FALSE;
     This->manager = NULL;
     return S_OK;
diff --git a/dlls/msctf/msctf_internal.h b/dlls/msctf/msctf_internal.h
index 584bb1044e..db6e966b50 100644
--- a/dlls/msctf/msctf_internal.h
+++ b/dlls/msctf/msctf_internal.h
@@ -44,7 +44,8 @@ extern HRESULT DocumentMgr_Constructor(ITfThreadMgrEventSink*, ITfDocumentMgr **
 extern HRESULT Context_Constructor(TfClientId tidOwner, IUnknown *punk, ITfDocumentMgr *mgr, ITfContext **ppOut, TfEditCookie *pecTextStore) DECLSPEC_HIDDEN;
 extern HRESULT InputProcessorProfiles_Constructor(IUnknown *pUnkOuter, IUnknown **ppOut) DECLSPEC_HIDDEN;
 extern HRESULT CategoryMgr_Constructor(IUnknown *pUnkOuter, IUnknown **ppOut) DECLSPEC_HIDDEN;
-extern HRESULT Range_Constructor(ITfContext *context, ITextStoreACP *textstore, DWORD lockType, DWORD anchorStart, DWORD anchorEnd, ITfRange **ppOut) DECLSPEC_HIDDEN;
+extern HRESULT Range_Constructor(ITfContext *context, ITextStoreACP2 *textstore, UINT textstore_ver, DWORD lockType,
+                                 DWORD anchorStart, DWORD anchorEnd, ITfRange **ppOut) DECLSPEC_HIDDEN;
 extern HRESULT CompartmentMgr_Constructor(IUnknown *pUnkOuter, REFIID riid, IUnknown **ppOut) DECLSPEC_HIDDEN;
 extern HRESULT CompartmentMgr_Destructor(ITfCompartmentMgr *This) DECLSPEC_HIDDEN;
 extern HRESULT LangBarMgr_Constructor(IUnknown *pUnkOuter, IUnknown **ppOut) DECLSPEC_HIDDEN;
diff --git a/dlls/msctf/range.c b/dlls/msctf/range.c
index c4eee2501f..22dc8303a6 100644
--- a/dlls/msctf/range.c
+++ b/dlls/msctf/range.c
@@ -41,7 +41,8 @@ typedef struct tagRange {
     /* const ITfRangeACPVtb *RangeACPVtbl; */
     LONG refCount;
 
-    ITextStoreACP   *pITextStoreACP;
+    ITextStoreACP2 *textstore;
+    UINT textstore_ver;
     ITfContext      *pITfContext;
 
     DWORD lockType;
@@ -322,7 +323,8 @@ static const ITfRangeVtbl Range_RangeVtbl =
     Range_GetContext
 };
 
-HRESULT Range_Constructor(ITfContext *context, ITextStoreACP *textstore, DWORD lockType, DWORD anchorStart, DWORD anchorEnd, ITfRange **ppOut)
+HRESULT Range_Constructor(ITfContext *context, ITextStoreACP2 *textstore, UINT textstore_ver,
+                          DWORD lockType, DWORD anchorStart, DWORD anchorEnd, ITfRange **ppOut)
 {
     Range *This;
 
@@ -335,7 +337,8 @@ HRESULT Range_Constructor(ITfContext *context, ITextStoreACP *textstore, DWORD l
     This->ITfRange_iface.lpVtbl = &Range_RangeVtbl;
     This->refCount = 1;
     This->pITfContext = context;
-    This->pITextStoreACP = textstore;
+    This->textstore = textstore;
+    This->textstore_ver = textstore_ver;
     This->lockType = lockType;
     This->anchorStart = anchorStart;
     This->anchorEnd = anchorEnd;
diff --git a/dlls/msctf/tests/inputprocessor.c b/dlls/msctf/tests/inputprocessor.c
index ebc0e36154..f0f8031ae8 100644
--- a/dlls/msctf/tests/inputprocessor.c
+++ b/dlls/msctf/tests/inputprocessor.c
@@ -192,13 +192,23 @@ static void TextStoreACP_Destructor(TextStoreACP *This)
     HeapFree(GetProcessHeap(),0,This);
 }
 
+static int text_store_acp_ver = 0;
+static BOOL acp2only = FALSE;
+
 static HRESULT WINAPI TextStoreACP_QueryInterface(ITextStoreACP *iface, REFIID iid, LPVOID *ppvOut)
 {
     *ppvOut = NULL;
 
-    if (IsEqualIID(iid, &IID_IUnknown) || IsEqualIID(iid, &IID_ITextStoreACP))
+    if (IsEqualIID(iid, &IID_IUnknown) ||
+        (IsEqualIID(iid, &IID_ITextStoreACP) && !acp2only))
+    {
+        *ppvOut = iface;
+        text_store_acp_ver = 1;
+    }
+    else if (IsEqualIID(iid, &IID_ITextStoreACP2))
     {
         *ppvOut = iface;
+        text_store_acp_ver = 2;
     }
 
     if (*ppvOut)
@@ -2561,9 +2571,12 @@ static void test_MultiThreadApartment(void)
 static void test_thread_mgr2(void)
 {
     TfClientId clientid1, clientid2, clientid3;
+    ITextStoreACP *textstore;
     ITfDocumentMgr *docmgr;
     ITfThreadMgr2 *thmgr2;
     ITfThreadMgr *thmgr;
+    ITfContext *context;
+    DWORD cookie;
     HRESULT hr;
 
     hr = CoCreateInstance(&CLSID_TF_ThreadMgr, NULL, CLSCTX_INPROC_SERVER,
@@ -2595,6 +2608,22 @@ static void test_thread_mgr2(void)
     hr = ITfThreadMgr2_CreateDocumentMgr(thmgr2, &docmgr);
     ok(hr == S_OK, "ITfThreadMgr2_CreateDocumentMgr failed: %#x.\n", hr);
 
+    hr = TextStoreACP_Constructor((IUnknown**)&textstore);
+    ok(hr == S_OK,"TextStoreACP_Constructor failed: %#x.\n", hr);
+
+    hr = ITfDocumentMgr_CreateContext(docmgr, clientid1, 0, (IUnknown *)textstore, &context, &cookie);
+    ok(hr == S_OK,"ITfDocumentMgr_CreateContext failed: %#x.\n", hr);
+    ok(text_store_acp_ver == 1, "Got wrong TextStoreACP version: %d.\n", text_store_acp_ver);
+    ITfContext_Release(context);
+
+    acp2only = TRUE;
+    hr = ITfDocumentMgr_CreateContext(docmgr, clientid1, 0, (IUnknown *)textstore, &context, &cookie);
+    ok(hr == S_OK,"ITfDocumentMgr_CreateContext failed: %#x.\n", hr);
+    ok(text_store_acp_ver == 2, "Got wrong TextStoreACP version: %d.\n", text_store_acp_ver);
+    acp2only = FALSE;
+    ITfContext_Release(context);
+    TextStoreACP_Release(textstore);
+
     hr = ITfThreadMgr2_Deactivate(thmgr2);
     ok(hr == S_OK, "ITfThreadMgr2_Deactivate failed: %#x.\n", hr);
     hr = ITfThreadMgr2_Deactivate(thmgr2);
-- 
2.23.0




More information about the wine-devel mailing list