From 45c3ff2ff827bbc11d39a15ba524e55e5b65ab9d Mon Sep 17 00:00:00 2001 From: Aric Stewart Date: Thu, 7 May 2009 08:31:32 -0500 Subject: [PATCH] msctf: Implement ITfKeystrokeMgr::PreserveKey. --- dlls/msctf/tests/inputprocessor.c | 2 +- dlls/msctf/threadmgr.c | 59 +++++++++++++++++++++++++++++-- 2 files changed, 58 insertions(+), 3 deletions(-) diff --git a/dlls/msctf/tests/inputprocessor.c b/dlls/msctf/tests/inputprocessor.c index 8d6579b1d65..d29b31947de 100644 --- a/dlls/msctf/tests/inputprocessor.c +++ b/dlls/msctf/tests/inputprocessor.c @@ -409,7 +409,7 @@ static void test_KeystrokeMgr(void) todo_wine ok(test_KEV_OnSetFocus == SINK_FIRED, "KeyEventSink_OnSetFocus not fired as expected\n"); hr =ITfKeystrokeMgr_PreserveKey(keymgr, 0, &CLSID_PreservedKey, &tfpk, NULL, 0); - todo_wine ok(hr==E_INVALIDARG,"ITfKeystrokeMgr_PreserveKey inproperly succeeded\n"); + 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"); diff --git a/dlls/msctf/threadmgr.c b/dlls/msctf/threadmgr.c index fcd4daee963..5580410f164 100644 --- a/dlls/msctf/threadmgr.c +++ b/dlls/msctf/threadmgr.c @@ -56,6 +56,15 @@ typedef struct tagThreadMgrSink { } interfaces; } ThreadMgrSink; +typedef struct tagPreservedKey +{ + struct list entry; + GUID guid; + TF_PRESERVEDKEY prekey; + LPWSTR description; + TfClientId tid; +} PreservedKey; + typedef struct tagACLMulti { const ITfThreadMgrVtbl *ThreadMgrVtbl; const ITfSourceVtbl *SourceVtbl; @@ -68,6 +77,8 @@ typedef struct tagACLMulti { ITfDocumentMgr *focus; + struct list CurrentPreservedKeys; + /* kept as separate lists to reduce unnecessary iterations */ struct list ActiveLanguageProfileNotifySink; struct list DisplayAttributeNotifySink; @@ -155,6 +166,14 @@ static void ThreadMgr_Destructor(ThreadMgr *This) free_sink(sink); } + LIST_FOR_EACH_SAFE(cursor, cursor2, &This->CurrentPreservedKeys) + { + PreservedKey* key = LIST_ENTRY(cursor,PreservedKey,entry); + list_remove(cursor); + HeapFree(GetProcessHeap(),0,key->description); + HeapFree(GetProcessHeap(),0,key); + } + HeapFree(GetProcessHeap(),0,This); } @@ -537,8 +556,42 @@ static HRESULT WINAPI KeystrokeMgr_PreserveKey(ITfKeystrokeMgr *iface, const WCHAR *pchDesc, ULONG cchDesc) { ThreadMgr *This = impl_from_ITfKeystrokeMgrVtbl(iface); - FIXME("STUB:(%p)\n",This); - return E_NOTIMPL; + struct list *cursor; + PreservedKey *newkey; + + TRACE("(%p) %x %s (%x,%x) %s\n",This,tid, debugstr_guid(rguid),(prekey)?prekey->uVKey:0,(prekey)?prekey->uModifiers:0,debugstr_wn(pchDesc,cchDesc)); + + if (!tid || ! rguid || !prekey || (cchDesc && !pchDesc)) + return E_INVALIDARG; + + LIST_FOR_EACH(cursor, &This->CurrentPreservedKeys) + { + PreservedKey* key = LIST_ENTRY(cursor,PreservedKey,entry); + if (IsEqualGUID(rguid,&key->guid) && prekey->uVKey == key->prekey.uVKey && prekey->uModifiers == key->prekey.uModifiers) + return TF_E_ALREADY_EXISTS; + } + + newkey = HeapAlloc(GetProcessHeap(),0,sizeof(PreservedKey)); + if (!newkey) + return E_OUTOFMEMORY; + + newkey->guid = *rguid; + newkey->prekey = *prekey; + newkey->tid = tid; + if (cchDesc) + { + newkey->description = HeapAlloc(GetProcessHeap(),0,cchDesc * sizeof(WCHAR)); + if (!newkey->description) + { + HeapFree(GetProcessHeap(),0,newkey); + return E_OUTOFMEMORY; + } + memcpy(newkey->description, pchDesc, cchDesc*sizeof(WCHAR)); + } + + list_add_head(&This->CurrentPreservedKeys,&newkey->entry); + + return S_OK; } static HRESULT WINAPI KeystrokeMgr_UnpreserveKey(ITfKeystrokeMgr *iface, @@ -866,6 +919,8 @@ HRESULT ThreadMgr_Constructor(IUnknown *pUnkOuter, IUnknown **ppOut) This->refCount = 1; TlsSetValue(tlsIndex,This); + list_init(&This->CurrentPreservedKeys); + list_init(&This->ActiveLanguageProfileNotifySink); list_init(&This->DisplayAttributeNotifySink); list_init(&This->KeyTraceEventSink);