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