Aric Stewart : msctf: Implement ITfThreadMgr::Activate and ITfThreadMgr:: Deactivate.

Alexandre Julliard julliard at winehq.org
Fri May 8 08:06:29 CDT 2009


Module: wine
Branch: master
Commit: 43f5b64f06fcd2a835bea41f27cd49074478d7b3
URL:    http://source.winehq.org/git/wine.git/?a=commit;h=43f5b64f06fcd2a835bea41f27cd49074478d7b3

Author: Aric Stewart <aric at codeweavers.com>
Date:   Thu May  7 14:28:00 2009 -0500

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 57cd477..c8dd486 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 7bfc221..433b79e 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 39f58e6..7ba9140 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 f0c76b1..2afee39 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




More information about the wine-cvs mailing list