Signed-off-by: Jactry Zeng jzeng@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);