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 tagACLMulti {
60 const ITfThreadMgrVtbl *ThreadMgrVtbl;
61 const ITfSourceVtbl *SourceVtbl;
62 const ITfKeystrokeMgrVtbl *KeystrokeMgrVtbl;
63 const ITfMessagePumpVtbl *MessagePumpVtbl;
64 const ITfClientIdVtbl *ClientIdVtbl;
67 const ITfThreadMgrEventSinkVtbl *ThreadMgrEventSinkVtbl; /* internal */
69 ITfDocumentMgr *focus;
71 /* kept as separate lists to reduce unnecessary iterations */
72 struct list ActiveLanguageProfileNotifySink;
73 struct list DisplayAttributeNotifySink;
74 struct list KeyTraceEventSink;
75 struct list PreservedKeyNotifySink;
76 struct list ThreadFocusSink;
77 struct list ThreadMgrEventSink;
80 static inline ThreadMgr *impl_from_ITfSourceVtbl(ITfSource *iface)
82 return (ThreadMgr *)((char *)iface - FIELD_OFFSET(ThreadMgr,SourceVtbl));
85 static inline ThreadMgr *impl_from_ITfKeystrokeMgrVtbl(ITfKeystrokeMgr *iface)
87 return (ThreadMgr *)((char *)iface - FIELD_OFFSET(ThreadMgr,KeystrokeMgrVtbl));
90 static inline ThreadMgr *impl_from_ITfMessagePumpVtbl(ITfMessagePump *iface)
92 return (ThreadMgr *)((char *)iface - FIELD_OFFSET(ThreadMgr,MessagePumpVtbl));
95 static inline ThreadMgr *impl_from_ITfClientIdVtbl(ITfClientId *iface)
97 return (ThreadMgr *)((char *)iface - FIELD_OFFSET(ThreadMgr,ClientIdVtbl));
100 static inline ThreadMgr *impl_from_ITfThreadMgrEventSink(ITfThreadMgrEventSink *iface)
102 return (ThreadMgr *)((char *)iface - FIELD_OFFSET(ThreadMgr,ThreadMgrEventSinkVtbl));
105 static void free_sink(ThreadMgrSink *sink)
107 IUnknown_Release(sink->interfaces.pIUnknown);
108 HeapFree(GetProcessHeap(),0,sink);
111 static void ThreadMgr_Destructor(ThreadMgr *This)
113 struct list *cursor, *cursor2;
115 TlsSetValue(tlsIndex,NULL);
116 TRACE("destroying %p\n", This);
118 ITfDocumentMgr_Release(This->focus);
121 LIST_FOR_EACH_SAFE(cursor, cursor2, &This->ActiveLanguageProfileNotifySink)
123 ThreadMgrSink* sink = LIST_ENTRY(cursor,ThreadMgrSink,entry);
127 LIST_FOR_EACH_SAFE(cursor, cursor2, &This->DisplayAttributeNotifySink)
129 ThreadMgrSink* sink = LIST_ENTRY(cursor,ThreadMgrSink,entry);
133 LIST_FOR_EACH_SAFE(cursor, cursor2, &This->KeyTraceEventSink)
135 ThreadMgrSink* sink = LIST_ENTRY(cursor,ThreadMgrSink,entry);
139 LIST_FOR_EACH_SAFE(cursor, cursor2, &This->PreservedKeyNotifySink)
141 ThreadMgrSink* sink = LIST_ENTRY(cursor,ThreadMgrSink,entry);
145 LIST_FOR_EACH_SAFE(cursor, cursor2, &This->ThreadFocusSink)
147 ThreadMgrSink* sink = LIST_ENTRY(cursor,ThreadMgrSink,entry);
151 LIST_FOR_EACH_SAFE(cursor, cursor2, &This->ThreadMgrEventSink)
153 ThreadMgrSink* sink = LIST_ENTRY(cursor,ThreadMgrSink,entry);
158 HeapFree(GetProcessHeap(),0,This);
161 static HRESULT WINAPI ThreadMgr_QueryInterface(ITfThreadMgr *iface, REFIID iid, LPVOID *ppvOut)
163 ThreadMgr *This = (ThreadMgr *)iface;
166 if (IsEqualIID(iid, &IID_IUnknown) || IsEqualIID(iid, &IID_ITfThreadMgr))
170 else if (IsEqualIID(iid, &IID_ITfSource))
172 *ppvOut = &This->SourceVtbl;
174 else if (IsEqualIID(iid, &IID_ITfKeystrokeMgr))
176 *ppvOut = &This->KeystrokeMgrVtbl;
178 else if (IsEqualIID(iid, &IID_ITfMessagePump))
180 *ppvOut = &This->MessagePumpVtbl;
182 else if (IsEqualIID(iid, &IID_ITfClientId))
184 *ppvOut = &This->ClientIdVtbl;
189 IUnknown_AddRef(iface);
193 WARN("unsupported interface: %s\n", debugstr_guid(iid));
194 return E_NOINTERFACE;
197 static ULONG WINAPI ThreadMgr_AddRef(ITfThreadMgr *iface)
199 ThreadMgr *This = (ThreadMgr *)iface;
200 return InterlockedIncrement(&This->refCount);
203 static ULONG WINAPI ThreadMgr_Release(ITfThreadMgr *iface)
205 ThreadMgr *This = (ThreadMgr *)iface;
208 ret = InterlockedDecrement(&This->refCount);
210 ThreadMgr_Destructor(This);
214 /*****************************************************
215 * ITfThreadMgr functions
216 *****************************************************/
218 static HRESULT WINAPI ThreadMgr_fnActivate( ITfThreadMgr* iface, TfClientId *ptid)
220 ThreadMgr *This = (ThreadMgr *)iface;
221 FIXME("STUB:(%p)\n",This);
225 static HRESULT WINAPI ThreadMgr_fnDeactivate( ITfThreadMgr* iface)
227 ThreadMgr *This = (ThreadMgr *)iface;
228 FIXME("STUB:(%p)\n",This);
232 ITfThreadMgrEventSink_OnSetFocus((ITfThreadMgrEventSink*)&This->ThreadMgrEventSinkVtbl, 0, This->focus);
233 ITfDocumentMgr_Release(This->focus);
240 static HRESULT WINAPI ThreadMgr_CreateDocumentMgr( ITfThreadMgr* iface, ITfDocumentMgr
243 ThreadMgr *This = (ThreadMgr *)iface;
244 TRACE("(%p)\n",iface);
245 return DocumentMgr_Constructor((ITfThreadMgrEventSink*)&This->ThreadMgrEventSinkVtbl, ppdim);
248 static HRESULT WINAPI ThreadMgr_EnumDocumentMgrs( ITfThreadMgr* iface, IEnumTfDocumentMgrs
251 ThreadMgr *This = (ThreadMgr *)iface;
252 FIXME("STUB:(%p)\n",This);
256 static HRESULT WINAPI ThreadMgr_GetFocus( ITfThreadMgr* iface, ITfDocumentMgr
259 ThreadMgr *This = (ThreadMgr *)iface;
260 TRACE("(%p)\n",This);
265 *ppdimFocus = This->focus;
267 TRACE("->%p\n",This->focus);
269 if (This->focus == NULL)
272 ITfDocumentMgr_AddRef(This->focus);
277 static HRESULT WINAPI ThreadMgr_SetFocus( ITfThreadMgr* iface, ITfDocumentMgr *pdimFocus)
279 ITfDocumentMgr *check;
280 ThreadMgr *This = (ThreadMgr *)iface;
282 TRACE("(%p) %p\n",This,pdimFocus);
284 if (!pdimFocus || FAILED(IUnknown_QueryInterface(pdimFocus,&IID_ITfDocumentMgr,(LPVOID*) &check)))
287 ITfThreadMgrEventSink_OnSetFocus((ITfThreadMgrEventSink*)&This->ThreadMgrEventSinkVtbl, check, This->focus);
290 ITfDocumentMgr_Release(This->focus);
296 static HRESULT WINAPI ThreadMgr_AssociateFocus( ITfThreadMgr* iface, HWND hwnd,
297 ITfDocumentMgr *pdimNew, ITfDocumentMgr **ppdimPrev)
299 ThreadMgr *This = (ThreadMgr *)iface;
300 FIXME("STUB:(%p)\n",This);
304 static HRESULT WINAPI ThreadMgr_IsThreadFocus( ITfThreadMgr* iface, BOOL *pfThreadFocus)
306 ThreadMgr *This = (ThreadMgr *)iface;
307 FIXME("STUB:(%p)\n",This);
311 static HRESULT WINAPI ThreadMgr_GetFunctionProvider( ITfThreadMgr* iface, REFCLSID clsid,
312 ITfFunctionProvider **ppFuncProv)
314 ThreadMgr *This = (ThreadMgr *)iface;
315 FIXME("STUB:(%p)\n",This);
319 static HRESULT WINAPI ThreadMgr_EnumFunctionProviders( ITfThreadMgr* iface,
320 IEnumTfFunctionProviders **ppEnum)
322 ThreadMgr *This = (ThreadMgr *)iface;
323 FIXME("STUB:(%p)\n",This);
327 static HRESULT WINAPI ThreadMgr_GetGlobalCompartment( ITfThreadMgr* iface,
328 ITfCompartmentMgr **ppCompMgr)
330 ThreadMgr *This = (ThreadMgr *)iface;
331 FIXME("STUB:(%p)\n",This);
335 static const ITfThreadMgrVtbl ThreadMgr_ThreadMgrVtbl =
337 ThreadMgr_QueryInterface,
341 ThreadMgr_fnActivate,
342 ThreadMgr_fnDeactivate,
343 ThreadMgr_CreateDocumentMgr,
344 ThreadMgr_EnumDocumentMgrs,
347 ThreadMgr_AssociateFocus,
348 ThreadMgr_IsThreadFocus,
349 ThreadMgr_GetFunctionProvider,
350 ThreadMgr_EnumFunctionProviders,
351 ThreadMgr_GetGlobalCompartment
355 static HRESULT WINAPI Source_QueryInterface(ITfSource *iface, REFIID iid, LPVOID *ppvOut)
357 ThreadMgr *This = impl_from_ITfSourceVtbl(iface);
358 return ThreadMgr_QueryInterface((ITfThreadMgr *)This, iid, *ppvOut);
361 static ULONG WINAPI Source_AddRef(ITfSource *iface)
363 ThreadMgr *This = impl_from_ITfSourceVtbl(iface);
364 return ThreadMgr_AddRef((ITfThreadMgr*)This);
367 static ULONG WINAPI Source_Release(ITfSource *iface)
369 ThreadMgr *This = impl_from_ITfSourceVtbl(iface);
370 return ThreadMgr_Release((ITfThreadMgr *)This);
373 /*****************************************************
374 * ITfSource functions
375 *****************************************************/
376 static WINAPI HRESULT ThreadMgrSource_AdviseSink(ITfSource *iface,
377 REFIID riid, IUnknown *punk, DWORD *pdwCookie)
380 ThreadMgr *This = impl_from_ITfSourceVtbl(iface);
382 TRACE("(%p) %s %p %p\n",This,debugstr_guid(riid),punk,pdwCookie);
384 if (!riid || !punk || !pdwCookie)
387 if (IsEqualIID(riid, &IID_ITfThreadMgrEventSink))
389 tms = HeapAlloc(GetProcessHeap(),0,sizeof(ThreadMgrSink));
391 return E_OUTOFMEMORY;
392 if (!SUCCEEDED(IUnknown_QueryInterface(punk, riid, (LPVOID*)&tms->interfaces.pITfThreadMgrEventSink)))
394 HeapFree(GetProcessHeap(),0,tms);
395 return CONNECT_E_CANNOTCONNECT;
397 list_add_head(&This->ThreadMgrEventSink,&tms->entry);
398 *pdwCookie = generate_Cookie(COOKIE_MAGIC_TMSINK, tms);
402 FIXME("(%p) Unhandled Sink: %s\n",This,debugstr_guid(riid));
406 TRACE("cookie %x\n",*pdwCookie);
411 static WINAPI HRESULT ThreadMgrSource_UnadviseSink(ITfSource *iface, DWORD pdwCookie)
414 ThreadMgr *This = impl_from_ITfSourceVtbl(iface);
416 TRACE("(%p) %x\n",This,pdwCookie);
418 if (get_Cookie_magic(pdwCookie)!=COOKIE_MAGIC_TMSINK)
421 sink = (ThreadMgrSink*)remove_Cookie(pdwCookie);
423 return CONNECT_E_NOCONNECTION;
425 list_remove(&sink->entry);
431 static const ITfSourceVtbl ThreadMgr_SourceVtbl =
433 Source_QueryInterface,
437 ThreadMgrSource_AdviseSink,
438 ThreadMgrSource_UnadviseSink,
441 /*****************************************************
442 * ITfKeystrokeMgr functions
443 *****************************************************/
445 static HRESULT WINAPI KeystrokeMgr_QueryInterface(ITfKeystrokeMgr *iface, REFIID iid, LPVOID *ppvOut)
447 ThreadMgr *This = impl_from_ITfKeystrokeMgrVtbl(iface);
448 return ThreadMgr_QueryInterface((ITfThreadMgr *)This, iid, *ppvOut);
451 static ULONG WINAPI KeystrokeMgr_AddRef(ITfKeystrokeMgr *iface)
453 ThreadMgr *This = impl_from_ITfKeystrokeMgrVtbl(iface);
454 return ThreadMgr_AddRef((ITfThreadMgr*)This);
457 static ULONG WINAPI KeystrokeMgr_Release(ITfKeystrokeMgr *iface)
459 ThreadMgr *This = impl_from_ITfKeystrokeMgrVtbl(iface);
460 return ThreadMgr_Release((ITfThreadMgr *)This);
463 static HRESULT WINAPI KeystrokeMgr_AdviseKeyEventSink(ITfKeystrokeMgr *iface,
464 TfClientId tid, ITfKeyEventSink *pSink, BOOL fForeground)
466 ThreadMgr *This = impl_from_ITfKeystrokeMgrVtbl(iface);
467 FIXME("STUB:(%p)\n",This);
471 static HRESULT WINAPI KeystrokeMgr_UnadviseKeyEventSink(ITfKeystrokeMgr *iface,
474 ThreadMgr *This = impl_from_ITfKeystrokeMgrVtbl(iface);
475 FIXME("STUB:(%p)\n",This);
479 static HRESULT WINAPI KeystrokeMgr_GetForeground(ITfKeystrokeMgr *iface,
482 ThreadMgr *This = impl_from_ITfKeystrokeMgrVtbl(iface);
483 FIXME("STUB:(%p)\n",This);
487 static HRESULT WINAPI KeystrokeMgr_TestKeyDown(ITfKeystrokeMgr *iface,
488 WPARAM wParam, LPARAM lParam, BOOL *pfEaten)
490 ThreadMgr *This = impl_from_ITfKeystrokeMgrVtbl(iface);
491 FIXME("STUB:(%p)\n",This);
495 static HRESULT WINAPI KeystrokeMgr_TestKeyUp(ITfKeystrokeMgr *iface,
496 WPARAM wParam, LPARAM lParam, BOOL *pfEaten)
498 ThreadMgr *This = impl_from_ITfKeystrokeMgrVtbl(iface);
499 FIXME("STUB:(%p)\n",This);
503 static HRESULT WINAPI KeystrokeMgr_KeyDown(ITfKeystrokeMgr *iface,
504 WPARAM wParam, LPARAM lParam, BOOL *pfEaten)
506 ThreadMgr *This = impl_from_ITfKeystrokeMgrVtbl(iface);
507 FIXME("STUB:(%p)\n",This);
511 static HRESULT WINAPI KeystrokeMgr_KeyUp(ITfKeystrokeMgr *iface,
512 WPARAM wParam, LPARAM lParam, BOOL *pfEaten)
514 ThreadMgr *This = impl_from_ITfKeystrokeMgrVtbl(iface);
515 FIXME("STUB:(%p)\n",This);
519 static HRESULT WINAPI KeystrokeMgr_GetPreservedKey(ITfKeystrokeMgr *iface,
520 ITfContext *pic, const TF_PRESERVEDKEY *pprekey, GUID *pguid)
522 ThreadMgr *This = impl_from_ITfKeystrokeMgrVtbl(iface);
523 FIXME("STUB:(%p)\n",This);
527 static HRESULT WINAPI KeystrokeMgr_IsPreservedKey(ITfKeystrokeMgr *iface,
528 REFGUID rguid, const TF_PRESERVEDKEY *pprekey, BOOL *pfRegistered)
530 ThreadMgr *This = impl_from_ITfKeystrokeMgrVtbl(iface);
531 FIXME("STUB:(%p)\n",This);
535 static HRESULT WINAPI KeystrokeMgr_PreserveKey(ITfKeystrokeMgr *iface,
536 TfClientId tid, REFGUID rguid, const TF_PRESERVEDKEY *prekey,
537 const WCHAR *pchDesc, ULONG cchDesc)
539 ThreadMgr *This = impl_from_ITfKeystrokeMgrVtbl(iface);
540 FIXME("STUB:(%p)\n",This);
544 static HRESULT WINAPI KeystrokeMgr_UnpreserveKey(ITfKeystrokeMgr *iface,
545 REFGUID rguid, const TF_PRESERVEDKEY *pprekey)
547 ThreadMgr *This = impl_from_ITfKeystrokeMgrVtbl(iface);
548 FIXME("STUB:(%p)\n",This);
552 static HRESULT WINAPI KeystrokeMgr_SetPreservedKeyDescription(ITfKeystrokeMgr *iface,
553 REFGUID rguid, const WCHAR *pchDesc, ULONG cchDesc)
555 ThreadMgr *This = impl_from_ITfKeystrokeMgrVtbl(iface);
556 FIXME("STUB:(%p)\n",This);
560 static HRESULT WINAPI KeystrokeMgr_GetPreservedKeyDescription(ITfKeystrokeMgr *iface,
561 REFGUID rguid, BSTR *pbstrDesc)
563 ThreadMgr *This = impl_from_ITfKeystrokeMgrVtbl(iface);
564 FIXME("STUB:(%p)\n",This);
568 static HRESULT WINAPI KeystrokeMgr_SimulatePreservedKey(ITfKeystrokeMgr *iface,
569 ITfContext *pic, REFGUID rguid, BOOL *pfEaten)
571 ThreadMgr *This = impl_from_ITfKeystrokeMgrVtbl(iface);
572 FIXME("STUB:(%p)\n",This);
576 static const ITfKeystrokeMgrVtbl ThreadMgr_KeystrokeMgrVtbl =
578 KeystrokeMgr_QueryInterface,
580 KeystrokeMgr_Release,
582 KeystrokeMgr_AdviseKeyEventSink,
583 KeystrokeMgr_UnadviseKeyEventSink,
584 KeystrokeMgr_GetForeground,
585 KeystrokeMgr_TestKeyDown,
586 KeystrokeMgr_TestKeyUp,
587 KeystrokeMgr_KeyDown,
589 KeystrokeMgr_GetPreservedKey,
590 KeystrokeMgr_IsPreservedKey,
591 KeystrokeMgr_PreserveKey,
592 KeystrokeMgr_UnpreserveKey,
593 KeystrokeMgr_SetPreservedKeyDescription,
594 KeystrokeMgr_GetPreservedKeyDescription,
595 KeystrokeMgr_SimulatePreservedKey
598 /*****************************************************
599 * ITfMessagePump functions
600 *****************************************************/
602 static HRESULT WINAPI MessagePump_QueryInterface(ITfMessagePump *iface, REFIID iid, LPVOID *ppvOut)
604 ThreadMgr *This = impl_from_ITfMessagePumpVtbl(iface);
605 return ThreadMgr_QueryInterface((ITfThreadMgr *)This, iid, *ppvOut);
608 static ULONG WINAPI MessagePump_AddRef(ITfMessagePump *iface)
610 ThreadMgr *This = impl_from_ITfMessagePumpVtbl(iface);
611 return ThreadMgr_AddRef((ITfThreadMgr*)This);
614 static ULONG WINAPI MessagePump_Release(ITfMessagePump *iface)
616 ThreadMgr *This = impl_from_ITfMessagePumpVtbl(iface);
617 return ThreadMgr_Release((ITfThreadMgr *)This);
620 static HRESULT WINAPI MessagePump_PeekMessageA(ITfMessagePump *iface,
621 LPMSG pMsg, HWND hwnd, UINT wMsgFilterMin, UINT wMsgFilterMax,
622 UINT wRemoveMsg, BOOL *pfResult)
626 *pfResult = PeekMessageA(pMsg, hwnd, wMsgFilterMin, wMsgFilterMax, wRemoveMsg);
630 static HRESULT WINAPI MessagePump_GetMessageA(ITfMessagePump *iface,
631 LPMSG pMsg, HWND hwnd, UINT wMsgFilterMin, UINT wMsgFilterMax,
636 *pfResult = GetMessageA(pMsg, hwnd, wMsgFilterMin, wMsgFilterMax);
640 static HRESULT WINAPI MessagePump_PeekMessageW(ITfMessagePump *iface,
641 LPMSG pMsg, HWND hwnd, UINT wMsgFilterMin, UINT wMsgFilterMax,
642 UINT wRemoveMsg, BOOL *pfResult)
646 *pfResult = PeekMessageW(pMsg, hwnd, wMsgFilterMin, wMsgFilterMax, wRemoveMsg);
650 static HRESULT WINAPI MessagePump_GetMessageW(ITfMessagePump *iface,
651 LPMSG pMsg, HWND hwnd, UINT wMsgFilterMin, UINT wMsgFilterMax,
656 *pfResult = GetMessageW(pMsg, hwnd, wMsgFilterMin, wMsgFilterMax);
660 static const ITfMessagePumpVtbl ThreadMgr_MessagePumpVtbl =
662 MessagePump_QueryInterface,
666 MessagePump_PeekMessageA,
667 MessagePump_GetMessageA,
668 MessagePump_PeekMessageW,
669 MessagePump_GetMessageW
672 /*****************************************************
673 * ITfClientId functions
674 *****************************************************/
676 static HRESULT WINAPI ClientId_QueryInterface(ITfClientId *iface, REFIID iid, LPVOID *ppvOut)
678 ThreadMgr *This = impl_from_ITfClientIdVtbl(iface);
679 return ThreadMgr_QueryInterface((ITfThreadMgr *)This, iid, *ppvOut);
682 static ULONG WINAPI ClientId_AddRef(ITfClientId *iface)
684 ThreadMgr *This = impl_from_ITfClientIdVtbl(iface);
685 return ThreadMgr_AddRef((ITfThreadMgr*)This);
688 static ULONG WINAPI ClientId_Release(ITfClientId *iface)
690 ThreadMgr *This = impl_from_ITfClientIdVtbl(iface);
691 return ThreadMgr_Release((ITfThreadMgr *)This);
694 static HRESULT WINAPI ClientId_GetClientId(ITfClientId *iface,
695 REFCLSID rclsid, TfClientId *ptid)
699 ITfCategoryMgr *catmgr;
700 ThreadMgr *This = impl_from_ITfClientIdVtbl(iface);
702 TRACE("(%p) %s\n",This,debugstr_guid(rclsid));
704 CategoryMgr_Constructor(NULL,(IUnknown**)&catmgr);
705 hr = ITfCategoryMgr_RegisterGUID(catmgr,rclsid,ptid);
706 ITfCategoryMgr_Release(catmgr);
711 static const ITfClientIdVtbl ThreadMgr_ClientIdVtbl =
713 ClientId_QueryInterface,
720 /*****************************************************
721 * ITfThreadMgrEventSink functions (internal)
722 *****************************************************/
723 static HRESULT WINAPI ThreadMgrEventSink_QueryInterface(ITfThreadMgrEventSink *iface, REFIID iid, LPVOID *ppvOut)
725 ThreadMgr *This = impl_from_ITfThreadMgrEventSink(iface);
726 return ThreadMgr_QueryInterface((ITfThreadMgr *)This, iid, *ppvOut);
729 static ULONG WINAPI ThreadMgrEventSink_AddRef(ITfThreadMgrEventSink *iface)
731 ThreadMgr *This = impl_from_ITfThreadMgrEventSink(iface);
732 return ThreadMgr_AddRef((ITfThreadMgr*)This);
735 static ULONG WINAPI ThreadMgrEventSink_Release(ITfThreadMgrEventSink *iface)
737 ThreadMgr *This = impl_from_ITfThreadMgrEventSink(iface);
738 return ThreadMgr_Release((ITfThreadMgr *)This);
742 static WINAPI HRESULT ThreadMgrEventSink_OnInitDocumentMgr(
743 ITfThreadMgrEventSink *iface,ITfDocumentMgr *pdim)
746 ThreadMgr *This = impl_from_ITfThreadMgrEventSink(iface);
748 TRACE("(%p) %p\n",This,pdim);
750 LIST_FOR_EACH(cursor, &This->ThreadMgrEventSink)
752 ThreadMgrSink* sink = LIST_ENTRY(cursor,ThreadMgrSink,entry);
753 ITfThreadMgrEventSink_OnInitDocumentMgr(sink->interfaces.pITfThreadMgrEventSink,pdim);
759 static WINAPI HRESULT ThreadMgrEventSink_OnUninitDocumentMgr(
760 ITfThreadMgrEventSink *iface, ITfDocumentMgr *pdim)
763 ThreadMgr *This = impl_from_ITfThreadMgrEventSink(iface);
765 TRACE("(%p) %p\n",This,pdim);
767 LIST_FOR_EACH(cursor, &This->ThreadMgrEventSink)
769 ThreadMgrSink* sink = LIST_ENTRY(cursor,ThreadMgrSink,entry);
770 ITfThreadMgrEventSink_OnUninitDocumentMgr(sink->interfaces.pITfThreadMgrEventSink,pdim);
776 static WINAPI HRESULT ThreadMgrEventSink_OnSetFocus(
777 ITfThreadMgrEventSink *iface, ITfDocumentMgr *pdimFocus,
778 ITfDocumentMgr *pdimPrevFocus)
781 ThreadMgr *This = impl_from_ITfThreadMgrEventSink(iface);
783 TRACE("(%p) %p %p\n",This,pdimFocus, pdimPrevFocus);
785 LIST_FOR_EACH(cursor, &This->ThreadMgrEventSink)
787 ThreadMgrSink* sink = LIST_ENTRY(cursor,ThreadMgrSink,entry);
788 ITfThreadMgrEventSink_OnSetFocus(sink->interfaces.pITfThreadMgrEventSink, pdimFocus, pdimPrevFocus);
794 static WINAPI HRESULT ThreadMgrEventSink_OnPushContext(
795 ITfThreadMgrEventSink *iface, ITfContext *pic)
798 ThreadMgr *This = impl_from_ITfThreadMgrEventSink(iface);
800 TRACE("(%p) %p\n",This,pic);
802 LIST_FOR_EACH(cursor, &This->ThreadMgrEventSink)
804 ThreadMgrSink* sink = LIST_ENTRY(cursor,ThreadMgrSink,entry);
805 ITfThreadMgrEventSink_OnPushContext(sink->interfaces.pITfThreadMgrEventSink,pic);
811 static WINAPI HRESULT ThreadMgrEventSink_OnPopContext(
812 ITfThreadMgrEventSink *iface, ITfContext *pic)
815 ThreadMgr *This = impl_from_ITfThreadMgrEventSink(iface);
817 TRACE("(%p) %p\n",This,pic);
819 LIST_FOR_EACH(cursor, &This->ThreadMgrEventSink)
821 ThreadMgrSink* sink = LIST_ENTRY(cursor,ThreadMgrSink,entry);
822 ITfThreadMgrEventSink_OnPopContext(sink->interfaces.pITfThreadMgrEventSink,pic);
828 static const ITfThreadMgrEventSinkVtbl ThreadMgr_ThreadMgrEventSinkVtbl =
830 ThreadMgrEventSink_QueryInterface,
831 ThreadMgrEventSink_AddRef,
832 ThreadMgrEventSink_Release,
834 ThreadMgrEventSink_OnInitDocumentMgr,
835 ThreadMgrEventSink_OnUninitDocumentMgr,
836 ThreadMgrEventSink_OnSetFocus,
837 ThreadMgrEventSink_OnPushContext,
838 ThreadMgrEventSink_OnPopContext
841 HRESULT ThreadMgr_Constructor(IUnknown *pUnkOuter, IUnknown **ppOut)
845 return CLASS_E_NOAGGREGATION;
847 /* Only 1 ThreadMgr is created per thread */
848 This = TlsGetValue(tlsIndex);
851 ThreadMgr_AddRef((ITfThreadMgr*)This);
852 *ppOut = (IUnknown*)This;
856 This = HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,sizeof(ThreadMgr));
858 return E_OUTOFMEMORY;
860 This->ThreadMgrVtbl= &ThreadMgr_ThreadMgrVtbl;
861 This->SourceVtbl = &ThreadMgr_SourceVtbl;
862 This->KeystrokeMgrVtbl= &ThreadMgr_KeystrokeMgrVtbl;
863 This->MessagePumpVtbl= &ThreadMgr_MessagePumpVtbl;
864 This->ClientIdVtbl = &ThreadMgr_ClientIdVtbl;
865 This->ThreadMgrEventSinkVtbl = &ThreadMgr_ThreadMgrEventSinkVtbl;
867 TlsSetValue(tlsIndex,This);
869 list_init(&This->ActiveLanguageProfileNotifySink);
870 list_init(&This->DisplayAttributeNotifySink);
871 list_init(&This->KeyTraceEventSink);
872 list_init(&This->PreservedKeyNotifySink);
873 list_init(&This->ThreadFocusSink);
874 list_init(&This->ThreadMgrEventSink);
876 TRACE("returning %p\n", This);
877 *ppOut = (IUnknown *)This;