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
;
65 const ITfThreadMgrEventSinkVtbl
*ThreadMgrEventSinkVtbl
; /* internal */
67 ITfDocumentMgr
*focus
;
69 /* kept as separate lists to reduce unnecessary iterations */
70 struct list ActiveLanguageProfileNotifySink
;
71 struct list DisplayAttributeNotifySink
;
72 struct list KeyTraceEventSink
;
73 struct list PreservedKeyNotifySink
;
74 struct list ThreadFocusSink
;
75 struct list ThreadMgrEventSink
;
78 static inline ThreadMgr
*impl_from_ITfSourceVtbl(ITfSource
*iface
)
80 return (ThreadMgr
*)((char *)iface
- FIELD_OFFSET(ThreadMgr
,SourceVtbl
));
83 static inline ThreadMgr
*impl_from_ITfKeystrokeMgrVtbl(ITfKeystrokeMgr
*iface
)
85 return (ThreadMgr
*)((char *)iface
- FIELD_OFFSET(ThreadMgr
,KeystrokeMgrVtbl
));
88 static inline ThreadMgr
*impl_from_ITfThreadMgrEventSink(ITfThreadMgrEventSink
*iface
)
90 return (ThreadMgr
*)((char *)iface
- FIELD_OFFSET(ThreadMgr
,ThreadMgrEventSinkVtbl
));
93 static void free_sink(ThreadMgrSink
*sink
)
95 IUnknown_Release(sink
->interfaces
.pIUnknown
);
96 HeapFree(GetProcessHeap(),0,sink
);
99 static void ThreadMgr_Destructor(ThreadMgr
*This
)
101 struct list
*cursor
, *cursor2
;
103 TlsSetValue(tlsIndex
,NULL
);
104 TRACE("destroying %p\n", This
);
106 ITfDocumentMgr_Release(This
->focus
);
109 LIST_FOR_EACH_SAFE(cursor
, cursor2
, &This
->ActiveLanguageProfileNotifySink
)
111 ThreadMgrSink
* sink
= LIST_ENTRY(cursor
,ThreadMgrSink
,entry
);
115 LIST_FOR_EACH_SAFE(cursor
, cursor2
, &This
->DisplayAttributeNotifySink
)
117 ThreadMgrSink
* sink
= LIST_ENTRY(cursor
,ThreadMgrSink
,entry
);
121 LIST_FOR_EACH_SAFE(cursor
, cursor2
, &This
->KeyTraceEventSink
)
123 ThreadMgrSink
* sink
= LIST_ENTRY(cursor
,ThreadMgrSink
,entry
);
127 LIST_FOR_EACH_SAFE(cursor
, cursor2
, &This
->PreservedKeyNotifySink
)
129 ThreadMgrSink
* sink
= LIST_ENTRY(cursor
,ThreadMgrSink
,entry
);
133 LIST_FOR_EACH_SAFE(cursor
, cursor2
, &This
->ThreadFocusSink
)
135 ThreadMgrSink
* sink
= LIST_ENTRY(cursor
,ThreadMgrSink
,entry
);
139 LIST_FOR_EACH_SAFE(cursor
, cursor2
, &This
->ThreadMgrEventSink
)
141 ThreadMgrSink
* sink
= LIST_ENTRY(cursor
,ThreadMgrSink
,entry
);
146 HeapFree(GetProcessHeap(),0,This
);
149 static HRESULT WINAPI
ThreadMgr_QueryInterface(ITfThreadMgr
*iface
, REFIID iid
, LPVOID
*ppvOut
)
151 ThreadMgr
*This
= (ThreadMgr
*)iface
;
154 if (IsEqualIID(iid
, &IID_IUnknown
) || IsEqualIID(iid
, &IID_ITfThreadMgr
))
158 else if (IsEqualIID(iid
, &IID_ITfSource
))
160 *ppvOut
= &This
->SourceVtbl
;
162 else if (IsEqualIID(iid
, &IID_ITfKeystrokeMgr
))
164 *ppvOut
= &This
->KeystrokeMgrVtbl
;
169 IUnknown_AddRef(iface
);
173 WARN("unsupported interface: %s\n", debugstr_guid(iid
));
174 return E_NOINTERFACE
;
177 static ULONG WINAPI
ThreadMgr_AddRef(ITfThreadMgr
*iface
)
179 ThreadMgr
*This
= (ThreadMgr
*)iface
;
180 return InterlockedIncrement(&This
->refCount
);
183 static ULONG WINAPI
ThreadMgr_Release(ITfThreadMgr
*iface
)
185 ThreadMgr
*This
= (ThreadMgr
*)iface
;
188 ret
= InterlockedDecrement(&This
->refCount
);
190 ThreadMgr_Destructor(This
);
194 /*****************************************************
195 * ITfThreadMgr functions
196 *****************************************************/
198 static HRESULT WINAPI
ThreadMgr_fnActivate( ITfThreadMgr
* iface
, TfClientId
*ptid
)
200 ThreadMgr
*This
= (ThreadMgr
*)iface
;
201 FIXME("STUB:(%p)\n",This
);
205 static HRESULT WINAPI
ThreadMgr_fnDeactivate( ITfThreadMgr
* iface
)
207 ThreadMgr
*This
= (ThreadMgr
*)iface
;
208 FIXME("STUB:(%p)\n",This
);
212 ITfThreadMgrEventSink_OnSetFocus((ITfThreadMgrEventSink
*)&This
->ThreadMgrEventSinkVtbl
, 0, This
->focus
);
213 ITfDocumentMgr_Release(This
->focus
);
220 static HRESULT WINAPI
ThreadMgr_CreateDocumentMgr( ITfThreadMgr
* iface
, ITfDocumentMgr
223 ThreadMgr
*This
= (ThreadMgr
*)iface
;
224 TRACE("(%p)\n",iface
);
225 return DocumentMgr_Constructor((ITfThreadMgrEventSink
*)&This
->ThreadMgrEventSinkVtbl
, ppdim
);
228 static HRESULT WINAPI
ThreadMgr_EnumDocumentMgrs( ITfThreadMgr
* iface
, IEnumTfDocumentMgrs
231 ThreadMgr
*This
= (ThreadMgr
*)iface
;
232 FIXME("STUB:(%p)\n",This
);
236 static HRESULT WINAPI
ThreadMgr_GetFocus( ITfThreadMgr
* iface
, ITfDocumentMgr
239 ThreadMgr
*This
= (ThreadMgr
*)iface
;
240 TRACE("(%p)\n",This
);
245 *ppdimFocus
= This
->focus
;
247 TRACE("->%p\n",This
->focus
);
249 if (This
->focus
== NULL
)
252 ITfDocumentMgr_AddRef(This
->focus
);
257 static HRESULT WINAPI
ThreadMgr_SetFocus( ITfThreadMgr
* iface
, ITfDocumentMgr
*pdimFocus
)
259 ITfDocumentMgr
*check
;
260 ThreadMgr
*This
= (ThreadMgr
*)iface
;
262 TRACE("(%p) %p\n",This
,pdimFocus
);
264 if (!pdimFocus
|| FAILED(IUnknown_QueryInterface(pdimFocus
,&IID_ITfDocumentMgr
,(LPVOID
*) &check
)))
267 ITfThreadMgrEventSink_OnSetFocus((ITfThreadMgrEventSink
*)&This
->ThreadMgrEventSinkVtbl
, check
, This
->focus
);
270 ITfDocumentMgr_Release(This
->focus
);
276 static HRESULT WINAPI
ThreadMgr_AssociateFocus( ITfThreadMgr
* iface
, HWND hwnd
,
277 ITfDocumentMgr
*pdimNew
, ITfDocumentMgr
**ppdimPrev
)
279 ThreadMgr
*This
= (ThreadMgr
*)iface
;
280 FIXME("STUB:(%p)\n",This
);
284 static HRESULT WINAPI
ThreadMgr_IsThreadFocus( ITfThreadMgr
* iface
, BOOL
*pfThreadFocus
)
286 ThreadMgr
*This
= (ThreadMgr
*)iface
;
287 FIXME("STUB:(%p)\n",This
);
291 static HRESULT WINAPI
ThreadMgr_GetFunctionProvider( ITfThreadMgr
* iface
, REFCLSID clsid
,
292 ITfFunctionProvider
**ppFuncProv
)
294 ThreadMgr
*This
= (ThreadMgr
*)iface
;
295 FIXME("STUB:(%p)\n",This
);
299 static HRESULT WINAPI
ThreadMgr_EnumFunctionProviders( ITfThreadMgr
* iface
,
300 IEnumTfFunctionProviders
**ppEnum
)
302 ThreadMgr
*This
= (ThreadMgr
*)iface
;
303 FIXME("STUB:(%p)\n",This
);
307 static HRESULT WINAPI
ThreadMgr_GetGlobalCompartment( ITfThreadMgr
* iface
,
308 ITfCompartmentMgr
**ppCompMgr
)
310 ThreadMgr
*This
= (ThreadMgr
*)iface
;
311 FIXME("STUB:(%p)\n",This
);
315 static const ITfThreadMgrVtbl ThreadMgr_ThreadMgrVtbl
=
317 ThreadMgr_QueryInterface
,
321 ThreadMgr_fnActivate
,
322 ThreadMgr_fnDeactivate
,
323 ThreadMgr_CreateDocumentMgr
,
324 ThreadMgr_EnumDocumentMgrs
,
327 ThreadMgr_AssociateFocus
,
328 ThreadMgr_IsThreadFocus
,
329 ThreadMgr_GetFunctionProvider
,
330 ThreadMgr_EnumFunctionProviders
,
331 ThreadMgr_GetGlobalCompartment
335 static HRESULT WINAPI
Source_QueryInterface(ITfSource
*iface
, REFIID iid
, LPVOID
*ppvOut
)
337 ThreadMgr
*This
= impl_from_ITfSourceVtbl(iface
);
338 return ThreadMgr_QueryInterface((ITfThreadMgr
*)This
, iid
, *ppvOut
);
341 static ULONG WINAPI
Source_AddRef(ITfSource
*iface
)
343 ThreadMgr
*This
= impl_from_ITfSourceVtbl(iface
);
344 return ThreadMgr_AddRef((ITfThreadMgr
*)This
);
347 static ULONG WINAPI
Source_Release(ITfSource
*iface
)
349 ThreadMgr
*This
= impl_from_ITfSourceVtbl(iface
);
350 return ThreadMgr_Release((ITfThreadMgr
*)This
);
353 /*****************************************************
354 * ITfSource functions
355 *****************************************************/
356 static WINAPI HRESULT
ThreadMgrSource_AdviseSink(ITfSource
*iface
,
357 REFIID riid
, IUnknown
*punk
, DWORD
*pdwCookie
)
360 ThreadMgr
*This
= impl_from_ITfSourceVtbl(iface
);
362 TRACE("(%p) %s %p %p\n",This
,debugstr_guid(riid
),punk
,pdwCookie
);
364 if (!riid
|| !punk
|| !pdwCookie
)
367 if (IsEqualIID(riid
, &IID_ITfThreadMgrEventSink
))
369 tms
= HeapAlloc(GetProcessHeap(),0,sizeof(ThreadMgrSink
));
371 return E_OUTOFMEMORY
;
372 if (!SUCCEEDED(IUnknown_QueryInterface(punk
, riid
, (LPVOID
*)&tms
->interfaces
.pITfThreadMgrEventSink
)))
374 HeapFree(GetProcessHeap(),0,tms
);
375 return CONNECT_E_CANNOTCONNECT
;
377 list_add_head(&This
->ThreadMgrEventSink
,&tms
->entry
);
378 *pdwCookie
= generate_Cookie(COOKIE_MAGIC_TMSINK
, tms
);
382 FIXME("(%p) Unhandled Sink: %s\n",This
,debugstr_guid(riid
));
386 TRACE("cookie %x\n",*pdwCookie
);
391 static WINAPI HRESULT
ThreadMgrSource_UnadviseSink(ITfSource
*iface
, DWORD pdwCookie
)
394 ThreadMgr
*This
= impl_from_ITfSourceVtbl(iface
);
396 TRACE("(%p) %x\n",This
,pdwCookie
);
398 if (get_Cookie_magic(pdwCookie
)!=COOKIE_MAGIC_TMSINK
)
401 sink
= (ThreadMgrSink
*)remove_Cookie(pdwCookie
);
403 return CONNECT_E_NOCONNECTION
;
405 list_remove(&sink
->entry
);
411 static const ITfSourceVtbl ThreadMgr_SourceVtbl
=
413 Source_QueryInterface
,
417 ThreadMgrSource_AdviseSink
,
418 ThreadMgrSource_UnadviseSink
,
421 /*****************************************************
422 * ITfKeystrokeMgr functions
423 *****************************************************/
425 static HRESULT WINAPI
KeystrokeMgr_QueryInterface(ITfKeystrokeMgr
*iface
, REFIID iid
, LPVOID
*ppvOut
)
427 ThreadMgr
*This
= impl_from_ITfKeystrokeMgrVtbl(iface
);
428 return ThreadMgr_QueryInterface((ITfThreadMgr
*)This
, iid
, *ppvOut
);
431 static ULONG WINAPI
KeystrokeMgr_AddRef(ITfKeystrokeMgr
*iface
)
433 ThreadMgr
*This
= impl_from_ITfKeystrokeMgrVtbl(iface
);
434 return ThreadMgr_AddRef((ITfThreadMgr
*)This
);
437 static ULONG WINAPI
KeystrokeMgr_Release(ITfKeystrokeMgr
*iface
)
439 ThreadMgr
*This
= impl_from_ITfKeystrokeMgrVtbl(iface
);
440 return ThreadMgr_Release((ITfThreadMgr
*)This
);
443 static HRESULT WINAPI
KeystrokeMgr_AdviseKeyEventSink(ITfKeystrokeMgr
*iface
,
444 TfClientId tid
, ITfKeyEventSink
*pSink
, BOOL fForeground
)
446 ThreadMgr
*This
= impl_from_ITfKeystrokeMgrVtbl(iface
);
447 FIXME("STUB:(%p)\n",This
);
451 static HRESULT WINAPI
KeystrokeMgr_UnadviseKeyEventSink(ITfKeystrokeMgr
*iface
,
454 ThreadMgr
*This
= impl_from_ITfKeystrokeMgrVtbl(iface
);
455 FIXME("STUB:(%p)\n",This
);
459 static HRESULT WINAPI
KeystrokeMgr_GetForeground(ITfKeystrokeMgr
*iface
,
462 ThreadMgr
*This
= impl_from_ITfKeystrokeMgrVtbl(iface
);
463 FIXME("STUB:(%p)\n",This
);
467 static HRESULT WINAPI
KeystrokeMgr_TestKeyDown(ITfKeystrokeMgr
*iface
,
468 WPARAM wParam
, LPARAM lParam
, BOOL
*pfEaten
)
470 ThreadMgr
*This
= impl_from_ITfKeystrokeMgrVtbl(iface
);
471 FIXME("STUB:(%p)\n",This
);
475 static HRESULT WINAPI
KeystrokeMgr_TestKeyUp(ITfKeystrokeMgr
*iface
,
476 WPARAM wParam
, LPARAM lParam
, BOOL
*pfEaten
)
478 ThreadMgr
*This
= impl_from_ITfKeystrokeMgrVtbl(iface
);
479 FIXME("STUB:(%p)\n",This
);
483 static HRESULT WINAPI
KeystrokeMgr_KeyDown(ITfKeystrokeMgr
*iface
,
484 WPARAM wParam
, LPARAM lParam
, BOOL
*pfEaten
)
486 ThreadMgr
*This
= impl_from_ITfKeystrokeMgrVtbl(iface
);
487 FIXME("STUB:(%p)\n",This
);
491 static HRESULT WINAPI
KeystrokeMgr_KeyUp(ITfKeystrokeMgr
*iface
,
492 WPARAM wParam
, LPARAM lParam
, BOOL
*pfEaten
)
494 ThreadMgr
*This
= impl_from_ITfKeystrokeMgrVtbl(iface
);
495 FIXME("STUB:(%p)\n",This
);
499 static HRESULT WINAPI
KeystrokeMgr_GetPreservedKey(ITfKeystrokeMgr
*iface
,
500 ITfContext
*pic
, const TF_PRESERVEDKEY
*pprekey
, GUID
*pguid
)
502 ThreadMgr
*This
= impl_from_ITfKeystrokeMgrVtbl(iface
);
503 FIXME("STUB:(%p)\n",This
);
507 static HRESULT WINAPI
KeystrokeMgr_IsPreservedKey(ITfKeystrokeMgr
*iface
,
508 REFGUID rguid
, const TF_PRESERVEDKEY
*pprekey
, BOOL
*pfRegistered
)
510 ThreadMgr
*This
= impl_from_ITfKeystrokeMgrVtbl(iface
);
511 FIXME("STUB:(%p)\n",This
);
515 static HRESULT WINAPI
KeystrokeMgr_PreserveKey(ITfKeystrokeMgr
*iface
,
516 TfClientId tid
, REFGUID rguid
, const TF_PRESERVEDKEY
*prekey
,
517 const WCHAR
*pchDesc
, ULONG cchDesc
)
519 ThreadMgr
*This
= impl_from_ITfKeystrokeMgrVtbl(iface
);
520 FIXME("STUB:(%p)\n",This
);
524 static HRESULT WINAPI
KeystrokeMgr_UnpreserveKey(ITfKeystrokeMgr
*iface
,
525 REFGUID rguid
, const TF_PRESERVEDKEY
*pprekey
)
527 ThreadMgr
*This
= impl_from_ITfKeystrokeMgrVtbl(iface
);
528 FIXME("STUB:(%p)\n",This
);
532 static HRESULT WINAPI
KeystrokeMgr_SetPreservedKeyDescription(ITfKeystrokeMgr
*iface
,
533 REFGUID rguid
, const WCHAR
*pchDesc
, ULONG cchDesc
)
535 ThreadMgr
*This
= impl_from_ITfKeystrokeMgrVtbl(iface
);
536 FIXME("STUB:(%p)\n",This
);
540 static HRESULT WINAPI
KeystrokeMgr_GetPreservedKeyDescription(ITfKeystrokeMgr
*iface
,
541 REFGUID rguid
, BSTR
*pbstrDesc
)
543 ThreadMgr
*This
= impl_from_ITfKeystrokeMgrVtbl(iface
);
544 FIXME("STUB:(%p)\n",This
);
548 static HRESULT WINAPI
KeystrokeMgr_SimulatePreservedKey(ITfKeystrokeMgr
*iface
,
549 ITfContext
*pic
, REFGUID rguid
, BOOL
*pfEaten
)
551 ThreadMgr
*This
= impl_from_ITfKeystrokeMgrVtbl(iface
);
552 FIXME("STUB:(%p)\n",This
);
556 static const ITfKeystrokeMgrVtbl ThreadMgr_KeystrokeMgrVtbl
=
558 KeystrokeMgr_QueryInterface
,
560 KeystrokeMgr_Release
,
562 KeystrokeMgr_AdviseKeyEventSink
,
563 KeystrokeMgr_UnadviseKeyEventSink
,
564 KeystrokeMgr_GetForeground
,
565 KeystrokeMgr_TestKeyDown
,
566 KeystrokeMgr_TestKeyUp
,
567 KeystrokeMgr_KeyDown
,
569 KeystrokeMgr_GetPreservedKey
,
570 KeystrokeMgr_IsPreservedKey
,
571 KeystrokeMgr_PreserveKey
,
572 KeystrokeMgr_UnpreserveKey
,
573 KeystrokeMgr_SetPreservedKeyDescription
,
574 KeystrokeMgr_GetPreservedKeyDescription
,
575 KeystrokeMgr_SimulatePreservedKey
578 /*****************************************************
579 * ITfThreadMgrEventSink functions (internal)
580 *****************************************************/
581 static HRESULT WINAPI
ThreadMgrEventSink_QueryInterface(ITfThreadMgrEventSink
*iface
, REFIID iid
, LPVOID
*ppvOut
)
583 ThreadMgr
*This
= impl_from_ITfThreadMgrEventSink(iface
);
584 return ThreadMgr_QueryInterface((ITfThreadMgr
*)This
, iid
, *ppvOut
);
587 static ULONG WINAPI
ThreadMgrEventSink_AddRef(ITfThreadMgrEventSink
*iface
)
589 ThreadMgr
*This
= impl_from_ITfThreadMgrEventSink(iface
);
590 return ThreadMgr_AddRef((ITfThreadMgr
*)This
);
593 static ULONG WINAPI
ThreadMgrEventSink_Release(ITfThreadMgrEventSink
*iface
)
595 ThreadMgr
*This
= impl_from_ITfThreadMgrEventSink(iface
);
596 return ThreadMgr_Release((ITfThreadMgr
*)This
);
600 static WINAPI HRESULT
ThreadMgrEventSink_OnInitDocumentMgr(
601 ITfThreadMgrEventSink
*iface
,ITfDocumentMgr
*pdim
)
604 ThreadMgr
*This
= impl_from_ITfThreadMgrEventSink(iface
);
606 TRACE("(%p) %p\n",This
,pdim
);
608 LIST_FOR_EACH(cursor
, &This
->ThreadMgrEventSink
)
610 ThreadMgrSink
* sink
= LIST_ENTRY(cursor
,ThreadMgrSink
,entry
);
611 ITfThreadMgrEventSink_OnInitDocumentMgr(sink
->interfaces
.pITfThreadMgrEventSink
,pdim
);
617 static WINAPI HRESULT
ThreadMgrEventSink_OnUninitDocumentMgr(
618 ITfThreadMgrEventSink
*iface
, ITfDocumentMgr
*pdim
)
621 ThreadMgr
*This
= impl_from_ITfThreadMgrEventSink(iface
);
623 TRACE("(%p) %p\n",This
,pdim
);
625 LIST_FOR_EACH(cursor
, &This
->ThreadMgrEventSink
)
627 ThreadMgrSink
* sink
= LIST_ENTRY(cursor
,ThreadMgrSink
,entry
);
628 ITfThreadMgrEventSink_OnUninitDocumentMgr(sink
->interfaces
.pITfThreadMgrEventSink
,pdim
);
634 static WINAPI HRESULT
ThreadMgrEventSink_OnSetFocus(
635 ITfThreadMgrEventSink
*iface
, ITfDocumentMgr
*pdimFocus
,
636 ITfDocumentMgr
*pdimPrevFocus
)
639 ThreadMgr
*This
= impl_from_ITfThreadMgrEventSink(iface
);
641 TRACE("(%p) %p %p\n",This
,pdimFocus
, pdimPrevFocus
);
643 LIST_FOR_EACH(cursor
, &This
->ThreadMgrEventSink
)
645 ThreadMgrSink
* sink
= LIST_ENTRY(cursor
,ThreadMgrSink
,entry
);
646 ITfThreadMgrEventSink_OnSetFocus(sink
->interfaces
.pITfThreadMgrEventSink
, pdimFocus
, pdimPrevFocus
);
652 static WINAPI HRESULT
ThreadMgrEventSink_OnPushContext(
653 ITfThreadMgrEventSink
*iface
, ITfContext
*pic
)
656 ThreadMgr
*This
= impl_from_ITfThreadMgrEventSink(iface
);
658 TRACE("(%p) %p\n",This
,pic
);
660 LIST_FOR_EACH(cursor
, &This
->ThreadMgrEventSink
)
662 ThreadMgrSink
* sink
= LIST_ENTRY(cursor
,ThreadMgrSink
,entry
);
663 ITfThreadMgrEventSink_OnPushContext(sink
->interfaces
.pITfThreadMgrEventSink
,pic
);
669 static WINAPI HRESULT
ThreadMgrEventSink_OnPopContext(
670 ITfThreadMgrEventSink
*iface
, ITfContext
*pic
)
673 ThreadMgr
*This
= impl_from_ITfThreadMgrEventSink(iface
);
675 TRACE("(%p) %p\n",This
,pic
);
677 LIST_FOR_EACH(cursor
, &This
->ThreadMgrEventSink
)
679 ThreadMgrSink
* sink
= LIST_ENTRY(cursor
,ThreadMgrSink
,entry
);
680 ITfThreadMgrEventSink_OnPopContext(sink
->interfaces
.pITfThreadMgrEventSink
,pic
);
686 static const ITfThreadMgrEventSinkVtbl ThreadMgr_ThreadMgrEventSinkVtbl
=
688 ThreadMgrEventSink_QueryInterface
,
689 ThreadMgrEventSink_AddRef
,
690 ThreadMgrEventSink_Release
,
692 ThreadMgrEventSink_OnInitDocumentMgr
,
693 ThreadMgrEventSink_OnUninitDocumentMgr
,
694 ThreadMgrEventSink_OnSetFocus
,
695 ThreadMgrEventSink_OnPushContext
,
696 ThreadMgrEventSink_OnPopContext
699 HRESULT
ThreadMgr_Constructor(IUnknown
*pUnkOuter
, IUnknown
**ppOut
)
703 return CLASS_E_NOAGGREGATION
;
705 /* Only 1 ThreadMgr is created per thread */
706 This
= TlsGetValue(tlsIndex
);
709 ThreadMgr_AddRef((ITfThreadMgr
*)This
);
710 *ppOut
= (IUnknown
*)This
;
714 This
= HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY
,sizeof(ThreadMgr
));
716 return E_OUTOFMEMORY
;
718 This
->ThreadMgrVtbl
= &ThreadMgr_ThreadMgrVtbl
;
719 This
->SourceVtbl
= &ThreadMgr_SourceVtbl
;
720 This
->KeystrokeMgrVtbl
= &ThreadMgr_KeystrokeMgrVtbl
;
721 This
->ThreadMgrEventSinkVtbl
= &ThreadMgr_ThreadMgrEventSinkVtbl
;
723 TlsSetValue(tlsIndex
,This
);
725 list_init(&This
->ActiveLanguageProfileNotifySink
);
726 list_init(&This
->DisplayAttributeNotifySink
);
727 list_init(&This
->KeyTraceEventSink
);
728 list_init(&This
->PreservedKeyNotifySink
);
729 list_init(&This
->ThreadFocusSink
);
730 list_init(&This
->ThreadMgrEventSink
);
732 TRACE("returning %p\n", This
);
733 *ppOut
= (IUnknown
*)This
;