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);
552 TRACE("(%p) %s (%x %x) %p\n",This,debugstr_guid(rguid), (pprekey)?pprekey->uVKey:0, (pprekey)?pprekey->uModifiers:0, pfRegistered);
554 if (!rguid || !pprekey || !pfRegistered)
557 LIST_FOR_EACH(cursor, &This->CurrentPreservedKeys)
559 PreservedKey* key = LIST_ENTRY(cursor,PreservedKey,entry);
560 if (IsEqualGUID(rguid,&key->guid) && pprekey->uVKey == key->prekey.uVKey && pprekey->uModifiers == key->prekey.uModifiers)
562 *pfRegistered = TRUE;
567 *pfRegistered = FALSE;
571 static HRESULT WINAPI KeystrokeMgr_PreserveKey(ITfKeystrokeMgr *iface,
572 TfClientId tid, REFGUID rguid, const TF_PRESERVEDKEY *prekey,
573 const WCHAR *pchDesc, ULONG cchDesc)
575 ThreadMgr *This = impl_from_ITfKeystrokeMgrVtbl(iface);
577 PreservedKey *newkey;
579 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));
581 if (!tid || ! rguid || !prekey || (cchDesc && !pchDesc))
584 LIST_FOR_EACH(cursor, &This->CurrentPreservedKeys)
586 PreservedKey* key = LIST_ENTRY(cursor,PreservedKey,entry);
587 if (IsEqualGUID(rguid,&key->guid) && prekey->uVKey == key->prekey.uVKey && prekey->uModifiers == key->prekey.uModifiers)
588 return TF_E_ALREADY_EXISTS;
591 newkey = HeapAlloc(GetProcessHeap(),0,sizeof(PreservedKey));
593 return E_OUTOFMEMORY;
595 newkey->guid = *rguid;
596 newkey->prekey = *prekey;
600 newkey->description = HeapAlloc(GetProcessHeap(),0,cchDesc * sizeof(WCHAR));
601 if (!newkey->description)
603 HeapFree(GetProcessHeap(),0,newkey);
604 return E_OUTOFMEMORY;
606 memcpy(newkey->description, pchDesc, cchDesc*sizeof(WCHAR));
609 list_add_head(&This->CurrentPreservedKeys,&newkey->entry);
614 static HRESULT WINAPI KeystrokeMgr_UnpreserveKey(ITfKeystrokeMgr *iface,
615 REFGUID rguid, const TF_PRESERVEDKEY *pprekey)
617 ThreadMgr *This = impl_from_ITfKeystrokeMgrVtbl(iface);
618 PreservedKey* key = NULL;
620 TRACE("(%p) %s (%x %x)\n",This,debugstr_guid(rguid),(pprekey)?pprekey->uVKey:0, (pprekey)?pprekey->uModifiers:0);
622 if (!pprekey || !rguid)
625 LIST_FOR_EACH(cursor, &This->CurrentPreservedKeys)
627 key = LIST_ENTRY(cursor,PreservedKey,entry);
628 if (IsEqualGUID(rguid,&key->guid) && pprekey->uVKey == key->prekey.uVKey && pprekey->uModifiers == key->prekey.uModifiers)
634 return CONNECT_E_NOCONNECTION;
636 list_remove(&key->entry);
637 HeapFree(GetProcessHeap(),0,key->description);
638 HeapFree(GetProcessHeap(),0,key);
643 static HRESULT WINAPI KeystrokeMgr_SetPreservedKeyDescription(ITfKeystrokeMgr *iface,
644 REFGUID rguid, const WCHAR *pchDesc, ULONG cchDesc)
646 ThreadMgr *This = impl_from_ITfKeystrokeMgrVtbl(iface);
647 FIXME("STUB:(%p)\n",This);
651 static HRESULT WINAPI KeystrokeMgr_GetPreservedKeyDescription(ITfKeystrokeMgr *iface,
652 REFGUID rguid, BSTR *pbstrDesc)
654 ThreadMgr *This = impl_from_ITfKeystrokeMgrVtbl(iface);
655 FIXME("STUB:(%p)\n",This);
659 static HRESULT WINAPI KeystrokeMgr_SimulatePreservedKey(ITfKeystrokeMgr *iface,
660 ITfContext *pic, REFGUID rguid, BOOL *pfEaten)
662 ThreadMgr *This = impl_from_ITfKeystrokeMgrVtbl(iface);
663 FIXME("STUB:(%p)\n",This);
667 static const ITfKeystrokeMgrVtbl ThreadMgr_KeystrokeMgrVtbl =
669 KeystrokeMgr_QueryInterface,
671 KeystrokeMgr_Release,
673 KeystrokeMgr_AdviseKeyEventSink,
674 KeystrokeMgr_UnadviseKeyEventSink,
675 KeystrokeMgr_GetForeground,
676 KeystrokeMgr_TestKeyDown,
677 KeystrokeMgr_TestKeyUp,
678 KeystrokeMgr_KeyDown,
680 KeystrokeMgr_GetPreservedKey,
681 KeystrokeMgr_IsPreservedKey,
682 KeystrokeMgr_PreserveKey,
683 KeystrokeMgr_UnpreserveKey,
684 KeystrokeMgr_SetPreservedKeyDescription,
685 KeystrokeMgr_GetPreservedKeyDescription,
686 KeystrokeMgr_SimulatePreservedKey
689 /*****************************************************
690 * ITfMessagePump functions
691 *****************************************************/
693 static HRESULT WINAPI MessagePump_QueryInterface(ITfMessagePump *iface, REFIID iid, LPVOID *ppvOut)
695 ThreadMgr *This = impl_from_ITfMessagePumpVtbl(iface);
696 return ThreadMgr_QueryInterface((ITfThreadMgr *)This, iid, *ppvOut);
699 static ULONG WINAPI MessagePump_AddRef(ITfMessagePump *iface)
701 ThreadMgr *This = impl_from_ITfMessagePumpVtbl(iface);
702 return ThreadMgr_AddRef((ITfThreadMgr*)This);
705 static ULONG WINAPI MessagePump_Release(ITfMessagePump *iface)
707 ThreadMgr *This = impl_from_ITfMessagePumpVtbl(iface);
708 return ThreadMgr_Release((ITfThreadMgr *)This);
711 static HRESULT WINAPI MessagePump_PeekMessageA(ITfMessagePump *iface,
712 LPMSG pMsg, HWND hwnd, UINT wMsgFilterMin, UINT wMsgFilterMax,
713 UINT wRemoveMsg, BOOL *pfResult)
717 *pfResult = PeekMessageA(pMsg, hwnd, wMsgFilterMin, wMsgFilterMax, wRemoveMsg);
721 static HRESULT WINAPI MessagePump_GetMessageA(ITfMessagePump *iface,
722 LPMSG pMsg, HWND hwnd, UINT wMsgFilterMin, UINT wMsgFilterMax,
727 *pfResult = GetMessageA(pMsg, hwnd, wMsgFilterMin, wMsgFilterMax);
731 static HRESULT WINAPI MessagePump_PeekMessageW(ITfMessagePump *iface,
732 LPMSG pMsg, HWND hwnd, UINT wMsgFilterMin, UINT wMsgFilterMax,
733 UINT wRemoveMsg, BOOL *pfResult)
737 *pfResult = PeekMessageW(pMsg, hwnd, wMsgFilterMin, wMsgFilterMax, wRemoveMsg);
741 static HRESULT WINAPI MessagePump_GetMessageW(ITfMessagePump *iface,
742 LPMSG pMsg, HWND hwnd, UINT wMsgFilterMin, UINT wMsgFilterMax,
747 *pfResult = GetMessageW(pMsg, hwnd, wMsgFilterMin, wMsgFilterMax);
751 static const ITfMessagePumpVtbl ThreadMgr_MessagePumpVtbl =
753 MessagePump_QueryInterface,
757 MessagePump_PeekMessageA,
758 MessagePump_GetMessageA,
759 MessagePump_PeekMessageW,
760 MessagePump_GetMessageW
763 /*****************************************************
764 * ITfClientId functions
765 *****************************************************/
767 static HRESULT WINAPI ClientId_QueryInterface(ITfClientId *iface, REFIID iid, LPVOID *ppvOut)
769 ThreadMgr *This = impl_from_ITfClientIdVtbl(iface);
770 return ThreadMgr_QueryInterface((ITfThreadMgr *)This, iid, *ppvOut);
773 static ULONG WINAPI ClientId_AddRef(ITfClientId *iface)
775 ThreadMgr *This = impl_from_ITfClientIdVtbl(iface);
776 return ThreadMgr_AddRef((ITfThreadMgr*)This);
779 static ULONG WINAPI ClientId_Release(ITfClientId *iface)
781 ThreadMgr *This = impl_from_ITfClientIdVtbl(iface);
782 return ThreadMgr_Release((ITfThreadMgr *)This);
785 static HRESULT WINAPI ClientId_GetClientId(ITfClientId *iface,
786 REFCLSID rclsid, TfClientId *ptid)
790 ITfCategoryMgr *catmgr;
791 ThreadMgr *This = impl_from_ITfClientIdVtbl(iface);
793 TRACE("(%p) %s\n",This,debugstr_guid(rclsid));
795 CategoryMgr_Constructor(NULL,(IUnknown**)&catmgr);
796 hr = ITfCategoryMgr_RegisterGUID(catmgr,rclsid,ptid);
797 ITfCategoryMgr_Release(catmgr);
802 static const ITfClientIdVtbl ThreadMgr_ClientIdVtbl =
804 ClientId_QueryInterface,
811 /*****************************************************
812 * ITfThreadMgrEventSink functions (internal)
813 *****************************************************/
814 static HRESULT WINAPI ThreadMgrEventSink_QueryInterface(ITfThreadMgrEventSink *iface, REFIID iid, LPVOID *ppvOut)
816 ThreadMgr *This = impl_from_ITfThreadMgrEventSink(iface);
817 return ThreadMgr_QueryInterface((ITfThreadMgr *)This, iid, *ppvOut);
820 static ULONG WINAPI ThreadMgrEventSink_AddRef(ITfThreadMgrEventSink *iface)
822 ThreadMgr *This = impl_from_ITfThreadMgrEventSink(iface);
823 return ThreadMgr_AddRef((ITfThreadMgr*)This);
826 static ULONG WINAPI ThreadMgrEventSink_Release(ITfThreadMgrEventSink *iface)
828 ThreadMgr *This = impl_from_ITfThreadMgrEventSink(iface);
829 return ThreadMgr_Release((ITfThreadMgr *)This);
833 static WINAPI HRESULT ThreadMgrEventSink_OnInitDocumentMgr(
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_OnInitDocumentMgr(sink->interfaces.pITfThreadMgrEventSink,pdim);
850 static WINAPI HRESULT ThreadMgrEventSink_OnUninitDocumentMgr(
851 ITfThreadMgrEventSink *iface, ITfDocumentMgr *pdim)
854 ThreadMgr *This = impl_from_ITfThreadMgrEventSink(iface);
856 TRACE("(%p) %p\n",This,pdim);
858 LIST_FOR_EACH(cursor, &This->ThreadMgrEventSink)
860 ThreadMgrSink* sink = LIST_ENTRY(cursor,ThreadMgrSink,entry);
861 ITfThreadMgrEventSink_OnUninitDocumentMgr(sink->interfaces.pITfThreadMgrEventSink,pdim);
867 static WINAPI HRESULT ThreadMgrEventSink_OnSetFocus(
868 ITfThreadMgrEventSink *iface, ITfDocumentMgr *pdimFocus,
869 ITfDocumentMgr *pdimPrevFocus)
872 ThreadMgr *This = impl_from_ITfThreadMgrEventSink(iface);
874 TRACE("(%p) %p %p\n",This,pdimFocus, pdimPrevFocus);
876 LIST_FOR_EACH(cursor, &This->ThreadMgrEventSink)
878 ThreadMgrSink* sink = LIST_ENTRY(cursor,ThreadMgrSink,entry);
879 ITfThreadMgrEventSink_OnSetFocus(sink->interfaces.pITfThreadMgrEventSink, pdimFocus, pdimPrevFocus);
885 static WINAPI HRESULT ThreadMgrEventSink_OnPushContext(
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_OnPushContext(sink->interfaces.pITfThreadMgrEventSink,pic);
902 static WINAPI HRESULT ThreadMgrEventSink_OnPopContext(
903 ITfThreadMgrEventSink *iface, ITfContext *pic)
906 ThreadMgr *This = impl_from_ITfThreadMgrEventSink(iface);
908 TRACE("(%p) %p\n",This,pic);
910 LIST_FOR_EACH(cursor, &This->ThreadMgrEventSink)
912 ThreadMgrSink* sink = LIST_ENTRY(cursor,ThreadMgrSink,entry);
913 ITfThreadMgrEventSink_OnPopContext(sink->interfaces.pITfThreadMgrEventSink,pic);
919 static const ITfThreadMgrEventSinkVtbl ThreadMgr_ThreadMgrEventSinkVtbl =
921 ThreadMgrEventSink_QueryInterface,
922 ThreadMgrEventSink_AddRef,
923 ThreadMgrEventSink_Release,
925 ThreadMgrEventSink_OnInitDocumentMgr,
926 ThreadMgrEventSink_OnUninitDocumentMgr,
927 ThreadMgrEventSink_OnSetFocus,
928 ThreadMgrEventSink_OnPushContext,
929 ThreadMgrEventSink_OnPopContext
932 HRESULT ThreadMgr_Constructor(IUnknown *pUnkOuter, IUnknown **ppOut)
936 return CLASS_E_NOAGGREGATION;
938 /* Only 1 ThreadMgr is created per thread */
939 This = TlsGetValue(tlsIndex);
942 ThreadMgr_AddRef((ITfThreadMgr*)This);
943 *ppOut = (IUnknown*)This;
947 This = HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,sizeof(ThreadMgr));
949 return E_OUTOFMEMORY;
951 This->ThreadMgrVtbl= &ThreadMgr_ThreadMgrVtbl;
952 This->SourceVtbl = &ThreadMgr_SourceVtbl;
953 This->KeystrokeMgrVtbl= &ThreadMgr_KeystrokeMgrVtbl;
954 This->MessagePumpVtbl= &ThreadMgr_MessagePumpVtbl;
955 This->ClientIdVtbl = &ThreadMgr_ClientIdVtbl;
956 This->ThreadMgrEventSinkVtbl = &ThreadMgr_ThreadMgrEventSinkVtbl;
958 TlsSetValue(tlsIndex,This);
960 list_init(&This->CurrentPreservedKeys);
962 list_init(&This->ActiveLanguageProfileNotifySink);
963 list_init(&This->DisplayAttributeNotifySink);
964 list_init(&This->KeyTraceEventSink);
965 list_init(&This->PreservedKeyNotifySink);
966 list_init(&This->ThreadFocusSink);
967 list_init(&This->ThreadMgrEventSink);
969 TRACE("returning %p\n", This);
970 *ppOut = (IUnknown *)This;