Module: wine Branch: master Commit: f20c4d69c95ad42fb299a648fcef3f333a90caad URL: http://source.winehq.org/git/wine.git/?a=commit;h=f20c4d69c95ad42fb299a648fc...
Author: Aric Stewart aric@codeweavers.com Date: Fri May 8 08:50:59 2009 -0500
msctf: Implement ITfKeystrokeMgr::AdviseKeyEventSink.
---
dlls/msctf/msctf.c | 46 +++++++++++++++++++++++++++++++++++++ dlls/msctf/msctf_internal.h | 4 +++ dlls/msctf/tests/inputprocessor.c | 6 ++++- dlls/msctf/threadmgr.c | 33 +++++++++++++++++++++++++- 4 files changed, 86 insertions(+), 3 deletions(-)
diff --git a/dlls/msctf/msctf.c b/dlls/msctf/msctf.c index c8dd486..55a8075 100644 --- a/dlls/msctf/msctf.c +++ b/dlls/msctf/msctf.c @@ -55,6 +55,7 @@ typedef struct { TF_LANGUAGEPROFILE LanguageProfile; ITfTextInputProcessor *pITfTextInputProcessor; ITfThreadMgr *pITfThreadMgr; + ITfKeyEventSink *pITfKeyEventSink; TfClientId tid; } ActivatedTextService;
@@ -378,6 +379,7 @@ HRESULT add_active_textservice(TF_LANGUAGEPROFILE *lp) actsvr->pITfTextInputProcessor = NULL; actsvr->LanguageProfile = *lp; actsvr->LanguageProfile.fActive = TRUE; + actsvr->pITfKeyEventSink = NULL;
/* get TIP category */ if (SUCCEEDED(CategoryMgr_Constructor(NULL,(IUnknown**)&catmgr))) @@ -456,6 +458,50 @@ HRESULT deactivate_textservices(void) return S_OK; }
+CLSID get_textservice_clsid(TfClientId tid) +{ + AtsEntry *ats; + + LIST_FOR_EACH_ENTRY(ats, &AtsList, AtsEntry, entry) + if (ats->ats->tid == tid) + return ats->ats->LanguageProfile.clsid; + return GUID_NULL; +} + +HRESULT get_textservice_sink(TfClientId tid, REFCLSID iid, IUnknown **sink) +{ + AtsEntry *ats; + + if (!IsEqualCLSID(iid,&IID_ITfKeyEventSink)) + return E_NOINTERFACE; + + LIST_FOR_EACH_ENTRY(ats, &AtsList, AtsEntry, entry) + if (ats->ats->tid == tid) + { + *sink = (IUnknown*)ats->ats->pITfKeyEventSink; + return S_OK; + } + + return E_FAIL; +} + +HRESULT set_textservice_sink(TfClientId tid, REFCLSID iid, IUnknown* sink) +{ + AtsEntry *ats; + + if (!IsEqualCLSID(iid,&IID_ITfKeyEventSink)) + return E_NOINTERFACE; + + LIST_FOR_EACH_ENTRY(ats, &AtsList, AtsEntry, entry) + if (ats->ats->tid == tid) + { + ats->ats->pITfKeyEventSink = (ITfKeyEventSink*)sink; + return S_OK; + } + + return E_FAIL; +} + /************************************************************************* * MSCTF DllMain */ diff --git a/dlls/msctf/msctf_internal.h b/dlls/msctf/msctf_internal.h index 433b79e..0df88de 100644 --- a/dlls/msctf/msctf_internal.h +++ b/dlls/msctf/msctf_internal.h @@ -47,5 +47,9 @@ extern BOOL get_active_textservice(REFCLSID rclsid, TF_LANGUAGEPROFILE *lp); extern HRESULT activate_textservices(ITfThreadMgr *tm); extern HRESULT deactivate_textservices(void);
+extern CLSID get_textservice_clsid(TfClientId tid); +extern HRESULT get_textservice_sink(TfClientId tid, REFCLSID iid, IUnknown** sink); +extern HRESULT set_textservice_sink(TfClientId tid, REFCLSID iid, IUnknown* sink); + extern const WCHAR szwSystemTIPKey[]; #endif /* __WINE_MSCTF_I_H */ diff --git a/dlls/msctf/tests/inputprocessor.c b/dlls/msctf/tests/inputprocessor.c index 7ba9140..4ea2ec9 100644 --- a/dlls/msctf/tests/inputprocessor.c +++ b/dlls/msctf/tests/inputprocessor.c @@ -405,8 +405,12 @@ static void test_KeystrokeMgr(void)
test_KEV_OnSetFocus = SINK_EXPECTED; hr = ITfKeystrokeMgr_AdviseKeyEventSink(keymgr,tid,sink,TRUE); - todo_wine ok(SUCCEEDED(hr),"ITfKeystrokeMgr_AdviseKeyEventSink failed\n"); + ok(SUCCEEDED(hr),"ITfKeystrokeMgr_AdviseKeyEventSink failed\n"); todo_wine ok(test_KEV_OnSetFocus == SINK_FIRED, "KeyEventSink_OnSetFocus not fired as expected\n"); + hr = ITfKeystrokeMgr_AdviseKeyEventSink(keymgr,tid,sink,TRUE); + ok(hr == CONNECT_E_ADVISELIMIT,"Wrong return, expected CONNECT_E_ADVISELIMIT\n"); + hr = ITfKeystrokeMgr_AdviseKeyEventSink(keymgr,cid,sink,TRUE); + ok(hr == E_INVALIDARG,"Wrong return, expected E_INVALIDARG\n");
hr =ITfKeystrokeMgr_PreserveKey(keymgr, 0, &CLSID_PreservedKey, &tfpk, NULL, 0); ok(hr==E_INVALIDARG,"ITfKeystrokeMgr_PreserveKey inproperly succeeded\n"); diff --git a/dlls/msctf/threadmgr.c b/dlls/msctf/threadmgr.c index 2afee39..e8743ec 100644 --- a/dlls/msctf/threadmgr.c +++ b/dlls/msctf/threadmgr.c @@ -78,6 +78,8 @@ typedef struct tagACLMulti { ITfDocumentMgr *focus; LONG activationCount;
+ ITfKeyEventSink *forgroundKeyEventSink; + struct list CurrentPreservedKeys;
/* kept as separate lists to reduce unnecessary iterations */ @@ -509,8 +511,35 @@ static HRESULT WINAPI KeystrokeMgr_AdviseKeyEventSink(ITfKeystrokeMgr *iface, TfClientId tid, ITfKeyEventSink *pSink, BOOL fForeground) { ThreadMgr *This = impl_from_ITfKeystrokeMgrVtbl(iface); - FIXME("STUB:(%p)\n",This); - return E_NOTIMPL; + CLSID textservice; + ITfKeyEventSink *check = NULL; + + TRACE("(%p) %x %p %i\n",This,tid,pSink,fForeground); + + if (!tid || !pSink) + return E_INVALIDARG; + + textservice = get_textservice_clsid(tid); + if (IsEqualCLSID(&GUID_NULL,&textservice)) + return E_INVALIDARG; + + get_textservice_sink(tid, &IID_ITfKeyEventSink, (IUnknown**)&check); + if (check != NULL) + return CONNECT_E_ADVISELIMIT; + + if (FAILED(IUnknown_QueryInterface(pSink,&IID_ITfKeyEventSink,(LPVOID*) &check))) + return E_INVALIDARG; + + set_textservice_sink(tid, &IID_ITfKeyEventSink, (IUnknown*)check); + + if (fForeground) + { + if (This->forgroundKeyEventSink) + ITfKeyEventSink_Release(This->forgroundKeyEventSink); + ITfKeyEventSink_AddRef(check); + This->forgroundKeyEventSink = check; + } + return S_OK; }
static HRESULT WINAPI KeystrokeMgr_UnadviseKeyEventSink(ITfKeystrokeMgr *iface,