2 * ITfThreadMgr implementation
4 * Copyright 2008 Aric Stewart, CodeWeavers
6 * This library is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Lesser General Public
8 * License as published by the Free Software Foundation; either
9 * version 2.1 of the License, or (at your option) any later version.
11 * This library is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Lesser General Public License for more details.
16 * You should have received a copy of the GNU Lesser General Public
17 * License along with this library; if not, write to the Free Software
18 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
27 #include "wine/debug.h"
37 #include "wine/unicode.h"
38 #include "wine/list.h"
41 #include "msctf_internal.h"
43 WINE_DEFAULT_DEBUG_CHANNEL(msctf);
45 typedef struct tagThreadMgrSink {
50 /* ITfActiveLanguageProfileNotifySink *pITfActiveLanguageProfileNotifySink; */
51 /* ITfDisplayAttributeNotifySink *pITfDisplayAttributeNotifySink; */
52 /* ITfKeyTraceEventSink *pITfKeyTraceEventSink; */
53 /* ITfPreservedKeyNotifySink *pITfPreservedKeyNotifySink; */
54 /* ITfThreadFocusSink *pITfThreadFocusSink; */
55 ITfThreadMgrEventSink *pITfThreadMgrEventSink;
59 typedef struct tagPreservedKey
63 TF_PRESERVEDKEY prekey;
68 typedef struct tagACLMulti {
69 const ITfThreadMgrVtbl *ThreadMgrVtbl;
70 const ITfSourceVtbl *SourceVtbl;
71 const ITfKeystrokeMgrVtbl *KeystrokeMgrVtbl;
72 const ITfMessagePumpVtbl *MessagePumpVtbl;
73 const ITfClientIdVtbl *ClientIdVtbl;
76 const ITfThreadMgrEventSinkVtbl *ThreadMgrEventSinkVtbl; /* internal */
78 ITfDocumentMgr *focus;
81 ITfKeyEventSink *forgroundKeyEventSink;
83 struct list CurrentPreservedKeys;
85 /* kept as separate lists to reduce unnecessary iterations */
86 struct list ActiveLanguageProfileNotifySink;
87 struct list DisplayAttributeNotifySink;
88 struct list KeyTraceEventSink;
89 struct list PreservedKeyNotifySink;
90 struct list ThreadFocusSink;
91 struct list ThreadMgrEventSink;
94 static inline ThreadMgr *impl_from_ITfSourceVtbl(ITfSource *iface)
96 return (ThreadMgr *)((char *)iface - FIELD_OFFSET(ThreadMgr,SourceVtbl));
99 static inline ThreadMgr *impl_from_ITfKeystrokeMgrVtbl(ITfKeystrokeMgr *iface)
101 return (ThreadMgr *)((char *)iface - FIELD_OFFSET(ThreadMgr,KeystrokeMgrVtbl));
104 static inline ThreadMgr *impl_from_ITfMessagePumpVtbl(ITfMessagePump *iface)
106 return (ThreadMgr *)((char *)iface - FIELD_OFFSET(ThreadMgr,MessagePumpVtbl));
109 static inline ThreadMgr *impl_from_ITfClientIdVtbl(ITfClientId *iface)
111 return (ThreadMgr *)((char *)iface - FIELD_OFFSET(ThreadMgr,ClientIdVtbl));
114 static inline ThreadMgr *impl_from_ITfThreadMgrEventSink(ITfThreadMgrEventSink *iface)
116 return (ThreadMgr *)((char *)iface - FIELD_OFFSET(ThreadMgr,ThreadMgrEventSinkVtbl));
119 static void free_sink(ThreadMgrSink *sink)
121 IUnknown_Release(sink->interfaces.pIUnknown);
122 HeapFree(GetProcessHeap(),0,sink);
125 static void ThreadMgr_Destructor(ThreadMgr *This)
127 struct list *cursor, *cursor2;
129 TlsSetValue(tlsIndex,NULL);
130 TRACE("destroying %p\n", This);
132 ITfDocumentMgr_Release(This->focus);
135 LIST_FOR_EACH_SAFE(cursor, cursor2, &This->ActiveLanguageProfileNotifySink)
137 ThreadMgrSink* sink = LIST_ENTRY(cursor,ThreadMgrSink,entry);
141 LIST_FOR_EACH_SAFE(cursor, cursor2, &This->DisplayAttributeNotifySink)
143 ThreadMgrSink* sink = LIST_ENTRY(cursor,ThreadMgrSink,entry);
147 LIST_FOR_EACH_SAFE(cursor, cursor2, &This->KeyTraceEventSink)
149 ThreadMgrSink* sink = LIST_ENTRY(cursor,ThreadMgrSink,entry);
153 LIST_FOR_EACH_SAFE(cursor, cursor2, &This->PreservedKeyNotifySink)
155 ThreadMgrSink* sink = LIST_ENTRY(cursor,ThreadMgrSink,entry);
159 LIST_FOR_EACH_SAFE(cursor, cursor2, &This->ThreadFocusSink)
161 ThreadMgrSink* sink = LIST_ENTRY(cursor,ThreadMgrSink,entry);
165 LIST_FOR_EACH_SAFE(cursor, cursor2, &This->ThreadMgrEventSink)
167 ThreadMgrSink* sink = LIST_ENTRY(cursor,ThreadMgrSink,entry);
172 LIST_FOR_EACH_SAFE(cursor, cursor2, &This->CurrentPreservedKeys)
174 PreservedKey* key = LIST_ENTRY(cursor,PreservedKey,entry);
176 HeapFree(GetProcessHeap(),0,key->description);
177 HeapFree(GetProcessHeap(),0,key);
180 HeapFree(GetProcessHeap(),0,This);
183 static HRESULT WINAPI ThreadMgr_QueryInterface(ITfThreadMgr *iface, REFIID iid, LPVOID *ppvOut)
185 ThreadMgr *This = (ThreadMgr *)iface;
188 if (IsEqualIID(iid, &IID_IUnknown) || IsEqualIID(iid, &IID_ITfThreadMgr))
192 else if (IsEqualIID(iid, &IID_ITfSource))
194 *ppvOut = &This->SourceVtbl;
196 else if (IsEqualIID(iid, &IID_ITfKeystrokeMgr))
198 *ppvOut = &This->KeystrokeMgrVtbl;
200 else if (IsEqualIID(iid, &IID_ITfMessagePump))
202 *ppvOut = &This->MessagePumpVtbl;
204 else if (IsEqualIID(iid, &IID_ITfClientId))
206 *ppvOut = &This->ClientIdVtbl;
211 IUnknown_AddRef(iface);
215 WARN("unsupported interface: %s\n", debugstr_guid(iid));
216 return E_NOINTERFACE;
219 static ULONG WINAPI ThreadMgr_AddRef(ITfThreadMgr *iface)
221 ThreadMgr *This = (ThreadMgr *)iface;
222 return InterlockedIncrement(&This->refCount);
225 static ULONG WINAPI ThreadMgr_Release(ITfThreadMgr *iface)
227 ThreadMgr *This = (ThreadMgr *)iface;
230 ret = InterlockedDecrement(&This->refCount);
232 ThreadMgr_Destructor(This);
236 /*****************************************************
237 * ITfThreadMgr functions
238 *****************************************************/
240 static HRESULT WINAPI ThreadMgr_fnActivate( ITfThreadMgr* iface, TfClientId *ptid)
242 ThreadMgr *This = (ThreadMgr *)iface;
244 TRACE("(%p) %p\n",This, ptid);
253 ITfClientId_GetClientId((ITfClientId*)&This->ClientIdVtbl,&guid,&processId);
256 activate_textservices(iface);
257 This->activationCount++;
262 static HRESULT WINAPI ThreadMgr_fnDeactivate( ITfThreadMgr* iface)
264 ThreadMgr *This = (ThreadMgr *)iface;
265 TRACE("(%p)\n",This);
267 if (This->activationCount == 0)
270 This->activationCount --;
272 if (This->activationCount == 0)
276 ITfThreadMgrEventSink_OnSetFocus((ITfThreadMgrEventSink*)&This->ThreadMgrEventSinkVtbl, 0, This->focus);
277 ITfDocumentMgr_Release(This->focus);
282 deactivate_textservices();
287 static HRESULT WINAPI ThreadMgr_CreateDocumentMgr( ITfThreadMgr* iface, ITfDocumentMgr
290 ThreadMgr *This = (ThreadMgr *)iface;
291 TRACE("(%p)\n",iface);
292 return DocumentMgr_Constructor((ITfThreadMgrEventSink*)&This->ThreadMgrEventSinkVtbl, ppdim);
295 static HRESULT WINAPI ThreadMgr_EnumDocumentMgrs( ITfThreadMgr* iface, IEnumTfDocumentMgrs
298 ThreadMgr *This = (ThreadMgr *)iface;
299 FIXME("STUB:(%p)\n",This);
303 static HRESULT WINAPI ThreadMgr_GetFocus( ITfThreadMgr* iface, ITfDocumentMgr
306 ThreadMgr *This = (ThreadMgr *)iface;
307 TRACE("(%p)\n",This);
312 *ppdimFocus = This->focus;
314 TRACE("->%p\n",This->focus);
316 if (This->focus == NULL)
319 ITfDocumentMgr_AddRef(This->focus);
324 static HRESULT WINAPI ThreadMgr_SetFocus( ITfThreadMgr* iface, ITfDocumentMgr *pdimFocus)
326 ITfDocumentMgr *check;
327 ThreadMgr *This = (ThreadMgr *)iface;
329 TRACE("(%p) %p\n",This,pdimFocus);
331 if (!pdimFocus || FAILED(IUnknown_QueryInterface(pdimFocus,&IID_ITfDocumentMgr,(LPVOID*) &check)))
334 ITfThreadMgrEventSink_OnSetFocus((ITfThreadMgrEventSink*)&This->ThreadMgrEventSinkVtbl, check, This->focus);
337 ITfDocumentMgr_Release(This->focus);
343 static HRESULT WINAPI ThreadMgr_AssociateFocus( ITfThreadMgr* iface, HWND hwnd,
344 ITfDocumentMgr *pdimNew, ITfDocumentMgr **ppdimPrev)
346 ThreadMgr *This = (ThreadMgr *)iface;
347 FIXME("STUB:(%p)\n",This);
351 static HRESULT WINAPI ThreadMgr_IsThreadFocus( ITfThreadMgr* iface, BOOL *pfThreadFocus)
353 ThreadMgr *This = (ThreadMgr *)iface;
354 FIXME("STUB:(%p)\n",This);
358 static HRESULT WINAPI ThreadMgr_GetFunctionProvider( ITfThreadMgr* iface, REFCLSID clsid,
359 ITfFunctionProvider **ppFuncProv)
361 ThreadMgr *This = (ThreadMgr *)iface;
362 FIXME("STUB:(%p)\n",This);
366 static HRESULT WINAPI ThreadMgr_EnumFunctionProviders( ITfThreadMgr* iface,
367 IEnumTfFunctionProviders **ppEnum)
369 ThreadMgr *This = (ThreadMgr *)iface;
370 FIXME("STUB:(%p)\n",This);
374 static HRESULT WINAPI ThreadMgr_GetGlobalCompartment( ITfThreadMgr* iface,
375 ITfCompartmentMgr **ppCompMgr)
377 ThreadMgr *This = (ThreadMgr *)iface;
378 FIXME("STUB:(%p)\n",This);
382 static const ITfThreadMgrVtbl ThreadMgr_ThreadMgrVtbl =
384 ThreadMgr_QueryInterface,
388 ThreadMgr_fnActivate,
389 ThreadMgr_fnDeactivate,
390 ThreadMgr_CreateDocumentMgr,
391 ThreadMgr_EnumDocumentMgrs,
394 ThreadMgr_AssociateFocus,
395 ThreadMgr_IsThreadFocus,
396 ThreadMgr_GetFunctionProvider,
397 ThreadMgr_EnumFunctionProviders,
398 ThreadMgr_GetGlobalCompartment
402 static HRESULT WINAPI Source_QueryInterface(ITfSource *iface, REFIID iid, LPVOID *ppvOut)
404 ThreadMgr *This = impl_from_ITfSourceVtbl(iface);
405 return ThreadMgr_QueryInterface((ITfThreadMgr *)This, iid, *ppvOut);
408 static ULONG WINAPI Source_AddRef(ITfSource *iface)
410 ThreadMgr *This = impl_from_ITfSourceVtbl(iface);
411 return ThreadMgr_AddRef((ITfThreadMgr*)This);
414 static ULONG WINAPI Source_Release(ITfSource *iface)
416 ThreadMgr *This = impl_from_ITfSourceVtbl(iface);
417 return ThreadMgr_Release((ITfThreadMgr *)This);
420 /*****************************************************
421 * ITfSource functions
422 *****************************************************/
423 static WINAPI HRESULT ThreadMgrSource_AdviseSink(ITfSource *iface,
424 REFIID riid, IUnknown *punk, DWORD *pdwCookie)
427 ThreadMgr *This = impl_from_ITfSourceVtbl(iface);
429 TRACE("(%p) %s %p %p\n",This,debugstr_guid(riid),punk,pdwCookie);
431 if (!riid || !punk || !pdwCookie)
434 if (IsEqualIID(riid, &IID_ITfThreadMgrEventSink))
436 tms = HeapAlloc(GetProcessHeap(),0,sizeof(ThreadMgrSink));
438 return E_OUTOFMEMORY;
439 if (!SUCCEEDED(IUnknown_QueryInterface(punk, riid, (LPVOID*)&tms->interfaces.pITfThreadMgrEventSink)))
441 HeapFree(GetProcessHeap(),0,tms);
442 return CONNECT_E_CANNOTCONNECT;
444 list_add_head(&This->ThreadMgrEventSink,&tms->entry);
445 *pdwCookie = generate_Cookie(COOKIE_MAGIC_TMSINK, tms);
449 FIXME("(%p) Unhandled Sink: %s\n",This,debugstr_guid(riid));
453 TRACE("cookie %x\n",*pdwCookie);
458 static WINAPI HRESULT ThreadMgrSource_UnadviseSink(ITfSource *iface, DWORD pdwCookie)
461 ThreadMgr *This = impl_from_ITfSourceVtbl(iface);
463 TRACE("(%p) %x\n",This,pdwCookie);
465 if (get_Cookie_magic(pdwCookie)!=COOKIE_MAGIC_TMSINK)
468 sink = (ThreadMgrSink*)remove_Cookie(pdwCookie);
470 return CONNECT_E_NOCONNECTION;
472 list_remove(&sink->entry);
478 static const ITfSourceVtbl ThreadMgr_SourceVtbl =
480 Source_QueryInterface,
484 ThreadMgrSource_AdviseSink,
485 ThreadMgrSource_UnadviseSink,
488 /*****************************************************
489 * ITfKeystrokeMgr functions
490 *****************************************************/
492 static HRESULT WINAPI KeystrokeMgr_QueryInterface(ITfKeystrokeMgr *iface, REFIID iid, LPVOID *ppvOut)
494 ThreadMgr *This = impl_from_ITfKeystrokeMgrVtbl(iface);
495 return ThreadMgr_QueryInterface((ITfThreadMgr *)This, iid, *ppvOut);
498 static ULONG WINAPI KeystrokeMgr_AddRef(ITfKeystrokeMgr *iface)
500 ThreadMgr *This = impl_from_ITfKeystrokeMgrVtbl(iface);
501 return ThreadMgr_AddRef((ITfThreadMgr*)This);
504 static ULONG WINAPI KeystrokeMgr_Release(ITfKeystrokeMgr *iface)
506 ThreadMgr *This = impl_from_ITfKeystrokeMgrVtbl(iface);
507 return ThreadMgr_Release((ITfThreadMgr *)This);
510 static HRESULT WINAPI KeystrokeMgr_AdviseKeyEventSink(ITfKeystrokeMgr *iface,
511 TfClientId tid, ITfKeyEventSink *pSink, BOOL fForeground)
513 ThreadMgr *This = impl_from_ITfKeystrokeMgrVtbl(iface);
515 ITfKeyEventSink *check = NULL;
517 TRACE("(%p) %x %p %i\n",This,tid,pSink,fForeground);
522 textservice = get_textservice_clsid(tid);
523 if (IsEqualCLSID(&GUID_NULL,&textservice))
526 get_textservice_sink(tid, &IID_ITfKeyEventSink, (IUnknown**)&check);
528 return CONNECT_E_ADVISELIMIT;
530 if (FAILED(IUnknown_QueryInterface(pSink,&IID_ITfKeyEventSink,(LPVOID*) &check)))
533 set_textservice_sink(tid, &IID_ITfKeyEventSink, (IUnknown*)check);
537 if (This->forgroundKeyEventSink)
538 ITfKeyEventSink_Release(This->forgroundKeyEventSink);
539 ITfKeyEventSink_AddRef(check);
540 This->forgroundKeyEventSink = check;
545 static HRESULT WINAPI KeystrokeMgr_UnadviseKeyEventSink(ITfKeystrokeMgr *iface,
548 ThreadMgr *This = impl_from_ITfKeystrokeMgrVtbl(iface);
550 ITfKeyEventSink *check = NULL;
551 TRACE("(%p) %x\n",This,tid);
556 textservice = get_textservice_clsid(tid);
557 if (IsEqualCLSID(&GUID_NULL,&textservice))
560 get_textservice_sink(tid, &IID_ITfKeyEventSink, (IUnknown**)&check);
563 return CONNECT_E_NOCONNECTION;
565 set_textservice_sink(tid, &IID_ITfKeyEventSink, NULL);
566 ITfKeyEventSink_Release(check);
568 if (This->forgroundKeyEventSink == check)
570 ITfKeyEventSink_Release(This->forgroundKeyEventSink);
571 This->forgroundKeyEventSink = NULL;
576 static HRESULT WINAPI KeystrokeMgr_GetForeground(ITfKeystrokeMgr *iface,
579 ThreadMgr *This = impl_from_ITfKeystrokeMgrVtbl(iface);
580 FIXME("STUB:(%p)\n",This);
584 static HRESULT WINAPI KeystrokeMgr_TestKeyDown(ITfKeystrokeMgr *iface,
585 WPARAM wParam, LPARAM lParam, BOOL *pfEaten)
587 ThreadMgr *This = impl_from_ITfKeystrokeMgrVtbl(iface);
588 FIXME("STUB:(%p)\n",This);
592 static HRESULT WINAPI KeystrokeMgr_TestKeyUp(ITfKeystrokeMgr *iface,
593 WPARAM wParam, LPARAM lParam, BOOL *pfEaten)
595 ThreadMgr *This = impl_from_ITfKeystrokeMgrVtbl(iface);
596 FIXME("STUB:(%p)\n",This);
600 static HRESULT WINAPI KeystrokeMgr_KeyDown(ITfKeystrokeMgr *iface,
601 WPARAM wParam, LPARAM lParam, BOOL *pfEaten)
603 ThreadMgr *This = impl_from_ITfKeystrokeMgrVtbl(iface);
604 FIXME("STUB:(%p)\n",This);
608 static HRESULT WINAPI KeystrokeMgr_KeyUp(ITfKeystrokeMgr *iface,
609 WPARAM wParam, LPARAM lParam, BOOL *pfEaten)
611 ThreadMgr *This = impl_from_ITfKeystrokeMgrVtbl(iface);
612 FIXME("STUB:(%p)\n",This);
616 static HRESULT WINAPI KeystrokeMgr_GetPreservedKey(ITfKeystrokeMgr *iface,
617 ITfContext *pic, const TF_PRESERVEDKEY *pprekey, GUID *pguid)
619 ThreadMgr *This = impl_from_ITfKeystrokeMgrVtbl(iface);
620 FIXME("STUB:(%p)\n",This);
624 static HRESULT WINAPI KeystrokeMgr_IsPreservedKey(ITfKeystrokeMgr *iface,
625 REFGUID rguid, const TF_PRESERVEDKEY *pprekey, BOOL *pfRegistered)
627 ThreadMgr *This = impl_from_ITfKeystrokeMgrVtbl(iface);
630 TRACE("(%p) %s (%x %x) %p\n",This,debugstr_guid(rguid), (pprekey)?pprekey->uVKey:0, (pprekey)?pprekey->uModifiers:0, pfRegistered);
632 if (!rguid || !pprekey || !pfRegistered)
635 LIST_FOR_EACH(cursor, &This->CurrentPreservedKeys)
637 PreservedKey* key = LIST_ENTRY(cursor,PreservedKey,entry);
638 if (IsEqualGUID(rguid,&key->guid) && pprekey->uVKey == key->prekey.uVKey && pprekey->uModifiers == key->prekey.uModifiers)
640 *pfRegistered = TRUE;
645 *pfRegistered = FALSE;
649 static HRESULT WINAPI KeystrokeMgr_PreserveKey(ITfKeystrokeMgr *iface,
650 TfClientId tid, REFGUID rguid, const TF_PRESERVEDKEY *prekey,
651 const WCHAR *pchDesc, ULONG cchDesc)
653 ThreadMgr *This = impl_from_ITfKeystrokeMgrVtbl(iface);
655 PreservedKey *newkey;
657 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));
659 if (!tid || ! rguid || !prekey || (cchDesc && !pchDesc))
662 LIST_FOR_EACH(cursor, &This->CurrentPreservedKeys)
664 PreservedKey* key = LIST_ENTRY(cursor,PreservedKey,entry);
665 if (IsEqualGUID(rguid,&key->guid) && prekey->uVKey == key->prekey.uVKey && prekey->uModifiers == key->prekey.uModifiers)
666 return TF_E_ALREADY_EXISTS;
669 newkey = HeapAlloc(GetProcessHeap(),0,sizeof(PreservedKey));
671 return E_OUTOFMEMORY;
673 newkey->guid = *rguid;
674 newkey->prekey = *prekey;
678 newkey->description = HeapAlloc(GetProcessHeap(),0,cchDesc * sizeof(WCHAR));
679 if (!newkey->description)
681 HeapFree(GetProcessHeap(),0,newkey);
682 return E_OUTOFMEMORY;
684 memcpy(newkey->description, pchDesc, cchDesc*sizeof(WCHAR));
687 list_add_head(&This->CurrentPreservedKeys,&newkey->entry);
692 static HRESULT WINAPI KeystrokeMgr_UnpreserveKey(ITfKeystrokeMgr *iface,
693 REFGUID rguid, const TF_PRESERVEDKEY *pprekey)
695 ThreadMgr *This = impl_from_ITfKeystrokeMgrVtbl(iface);
696 PreservedKey* key = NULL;
698 TRACE("(%p) %s (%x %x)\n",This,debugstr_guid(rguid),(pprekey)?pprekey->uVKey:0, (pprekey)?pprekey->uModifiers:0);
700 if (!pprekey || !rguid)
703 LIST_FOR_EACH(cursor, &This->CurrentPreservedKeys)
705 key = LIST_ENTRY(cursor,PreservedKey,entry);
706 if (IsEqualGUID(rguid,&key->guid) && pprekey->uVKey == key->prekey.uVKey && pprekey->uModifiers == key->prekey.uModifiers)
712 return CONNECT_E_NOCONNECTION;
714 list_remove(&key->entry);
715 HeapFree(GetProcessHeap(),0,key->description);
716 HeapFree(GetProcessHeap(),0,key);
721 static HRESULT WINAPI KeystrokeMgr_SetPreservedKeyDescription(ITfKeystrokeMgr *iface,
722 REFGUID rguid, const WCHAR *pchDesc, ULONG cchDesc)
724 ThreadMgr *This = impl_from_ITfKeystrokeMgrVtbl(iface);
725 FIXME("STUB:(%p)\n",This);
729 static HRESULT WINAPI KeystrokeMgr_GetPreservedKeyDescription(ITfKeystrokeMgr *iface,
730 REFGUID rguid, BSTR *pbstrDesc)
732 ThreadMgr *This = impl_from_ITfKeystrokeMgrVtbl(iface);
733 FIXME("STUB:(%p)\n",This);
737 static HRESULT WINAPI KeystrokeMgr_SimulatePreservedKey(ITfKeystrokeMgr *iface,
738 ITfContext *pic, REFGUID rguid, BOOL *pfEaten)
740 ThreadMgr *This = impl_from_ITfKeystrokeMgrVtbl(iface);
741 FIXME("STUB:(%p)\n",This);
745 static const ITfKeystrokeMgrVtbl ThreadMgr_KeystrokeMgrVtbl =
747 KeystrokeMgr_QueryInterface,
749 KeystrokeMgr_Release,
751 KeystrokeMgr_AdviseKeyEventSink,
752 KeystrokeMgr_UnadviseKeyEventSink,
753 KeystrokeMgr_GetForeground,
754 KeystrokeMgr_TestKeyDown,
755 KeystrokeMgr_TestKeyUp,
756 KeystrokeMgr_KeyDown,
758 KeystrokeMgr_GetPreservedKey,
759 KeystrokeMgr_IsPreservedKey,
760 KeystrokeMgr_PreserveKey,
761 KeystrokeMgr_UnpreserveKey,
762 KeystrokeMgr_SetPreservedKeyDescription,
763 KeystrokeMgr_GetPreservedKeyDescription,
764 KeystrokeMgr_SimulatePreservedKey
767 /*****************************************************
768 * ITfMessagePump functions
769 *****************************************************/
771 static HRESULT WINAPI MessagePump_QueryInterface(ITfMessagePump *iface, REFIID iid, LPVOID *ppvOut)
773 ThreadMgr *This = impl_from_ITfMessagePumpVtbl(iface);
774 return ThreadMgr_QueryInterface((ITfThreadMgr *)This, iid, *ppvOut);
777 static ULONG WINAPI MessagePump_AddRef(ITfMessagePump *iface)
779 ThreadMgr *This = impl_from_ITfMessagePumpVtbl(iface);
780 return ThreadMgr_AddRef((ITfThreadMgr*)This);
783 static ULONG WINAPI MessagePump_Release(ITfMessagePump *iface)
785 ThreadMgr *This = impl_from_ITfMessagePumpVtbl(iface);
786 return ThreadMgr_Release((ITfThreadMgr *)This);
789 static HRESULT WINAPI MessagePump_PeekMessageA(ITfMessagePump *iface,
790 LPMSG pMsg, HWND hwnd, UINT wMsgFilterMin, UINT wMsgFilterMax,
791 UINT wRemoveMsg, BOOL *pfResult)
795 *pfResult = PeekMessageA(pMsg, hwnd, wMsgFilterMin, wMsgFilterMax, wRemoveMsg);
799 static HRESULT WINAPI MessagePump_GetMessageA(ITfMessagePump *iface,
800 LPMSG pMsg, HWND hwnd, UINT wMsgFilterMin, UINT wMsgFilterMax,
805 *pfResult = GetMessageA(pMsg, hwnd, wMsgFilterMin, wMsgFilterMax);
809 static HRESULT WINAPI MessagePump_PeekMessageW(ITfMessagePump *iface,
810 LPMSG pMsg, HWND hwnd, UINT wMsgFilterMin, UINT wMsgFilterMax,
811 UINT wRemoveMsg, BOOL *pfResult)
815 *pfResult = PeekMessageW(pMsg, hwnd, wMsgFilterMin, wMsgFilterMax, wRemoveMsg);
819 static HRESULT WINAPI MessagePump_GetMessageW(ITfMessagePump *iface,
820 LPMSG pMsg, HWND hwnd, UINT wMsgFilterMin, UINT wMsgFilterMax,
825 *pfResult = GetMessageW(pMsg, hwnd, wMsgFilterMin, wMsgFilterMax);
829 static const ITfMessagePumpVtbl ThreadMgr_MessagePumpVtbl =
831 MessagePump_QueryInterface,
835 MessagePump_PeekMessageA,
836 MessagePump_GetMessageA,
837 MessagePump_PeekMessageW,
838 MessagePump_GetMessageW
841 /*****************************************************
842 * ITfClientId functions
843 *****************************************************/
845 static HRESULT WINAPI ClientId_QueryInterface(ITfClientId *iface, REFIID iid, LPVOID *ppvOut)
847 ThreadMgr *This = impl_from_ITfClientIdVtbl(iface);
848 return ThreadMgr_QueryInterface((ITfThreadMgr *)This, iid, *ppvOut);
851 static ULONG WINAPI ClientId_AddRef(ITfClientId *iface)
853 ThreadMgr *This = impl_from_ITfClientIdVtbl(iface);
854 return ThreadMgr_AddRef((ITfThreadMgr*)This);
857 static ULONG WINAPI ClientId_Release(ITfClientId *iface)
859 ThreadMgr *This = impl_from_ITfClientIdVtbl(iface);
860 return ThreadMgr_Release((ITfThreadMgr *)This);
863 static HRESULT WINAPI ClientId_GetClientId(ITfClientId *iface,
864 REFCLSID rclsid, TfClientId *ptid)
868 ITfCategoryMgr *catmgr;
869 ThreadMgr *This = impl_from_ITfClientIdVtbl(iface);
871 TRACE("(%p) %s\n",This,debugstr_guid(rclsid));
873 CategoryMgr_Constructor(NULL,(IUnknown**)&catmgr);
874 hr = ITfCategoryMgr_RegisterGUID(catmgr,rclsid,ptid);
875 ITfCategoryMgr_Release(catmgr);
880 static const ITfClientIdVtbl ThreadMgr_ClientIdVtbl =
882 ClientId_QueryInterface,
889 /*****************************************************
890 * ITfThreadMgrEventSink functions (internal)
891 *****************************************************/
892 static HRESULT WINAPI ThreadMgrEventSink_QueryInterface(ITfThreadMgrEventSink *iface, REFIID iid, LPVOID *ppvOut)
894 ThreadMgr *This = impl_from_ITfThreadMgrEventSink(iface);
895 return ThreadMgr_QueryInterface((ITfThreadMgr *)This, iid, *ppvOut);
898 static ULONG WINAPI ThreadMgrEventSink_AddRef(ITfThreadMgrEventSink *iface)
900 ThreadMgr *This = impl_from_ITfThreadMgrEventSink(iface);
901 return ThreadMgr_AddRef((ITfThreadMgr*)This);
904 static ULONG WINAPI ThreadMgrEventSink_Release(ITfThreadMgrEventSink *iface)
906 ThreadMgr *This = impl_from_ITfThreadMgrEventSink(iface);
907 return ThreadMgr_Release((ITfThreadMgr *)This);
911 static WINAPI HRESULT ThreadMgrEventSink_OnInitDocumentMgr(
912 ITfThreadMgrEventSink *iface,ITfDocumentMgr *pdim)
915 ThreadMgr *This = impl_from_ITfThreadMgrEventSink(iface);
917 TRACE("(%p) %p\n",This,pdim);
919 LIST_FOR_EACH(cursor, &This->ThreadMgrEventSink)
921 ThreadMgrSink* sink = LIST_ENTRY(cursor,ThreadMgrSink,entry);
922 ITfThreadMgrEventSink_OnInitDocumentMgr(sink->interfaces.pITfThreadMgrEventSink,pdim);
928 static WINAPI HRESULT ThreadMgrEventSink_OnUninitDocumentMgr(
929 ITfThreadMgrEventSink *iface, ITfDocumentMgr *pdim)
932 ThreadMgr *This = impl_from_ITfThreadMgrEventSink(iface);
934 TRACE("(%p) %p\n",This,pdim);
936 LIST_FOR_EACH(cursor, &This->ThreadMgrEventSink)
938 ThreadMgrSink* sink = LIST_ENTRY(cursor,ThreadMgrSink,entry);
939 ITfThreadMgrEventSink_OnUninitDocumentMgr(sink->interfaces.pITfThreadMgrEventSink,pdim);
945 static WINAPI HRESULT ThreadMgrEventSink_OnSetFocus(
946 ITfThreadMgrEventSink *iface, ITfDocumentMgr *pdimFocus,
947 ITfDocumentMgr *pdimPrevFocus)
950 ThreadMgr *This = impl_from_ITfThreadMgrEventSink(iface);
952 TRACE("(%p) %p %p\n",This,pdimFocus, pdimPrevFocus);
954 LIST_FOR_EACH(cursor, &This->ThreadMgrEventSink)
956 ThreadMgrSink* sink = LIST_ENTRY(cursor,ThreadMgrSink,entry);
957 ITfThreadMgrEventSink_OnSetFocus(sink->interfaces.pITfThreadMgrEventSink, pdimFocus, pdimPrevFocus);
963 static WINAPI HRESULT ThreadMgrEventSink_OnPushContext(
964 ITfThreadMgrEventSink *iface, ITfContext *pic)
967 ThreadMgr *This = impl_from_ITfThreadMgrEventSink(iface);
969 TRACE("(%p) %p\n",This,pic);
971 LIST_FOR_EACH(cursor, &This->ThreadMgrEventSink)
973 ThreadMgrSink* sink = LIST_ENTRY(cursor,ThreadMgrSink,entry);
974 ITfThreadMgrEventSink_OnPushContext(sink->interfaces.pITfThreadMgrEventSink,pic);
980 static WINAPI HRESULT ThreadMgrEventSink_OnPopContext(
981 ITfThreadMgrEventSink *iface, ITfContext *pic)
984 ThreadMgr *This = impl_from_ITfThreadMgrEventSink(iface);
986 TRACE("(%p) %p\n",This,pic);
988 LIST_FOR_EACH(cursor, &This->ThreadMgrEventSink)
990 ThreadMgrSink* sink = LIST_ENTRY(cursor,ThreadMgrSink,entry);
991 ITfThreadMgrEventSink_OnPopContext(sink->interfaces.pITfThreadMgrEventSink,pic);
997 static const ITfThreadMgrEventSinkVtbl ThreadMgr_ThreadMgrEventSinkVtbl =
999 ThreadMgrEventSink_QueryInterface,
1000 ThreadMgrEventSink_AddRef,
1001 ThreadMgrEventSink_Release,
1003 ThreadMgrEventSink_OnInitDocumentMgr,
1004 ThreadMgrEventSink_OnUninitDocumentMgr,
1005 ThreadMgrEventSink_OnSetFocus,
1006 ThreadMgrEventSink_OnPushContext,
1007 ThreadMgrEventSink_OnPopContext
1010 HRESULT ThreadMgr_Constructor(IUnknown *pUnkOuter, IUnknown **ppOut)
1014 return CLASS_E_NOAGGREGATION;
1016 /* Only 1 ThreadMgr is created per thread */
1017 This = TlsGetValue(tlsIndex);
1020 ThreadMgr_AddRef((ITfThreadMgr*)This);
1021 *ppOut = (IUnknown*)This;
1025 This = HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,sizeof(ThreadMgr));
1027 return E_OUTOFMEMORY;
1029 This->ThreadMgrVtbl= &ThreadMgr_ThreadMgrVtbl;
1030 This->SourceVtbl = &ThreadMgr_SourceVtbl;
1031 This->KeystrokeMgrVtbl= &ThreadMgr_KeystrokeMgrVtbl;
1032 This->MessagePumpVtbl= &ThreadMgr_MessagePumpVtbl;
1033 This->ClientIdVtbl = &ThreadMgr_ClientIdVtbl;
1034 This->ThreadMgrEventSinkVtbl = &ThreadMgr_ThreadMgrEventSinkVtbl;
1036 TlsSetValue(tlsIndex,This);
1038 list_init(&This->CurrentPreservedKeys);
1040 list_init(&This->ActiveLanguageProfileNotifySink);
1041 list_init(&This->DisplayAttributeNotifySink);
1042 list_init(&This->KeyTraceEventSink);
1043 list_init(&This->PreservedKeyNotifySink);
1044 list_init(&This->ThreadFocusSink);
1045 list_init(&This->ThreadMgrEventSink);
1047 TRACE("returning %p\n", This);
1048 *ppOut = (IUnknown *)This;