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;
80 struct list CurrentPreservedKeys;
82 /* kept as separate lists to reduce unnecessary iterations */
83 struct list ActiveLanguageProfileNotifySink;
84 struct list DisplayAttributeNotifySink;
85 struct list KeyTraceEventSink;
86 struct list PreservedKeyNotifySink;
87 struct list ThreadFocusSink;
88 struct list ThreadMgrEventSink;
91 static inline ThreadMgr *impl_from_ITfSourceVtbl(ITfSource *iface)
93 return (ThreadMgr *)((char *)iface - FIELD_OFFSET(ThreadMgr,SourceVtbl));
96 static inline ThreadMgr *impl_from_ITfKeystrokeMgrVtbl(ITfKeystrokeMgr *iface)
98 return (ThreadMgr *)((char *)iface - FIELD_OFFSET(ThreadMgr,KeystrokeMgrVtbl));
101 static inline ThreadMgr *impl_from_ITfMessagePumpVtbl(ITfMessagePump *iface)
103 return (ThreadMgr *)((char *)iface - FIELD_OFFSET(ThreadMgr,MessagePumpVtbl));
106 static inline ThreadMgr *impl_from_ITfClientIdVtbl(ITfClientId *iface)
108 return (ThreadMgr *)((char *)iface - FIELD_OFFSET(ThreadMgr,ClientIdVtbl));
111 static inline ThreadMgr *impl_from_ITfThreadMgrEventSink(ITfThreadMgrEventSink *iface)
113 return (ThreadMgr *)((char *)iface - FIELD_OFFSET(ThreadMgr,ThreadMgrEventSinkVtbl));
116 static void free_sink(ThreadMgrSink *sink)
118 IUnknown_Release(sink->interfaces.pIUnknown);
119 HeapFree(GetProcessHeap(),0,sink);
122 static void ThreadMgr_Destructor(ThreadMgr *This)
124 struct list *cursor, *cursor2;
126 TlsSetValue(tlsIndex,NULL);
127 TRACE("destroying %p\n", This);
129 ITfDocumentMgr_Release(This->focus);
132 LIST_FOR_EACH_SAFE(cursor, cursor2, &This->ActiveLanguageProfileNotifySink)
134 ThreadMgrSink* sink = LIST_ENTRY(cursor,ThreadMgrSink,entry);
138 LIST_FOR_EACH_SAFE(cursor, cursor2, &This->DisplayAttributeNotifySink)
140 ThreadMgrSink* sink = LIST_ENTRY(cursor,ThreadMgrSink,entry);
144 LIST_FOR_EACH_SAFE(cursor, cursor2, &This->KeyTraceEventSink)
146 ThreadMgrSink* sink = LIST_ENTRY(cursor,ThreadMgrSink,entry);
150 LIST_FOR_EACH_SAFE(cursor, cursor2, &This->PreservedKeyNotifySink)
152 ThreadMgrSink* sink = LIST_ENTRY(cursor,ThreadMgrSink,entry);
156 LIST_FOR_EACH_SAFE(cursor, cursor2, &This->ThreadFocusSink)
158 ThreadMgrSink* sink = LIST_ENTRY(cursor,ThreadMgrSink,entry);
162 LIST_FOR_EACH_SAFE(cursor, cursor2, &This->ThreadMgrEventSink)
164 ThreadMgrSink* sink = LIST_ENTRY(cursor,ThreadMgrSink,entry);
169 LIST_FOR_EACH_SAFE(cursor, cursor2, &This->CurrentPreservedKeys)
171 PreservedKey* key = LIST_ENTRY(cursor,PreservedKey,entry);
173 HeapFree(GetProcessHeap(),0,key->description);
174 HeapFree(GetProcessHeap(),0,key);
177 HeapFree(GetProcessHeap(),0,This);
180 static HRESULT WINAPI ThreadMgr_QueryInterface(ITfThreadMgr *iface, REFIID iid, LPVOID *ppvOut)
182 ThreadMgr *This = (ThreadMgr *)iface;
185 if (IsEqualIID(iid, &IID_IUnknown) || IsEqualIID(iid, &IID_ITfThreadMgr))
189 else if (IsEqualIID(iid, &IID_ITfSource))
191 *ppvOut = &This->SourceVtbl;
193 else if (IsEqualIID(iid, &IID_ITfKeystrokeMgr))
195 *ppvOut = &This->KeystrokeMgrVtbl;
197 else if (IsEqualIID(iid, &IID_ITfMessagePump))
199 *ppvOut = &This->MessagePumpVtbl;
201 else if (IsEqualIID(iid, &IID_ITfClientId))
203 *ppvOut = &This->ClientIdVtbl;
208 IUnknown_AddRef(iface);
212 WARN("unsupported interface: %s\n", debugstr_guid(iid));
213 return E_NOINTERFACE;
216 static ULONG WINAPI ThreadMgr_AddRef(ITfThreadMgr *iface)
218 ThreadMgr *This = (ThreadMgr *)iface;
219 return InterlockedIncrement(&This->refCount);
222 static ULONG WINAPI ThreadMgr_Release(ITfThreadMgr *iface)
224 ThreadMgr *This = (ThreadMgr *)iface;
227 ret = InterlockedDecrement(&This->refCount);
229 ThreadMgr_Destructor(This);
233 /*****************************************************
234 * ITfThreadMgr functions
235 *****************************************************/
237 static HRESULT WINAPI ThreadMgr_fnActivate( ITfThreadMgr* iface, TfClientId *ptid)
239 ThreadMgr *This = (ThreadMgr *)iface;
240 FIXME("STUB:(%p)\n",This);
244 static HRESULT WINAPI ThreadMgr_fnDeactivate( ITfThreadMgr* iface)
246 ThreadMgr *This = (ThreadMgr *)iface;
247 FIXME("STUB:(%p)\n",This);
251 ITfThreadMgrEventSink_OnSetFocus((ITfThreadMgrEventSink*)&This->ThreadMgrEventSinkVtbl, 0, This->focus);
252 ITfDocumentMgr_Release(This->focus);
259 static HRESULT WINAPI ThreadMgr_CreateDocumentMgr( ITfThreadMgr* iface, ITfDocumentMgr
262 ThreadMgr *This = (ThreadMgr *)iface;
263 TRACE("(%p)\n",iface);
264 return DocumentMgr_Constructor((ITfThreadMgrEventSink*)&This->ThreadMgrEventSinkVtbl, ppdim);
267 static HRESULT WINAPI ThreadMgr_EnumDocumentMgrs( ITfThreadMgr* iface, IEnumTfDocumentMgrs
270 ThreadMgr *This = (ThreadMgr *)iface;
271 FIXME("STUB:(%p)\n",This);
275 static HRESULT WINAPI ThreadMgr_GetFocus( ITfThreadMgr* iface, ITfDocumentMgr
278 ThreadMgr *This = (ThreadMgr *)iface;
279 TRACE("(%p)\n",This);
284 *ppdimFocus = This->focus;
286 TRACE("->%p\n",This->focus);
288 if (This->focus == NULL)
291 ITfDocumentMgr_AddRef(This->focus);
296 static HRESULT WINAPI ThreadMgr_SetFocus( ITfThreadMgr* iface, ITfDocumentMgr *pdimFocus)
298 ITfDocumentMgr *check;
299 ThreadMgr *This = (ThreadMgr *)iface;
301 TRACE("(%p) %p\n",This,pdimFocus);
303 if (!pdimFocus || FAILED(IUnknown_QueryInterface(pdimFocus,&IID_ITfDocumentMgr,(LPVOID*) &check)))
306 ITfThreadMgrEventSink_OnSetFocus((ITfThreadMgrEventSink*)&This->ThreadMgrEventSinkVtbl, check, This->focus);
309 ITfDocumentMgr_Release(This->focus);
315 static HRESULT WINAPI ThreadMgr_AssociateFocus( ITfThreadMgr* iface, HWND hwnd,
316 ITfDocumentMgr *pdimNew, ITfDocumentMgr **ppdimPrev)
318 ThreadMgr *This = (ThreadMgr *)iface;
319 FIXME("STUB:(%p)\n",This);
323 static HRESULT WINAPI ThreadMgr_IsThreadFocus( ITfThreadMgr* iface, BOOL *pfThreadFocus)
325 ThreadMgr *This = (ThreadMgr *)iface;
326 FIXME("STUB:(%p)\n",This);
330 static HRESULT WINAPI ThreadMgr_GetFunctionProvider( ITfThreadMgr* iface, REFCLSID clsid,
331 ITfFunctionProvider **ppFuncProv)
333 ThreadMgr *This = (ThreadMgr *)iface;
334 FIXME("STUB:(%p)\n",This);
338 static HRESULT WINAPI ThreadMgr_EnumFunctionProviders( ITfThreadMgr* iface,
339 IEnumTfFunctionProviders **ppEnum)
341 ThreadMgr *This = (ThreadMgr *)iface;
342 FIXME("STUB:(%p)\n",This);
346 static HRESULT WINAPI ThreadMgr_GetGlobalCompartment( ITfThreadMgr* iface,
347 ITfCompartmentMgr **ppCompMgr)
349 ThreadMgr *This = (ThreadMgr *)iface;
350 FIXME("STUB:(%p)\n",This);
354 static const ITfThreadMgrVtbl ThreadMgr_ThreadMgrVtbl =
356 ThreadMgr_QueryInterface,
360 ThreadMgr_fnActivate,
361 ThreadMgr_fnDeactivate,
362 ThreadMgr_CreateDocumentMgr,
363 ThreadMgr_EnumDocumentMgrs,
366 ThreadMgr_AssociateFocus,
367 ThreadMgr_IsThreadFocus,
368 ThreadMgr_GetFunctionProvider,
369 ThreadMgr_EnumFunctionProviders,
370 ThreadMgr_GetGlobalCompartment
374 static HRESULT WINAPI Source_QueryInterface(ITfSource *iface, REFIID iid, LPVOID *ppvOut)
376 ThreadMgr *This = impl_from_ITfSourceVtbl(iface);
377 return ThreadMgr_QueryInterface((ITfThreadMgr *)This, iid, *ppvOut);
380 static ULONG WINAPI Source_AddRef(ITfSource *iface)
382 ThreadMgr *This = impl_from_ITfSourceVtbl(iface);
383 return ThreadMgr_AddRef((ITfThreadMgr*)This);
386 static ULONG WINAPI Source_Release(ITfSource *iface)
388 ThreadMgr *This = impl_from_ITfSourceVtbl(iface);
389 return ThreadMgr_Release((ITfThreadMgr *)This);
392 /*****************************************************
393 * ITfSource functions
394 *****************************************************/
395 static WINAPI HRESULT ThreadMgrSource_AdviseSink(ITfSource *iface,
396 REFIID riid, IUnknown *punk, DWORD *pdwCookie)
399 ThreadMgr *This = impl_from_ITfSourceVtbl(iface);
401 TRACE("(%p) %s %p %p\n",This,debugstr_guid(riid),punk,pdwCookie);
403 if (!riid || !punk || !pdwCookie)
406 if (IsEqualIID(riid, &IID_ITfThreadMgrEventSink))
408 tms = HeapAlloc(GetProcessHeap(),0,sizeof(ThreadMgrSink));
410 return E_OUTOFMEMORY;
411 if (!SUCCEEDED(IUnknown_QueryInterface(punk, riid, (LPVOID*)&tms->interfaces.pITfThreadMgrEventSink)))
413 HeapFree(GetProcessHeap(),0,tms);
414 return CONNECT_E_CANNOTCONNECT;
416 list_add_head(&This->ThreadMgrEventSink,&tms->entry);
417 *pdwCookie = generate_Cookie(COOKIE_MAGIC_TMSINK, tms);
421 FIXME("(%p) Unhandled Sink: %s\n",This,debugstr_guid(riid));
425 TRACE("cookie %x\n",*pdwCookie);
430 static WINAPI HRESULT ThreadMgrSource_UnadviseSink(ITfSource *iface, DWORD pdwCookie)
433 ThreadMgr *This = impl_from_ITfSourceVtbl(iface);
435 TRACE("(%p) %x\n",This,pdwCookie);
437 if (get_Cookie_magic(pdwCookie)!=COOKIE_MAGIC_TMSINK)
440 sink = (ThreadMgrSink*)remove_Cookie(pdwCookie);
442 return CONNECT_E_NOCONNECTION;
444 list_remove(&sink->entry);
450 static const ITfSourceVtbl ThreadMgr_SourceVtbl =
452 Source_QueryInterface,
456 ThreadMgrSource_AdviseSink,
457 ThreadMgrSource_UnadviseSink,
460 /*****************************************************
461 * ITfKeystrokeMgr functions
462 *****************************************************/
464 static HRESULT WINAPI KeystrokeMgr_QueryInterface(ITfKeystrokeMgr *iface, REFIID iid, LPVOID *ppvOut)
466 ThreadMgr *This = impl_from_ITfKeystrokeMgrVtbl(iface);
467 return ThreadMgr_QueryInterface((ITfThreadMgr *)This, iid, *ppvOut);
470 static ULONG WINAPI KeystrokeMgr_AddRef(ITfKeystrokeMgr *iface)
472 ThreadMgr *This = impl_from_ITfKeystrokeMgrVtbl(iface);
473 return ThreadMgr_AddRef((ITfThreadMgr*)This);
476 static ULONG WINAPI KeystrokeMgr_Release(ITfKeystrokeMgr *iface)
478 ThreadMgr *This = impl_from_ITfKeystrokeMgrVtbl(iface);
479 return ThreadMgr_Release((ITfThreadMgr *)This);
482 static HRESULT WINAPI KeystrokeMgr_AdviseKeyEventSink(ITfKeystrokeMgr *iface,
483 TfClientId tid, ITfKeyEventSink *pSink, BOOL fForeground)
485 ThreadMgr *This = impl_from_ITfKeystrokeMgrVtbl(iface);
486 FIXME("STUB:(%p)\n",This);
490 static HRESULT WINAPI KeystrokeMgr_UnadviseKeyEventSink(ITfKeystrokeMgr *iface,
493 ThreadMgr *This = impl_from_ITfKeystrokeMgrVtbl(iface);
494 FIXME("STUB:(%p)\n",This);
498 static HRESULT WINAPI KeystrokeMgr_GetForeground(ITfKeystrokeMgr *iface,
501 ThreadMgr *This = impl_from_ITfKeystrokeMgrVtbl(iface);
502 FIXME("STUB:(%p)\n",This);
506 static HRESULT WINAPI KeystrokeMgr_TestKeyDown(ITfKeystrokeMgr *iface,
507 WPARAM wParam, LPARAM lParam, BOOL *pfEaten)
509 ThreadMgr *This = impl_from_ITfKeystrokeMgrVtbl(iface);
510 FIXME("STUB:(%p)\n",This);
514 static HRESULT WINAPI KeystrokeMgr_TestKeyUp(ITfKeystrokeMgr *iface,
515 WPARAM wParam, LPARAM lParam, BOOL *pfEaten)
517 ThreadMgr *This = impl_from_ITfKeystrokeMgrVtbl(iface);
518 FIXME("STUB:(%p)\n",This);
522 static HRESULT WINAPI KeystrokeMgr_KeyDown(ITfKeystrokeMgr *iface,
523 WPARAM wParam, LPARAM lParam, BOOL *pfEaten)
525 ThreadMgr *This = impl_from_ITfKeystrokeMgrVtbl(iface);
526 FIXME("STUB:(%p)\n",This);
530 static HRESULT WINAPI KeystrokeMgr_KeyUp(ITfKeystrokeMgr *iface,
531 WPARAM wParam, LPARAM lParam, BOOL *pfEaten)
533 ThreadMgr *This = impl_from_ITfKeystrokeMgrVtbl(iface);
534 FIXME("STUB:(%p)\n",This);
538 static HRESULT WINAPI KeystrokeMgr_GetPreservedKey(ITfKeystrokeMgr *iface,
539 ITfContext *pic, const TF_PRESERVEDKEY *pprekey, GUID *pguid)
541 ThreadMgr *This = impl_from_ITfKeystrokeMgrVtbl(iface);
542 FIXME("STUB:(%p)\n",This);
546 static HRESULT WINAPI KeystrokeMgr_IsPreservedKey(ITfKeystrokeMgr *iface,
547 REFGUID rguid, const TF_PRESERVEDKEY *pprekey, BOOL *pfRegistered)
549 ThreadMgr *This = impl_from_ITfKeystrokeMgrVtbl(iface);
550 FIXME("STUB:(%p)\n",This);
554 static HRESULT WINAPI KeystrokeMgr_PreserveKey(ITfKeystrokeMgr *iface,
555 TfClientId tid, REFGUID rguid, const TF_PRESERVEDKEY *prekey,
556 const WCHAR *pchDesc, ULONG cchDesc)
558 ThreadMgr *This = impl_from_ITfKeystrokeMgrVtbl(iface);
560 PreservedKey *newkey;
562 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));
564 if (!tid || ! rguid || !prekey || (cchDesc && !pchDesc))
567 LIST_FOR_EACH(cursor, &This->CurrentPreservedKeys)
569 PreservedKey* key = LIST_ENTRY(cursor,PreservedKey,entry);
570 if (IsEqualGUID(rguid,&key->guid) && prekey->uVKey == key->prekey.uVKey && prekey->uModifiers == key->prekey.uModifiers)
571 return TF_E_ALREADY_EXISTS;
574 newkey = HeapAlloc(GetProcessHeap(),0,sizeof(PreservedKey));
576 return E_OUTOFMEMORY;
578 newkey->guid = *rguid;
579 newkey->prekey = *prekey;
583 newkey->description = HeapAlloc(GetProcessHeap(),0,cchDesc * sizeof(WCHAR));
584 if (!newkey->description)
586 HeapFree(GetProcessHeap(),0,newkey);
587 return E_OUTOFMEMORY;
589 memcpy(newkey->description, pchDesc, cchDesc*sizeof(WCHAR));
592 list_add_head(&This->CurrentPreservedKeys,&newkey->entry);
597 static HRESULT WINAPI KeystrokeMgr_UnpreserveKey(ITfKeystrokeMgr *iface,
598 REFGUID rguid, const TF_PRESERVEDKEY *pprekey)
600 ThreadMgr *This = impl_from_ITfKeystrokeMgrVtbl(iface);
601 PreservedKey* key = NULL;
603 TRACE("(%p) %s (%x %x)\n",This,debugstr_guid(rguid),(pprekey)?pprekey->uVKey:0, (pprekey)?pprekey->uModifiers:0);
605 if (!pprekey || !rguid)
608 LIST_FOR_EACH(cursor, &This->CurrentPreservedKeys)
610 key = LIST_ENTRY(cursor,PreservedKey,entry);
611 if (IsEqualGUID(rguid,&key->guid) && pprekey->uVKey == key->prekey.uVKey && pprekey->uModifiers == key->prekey.uModifiers)
617 return CONNECT_E_NOCONNECTION;
619 list_remove(&key->entry);
620 HeapFree(GetProcessHeap(),0,key->description);
621 HeapFree(GetProcessHeap(),0,key);
626 static HRESULT WINAPI KeystrokeMgr_SetPreservedKeyDescription(ITfKeystrokeMgr *iface,
627 REFGUID rguid, const WCHAR *pchDesc, ULONG cchDesc)
629 ThreadMgr *This = impl_from_ITfKeystrokeMgrVtbl(iface);
630 FIXME("STUB:(%p)\n",This);
634 static HRESULT WINAPI KeystrokeMgr_GetPreservedKeyDescription(ITfKeystrokeMgr *iface,
635 REFGUID rguid, BSTR *pbstrDesc)
637 ThreadMgr *This = impl_from_ITfKeystrokeMgrVtbl(iface);
638 FIXME("STUB:(%p)\n",This);
642 static HRESULT WINAPI KeystrokeMgr_SimulatePreservedKey(ITfKeystrokeMgr *iface,
643 ITfContext *pic, REFGUID rguid, BOOL *pfEaten)
645 ThreadMgr *This = impl_from_ITfKeystrokeMgrVtbl(iface);
646 FIXME("STUB:(%p)\n",This);
650 static const ITfKeystrokeMgrVtbl ThreadMgr_KeystrokeMgrVtbl =
652 KeystrokeMgr_QueryInterface,
654 KeystrokeMgr_Release,
656 KeystrokeMgr_AdviseKeyEventSink,
657 KeystrokeMgr_UnadviseKeyEventSink,
658 KeystrokeMgr_GetForeground,
659 KeystrokeMgr_TestKeyDown,
660 KeystrokeMgr_TestKeyUp,
661 KeystrokeMgr_KeyDown,
663 KeystrokeMgr_GetPreservedKey,
664 KeystrokeMgr_IsPreservedKey,
665 KeystrokeMgr_PreserveKey,
666 KeystrokeMgr_UnpreserveKey,
667 KeystrokeMgr_SetPreservedKeyDescription,
668 KeystrokeMgr_GetPreservedKeyDescription,
669 KeystrokeMgr_SimulatePreservedKey
672 /*****************************************************
673 * ITfMessagePump functions
674 *****************************************************/
676 static HRESULT WINAPI MessagePump_QueryInterface(ITfMessagePump *iface, REFIID iid, LPVOID *ppvOut)
678 ThreadMgr *This = impl_from_ITfMessagePumpVtbl(iface);
679 return ThreadMgr_QueryInterface((ITfThreadMgr *)This, iid, *ppvOut);
682 static ULONG WINAPI MessagePump_AddRef(ITfMessagePump *iface)
684 ThreadMgr *This = impl_from_ITfMessagePumpVtbl(iface);
685 return ThreadMgr_AddRef((ITfThreadMgr*)This);
688 static ULONG WINAPI MessagePump_Release(ITfMessagePump *iface)
690 ThreadMgr *This = impl_from_ITfMessagePumpVtbl(iface);
691 return ThreadMgr_Release((ITfThreadMgr *)This);
694 static HRESULT WINAPI MessagePump_PeekMessageA(ITfMessagePump *iface,
695 LPMSG pMsg, HWND hwnd, UINT wMsgFilterMin, UINT wMsgFilterMax,
696 UINT wRemoveMsg, BOOL *pfResult)
700 *pfResult = PeekMessageA(pMsg, hwnd, wMsgFilterMin, wMsgFilterMax, wRemoveMsg);
704 static HRESULT WINAPI MessagePump_GetMessageA(ITfMessagePump *iface,
705 LPMSG pMsg, HWND hwnd, UINT wMsgFilterMin, UINT wMsgFilterMax,
710 *pfResult = GetMessageA(pMsg, hwnd, wMsgFilterMin, wMsgFilterMax);
714 static HRESULT WINAPI MessagePump_PeekMessageW(ITfMessagePump *iface,
715 LPMSG pMsg, HWND hwnd, UINT wMsgFilterMin, UINT wMsgFilterMax,
716 UINT wRemoveMsg, BOOL *pfResult)
720 *pfResult = PeekMessageW(pMsg, hwnd, wMsgFilterMin, wMsgFilterMax, wRemoveMsg);
724 static HRESULT WINAPI MessagePump_GetMessageW(ITfMessagePump *iface,
725 LPMSG pMsg, HWND hwnd, UINT wMsgFilterMin, UINT wMsgFilterMax,
730 *pfResult = GetMessageW(pMsg, hwnd, wMsgFilterMin, wMsgFilterMax);
734 static const ITfMessagePumpVtbl ThreadMgr_MessagePumpVtbl =
736 MessagePump_QueryInterface,
740 MessagePump_PeekMessageA,
741 MessagePump_GetMessageA,
742 MessagePump_PeekMessageW,
743 MessagePump_GetMessageW
746 /*****************************************************
747 * ITfClientId functions
748 *****************************************************/
750 static HRESULT WINAPI ClientId_QueryInterface(ITfClientId *iface, REFIID iid, LPVOID *ppvOut)
752 ThreadMgr *This = impl_from_ITfClientIdVtbl(iface);
753 return ThreadMgr_QueryInterface((ITfThreadMgr *)This, iid, *ppvOut);
756 static ULONG WINAPI ClientId_AddRef(ITfClientId *iface)
758 ThreadMgr *This = impl_from_ITfClientIdVtbl(iface);
759 return ThreadMgr_AddRef((ITfThreadMgr*)This);
762 static ULONG WINAPI ClientId_Release(ITfClientId *iface)
764 ThreadMgr *This = impl_from_ITfClientIdVtbl(iface);
765 return ThreadMgr_Release((ITfThreadMgr *)This);
768 static HRESULT WINAPI ClientId_GetClientId(ITfClientId *iface,
769 REFCLSID rclsid, TfClientId *ptid)
773 ITfCategoryMgr *catmgr;
774 ThreadMgr *This = impl_from_ITfClientIdVtbl(iface);
776 TRACE("(%p) %s\n",This,debugstr_guid(rclsid));
778 CategoryMgr_Constructor(NULL,(IUnknown**)&catmgr);
779 hr = ITfCategoryMgr_RegisterGUID(catmgr,rclsid,ptid);
780 ITfCategoryMgr_Release(catmgr);
785 static const ITfClientIdVtbl ThreadMgr_ClientIdVtbl =
787 ClientId_QueryInterface,
794 /*****************************************************
795 * ITfThreadMgrEventSink functions (internal)
796 *****************************************************/
797 static HRESULT WINAPI ThreadMgrEventSink_QueryInterface(ITfThreadMgrEventSink *iface, REFIID iid, LPVOID *ppvOut)
799 ThreadMgr *This = impl_from_ITfThreadMgrEventSink(iface);
800 return ThreadMgr_QueryInterface((ITfThreadMgr *)This, iid, *ppvOut);
803 static ULONG WINAPI ThreadMgrEventSink_AddRef(ITfThreadMgrEventSink *iface)
805 ThreadMgr *This = impl_from_ITfThreadMgrEventSink(iface);
806 return ThreadMgr_AddRef((ITfThreadMgr*)This);
809 static ULONG WINAPI ThreadMgrEventSink_Release(ITfThreadMgrEventSink *iface)
811 ThreadMgr *This = impl_from_ITfThreadMgrEventSink(iface);
812 return ThreadMgr_Release((ITfThreadMgr *)This);
816 static WINAPI HRESULT ThreadMgrEventSink_OnInitDocumentMgr(
817 ITfThreadMgrEventSink *iface,ITfDocumentMgr *pdim)
820 ThreadMgr *This = impl_from_ITfThreadMgrEventSink(iface);
822 TRACE("(%p) %p\n",This,pdim);
824 LIST_FOR_EACH(cursor, &This->ThreadMgrEventSink)
826 ThreadMgrSink* sink = LIST_ENTRY(cursor,ThreadMgrSink,entry);
827 ITfThreadMgrEventSink_OnInitDocumentMgr(sink->interfaces.pITfThreadMgrEventSink,pdim);
833 static WINAPI HRESULT ThreadMgrEventSink_OnUninitDocumentMgr(
834 ITfThreadMgrEventSink *iface, ITfDocumentMgr *pdim)
837 ThreadMgr *This = impl_from_ITfThreadMgrEventSink(iface);
839 TRACE("(%p) %p\n",This,pdim);
841 LIST_FOR_EACH(cursor, &This->ThreadMgrEventSink)
843 ThreadMgrSink* sink = LIST_ENTRY(cursor,ThreadMgrSink,entry);
844 ITfThreadMgrEventSink_OnUninitDocumentMgr(sink->interfaces.pITfThreadMgrEventSink,pdim);
850 static WINAPI HRESULT ThreadMgrEventSink_OnSetFocus(
851 ITfThreadMgrEventSink *iface, ITfDocumentMgr *pdimFocus,
852 ITfDocumentMgr *pdimPrevFocus)
855 ThreadMgr *This = impl_from_ITfThreadMgrEventSink(iface);
857 TRACE("(%p) %p %p\n",This,pdimFocus, pdimPrevFocus);
859 LIST_FOR_EACH(cursor, &This->ThreadMgrEventSink)
861 ThreadMgrSink* sink = LIST_ENTRY(cursor,ThreadMgrSink,entry);
862 ITfThreadMgrEventSink_OnSetFocus(sink->interfaces.pITfThreadMgrEventSink, pdimFocus, pdimPrevFocus);
868 static WINAPI HRESULT ThreadMgrEventSink_OnPushContext(
869 ITfThreadMgrEventSink *iface, ITfContext *pic)
872 ThreadMgr *This = impl_from_ITfThreadMgrEventSink(iface);
874 TRACE("(%p) %p\n",This,pic);
876 LIST_FOR_EACH(cursor, &This->ThreadMgrEventSink)
878 ThreadMgrSink* sink = LIST_ENTRY(cursor,ThreadMgrSink,entry);
879 ITfThreadMgrEventSink_OnPushContext(sink->interfaces.pITfThreadMgrEventSink,pic);
885 static WINAPI HRESULT ThreadMgrEventSink_OnPopContext(
886 ITfThreadMgrEventSink *iface, ITfContext *pic)
889 ThreadMgr *This = impl_from_ITfThreadMgrEventSink(iface);
891 TRACE("(%p) %p\n",This,pic);
893 LIST_FOR_EACH(cursor, &This->ThreadMgrEventSink)
895 ThreadMgrSink* sink = LIST_ENTRY(cursor,ThreadMgrSink,entry);
896 ITfThreadMgrEventSink_OnPopContext(sink->interfaces.pITfThreadMgrEventSink,pic);
902 static const ITfThreadMgrEventSinkVtbl ThreadMgr_ThreadMgrEventSinkVtbl =
904 ThreadMgrEventSink_QueryInterface,
905 ThreadMgrEventSink_AddRef,
906 ThreadMgrEventSink_Release,
908 ThreadMgrEventSink_OnInitDocumentMgr,
909 ThreadMgrEventSink_OnUninitDocumentMgr,
910 ThreadMgrEventSink_OnSetFocus,
911 ThreadMgrEventSink_OnPushContext,
912 ThreadMgrEventSink_OnPopContext
915 HRESULT ThreadMgr_Constructor(IUnknown *pUnkOuter, IUnknown **ppOut)
919 return CLASS_E_NOAGGREGATION;
921 /* Only 1 ThreadMgr is created per thread */
922 This = TlsGetValue(tlsIndex);
925 ThreadMgr_AddRef((ITfThreadMgr*)This);
926 *ppOut = (IUnknown*)This;
930 This = HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,sizeof(ThreadMgr));
932 return E_OUTOFMEMORY;
934 This->ThreadMgrVtbl= &ThreadMgr_ThreadMgrVtbl;
935 This->SourceVtbl = &ThreadMgr_SourceVtbl;
936 This->KeystrokeMgrVtbl= &ThreadMgr_KeystrokeMgrVtbl;
937 This->MessagePumpVtbl= &ThreadMgr_MessagePumpVtbl;
938 This->ClientIdVtbl = &ThreadMgr_ClientIdVtbl;
939 This->ThreadMgrEventSinkVtbl = &ThreadMgr_ThreadMgrEventSinkVtbl;
941 TlsSetValue(tlsIndex,This);
943 list_init(&This->CurrentPreservedKeys);
945 list_init(&This->ActiveLanguageProfileNotifySink);
946 list_init(&This->DisplayAttributeNotifySink);
947 list_init(&This->KeyTraceEventSink);
948 list_init(&This->PreservedKeyNotifySink);
949 list_init(&This->ThreadFocusSink);
950 list_init(&This->ThreadMgrEventSink);
952 TRACE("returning %p\n", This);
953 *ppOut = (IUnknown *)This;