From 43f5b64f06fcd2a835bea41f27cd49074478d7b3 Mon Sep 17 00:00:00 2001 From: Aric Stewart Date: Thu, 7 May 2009 14:28:00 -0500 Subject: [PATCH] msctf: Implement ITfThreadMgr::Activate and ITfThreadMgr::Deactivate. --- dlls/msctf/msctf.c | 17 +++++++++++-- dlls/msctf/msctf_internal.h | 1 + dlls/msctf/tests/inputprocessor.c | 35 ++++++++++++++++++-------- dlls/msctf/threadmgr.c | 42 +++++++++++++++++++++++++------ 4 files changed, 75 insertions(+), 20 deletions(-) diff --git a/dlls/msctf/msctf.c b/dlls/msctf/msctf.c index 57cd477975..c8dd486c63 100644 --- a/dlls/msctf/msctf.c +++ b/dlls/msctf/msctf.c @@ -69,8 +69,10 @@ static UINT id_last; static UINT array_size; static struct list AtsList = LIST_INIT(AtsList); +static UINT activated = 0; DWORD tlsIndex = 0; +TfClientId processId = 0; const WCHAR szwSystemTIPKey[] = {'S','O','F','T','W','A','R','E','\\','M','i','c','r','o','s','o','f','t','\\','C','T','F','\\','T','I','P',0}; @@ -397,6 +399,9 @@ HRESULT add_active_textservice(TF_LANGUAGEPROFILE *lp) if (!IsEqualGUID(&actsvr->LanguageProfile.catid,&GUID_NULL)) deactivate_remove_conflicting_ts(&actsvr->LanguageProfile.catid); + if (activated > 0) + activate_given_ts(actsvr, tm); + entry->ats = actsvr; list_add_head(&AtsList, &entry->entry); @@ -424,6 +429,10 @@ HRESULT activate_textservices(ITfThreadMgr *tm) HRESULT hr = S_OK; AtsEntry *ats; + activated ++; + if (activated > 1) + return S_OK; + LIST_FOR_EACH_ENTRY(ats, &AtsList, AtsEntry, entry) { hr = activate_given_ts(ats->ats, tm); @@ -437,8 +446,12 @@ HRESULT deactivate_textservices(void) { AtsEntry *ats; - LIST_FOR_EACH_ENTRY(ats, &AtsList, AtsEntry, entry) - deactivate_given_ts(ats->ats); + if (activated > 0) + activated --; + + if (activated == 0) + LIST_FOR_EACH_ENTRY(ats, &AtsList, AtsEntry, entry) + deactivate_given_ts(ats->ats); return S_OK; } diff --git a/dlls/msctf/msctf_internal.h b/dlls/msctf/msctf_internal.h index 7bfc22157b..433b79ea6a 100644 --- a/dlls/msctf/msctf_internal.h +++ b/dlls/msctf/msctf_internal.h @@ -26,6 +26,7 @@ #define COOKIE_MAGIC_GUIDATOM 0x0030 extern DWORD tlsIndex; +extern TfClientId processId; extern HRESULT ThreadMgr_Constructor(IUnknown *pUnkOuter, IUnknown **ppOut); extern HRESULT DocumentMgr_Constructor(ITfThreadMgrEventSink*, ITfDocumentMgr **ppOut); diff --git a/dlls/msctf/tests/inputprocessor.c b/dlls/msctf/tests/inputprocessor.c index 39f58e6600..7ba9140573 100644 --- a/dlls/msctf/tests/inputprocessor.c +++ b/dlls/msctf/tests/inputprocessor.c @@ -412,18 +412,18 @@ static void test_KeystrokeMgr(void) ok(hr==E_INVALIDARG,"ITfKeystrokeMgr_PreserveKey inproperly succeeded\n"); hr =ITfKeystrokeMgr_PreserveKey(keymgr, tid, &CLSID_PreservedKey, &tfpk, NULL, 0); - todo_wine ok(SUCCEEDED(hr),"ITfKeystrokeMgr_PreserveKey failed\n"); + ok(SUCCEEDED(hr),"ITfKeystrokeMgr_PreserveKey failed\n"); hr =ITfKeystrokeMgr_PreserveKey(keymgr, tid, &CLSID_PreservedKey, &tfpk, NULL, 0); - todo_wine ok(hr == TF_E_ALREADY_EXISTS,"ITfKeystrokeMgr_PreserveKey inproperly succeeded\n"); + ok(hr == TF_E_ALREADY_EXISTS,"ITfKeystrokeMgr_PreserveKey inproperly succeeded\n"); preserved = FALSE; hr = ITfKeystrokeMgr_IsPreservedKey(keymgr, &CLSID_PreservedKey, &tfpk, &preserved); - todo_wine ok(hr == S_OK, "ITfKeystrokeMgr_IsPreservedKey failed\n"); + ok(hr == S_OK, "ITfKeystrokeMgr_IsPreservedKey failed\n"); if (hr == S_OK) ok(preserved == TRUE,"misreporting preserved key\n"); hr = ITfKeystrokeMgr_UnpreserveKey(keymgr, &CLSID_PreservedKey,&tfpk); - todo_wine ok(SUCCEEDED(hr),"ITfKeystrokeMgr_UnpreserveKey failed\n"); + ok(SUCCEEDED(hr),"ITfKeystrokeMgr_UnpreserveKey failed\n"); hr = ITfKeystrokeMgr_IsPreservedKey(keymgr, &CLSID_PreservedKey, &tfpk, &preserved); ok(hr == S_FALSE, "ITfKeystrokeMgr_IsPreservedKey failed\n"); @@ -461,10 +461,23 @@ static void test_startSession(void) ITfDocumentMgr *dmtest; ITfContext *cxt,*cxt2,*cxt3,*cxtTest; ITextStoreACP *ts; + TfClientId cid2 = 0; + + hr = ITfThreadMgr_Deactivate(g_tm); + ok(hr == E_UNEXPECTED,"Deactivate should have failed with E_UNEXPECTED\n"); test_ShouldActivate = TRUE; - ITfThreadMgr_Activate(g_tm,&cid); - todo_wine ok(cid != tid,"TextService id mistakenly matches Client id\n"); + hr = ITfThreadMgr_Activate(g_tm,&cid); + ok(SUCCEEDED(hr),"Failed to Activate\n"); + ok(cid != tid,"TextService id mistakenly matches Client id\n"); + + test_ShouldActivate = FALSE; + hr = ITfThreadMgr_Activate(g_tm,&cid2); + ok(SUCCEEDED(hr),"Failed to Activate\n"); + ok (cid == cid2, "Second activate client ID does not match\n"); + + hr = ITfThreadMgr_Deactivate(g_tm); + ok(SUCCEEDED(hr),"Failed to Deactivate\n"); hr = ITfThreadMgr_CreateDocumentMgr(g_tm,&g_dm); ok(SUCCEEDED(hr),"CreateDocumentMgr failed\n"); @@ -600,11 +613,13 @@ static void test_startSession(void) static void test_endSession(void) { + HRESULT hr; test_ShouldDeactivate = TRUE; test_CurrentFocus = NULL; test_PrevFocus = g_dm; test_OnSetFocus = SINK_EXPECTED; - ITfThreadMgr_Deactivate(g_tm); + hr = ITfThreadMgr_Deactivate(g_tm); + ok(SUCCEEDED(hr),"Failed to Deactivate\n"); ok(test_OnSetFocus == SINK_FIRED, "OnSetFocus sink not called\n"); test_OnSetFocus = SINK_UNEXPECTED; } @@ -642,10 +657,10 @@ static void test_TfGuidAtom(void) /* show that cid and tid TfClientIds are also TfGuidAtoms */ hr = ITfCategoryMgr_IsEqualTfGuidAtom(g_cm,tid,&CLSID_FakeService,&equal); ok(SUCCEEDED(hr),"ITfCategoryMgr_IsEqualTfGuidAtom failed\n"); - todo_wine ok(equal == TRUE,"Equal value invalid\n"); + ok(equal == TRUE,"Equal value invalid\n"); hr = ITfCategoryMgr_GetGUID(g_cm,cid,&g1); ok(SUCCEEDED(hr),"ITfCategoryMgr_GetGUID failed\n"); - todo_wine ok(!IsEqualGUID(&g1,&GUID_NULL),"guid should not be NULL\n"); + ok(!IsEqualGUID(&g1,&GUID_NULL),"guid should not be NULL\n"); } static void test_ClientId(void) @@ -668,7 +683,7 @@ static void test_ClientId(void) hr = ITfClientId_GetClientId(pcid,&CLSID_FakeService,&id2); ok(SUCCEEDED(hr),"GetClientId failed\n"); ok(id2!=id1,"Id matches GUID_NULL\n"); - todo_wine ok(id2==tid,"Id for CLSID_FakeService not matching tid\n"); + ok(id2==tid,"Id for CLSID_FakeService not matching tid\n"); ok(id2!=cid,"Id for CLSID_FakeService matching cid\n"); hr = ITfClientId_GetClientId(pcid,&g2,&id2); ok(SUCCEEDED(hr),"GetClientId failed\n"); diff --git a/dlls/msctf/threadmgr.c b/dlls/msctf/threadmgr.c index f0c76b16b3..2afee3913b 100644 --- a/dlls/msctf/threadmgr.c +++ b/dlls/msctf/threadmgr.c @@ -76,6 +76,7 @@ typedef struct tagACLMulti { const ITfThreadMgrEventSinkVtbl *ThreadMgrEventSinkVtbl; /* internal */ ITfDocumentMgr *focus; + LONG activationCount; struct list CurrentPreservedKeys; @@ -237,23 +238,48 @@ static ULONG WINAPI ThreadMgr_Release(ITfThreadMgr *iface) static HRESULT WINAPI ThreadMgr_fnActivate( ITfThreadMgr* iface, TfClientId *ptid) { ThreadMgr *This = (ThreadMgr *)iface; - FIXME("STUB:(%p)\n",This); - return E_NOTIMPL; + + TRACE("(%p) %p\n",This, ptid); + + if (!ptid) + return E_INVALIDARG; + + if (!processId) + { + GUID guid; + CoCreateGuid(&guid); + ITfClientId_GetClientId((ITfClientId*)&This->ClientIdVtbl,&guid,&processId); + } + + activate_textservices(iface); + This->activationCount++; + *ptid = processId; + return S_OK; } static HRESULT WINAPI ThreadMgr_fnDeactivate( ITfThreadMgr* iface) { ThreadMgr *This = (ThreadMgr *)iface; - FIXME("STUB:(%p)\n",This); + TRACE("(%p)\n",This); - if (This->focus) + if (This->activationCount == 0) + return E_UNEXPECTED; + + This->activationCount --; + + if (This->activationCount == 0) { - ITfThreadMgrEventSink_OnSetFocus((ITfThreadMgrEventSink*)&This->ThreadMgrEventSinkVtbl, 0, This->focus); - ITfDocumentMgr_Release(This->focus); - This->focus = 0; + if (This->focus) + { + ITfThreadMgrEventSink_OnSetFocus((ITfThreadMgrEventSink*)&This->ThreadMgrEventSinkVtbl, 0, This->focus); + ITfDocumentMgr_Release(This->focus); + This->focus = 0; + } } - return E_NOTIMPL; + deactivate_textservices(); + + return S_OK; } static HRESULT WINAPI ThreadMgr_CreateDocumentMgr( ITfThreadMgr* iface, ITfDocumentMgr -- 2.32.0.93.g670b81a890