Aric Stewart : msctf: Implement ITfKeystrokeMgr::AdviseKeyEventSink.

Alexandre Julliard julliard at winehq.org
Mon May 11 09:10:48 CDT 2009


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

Author: Aric Stewart <aric at 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,




More information about the wine-cvs mailing list