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 struct list CurrentPreservedKeys;
83 /* kept as separate lists to reduce unnecessary iterations */
84 struct list ActiveLanguageProfileNotifySink;
85 struct list DisplayAttributeNotifySink;
86 struct list KeyTraceEventSink;
87 struct list PreservedKeyNotifySink;
88 struct list ThreadFocusSink;
89 struct list ThreadMgrEventSink;
92 static inline ThreadMgr *impl_from_ITfSourceVtbl(ITfSource *iface)
94 return (ThreadMgr *)((char *)iface - FIELD_OFFSET(ThreadMgr,SourceVtbl));
97 static inline ThreadMgr *impl_from_ITfKeystrokeMgrVtbl(ITfKeystrokeMgr *iface)
99 return (ThreadMgr *)((char *)iface - FIELD_OFFSET(ThreadMgr,KeystrokeMgrVtbl));
102 static inline ThreadMgr *impl_from_ITfMessagePumpVtbl(ITfMessagePump *iface)
104 return (ThreadMgr *)((char *)iface - FIELD_OFFSET(ThreadMgr,MessagePumpVtbl));
107 static inline ThreadMgr *impl_from_ITfClientIdVtbl(ITfClientId *iface)
109 return (ThreadMgr *)((char *)iface - FIELD_OFFSET(ThreadMgr,ClientIdVtbl));
112 static inline ThreadMgr *impl_from_ITfThreadMgrEventSink(ITfThreadMgrEventSink *iface)
114 return (ThreadMgr *)((char *)iface - FIELD_OFFSET(ThreadMgr,ThreadMgrEventSinkVtbl));
117 static void free_sink(ThreadMgrSink *sink)
119 IUnknown_Release(sink->interfaces.pIUnknown);
120 HeapFree(GetProcessHeap(),0,sink);
123 static void ThreadMgr_Destructor(ThreadMgr *This)
125 struct list *cursor, *cursor2;
127 TlsSetValue(tlsIndex,NULL);
128 TRACE("destroying %p\n", This);
130 ITfDocumentMgr_Release(This->focus);
133 LIST_FOR_EACH_SAFE(cursor, cursor2, &This->ActiveLanguageProfileNotifySink)
135 ThreadMgrSink* sink = LIST_ENTRY(cursor,ThreadMgrSink,entry);
139 LIST_FOR_EACH_SAFE(cursor, cursor2, &This->DisplayAttributeNotifySink)
141 ThreadMgrSink* sink = LIST_ENTRY(cursor,ThreadMgrSink,entry);
145 LIST_FOR_EACH_SAFE(cursor, cursor2, &This->KeyTraceEventSink)
147 ThreadMgrSink* sink = LIST_ENTRY(cursor,ThreadMgrSink,entry);
151 LIST_FOR_EACH_SAFE(cursor, cursor2, &This->PreservedKeyNotifySink)
153 ThreadMgrSink* sink = LIST_ENTRY(cursor,ThreadMgrSink,entry);
157 LIST_FOR_EACH_SAFE(cursor, cursor2, &This->ThreadFocusSink)
159 ThreadMgrSink* sink = LIST_ENTRY(cursor,ThreadMgrSink,entry);
163 LIST_FOR_EACH_SAFE(cursor, cursor2, &This->ThreadMgrEventSink)
165 ThreadMgrSink* sink = LIST_ENTRY(cursor,ThreadMgrSink,entry);
170 LIST_FOR_EACH_SAFE(cursor, cursor2, &This->CurrentPreservedKeys)
172 PreservedKey* key = LIST_ENTRY(cursor,PreservedKey,entry);
174 HeapFree(GetProcessHeap(),0,key->description);
175 HeapFree(GetProcessHeap(),0,key);
178 HeapFree(GetProcessHeap(),0,This);
181 static HRESULT WINAPI ThreadMgr_QueryInterface(ITfThreadMgr *iface, REFIID iid, LPVOID *ppvOut)
183 ThreadMgr *This = (ThreadMgr *)iface;
186 if (IsEqualIID(iid, &IID_IUnknown) || IsEqualIID(iid, &IID_ITfThreadMgr))
190 else if (IsEqualIID(iid, &IID_ITfSource))
192 *ppvOut = &This->SourceVtbl;
194 else if (IsEqualIID(iid, &IID_ITfKeystrokeMgr))
196 *ppvOut = &This->KeystrokeMgrVtbl;
198 else if (IsEqualIID(iid, &IID_ITfMessagePump))
200 *ppvOut = &This->MessagePumpVtbl;
202 else if (IsEqualIID(iid, &IID_ITfClientId))
204 *ppvOut = &This->ClientIdVtbl;
209 IUnknown_AddRef(iface);
213 WARN("unsupported interface: %s\n", debugstr_guid(iid));
214 return E_NOINTERFACE;
217 static ULONG WINAPI ThreadMgr_AddRef(ITfThreadMgr *iface)
219 ThreadMgr *This = (ThreadMgr *)iface;
220 return InterlockedIncrement(&This->refCount);
223 static ULONG WINAPI ThreadMgr_Release(ITfThreadMgr *iface)
225 ThreadMgr *This = (ThreadMgr *)iface;
228 ret = InterlockedDecrement(&This->refCount);
230 ThreadMgr_Destructor(This);
234 /*****************************************************
235 * ITfThreadMgr functions
236 *****************************************************/
238 static HRESULT WINAPI ThreadMgr_fnActivate( ITfThreadMgr* iface, TfClientId *ptid)
240 ThreadMgr *This = (ThreadMgr *)iface;
242 TRACE("(%p) %p\n",This, ptid);
251 ITfClientId_GetClientId((ITfClientId*)&This->ClientIdVtbl,&guid,&processId);
254 activate_textservices(iface);
255 This->activationCount++;
260 static HRESULT WINAPI ThreadMgr_fnDeactivate( ITfThreadMgr* iface)
262 ThreadMgr *This = (ThreadMgr *)iface;
263 TRACE("(%p)\n",This);
265 if (This->activationCount == 0)
268 This->activationCount --;
270 if (This->activationCount == 0)
274 ITfThreadMgrEventSink_OnSetFocus((ITfThreadMgrEventSink*)&This->ThreadMgrEventSinkVtbl, 0, This->focus);
275 ITfDocumentMgr_Release(This->focus);
280 deactivate_textservices();
285 static HRESULT WINAPI ThreadMgr_CreateDocumentMgr( ITfThreadMgr* iface, ITfDocumentMgr
288 ThreadMgr *This = (ThreadMgr *)iface;
289 TRACE("(%p)\n",iface);
290 return DocumentMgr_Constructor((ITfThreadMgrEventSink*)&This->ThreadMgrEventSinkVtbl, ppdim);
293 static HRESULT WINAPI ThreadMgr_EnumDocumentMgrs( ITfThreadMgr* iface, IEnumTfDocumentMgrs
296 ThreadMgr *This = (ThreadMgr *)iface;
297 FIXME("STUB:(%p)\n",This);
301 static HRESULT WINAPI ThreadMgr_GetFocus( ITfThreadMgr* iface, ITfDocumentMgr
304 ThreadMgr *This = (ThreadMgr *)iface;
305 TRACE("(%p)\n",This);
310 *ppdimFocus = This->focus;
312 TRACE("->%p\n",This->focus);
314 if (This->focus == NULL)
317 ITfDocumentMgr_AddRef(This->focus);
322 static HRESULT WINAPI ThreadMgr_SetFocus( ITfThreadMgr* iface, ITfDocumentMgr *pdimFocus)
324 ITfDocumentMgr *check;
325 ThreadMgr *This = (ThreadMgr *)iface;
327 TRACE("(%p) %p\n",This,pdimFocus);
329 if (!pdimFocus || FAILED(IUnknown_QueryInterface(pdimFocus,&IID_ITfDocumentMgr,(LPVOID*) &check)))
332 ITfThreadMgrEventSink_OnSetFocus((ITfThreadMgrEventSink*)&This->ThreadMgrEventSinkVtbl, check, This->focus);
335 ITfDocumentMgr_Release(This->focus);
341 static HRESULT WINAPI ThreadMgr_AssociateFocus( ITfThreadMgr* iface, HWND hwnd,
342 ITfDocumentMgr *pdimNew, ITfDocumentMgr **ppdimPrev)
344 ThreadMgr *This = (ThreadMgr *)iface;
345 FIXME("STUB:(%p)\n",This);
349 static HRESULT WINAPI ThreadMgr_IsThreadFocus( ITfThreadMgr* iface, BOOL *pfThreadFocus)
351 ThreadMgr *This = (ThreadMgr *)iface;
352 FIXME("STUB:(%p)\n",This);
356 static HRESULT WINAPI ThreadMgr_GetFunctionProvider( ITfThreadMgr* iface, REFCLSID clsid,
357 ITfFunctionProvider **ppFuncProv)
359 ThreadMgr *This = (ThreadMgr *)iface;
360 FIXME("STUB:(%p)\n",This);
364 static HRESULT WINAPI ThreadMgr_EnumFunctionProviders( ITfThreadMgr* iface,
365 IEnumTfFunctionProviders **ppEnum)
367 ThreadMgr *This = (ThreadMgr *)iface;
368 FIXME("STUB:(%p)\n",This);
372 static HRESULT WINAPI ThreadMgr_GetGlobalCompartment( ITfThreadMgr* iface,
373 ITfCompartmentMgr **ppCompMgr)
375 ThreadMgr *This = (ThreadMgr *)iface;
376 FIXME("STUB:(%p)\n",This);
380 static const ITfThreadMgrVtbl ThreadMgr_ThreadMgrVtbl =
382 ThreadMgr_QueryInterface,
386 ThreadMgr_fnActivate,
387 ThreadMgr_fnDeactivate,
388 ThreadMgr_CreateDocumentMgr,
389 ThreadMgr_EnumDocumentMgrs,
392 ThreadMgr_AssociateFocus,
393 ThreadMgr_IsThreadFocus,
394 ThreadMgr_GetFunctionProvider,
395 ThreadMgr_EnumFunctionProviders,
396 ThreadMgr_GetGlobalCompartment
400 static HRESULT WINAPI Source_QueryInterface(ITfSource *iface, REFIID iid, LPVOID *ppvOut)
402 ThreadMgr *This = impl_from_ITfSourceVtbl(iface);
403 return ThreadMgr_QueryInterface((ITfThreadMgr *)This, iid, *ppvOut);
406 static ULONG WINAPI Source_AddRef(ITfSource *iface)
408 ThreadMgr *This = impl_from_ITfSourceVtbl(iface);
409 return ThreadMgr_AddRef((ITfThreadMgr*)This);
412 static ULONG WINAPI Source_Release(ITfSource *iface)
414 ThreadMgr *This = impl_from_ITfSourceVtbl(iface);
415 return ThreadMgr_Release((ITfThreadMgr *)This);
418 /*****************************************************
419 * ITfSource functions
420 *****************************************************/
421 static WINAPI HRESULT ThreadMgrSource_AdviseSink(ITfSource *iface,
422 REFIID riid, IUnknown *punk, DWORD *pdwCookie)
425 ThreadMgr *This = impl_from_ITfSourceVtbl(iface);
427 TRACE("(%p) %s %p %p\n",This,debugstr_guid(riid),punk,pdwCookie);
429 if (!riid || !punk || !pdwCookie)
432 if (IsEqualIID(riid, &IID_ITfThreadMgrEventSink))
434 tms = HeapAlloc(GetProcessHeap(),0,sizeof(ThreadMgrSink));
436 return E_OUTOFMEMORY;
437 if (!SUCCEEDED(IUnknown_QueryInterface(punk, riid, (LPVOID*)&tms->interfaces.pITfThreadMgrEventSink)))
439 HeapFree(GetProcessHeap(),0,tms);
440 return CONNECT_E_CANNOTCONNECT;
442 list_add_head(&This->ThreadMgrEventSink,&tms->entry);
443 *pdwCookie = generate_Cookie(COOKIE_MAGIC_TMSINK, tms);
447 FIXME("(%p) Unhandled Sink: %s\n",This,debugstr_guid(riid));
451 TRACE("cookie %x\n",*pdwCookie);
456 static WINAPI HRESULT ThreadMgrSource_UnadviseSink(ITfSource *iface, DWORD pdwCookie)
459 ThreadMgr *This = impl_from_ITfSourceVtbl(iface);
461 TRACE("(%p) %x\n",This,pdwCookie);
463 if (get_Cookie_magic(pdwCookie)!=COOKIE_MAGIC_TMSINK)
466 sink = (ThreadMgrSink*)remove_Cookie(pdwCookie);
468 return CONNECT_E_NOCONNECTION;
470 list_remove(&sink->entry);
476 static const ITfSourceVtbl ThreadMgr_SourceVtbl =
478 Source_QueryInterface,
482 ThreadMgrSource_AdviseSink,
483 ThreadMgrSource_UnadviseSink,
486 /*****************************************************
487 * ITfKeystrokeMgr functions
488 *****************************************************/
490 static HRESULT WINAPI KeystrokeMgr_QueryInterface(ITfKeystrokeMgr *iface, REFIID iid, LPVOID *ppvOut)
492 ThreadMgr *This = impl_from_ITfKeystrokeMgrVtbl(iface);
493 return ThreadMgr_QueryInterface((ITfThreadMgr *)This, iid, *ppvOut);
496 static ULONG WINAPI KeystrokeMgr_AddRef(ITfKeystrokeMgr *iface)
498 ThreadMgr *This = impl_from_ITfKeystrokeMgrVtbl(iface);
499 return ThreadMgr_AddRef((ITfThreadMgr*)This);
502 static ULONG WINAPI KeystrokeMgr_Release(ITfKeystrokeMgr *iface)
504 ThreadMgr *This = impl_from_ITfKeystrokeMgrVtbl(iface);
505 return ThreadMgr_Release((ITfThreadMgr *)This);
508 static HRESULT WINAPI KeystrokeMgr_AdviseKeyEventSink(ITfKeystrokeMgr *iface,
509 TfClientId tid, ITfKeyEventSink *pSink, BOOL fForeground)
511 ThreadMgr *This = impl_from_ITfKeystrokeMgrVtbl(iface);
512 FIXME("STUB:(%p)\n",This);
516 static HRESULT WINAPI KeystrokeMgr_UnadviseKeyEventSink(ITfKeystrokeMgr *iface,
519 ThreadMgr *This = impl_from_ITfKeystrokeMgrVtbl(iface);
520 FIXME("STUB:(%p)\n",This);
524 static HRESULT WINAPI KeystrokeMgr_GetForeground(ITfKeystrokeMgr *iface,
527 ThreadMgr *This = impl_from_ITfKeystrokeMgrVtbl(iface);
528 FIXME("STUB:(%p)\n",This);
532 static HRESULT WINAPI KeystrokeMgr_TestKeyDown(ITfKeystrokeMgr *iface,
533 WPARAM wParam, LPARAM lParam, BOOL *pfEaten)
535 ThreadMgr *This = impl_from_ITfKeystrokeMgrVtbl(iface);
536 FIXME("STUB:(%p)\n",This);
540 static HRESULT WINAPI KeystrokeMgr_TestKeyUp(ITfKeystrokeMgr *iface,
541 WPARAM wParam, LPARAM lParam, BOOL *pfEaten)
543 ThreadMgr *This = impl_from_ITfKeystrokeMgrVtbl(iface);
544 FIXME("STUB:(%p)\n",This);
548 static HRESULT WINAPI KeystrokeMgr_KeyDown(ITfKeystrokeMgr *iface,
549 WPARAM wParam, LPARAM lParam, BOOL *pfEaten)
551 ThreadMgr *This = impl_from_ITfKeystrokeMgrVtbl(iface);
552 FIXME("STUB:(%p)\n",This);
556 static HRESULT WINAPI KeystrokeMgr_KeyUp(ITfKeystrokeMgr *iface,
557 WPARAM wParam, LPARAM lParam, BOOL *pfEaten)
559 ThreadMgr *This = impl_from_ITfKeystrokeMgrVtbl(iface);
560 FIXME("STUB:(%p)\n",This);
564 static HRESULT WINAPI KeystrokeMgr_GetPreservedKey(ITfKeystrokeMgr *iface,
565 ITfContext *pic, const TF_PRESERVEDKEY *pprekey, GUID *pguid)
567 ThreadMgr *This = impl_from_ITfKeystrokeMgrVtbl(iface);
568 FIXME("STUB:(%p)\n",This);
572 static HRESULT WINAPI KeystrokeMgr_IsPreservedKey(ITfKeystrokeMgr *iface,
573 REFGUID rguid, const TF_PRESERVEDKEY *pprekey, BOOL *pfRegistered)
575 ThreadMgr *This = impl_from_ITfKeystrokeMgrVtbl(iface);
578 TRACE("(%p) %s (%x %x) %p\n",This,debugstr_guid(rguid), (pprekey)?pprekey->uVKey:0, (pprekey)?pprekey->uModifiers:0, pfRegistered);
580 if (!rguid || !pprekey || !pfRegistered)
583 LIST_FOR_EACH(cursor, &This->CurrentPreservedKeys)
585 PreservedKey* key = LIST_ENTRY(cursor,PreservedKey,entry);
586 if (IsEqualGUID(rguid,&key->guid) && pprekey->uVKey == key->prekey.uVKey && pprekey->uModifiers == key->prekey.uModifiers)
588 *pfRegistered = TRUE;
593 *pfRegistered = FALSE;
597 static HRESULT WINAPI KeystrokeMgr_PreserveKey(ITfKeystrokeMgr *iface,
598 TfClientId tid, REFGUID rguid, const TF_PRESERVEDKEY *prekey,
599 const WCHAR *pchDesc, ULONG cchDesc)
601 ThreadMgr *This = impl_from_ITfKeystrokeMgrVtbl(iface);
603 PreservedKey *newkey;
605 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));
607 if (!tid || ! rguid || !prekey || (cchDesc && !pchDesc))
610 LIST_FOR_EACH(cursor, &This->CurrentPreservedKeys)
612 PreservedKey* key = LIST_ENTRY(cursor,PreservedKey,entry);
613 if (IsEqualGUID(rguid,&key->guid) && prekey->uVKey == key->prekey.uVKey && prekey->uModifiers == key->prekey.uModifiers)
614 return TF_E_ALREADY_EXISTS;
617 newkey = HeapAlloc(GetProcessHeap(),0,sizeof(PreservedKey));
619 return E_OUTOFMEMORY;
621 newkey->guid = *rguid;
622 newkey->prekey = *prekey;
626 newkey->description = HeapAlloc(GetProcessHeap(),0,cchDesc * sizeof(WCHAR));
627 if (!newkey->description)
629 HeapFree(GetProcessHeap(),0,newkey);
630 return E_OUTOFMEMORY;
632 memcpy(newkey->description, pchDesc, cchDesc*sizeof(WCHAR));
635 list_add_head(&This->CurrentPreservedKeys,&newkey->entry);
640 static HRESULT WINAPI KeystrokeMgr_UnpreserveKey(ITfKeystrokeMgr *iface,
641 REFGUID rguid, const TF_PRESERVEDKEY *pprekey)
643 ThreadMgr *This = impl_from_ITfKeystrokeMgrVtbl(iface);
644 PreservedKey* key = NULL;
646 TRACE("(%p) %s (%x %x)\n",This,debugstr_guid(rguid),(pprekey)?pprekey->uVKey:0, (pprekey)?pprekey->uModifiers:0);
648 if (!pprekey || !rguid)
651 LIST_FOR_EACH(cursor, &This->CurrentPreservedKeys)
653 key = LIST_ENTRY(cursor,PreservedKey,entry);
654 if (IsEqualGUID(rguid,&key->guid) && pprekey->uVKey == key->prekey.uVKey && pprekey->uModifiers == key->prekey.uModifiers)
660 return CONNECT_E_NOCONNECTION;
662 list_remove(&key->entry);
663 HeapFree(GetProcessHeap(),0,key->description);
664 HeapFree(GetProcessHeap(),0,key);
669 static HRESULT WINAPI KeystrokeMgr_SetPreservedKeyDescription(ITfKeystrokeMgr *iface,
670 REFGUID rguid, const WCHAR *pchDesc, ULONG cchDesc)
672 ThreadMgr *This = impl_from_ITfKeystrokeMgrVtbl(iface);
673 FIXME("STUB:(%p)\n",This);
677 static HRESULT WINAPI KeystrokeMgr_GetPreservedKeyDescription(ITfKeystrokeMgr *iface,
678 REFGUID rguid, BSTR *pbstrDesc)
680 ThreadMgr *This = impl_from_ITfKeystrokeMgrVtbl(iface);
681 FIXME("STUB:(%p)\n",This);
685 static HRESULT WINAPI KeystrokeMgr_SimulatePreservedKey(ITfKeystrokeMgr *iface,
686 ITfContext *pic, REFGUID rguid, BOOL *pfEaten)
688 ThreadMgr *This = impl_from_ITfKeystrokeMgrVtbl(iface);
689 FIXME("STUB:(%p)\n",This);
693 static const ITfKeystrokeMgrVtbl ThreadMgr_KeystrokeMgrVtbl =
695 KeystrokeMgr_QueryInterface,
697 KeystrokeMgr_Release,
699 KeystrokeMgr_AdviseKeyEventSink,
700 KeystrokeMgr_UnadviseKeyEventSink,
701 KeystrokeMgr_GetForeground,
702 KeystrokeMgr_TestKeyDown,
703 KeystrokeMgr_TestKeyUp,
704 KeystrokeMgr_KeyDown,
706 KeystrokeMgr_GetPreservedKey,
707 KeystrokeMgr_IsPreservedKey,
708 KeystrokeMgr_PreserveKey,
709 KeystrokeMgr_UnpreserveKey,
710 KeystrokeMgr_SetPreservedKeyDescription,
711 KeystrokeMgr_GetPreservedKeyDescription,
712 KeystrokeMgr_SimulatePreservedKey
715 /*****************************************************
716 * ITfMessagePump functions
717 *****************************************************/
719 static HRESULT WINAPI MessagePump_QueryInterface(ITfMessagePump *iface, REFIID iid, LPVOID *ppvOut)
721 ThreadMgr *This = impl_from_ITfMessagePumpVtbl(iface);
722 return ThreadMgr_QueryInterface((ITfThreadMgr *)This, iid, *ppvOut);
725 static ULONG WINAPI MessagePump_AddRef(ITfMessagePump *iface)
727 ThreadMgr *This = impl_from_ITfMessagePumpVtbl(iface);
728 return ThreadMgr_AddRef((ITfThreadMgr*)This);
731 static ULONG WINAPI MessagePump_Release(ITfMessagePump *iface)
733 ThreadMgr *This = impl_from_ITfMessagePumpVtbl(iface);
734 return ThreadMgr_Release((ITfThreadMgr *)This);
737 static HRESULT WINAPI MessagePump_PeekMessageA(ITfMessagePump *iface,
738 LPMSG pMsg, HWND hwnd, UINT wMsgFilterMin, UINT wMsgFilterMax,
739 UINT wRemoveMsg, BOOL *pfResult)
743 *pfResult = PeekMessageA(pMsg, hwnd, wMsgFilterMin, wMsgFilterMax, wRemoveMsg);
747 static HRESULT WINAPI MessagePump_GetMessageA(ITfMessagePump *iface,
748 LPMSG pMsg, HWND hwnd, UINT wMsgFilterMin, UINT wMsgFilterMax,
753 *pfResult = GetMessageA(pMsg, hwnd, wMsgFilterMin, wMsgFilterMax);
757 static HRESULT WINAPI MessagePump_PeekMessageW(ITfMessagePump *iface,
758 LPMSG pMsg, HWND hwnd, UINT wMsgFilterMin, UINT wMsgFilterMax,
759 UINT wRemoveMsg, BOOL *pfResult)
763 *pfResult = PeekMessageW(pMsg, hwnd, wMsgFilterMin, wMsgFilterMax, wRemoveMsg);
767 static HRESULT WINAPI MessagePump_GetMessageW(ITfMessagePump *iface,
768 LPMSG pMsg, HWND hwnd, UINT wMsgFilterMin, UINT wMsgFilterMax,
773 *pfResult = GetMessageW(pMsg, hwnd, wMsgFilterMin, wMsgFilterMax);
777 static const ITfMessagePumpVtbl ThreadMgr_MessagePumpVtbl =
779 MessagePump_QueryInterface,
783 MessagePump_PeekMessageA,
784 MessagePump_GetMessageA,
785 MessagePump_PeekMessageW,
786 MessagePump_GetMessageW
789 /*****************************************************
790 * ITfClientId functions
791 *****************************************************/
793 static HRESULT WINAPI ClientId_QueryInterface(ITfClientId *iface, REFIID iid, LPVOID *ppvOut)
795 ThreadMgr *This = impl_from_ITfClientIdVtbl(iface);
796 return ThreadMgr_QueryInterface((ITfThreadMgr *)This, iid, *ppvOut);
799 static ULONG WINAPI ClientId_AddRef(ITfClientId *iface)
801 ThreadMgr *This = impl_from_ITfClientIdVtbl(iface);
802 return ThreadMgr_AddRef((ITfThreadMgr*)This);
805 static ULONG WINAPI ClientId_Release(ITfClientId *iface)
807 ThreadMgr *This = impl_from_ITfClientIdVtbl(iface);
808 return ThreadMgr_Release((ITfThreadMgr *)This);
811 static HRESULT WINAPI ClientId_GetClientId(ITfClientId *iface,
812 REFCLSID rclsid, TfClientId *ptid)
816 ITfCategoryMgr *catmgr;
817 ThreadMgr *This = impl_from_ITfClientIdVtbl(iface);
819 TRACE("(%p) %s\n",This,debugstr_guid(rclsid));
821 CategoryMgr_Constructor(NULL,(IUnknown**)&catmgr);
822 hr = ITfCategoryMgr_RegisterGUID(catmgr,rclsid,ptid);
823 ITfCategoryMgr_Release(catmgr);
828 static const ITfClientIdVtbl ThreadMgr_ClientIdVtbl =
830 ClientId_QueryInterface,
837 /*****************************************************
838 * ITfThreadMgrEventSink functions (internal)
839 *****************************************************/
840 static HRESULT WINAPI ThreadMgrEventSink_QueryInterface(ITfThreadMgrEventSink *iface, REFIID iid, LPVOID *ppvOut)
842 ThreadMgr *This = impl_from_ITfThreadMgrEventSink(iface);
843 return ThreadMgr_QueryInterface((ITfThreadMgr *)This, iid, *ppvOut);
846 static ULONG WINAPI ThreadMgrEventSink_AddRef(ITfThreadMgrEventSink *iface)
848 ThreadMgr *This = impl_from_ITfThreadMgrEventSink(iface);
849 return ThreadMgr_AddRef((ITfThreadMgr*)This);
852 static ULONG WINAPI ThreadMgrEventSink_Release(ITfThreadMgrEventSink *iface)
854 ThreadMgr *This = impl_from_ITfThreadMgrEventSink(iface);
855 return ThreadMgr_Release((ITfThreadMgr *)This);
859 static WINAPI HRESULT ThreadMgrEventSink_OnInitDocumentMgr(
860 ITfThreadMgrEventSink *iface,ITfDocumentMgr *pdim)
863 ThreadMgr *This = impl_from_ITfThreadMgrEventSink(iface);
865 TRACE("(%p) %p\n",This,pdim);
867 LIST_FOR_EACH(cursor, &This->ThreadMgrEventSink)
869 ThreadMgrSink* sink = LIST_ENTRY(cursor,ThreadMgrSink,entry);
870 ITfThreadMgrEventSink_OnInitDocumentMgr(sink->interfaces.pITfThreadMgrEventSink,pdim);
876 static WINAPI HRESULT ThreadMgrEventSink_OnUninitDocumentMgr(
877 ITfThreadMgrEventSink *iface, ITfDocumentMgr *pdim)
880 ThreadMgr *This = impl_from_ITfThreadMgrEventSink(iface);
882 TRACE("(%p) %p\n",This,pdim);
884 LIST_FOR_EACH(cursor, &This->ThreadMgrEventSink)
886 ThreadMgrSink* sink = LIST_ENTRY(cursor,ThreadMgrSink,entry);
887 ITfThreadMgrEventSink_OnUninitDocumentMgr(sink->interfaces.pITfThreadMgrEventSink,pdim);
893 static WINAPI HRESULT ThreadMgrEventSink_OnSetFocus(
894 ITfThreadMgrEventSink *iface, ITfDocumentMgr *pdimFocus,
895 ITfDocumentMgr *pdimPrevFocus)
898 ThreadMgr *This = impl_from_ITfThreadMgrEventSink(iface);
900 TRACE("(%p) %p %p\n",This,pdimFocus, pdimPrevFocus);
902 LIST_FOR_EACH(cursor, &This->ThreadMgrEventSink)
904 ThreadMgrSink* sink = LIST_ENTRY(cursor,ThreadMgrSink,entry);
905 ITfThreadMgrEventSink_OnSetFocus(sink->interfaces.pITfThreadMgrEventSink, pdimFocus, pdimPrevFocus);
911 static WINAPI HRESULT ThreadMgrEventSink_OnPushContext(
912 ITfThreadMgrEventSink *iface, ITfContext *pic)
915 ThreadMgr *This = impl_from_ITfThreadMgrEventSink(iface);
917 TRACE("(%p) %p\n",This,pic);
919 LIST_FOR_EACH(cursor, &This->ThreadMgrEventSink)
921 ThreadMgrSink* sink = LIST_ENTRY(cursor,ThreadMgrSink,entry);
922 ITfThreadMgrEventSink_OnPushContext(sink->interfaces.pITfThreadMgrEventSink,pic);
928 static WINAPI HRESULT ThreadMgrEventSink_OnPopContext(
929 ITfThreadMgrEventSink *iface, ITfContext *pic)
932 ThreadMgr *This = impl_from_ITfThreadMgrEventSink(iface);
934 TRACE("(%p) %p\n",This,pic);
936 LIST_FOR_EACH(cursor, &This->ThreadMgrEventSink)
938 ThreadMgrSink* sink = LIST_ENTRY(cursor,ThreadMgrSink,entry);
939 ITfThreadMgrEventSink_OnPopContext(sink->interfaces.pITfThreadMgrEventSink,pic);
945 static const ITfThreadMgrEventSinkVtbl ThreadMgr_ThreadMgrEventSinkVtbl =
947 ThreadMgrEventSink_QueryInterface,
948 ThreadMgrEventSink_AddRef,
949 ThreadMgrEventSink_Release,
951 ThreadMgrEventSink_OnInitDocumentMgr,
952 ThreadMgrEventSink_OnUninitDocumentMgr,
953 ThreadMgrEventSink_OnSetFocus,
954 ThreadMgrEventSink_OnPushContext,
955 ThreadMgrEventSink_OnPopContext
958 HRESULT ThreadMgr_Constructor(IUnknown *pUnkOuter, IUnknown **ppOut)
962 return CLASS_E_NOAGGREGATION;
964 /* Only 1 ThreadMgr is created per thread */
965 This = TlsGetValue(tlsIndex);
968 ThreadMgr_AddRef((ITfThreadMgr*)This);
969 *ppOut = (IUnknown*)This;
973 This = HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,sizeof(ThreadMgr));
975 return E_OUTOFMEMORY;
977 This->ThreadMgrVtbl= &ThreadMgr_ThreadMgrVtbl;
978 This->SourceVtbl = &ThreadMgr_SourceVtbl;
979 This->KeystrokeMgrVtbl= &ThreadMgr_KeystrokeMgrVtbl;
980 This->MessagePumpVtbl= &ThreadMgr_MessagePumpVtbl;
981 This->ClientIdVtbl = &ThreadMgr_ClientIdVtbl;
982 This->ThreadMgrEventSinkVtbl = &ThreadMgr_ThreadMgrEventSinkVtbl;
984 TlsSetValue(tlsIndex,This);
986 list_init(&This->CurrentPreservedKeys);
988 list_init(&This->ActiveLanguageProfileNotifySink);
989 list_init(&This->DisplayAttributeNotifySink);
990 list_init(&This->KeyTraceEventSink);
991 list_init(&This->PreservedKeyNotifySink);
992 list_init(&This->ThreadFocusSink);
993 list_init(&This->ThreadMgrEventSink);
995 TRACE("returning %p\n", This);
996 *ppOut = (IUnknown *)This;