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 tagDocumentMgrs
71 ITfDocumentMgr
*docmgr
;
74 typedef struct tagAssociatedWindow
78 ITfDocumentMgr
*docmgr
;
81 typedef struct tagACLMulti
{
82 const ITfThreadMgrVtbl
*ThreadMgrVtbl
;
83 const ITfSourceVtbl
*SourceVtbl
;
84 const ITfKeystrokeMgrVtbl
*KeystrokeMgrVtbl
;
85 const ITfMessagePumpVtbl
*MessagePumpVtbl
;
86 const ITfClientIdVtbl
*ClientIdVtbl
;
87 /* const ITfThreadMgrExVtbl *ThreadMgrExVtbl; */
88 /* const ITfConfigureSystemKeystrokeFeedVtbl *ConfigureSystemKeystrokeFeedVtbl; */
89 /* const ITfLangBarItemMgrVtbl *LangBarItemMgrVtbl; */
90 /* const ITfUIElementMgrVtbl *UIElementMgrVtbl; */
91 const ITfSourceSingleVtbl
*SourceSingleVtbl
;
95 ITfCompartmentMgr
*CompartmentMgr
;
97 const ITfThreadMgrEventSinkVtbl
*ThreadMgrEventSinkVtbl
; /* internal */
99 ITfDocumentMgr
*focus
;
100 LONG activationCount
;
102 ITfKeyEventSink
*forgroundKeyEventSink
;
103 CLSID forgroundTextService
;
105 struct list CurrentPreservedKeys
;
106 struct list CreatedDocumentMgrs
;
108 struct list AssociatedFocusWindows
;
111 /* kept as separate lists to reduce unnecessary iterations */
112 struct list ActiveLanguageProfileNotifySink
;
113 struct list DisplayAttributeNotifySink
;
114 struct list KeyTraceEventSink
;
115 struct list PreservedKeyNotifySink
;
116 struct list ThreadFocusSink
;
117 struct list ThreadMgrEventSink
;
120 typedef struct tagEnumTfDocumentMgr
{
121 const IEnumTfDocumentMgrsVtbl
*Vtbl
;
128 static HRESULT
EnumTfDocumentMgr_Constructor(struct list
* head
, IEnumTfDocumentMgrs
**ppOut
);
130 static inline ThreadMgr
*impl_from_ITfSourceVtbl(ITfSource
*iface
)
132 return (ThreadMgr
*)((char *)iface
- FIELD_OFFSET(ThreadMgr
,SourceVtbl
));
135 static inline ThreadMgr
*impl_from_ITfKeystrokeMgrVtbl(ITfKeystrokeMgr
*iface
)
137 return (ThreadMgr
*)((char *)iface
- FIELD_OFFSET(ThreadMgr
,KeystrokeMgrVtbl
));
140 static inline ThreadMgr
*impl_from_ITfMessagePumpVtbl(ITfMessagePump
*iface
)
142 return (ThreadMgr
*)((char *)iface
- FIELD_OFFSET(ThreadMgr
,MessagePumpVtbl
));
145 static inline ThreadMgr
*impl_from_ITfClientIdVtbl(ITfClientId
*iface
)
147 return (ThreadMgr
*)((char *)iface
- FIELD_OFFSET(ThreadMgr
,ClientIdVtbl
));
150 static inline ThreadMgr
*impl_from_ITfThreadMgrEventSink(ITfThreadMgrEventSink
*iface
)
152 return (ThreadMgr
*)((char *)iface
- FIELD_OFFSET(ThreadMgr
,ThreadMgrEventSinkVtbl
));
155 static inline ThreadMgr
*impl_from_ITfSourceSingleVtbl(ITfSourceSingle
* iface
)
158 return (ThreadMgr
*)((char *)iface
- FIELD_OFFSET(ThreadMgr
,SourceSingleVtbl
));
161 static void free_sink(ThreadMgrSink
*sink
)
163 IUnknown_Release(sink
->interfaces
.pIUnknown
);
164 HeapFree(GetProcessHeap(),0,sink
);
167 static void ThreadMgr_Destructor(ThreadMgr
*This
)
169 struct list
*cursor
, *cursor2
;
171 /* unhook right away */
173 UnhookWindowsHookEx(This
->focusHook
);
175 TlsSetValue(tlsIndex
,NULL
);
176 TRACE("destroying %p\n", This
);
178 ITfDocumentMgr_Release(This
->focus
);
181 LIST_FOR_EACH_SAFE(cursor
, cursor2
, &This
->ActiveLanguageProfileNotifySink
)
183 ThreadMgrSink
* sink
= LIST_ENTRY(cursor
,ThreadMgrSink
,entry
);
187 LIST_FOR_EACH_SAFE(cursor
, cursor2
, &This
->DisplayAttributeNotifySink
)
189 ThreadMgrSink
* sink
= LIST_ENTRY(cursor
,ThreadMgrSink
,entry
);
193 LIST_FOR_EACH_SAFE(cursor
, cursor2
, &This
->KeyTraceEventSink
)
195 ThreadMgrSink
* sink
= LIST_ENTRY(cursor
,ThreadMgrSink
,entry
);
199 LIST_FOR_EACH_SAFE(cursor
, cursor2
, &This
->PreservedKeyNotifySink
)
201 ThreadMgrSink
* sink
= LIST_ENTRY(cursor
,ThreadMgrSink
,entry
);
205 LIST_FOR_EACH_SAFE(cursor
, cursor2
, &This
->ThreadFocusSink
)
207 ThreadMgrSink
* sink
= LIST_ENTRY(cursor
,ThreadMgrSink
,entry
);
211 LIST_FOR_EACH_SAFE(cursor
, cursor2
, &This
->ThreadMgrEventSink
)
213 ThreadMgrSink
* sink
= LIST_ENTRY(cursor
,ThreadMgrSink
,entry
);
218 LIST_FOR_EACH_SAFE(cursor
, cursor2
, &This
->CurrentPreservedKeys
)
220 PreservedKey
* key
= LIST_ENTRY(cursor
,PreservedKey
,entry
);
222 HeapFree(GetProcessHeap(),0,key
->description
);
223 HeapFree(GetProcessHeap(),0,key
);
226 LIST_FOR_EACH_SAFE(cursor
, cursor2
, &This
->CreatedDocumentMgrs
)
228 DocumentMgrEntry
*mgr
= LIST_ENTRY(cursor
,DocumentMgrEntry
,entry
);
230 FIXME("Left Over ITfDocumentMgr. Should we do something with it?\n");
231 HeapFree(GetProcessHeap(),0,mgr
);
234 LIST_FOR_EACH_SAFE(cursor
, cursor2
, &This
->AssociatedFocusWindows
)
236 AssociatedWindow
*wnd
= LIST_ENTRY(cursor
,AssociatedWindow
,entry
);
238 HeapFree(GetProcessHeap(),0,wnd
);
241 CompartmentMgr_Destructor(This
->CompartmentMgr
);
243 HeapFree(GetProcessHeap(),0,This
);
246 static HRESULT WINAPI
ThreadMgr_QueryInterface(ITfThreadMgr
*iface
, REFIID iid
, LPVOID
*ppvOut
)
248 ThreadMgr
*This
= (ThreadMgr
*)iface
;
251 if (IsEqualIID(iid
, &IID_IUnknown
) || IsEqualIID(iid
, &IID_ITfThreadMgr
))
255 else if (IsEqualIID(iid
, &IID_ITfSource
))
257 *ppvOut
= &This
->SourceVtbl
;
259 else if (IsEqualIID(iid
, &IID_ITfKeystrokeMgr
))
261 *ppvOut
= &This
->KeystrokeMgrVtbl
;
263 else if (IsEqualIID(iid
, &IID_ITfMessagePump
))
265 *ppvOut
= &This
->MessagePumpVtbl
;
267 else if (IsEqualIID(iid
, &IID_ITfClientId
))
269 *ppvOut
= &This
->ClientIdVtbl
;
271 else if (IsEqualIID(iid
, &IID_ITfCompartmentMgr
))
273 *ppvOut
= This
->CompartmentMgr
;
275 else if (IsEqualIID(iid
, &IID_ITfSourceSingle
))
277 *ppvOut
= &This
->SourceSingleVtbl
;
282 IUnknown_AddRef(iface
);
286 WARN("unsupported interface: %s\n", debugstr_guid(iid
));
287 return E_NOINTERFACE
;
290 static ULONG WINAPI
ThreadMgr_AddRef(ITfThreadMgr
*iface
)
292 ThreadMgr
*This
= (ThreadMgr
*)iface
;
293 return InterlockedIncrement(&This
->refCount
);
296 static ULONG WINAPI
ThreadMgr_Release(ITfThreadMgr
*iface
)
298 ThreadMgr
*This
= (ThreadMgr
*)iface
;
301 ret
= InterlockedDecrement(&This
->refCount
);
303 ThreadMgr_Destructor(This
);
307 /*****************************************************
308 * ITfThreadMgr functions
309 *****************************************************/
311 static HRESULT WINAPI
ThreadMgr_fnActivate( ITfThreadMgr
* iface
, TfClientId
*ptid
)
313 ThreadMgr
*This
= (ThreadMgr
*)iface
;
315 TRACE("(%p) %p\n",This
, ptid
);
324 ITfClientId_GetClientId((ITfClientId
*)&This
->ClientIdVtbl
,&guid
,&processId
);
327 activate_textservices(iface
);
328 This
->activationCount
++;
333 static HRESULT WINAPI
ThreadMgr_fnDeactivate( ITfThreadMgr
* iface
)
335 ThreadMgr
*This
= (ThreadMgr
*)iface
;
336 TRACE("(%p)\n",This
);
338 if (This
->activationCount
== 0)
341 This
->activationCount
--;
343 if (This
->activationCount
== 0)
347 ITfThreadMgrEventSink_OnSetFocus((ITfThreadMgrEventSink
*)&This
->ThreadMgrEventSinkVtbl
, 0, This
->focus
);
348 ITfDocumentMgr_Release(This
->focus
);
353 deactivate_textservices();
358 static HRESULT WINAPI
ThreadMgr_CreateDocumentMgr( ITfThreadMgr
* iface
, ITfDocumentMgr
361 ThreadMgr
*This
= (ThreadMgr
*)iface
;
362 DocumentMgrEntry
*mgrentry
;
365 TRACE("(%p)\n",iface
);
366 mgrentry
= HeapAlloc(GetProcessHeap(),0,sizeof(DocumentMgrEntry
));
367 if (mgrentry
== NULL
)
368 return E_OUTOFMEMORY
;
370 hr
= DocumentMgr_Constructor((ITfThreadMgrEventSink
*)&This
->ThreadMgrEventSinkVtbl
, ppdim
);
374 mgrentry
->docmgr
= *ppdim
;
375 list_add_head(&This
->CreatedDocumentMgrs
,&mgrentry
->entry
);
378 HeapFree(GetProcessHeap(),0,mgrentry
);
383 static HRESULT WINAPI
ThreadMgr_EnumDocumentMgrs( ITfThreadMgr
* iface
, IEnumTfDocumentMgrs
386 ThreadMgr
*This
= (ThreadMgr
*)iface
;
387 TRACE("(%p) %p\n",This
,ppEnum
);
392 return EnumTfDocumentMgr_Constructor(&This
->CreatedDocumentMgrs
, ppEnum
);
395 static HRESULT WINAPI
ThreadMgr_GetFocus( ITfThreadMgr
* iface
, ITfDocumentMgr
398 ThreadMgr
*This
= (ThreadMgr
*)iface
;
399 TRACE("(%p)\n",This
);
404 *ppdimFocus
= This
->focus
;
406 TRACE("->%p\n",This
->focus
);
408 if (This
->focus
== NULL
)
411 ITfDocumentMgr_AddRef(This
->focus
);
416 static HRESULT WINAPI
ThreadMgr_SetFocus( ITfThreadMgr
* iface
, ITfDocumentMgr
*pdimFocus
)
418 ITfDocumentMgr
*check
;
419 ThreadMgr
*This
= (ThreadMgr
*)iface
;
421 TRACE("(%p) %p\n",This
,pdimFocus
);
425 else if (FAILED(IUnknown_QueryInterface(pdimFocus
,&IID_ITfDocumentMgr
,(LPVOID
*) &check
)))
428 ITfThreadMgrEventSink_OnSetFocus((ITfThreadMgrEventSink
*)&This
->ThreadMgrEventSinkVtbl
, check
, This
->focus
);
431 ITfDocumentMgr_Release(This
->focus
);
437 static LRESULT CALLBACK
ThreadFocusHookProc(int nCode
, WPARAM wParam
, LPARAM lParam
)
441 This
= TlsGetValue(tlsIndex
);
444 ERR("Hook proc but no ThreadMgr for this thread. Serious Error\n");
447 if (!This
->focusHook
)
449 ERR("Hook proc but no ThreadMgr focus Hook. Serious Error\n");
453 if (nCode
== HCBT_SETFOCUS
) /* focus change within our thread */
457 LIST_FOR_EACH(cursor
, &This
->AssociatedFocusWindows
)
459 AssociatedWindow
*wnd
= LIST_ENTRY(cursor
,AssociatedWindow
,entry
);
460 if (wnd
->hwnd
== (HWND
)wParam
)
462 TRACE("Triggering Associated window focus\n");
463 if (This
->focus
!= wnd
->docmgr
)
464 ThreadMgr_SetFocus((ITfThreadMgr
*)This
, wnd
->docmgr
);
470 return CallNextHookEx(This
->focusHook
, nCode
, wParam
, lParam
);
473 static HRESULT
SetupWindowsHook(ThreadMgr
*This
)
475 if (!This
->focusHook
)
477 This
->focusHook
= SetWindowsHookExW(WH_CBT
, ThreadFocusHookProc
, 0,
478 GetCurrentThreadId());
479 if (!This
->focusHook
)
481 ERR("Unable to set focus hook\n");
489 static HRESULT WINAPI
ThreadMgr_AssociateFocus( ITfThreadMgr
* iface
, HWND hwnd
,
490 ITfDocumentMgr
*pdimNew
, ITfDocumentMgr
**ppdimPrev
)
492 struct list
*cursor
, *cursor2
;
493 ThreadMgr
*This
= (ThreadMgr
*)iface
;
494 AssociatedWindow
*wnd
;
496 TRACE("(%p) %p %p %p\n",This
,hwnd
,pdimNew
,ppdimPrev
);
503 LIST_FOR_EACH_SAFE(cursor
, cursor2
, &This
->AssociatedFocusWindows
)
505 wnd
= LIST_ENTRY(cursor
,AssociatedWindow
,entry
);
506 if (wnd
->hwnd
== hwnd
)
509 ITfDocumentMgr_AddRef(wnd
->docmgr
);
510 *ppdimPrev
= wnd
->docmgr
;
511 wnd
->docmgr
= pdimNew
;
512 if (GetFocus() == hwnd
)
513 ThreadMgr_SetFocus(iface
,pdimNew
);
518 wnd
= HeapAlloc(GetProcessHeap(),0,sizeof(AssociatedWindow
));
520 wnd
->docmgr
= pdimNew
;
521 list_add_head(&This
->AssociatedFocusWindows
,&wnd
->entry
);
523 if (GetFocus() == hwnd
)
524 ThreadMgr_SetFocus(iface
,pdimNew
);
526 SetupWindowsHook(This
);
531 static HRESULT WINAPI
ThreadMgr_IsThreadFocus( ITfThreadMgr
* iface
, BOOL
*pfThreadFocus
)
534 ThreadMgr
*This
= (ThreadMgr
*)iface
;
535 TRACE("(%p) %p\n",This
,pfThreadFocus
);
537 *pfThreadFocus
= (focus
== NULL
);
541 static HRESULT WINAPI
ThreadMgr_GetFunctionProvider( ITfThreadMgr
* iface
, REFCLSID clsid
,
542 ITfFunctionProvider
**ppFuncProv
)
544 ThreadMgr
*This
= (ThreadMgr
*)iface
;
545 FIXME("STUB:(%p)\n",This
);
549 static HRESULT WINAPI
ThreadMgr_EnumFunctionProviders( ITfThreadMgr
* iface
,
550 IEnumTfFunctionProviders
**ppEnum
)
552 ThreadMgr
*This
= (ThreadMgr
*)iface
;
553 FIXME("STUB:(%p)\n",This
);
557 static HRESULT WINAPI
ThreadMgr_GetGlobalCompartment( ITfThreadMgr
* iface
,
558 ITfCompartmentMgr
**ppCompMgr
)
560 ThreadMgr
*This
= (ThreadMgr
*)iface
;
562 TRACE("(%p) %p\n",This
, ppCompMgr
);
567 if (!globalCompartmentMgr
)
569 hr
= CompartmentMgr_Constructor(NULL
,&IID_ITfCompartmentMgr
,(IUnknown
**)&globalCompartmentMgr
);
574 ITfCompartmentMgr_AddRef(globalCompartmentMgr
);
575 *ppCompMgr
= globalCompartmentMgr
;
579 static const ITfThreadMgrVtbl ThreadMgr_ThreadMgrVtbl
=
581 ThreadMgr_QueryInterface
,
585 ThreadMgr_fnActivate
,
586 ThreadMgr_fnDeactivate
,
587 ThreadMgr_CreateDocumentMgr
,
588 ThreadMgr_EnumDocumentMgrs
,
591 ThreadMgr_AssociateFocus
,
592 ThreadMgr_IsThreadFocus
,
593 ThreadMgr_GetFunctionProvider
,
594 ThreadMgr_EnumFunctionProviders
,
595 ThreadMgr_GetGlobalCompartment
599 static HRESULT WINAPI
Source_QueryInterface(ITfSource
*iface
, REFIID iid
, LPVOID
*ppvOut
)
601 ThreadMgr
*This
= impl_from_ITfSourceVtbl(iface
);
602 return ThreadMgr_QueryInterface((ITfThreadMgr
*)This
, iid
, *ppvOut
);
605 static ULONG WINAPI
Source_AddRef(ITfSource
*iface
)
607 ThreadMgr
*This
= impl_from_ITfSourceVtbl(iface
);
608 return ThreadMgr_AddRef((ITfThreadMgr
*)This
);
611 static ULONG WINAPI
Source_Release(ITfSource
*iface
)
613 ThreadMgr
*This
= impl_from_ITfSourceVtbl(iface
);
614 return ThreadMgr_Release((ITfThreadMgr
*)This
);
617 /*****************************************************
618 * ITfSource functions
619 *****************************************************/
620 static HRESULT WINAPI
ThreadMgrSource_AdviseSink(ITfSource
*iface
,
621 REFIID riid
, IUnknown
*punk
, DWORD
*pdwCookie
)
624 ThreadMgr
*This
= impl_from_ITfSourceVtbl(iface
);
626 TRACE("(%p) %s %p %p\n",This
,debugstr_guid(riid
),punk
,pdwCookie
);
628 if (!riid
|| !punk
|| !pdwCookie
)
631 if (IsEqualIID(riid
, &IID_ITfThreadMgrEventSink
))
633 tms
= HeapAlloc(GetProcessHeap(),0,sizeof(ThreadMgrSink
));
635 return E_OUTOFMEMORY
;
636 if (FAILED(IUnknown_QueryInterface(punk
, riid
, (LPVOID
*)&tms
->interfaces
.pITfThreadMgrEventSink
)))
638 HeapFree(GetProcessHeap(),0,tms
);
639 return CONNECT_E_CANNOTCONNECT
;
641 list_add_head(&This
->ThreadMgrEventSink
,&tms
->entry
);
642 *pdwCookie
= generate_Cookie(COOKIE_MAGIC_TMSINK
, tms
);
646 FIXME("(%p) Unhandled Sink: %s\n",This
,debugstr_guid(riid
));
650 TRACE("cookie %x\n",*pdwCookie
);
655 static HRESULT WINAPI
ThreadMgrSource_UnadviseSink(ITfSource
*iface
, DWORD pdwCookie
)
658 ThreadMgr
*This
= impl_from_ITfSourceVtbl(iface
);
660 TRACE("(%p) %x\n",This
,pdwCookie
);
662 if (get_Cookie_magic(pdwCookie
)!=COOKIE_MAGIC_TMSINK
)
665 sink
= (ThreadMgrSink
*)remove_Cookie(pdwCookie
);
667 return CONNECT_E_NOCONNECTION
;
669 list_remove(&sink
->entry
);
675 static const ITfSourceVtbl ThreadMgr_SourceVtbl
=
677 Source_QueryInterface
,
681 ThreadMgrSource_AdviseSink
,
682 ThreadMgrSource_UnadviseSink
,
685 /*****************************************************
686 * ITfKeystrokeMgr functions
687 *****************************************************/
689 static HRESULT WINAPI
KeystrokeMgr_QueryInterface(ITfKeystrokeMgr
*iface
, REFIID iid
, LPVOID
*ppvOut
)
691 ThreadMgr
*This
= impl_from_ITfKeystrokeMgrVtbl(iface
);
692 return ThreadMgr_QueryInterface((ITfThreadMgr
*)This
, iid
, *ppvOut
);
695 static ULONG WINAPI
KeystrokeMgr_AddRef(ITfKeystrokeMgr
*iface
)
697 ThreadMgr
*This
= impl_from_ITfKeystrokeMgrVtbl(iface
);
698 return ThreadMgr_AddRef((ITfThreadMgr
*)This
);
701 static ULONG WINAPI
KeystrokeMgr_Release(ITfKeystrokeMgr
*iface
)
703 ThreadMgr
*This
= impl_from_ITfKeystrokeMgrVtbl(iface
);
704 return ThreadMgr_Release((ITfThreadMgr
*)This
);
707 static HRESULT WINAPI
KeystrokeMgr_AdviseKeyEventSink(ITfKeystrokeMgr
*iface
,
708 TfClientId tid
, ITfKeyEventSink
*pSink
, BOOL fForeground
)
710 ThreadMgr
*This
= impl_from_ITfKeystrokeMgrVtbl(iface
);
712 ITfKeyEventSink
*check
= NULL
;
714 TRACE("(%p) %x %p %i\n",This
,tid
,pSink
,fForeground
);
719 textservice
= get_textservice_clsid(tid
);
720 if (IsEqualCLSID(&GUID_NULL
,&textservice
))
723 get_textservice_sink(tid
, &IID_ITfKeyEventSink
, (IUnknown
**)&check
);
725 return CONNECT_E_ADVISELIMIT
;
727 if (FAILED(IUnknown_QueryInterface(pSink
,&IID_ITfKeyEventSink
,(LPVOID
*) &check
)))
730 set_textservice_sink(tid
, &IID_ITfKeyEventSink
, (IUnknown
*)check
);
734 if (This
->forgroundKeyEventSink
)
736 ITfKeyEventSink_OnSetFocus(This
->forgroundKeyEventSink
, FALSE
);
737 ITfKeyEventSink_Release(This
->forgroundKeyEventSink
);
739 ITfKeyEventSink_AddRef(check
);
740 ITfKeyEventSink_OnSetFocus(check
, TRUE
);
741 This
->forgroundKeyEventSink
= check
;
742 This
->forgroundTextService
= textservice
;
747 static HRESULT WINAPI
KeystrokeMgr_UnadviseKeyEventSink(ITfKeystrokeMgr
*iface
,
750 ThreadMgr
*This
= impl_from_ITfKeystrokeMgrVtbl(iface
);
752 ITfKeyEventSink
*check
= NULL
;
753 TRACE("(%p) %x\n",This
,tid
);
758 textservice
= get_textservice_clsid(tid
);
759 if (IsEqualCLSID(&GUID_NULL
,&textservice
))
762 get_textservice_sink(tid
, &IID_ITfKeyEventSink
, (IUnknown
**)&check
);
765 return CONNECT_E_NOCONNECTION
;
767 set_textservice_sink(tid
, &IID_ITfKeyEventSink
, NULL
);
768 ITfKeyEventSink_Release(check
);
770 if (This
->forgroundKeyEventSink
== check
)
772 ITfKeyEventSink_Release(This
->forgroundKeyEventSink
);
773 This
->forgroundKeyEventSink
= NULL
;
774 This
->forgroundTextService
= GUID_NULL
;
779 static HRESULT WINAPI
KeystrokeMgr_GetForeground(ITfKeystrokeMgr
*iface
,
782 ThreadMgr
*This
= impl_from_ITfKeystrokeMgrVtbl(iface
);
783 TRACE("(%p) %p\n",This
,pclsid
);
787 if (IsEqualCLSID(&This
->forgroundTextService
,&GUID_NULL
))
790 *pclsid
= This
->forgroundTextService
;
794 static HRESULT WINAPI
KeystrokeMgr_TestKeyDown(ITfKeystrokeMgr
*iface
,
795 WPARAM wParam
, LPARAM lParam
, BOOL
*pfEaten
)
797 ThreadMgr
*This
= impl_from_ITfKeystrokeMgrVtbl(iface
);
798 FIXME("STUB:(%p)\n",This
);
802 static HRESULT WINAPI
KeystrokeMgr_TestKeyUp(ITfKeystrokeMgr
*iface
,
803 WPARAM wParam
, LPARAM lParam
, BOOL
*pfEaten
)
805 ThreadMgr
*This
= impl_from_ITfKeystrokeMgrVtbl(iface
);
806 FIXME("STUB:(%p)\n",This
);
810 static HRESULT WINAPI
KeystrokeMgr_KeyDown(ITfKeystrokeMgr
*iface
,
811 WPARAM wParam
, LPARAM lParam
, BOOL
*pfEaten
)
813 ThreadMgr
*This
= impl_from_ITfKeystrokeMgrVtbl(iface
);
814 FIXME("STUB:(%p)\n",This
);
818 static HRESULT WINAPI
KeystrokeMgr_KeyUp(ITfKeystrokeMgr
*iface
,
819 WPARAM wParam
, LPARAM lParam
, BOOL
*pfEaten
)
821 ThreadMgr
*This
= impl_from_ITfKeystrokeMgrVtbl(iface
);
822 FIXME("STUB:(%p)\n",This
);
826 static HRESULT WINAPI
KeystrokeMgr_GetPreservedKey(ITfKeystrokeMgr
*iface
,
827 ITfContext
*pic
, const TF_PRESERVEDKEY
*pprekey
, GUID
*pguid
)
829 ThreadMgr
*This
= impl_from_ITfKeystrokeMgrVtbl(iface
);
830 FIXME("STUB:(%p)\n",This
);
834 static HRESULT WINAPI
KeystrokeMgr_IsPreservedKey(ITfKeystrokeMgr
*iface
,
835 REFGUID rguid
, const TF_PRESERVEDKEY
*pprekey
, BOOL
*pfRegistered
)
837 ThreadMgr
*This
= impl_from_ITfKeystrokeMgrVtbl(iface
);
840 TRACE("(%p) %s (%x %x) %p\n",This
,debugstr_guid(rguid
), (pprekey
)?pprekey
->uVKey
:0, (pprekey
)?pprekey
->uModifiers
:0, pfRegistered
);
842 if (!rguid
|| !pprekey
|| !pfRegistered
)
845 LIST_FOR_EACH(cursor
, &This
->CurrentPreservedKeys
)
847 PreservedKey
* key
= LIST_ENTRY(cursor
,PreservedKey
,entry
);
848 if (IsEqualGUID(rguid
,&key
->guid
) && pprekey
->uVKey
== key
->prekey
.uVKey
&& pprekey
->uModifiers
== key
->prekey
.uModifiers
)
850 *pfRegistered
= TRUE
;
855 *pfRegistered
= FALSE
;
859 static HRESULT WINAPI
KeystrokeMgr_PreserveKey(ITfKeystrokeMgr
*iface
,
860 TfClientId tid
, REFGUID rguid
, const TF_PRESERVEDKEY
*prekey
,
861 const WCHAR
*pchDesc
, ULONG cchDesc
)
863 ThreadMgr
*This
= impl_from_ITfKeystrokeMgrVtbl(iface
);
865 PreservedKey
*newkey
;
867 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
));
869 if (!tid
|| ! rguid
|| !prekey
|| (cchDesc
&& !pchDesc
))
872 LIST_FOR_EACH(cursor
, &This
->CurrentPreservedKeys
)
874 PreservedKey
* key
= LIST_ENTRY(cursor
,PreservedKey
,entry
);
875 if (IsEqualGUID(rguid
,&key
->guid
) && prekey
->uVKey
== key
->prekey
.uVKey
&& prekey
->uModifiers
== key
->prekey
.uModifiers
)
876 return TF_E_ALREADY_EXISTS
;
879 newkey
= HeapAlloc(GetProcessHeap(),0,sizeof(PreservedKey
));
881 return E_OUTOFMEMORY
;
883 newkey
->guid
= *rguid
;
884 newkey
->prekey
= *prekey
;
886 newkey
->description
= NULL
;
889 newkey
->description
= HeapAlloc(GetProcessHeap(),0,cchDesc
* sizeof(WCHAR
));
890 if (!newkey
->description
)
892 HeapFree(GetProcessHeap(),0,newkey
);
893 return E_OUTOFMEMORY
;
895 memcpy(newkey
->description
, pchDesc
, cchDesc
*sizeof(WCHAR
));
898 list_add_head(&This
->CurrentPreservedKeys
,&newkey
->entry
);
903 static HRESULT WINAPI
KeystrokeMgr_UnpreserveKey(ITfKeystrokeMgr
*iface
,
904 REFGUID rguid
, const TF_PRESERVEDKEY
*pprekey
)
906 ThreadMgr
*This
= impl_from_ITfKeystrokeMgrVtbl(iface
);
907 PreservedKey
* key
= NULL
;
909 TRACE("(%p) %s (%x %x)\n",This
,debugstr_guid(rguid
),(pprekey
)?pprekey
->uVKey
:0, (pprekey
)?pprekey
->uModifiers
:0);
911 if (!pprekey
|| !rguid
)
914 LIST_FOR_EACH(cursor
, &This
->CurrentPreservedKeys
)
916 key
= LIST_ENTRY(cursor
,PreservedKey
,entry
);
917 if (IsEqualGUID(rguid
,&key
->guid
) && pprekey
->uVKey
== key
->prekey
.uVKey
&& pprekey
->uModifiers
== key
->prekey
.uModifiers
)
923 return CONNECT_E_NOCONNECTION
;
925 list_remove(&key
->entry
);
926 HeapFree(GetProcessHeap(),0,key
->description
);
927 HeapFree(GetProcessHeap(),0,key
);
932 static HRESULT WINAPI
KeystrokeMgr_SetPreservedKeyDescription(ITfKeystrokeMgr
*iface
,
933 REFGUID rguid
, const WCHAR
*pchDesc
, ULONG cchDesc
)
935 ThreadMgr
*This
= impl_from_ITfKeystrokeMgrVtbl(iface
);
936 FIXME("STUB:(%p)\n",This
);
940 static HRESULT WINAPI
KeystrokeMgr_GetPreservedKeyDescription(ITfKeystrokeMgr
*iface
,
941 REFGUID rguid
, BSTR
*pbstrDesc
)
943 ThreadMgr
*This
= impl_from_ITfKeystrokeMgrVtbl(iface
);
944 FIXME("STUB:(%p)\n",This
);
948 static HRESULT WINAPI
KeystrokeMgr_SimulatePreservedKey(ITfKeystrokeMgr
*iface
,
949 ITfContext
*pic
, REFGUID rguid
, BOOL
*pfEaten
)
951 ThreadMgr
*This
= impl_from_ITfKeystrokeMgrVtbl(iface
);
952 FIXME("STUB:(%p)\n",This
);
956 static const ITfKeystrokeMgrVtbl ThreadMgr_KeystrokeMgrVtbl
=
958 KeystrokeMgr_QueryInterface
,
960 KeystrokeMgr_Release
,
962 KeystrokeMgr_AdviseKeyEventSink
,
963 KeystrokeMgr_UnadviseKeyEventSink
,
964 KeystrokeMgr_GetForeground
,
965 KeystrokeMgr_TestKeyDown
,
966 KeystrokeMgr_TestKeyUp
,
967 KeystrokeMgr_KeyDown
,
969 KeystrokeMgr_GetPreservedKey
,
970 KeystrokeMgr_IsPreservedKey
,
971 KeystrokeMgr_PreserveKey
,
972 KeystrokeMgr_UnpreserveKey
,
973 KeystrokeMgr_SetPreservedKeyDescription
,
974 KeystrokeMgr_GetPreservedKeyDescription
,
975 KeystrokeMgr_SimulatePreservedKey
978 /*****************************************************
979 * ITfMessagePump functions
980 *****************************************************/
982 static HRESULT WINAPI
MessagePump_QueryInterface(ITfMessagePump
*iface
, REFIID iid
, LPVOID
*ppvOut
)
984 ThreadMgr
*This
= impl_from_ITfMessagePumpVtbl(iface
);
985 return ThreadMgr_QueryInterface((ITfThreadMgr
*)This
, iid
, *ppvOut
);
988 static ULONG WINAPI
MessagePump_AddRef(ITfMessagePump
*iface
)
990 ThreadMgr
*This
= impl_from_ITfMessagePumpVtbl(iface
);
991 return ThreadMgr_AddRef((ITfThreadMgr
*)This
);
994 static ULONG WINAPI
MessagePump_Release(ITfMessagePump
*iface
)
996 ThreadMgr
*This
= impl_from_ITfMessagePumpVtbl(iface
);
997 return ThreadMgr_Release((ITfThreadMgr
*)This
);
1000 static HRESULT WINAPI
MessagePump_PeekMessageA(ITfMessagePump
*iface
,
1001 LPMSG pMsg
, HWND hwnd
, UINT wMsgFilterMin
, UINT wMsgFilterMax
,
1002 UINT wRemoveMsg
, BOOL
*pfResult
)
1005 return E_INVALIDARG
;
1006 *pfResult
= PeekMessageA(pMsg
, hwnd
, wMsgFilterMin
, wMsgFilterMax
, wRemoveMsg
);
1010 static HRESULT WINAPI
MessagePump_GetMessageA(ITfMessagePump
*iface
,
1011 LPMSG pMsg
, HWND hwnd
, UINT wMsgFilterMin
, UINT wMsgFilterMax
,
1015 return E_INVALIDARG
;
1016 *pfResult
= GetMessageA(pMsg
, hwnd
, wMsgFilterMin
, wMsgFilterMax
);
1020 static HRESULT WINAPI
MessagePump_PeekMessageW(ITfMessagePump
*iface
,
1021 LPMSG pMsg
, HWND hwnd
, UINT wMsgFilterMin
, UINT wMsgFilterMax
,
1022 UINT wRemoveMsg
, BOOL
*pfResult
)
1025 return E_INVALIDARG
;
1026 *pfResult
= PeekMessageW(pMsg
, hwnd
, wMsgFilterMin
, wMsgFilterMax
, wRemoveMsg
);
1030 static HRESULT WINAPI
MessagePump_GetMessageW(ITfMessagePump
*iface
,
1031 LPMSG pMsg
, HWND hwnd
, UINT wMsgFilterMin
, UINT wMsgFilterMax
,
1035 return E_INVALIDARG
;
1036 *pfResult
= GetMessageW(pMsg
, hwnd
, wMsgFilterMin
, wMsgFilterMax
);
1040 static const ITfMessagePumpVtbl ThreadMgr_MessagePumpVtbl
=
1042 MessagePump_QueryInterface
,
1044 MessagePump_Release
,
1046 MessagePump_PeekMessageA
,
1047 MessagePump_GetMessageA
,
1048 MessagePump_PeekMessageW
,
1049 MessagePump_GetMessageW
1052 /*****************************************************
1053 * ITfClientId functions
1054 *****************************************************/
1056 static HRESULT WINAPI
ClientId_QueryInterface(ITfClientId
*iface
, REFIID iid
, LPVOID
*ppvOut
)
1058 ThreadMgr
*This
= impl_from_ITfClientIdVtbl(iface
);
1059 return ThreadMgr_QueryInterface((ITfThreadMgr
*)This
, iid
, *ppvOut
);
1062 static ULONG WINAPI
ClientId_AddRef(ITfClientId
*iface
)
1064 ThreadMgr
*This
= impl_from_ITfClientIdVtbl(iface
);
1065 return ThreadMgr_AddRef((ITfThreadMgr
*)This
);
1068 static ULONG WINAPI
ClientId_Release(ITfClientId
*iface
)
1070 ThreadMgr
*This
= impl_from_ITfClientIdVtbl(iface
);
1071 return ThreadMgr_Release((ITfThreadMgr
*)This
);
1074 static HRESULT WINAPI
ClientId_GetClientId(ITfClientId
*iface
,
1075 REFCLSID rclsid
, TfClientId
*ptid
)
1079 ITfCategoryMgr
*catmgr
;
1080 ThreadMgr
*This
= impl_from_ITfClientIdVtbl(iface
);
1082 TRACE("(%p) %s\n",This
,debugstr_guid(rclsid
));
1084 CategoryMgr_Constructor(NULL
,(IUnknown
**)&catmgr
);
1085 hr
= ITfCategoryMgr_RegisterGUID(catmgr
,rclsid
,ptid
);
1086 ITfCategoryMgr_Release(catmgr
);
1091 static const ITfClientIdVtbl ThreadMgr_ClientIdVtbl
=
1093 ClientId_QueryInterface
,
1097 ClientId_GetClientId
1100 /*****************************************************
1101 * ITfThreadMgrEventSink functions (internal)
1102 *****************************************************/
1103 static HRESULT WINAPI
ThreadMgrEventSink_QueryInterface(ITfThreadMgrEventSink
*iface
, REFIID iid
, LPVOID
*ppvOut
)
1105 ThreadMgr
*This
= impl_from_ITfThreadMgrEventSink(iface
);
1106 return ThreadMgr_QueryInterface((ITfThreadMgr
*)This
, iid
, *ppvOut
);
1109 static ULONG WINAPI
ThreadMgrEventSink_AddRef(ITfThreadMgrEventSink
*iface
)
1111 ThreadMgr
*This
= impl_from_ITfThreadMgrEventSink(iface
);
1112 return ThreadMgr_AddRef((ITfThreadMgr
*)This
);
1115 static ULONG WINAPI
ThreadMgrEventSink_Release(ITfThreadMgrEventSink
*iface
)
1117 ThreadMgr
*This
= impl_from_ITfThreadMgrEventSink(iface
);
1118 return ThreadMgr_Release((ITfThreadMgr
*)This
);
1122 static HRESULT WINAPI
ThreadMgrEventSink_OnInitDocumentMgr(
1123 ITfThreadMgrEventSink
*iface
,ITfDocumentMgr
*pdim
)
1125 struct list
*cursor
;
1126 ThreadMgr
*This
= impl_from_ITfThreadMgrEventSink(iface
);
1128 TRACE("(%p) %p\n",This
,pdim
);
1130 LIST_FOR_EACH(cursor
, &This
->ThreadMgrEventSink
)
1132 ThreadMgrSink
* sink
= LIST_ENTRY(cursor
,ThreadMgrSink
,entry
);
1133 ITfThreadMgrEventSink_OnInitDocumentMgr(sink
->interfaces
.pITfThreadMgrEventSink
,pdim
);
1139 static HRESULT WINAPI
ThreadMgrEventSink_OnUninitDocumentMgr(
1140 ITfThreadMgrEventSink
*iface
, ITfDocumentMgr
*pdim
)
1142 struct list
*cursor
;
1143 ThreadMgr
*This
= impl_from_ITfThreadMgrEventSink(iface
);
1145 TRACE("(%p) %p\n",This
,pdim
);
1147 LIST_FOR_EACH(cursor
, &This
->ThreadMgrEventSink
)
1149 ThreadMgrSink
* sink
= LIST_ENTRY(cursor
,ThreadMgrSink
,entry
);
1150 ITfThreadMgrEventSink_OnUninitDocumentMgr(sink
->interfaces
.pITfThreadMgrEventSink
,pdim
);
1156 static HRESULT WINAPI
ThreadMgrEventSink_OnSetFocus(
1157 ITfThreadMgrEventSink
*iface
, ITfDocumentMgr
*pdimFocus
,
1158 ITfDocumentMgr
*pdimPrevFocus
)
1160 struct list
*cursor
;
1161 ThreadMgr
*This
= impl_from_ITfThreadMgrEventSink(iface
);
1163 TRACE("(%p) %p %p\n",This
,pdimFocus
, pdimPrevFocus
);
1165 LIST_FOR_EACH(cursor
, &This
->ThreadMgrEventSink
)
1167 ThreadMgrSink
* sink
= LIST_ENTRY(cursor
,ThreadMgrSink
,entry
);
1168 ITfThreadMgrEventSink_OnSetFocus(sink
->interfaces
.pITfThreadMgrEventSink
, pdimFocus
, pdimPrevFocus
);
1174 static HRESULT WINAPI
ThreadMgrEventSink_OnPushContext(
1175 ITfThreadMgrEventSink
*iface
, ITfContext
*pic
)
1177 struct list
*cursor
;
1178 ThreadMgr
*This
= impl_from_ITfThreadMgrEventSink(iface
);
1180 TRACE("(%p) %p\n",This
,pic
);
1182 LIST_FOR_EACH(cursor
, &This
->ThreadMgrEventSink
)
1184 ThreadMgrSink
* sink
= LIST_ENTRY(cursor
,ThreadMgrSink
,entry
);
1185 ITfThreadMgrEventSink_OnPushContext(sink
->interfaces
.pITfThreadMgrEventSink
,pic
);
1191 static HRESULT WINAPI
ThreadMgrEventSink_OnPopContext(
1192 ITfThreadMgrEventSink
*iface
, ITfContext
*pic
)
1194 struct list
*cursor
;
1195 ThreadMgr
*This
= impl_from_ITfThreadMgrEventSink(iface
);
1197 TRACE("(%p) %p\n",This
,pic
);
1199 LIST_FOR_EACH(cursor
, &This
->ThreadMgrEventSink
)
1201 ThreadMgrSink
* sink
= LIST_ENTRY(cursor
,ThreadMgrSink
,entry
);
1202 ITfThreadMgrEventSink_OnPopContext(sink
->interfaces
.pITfThreadMgrEventSink
,pic
);
1208 static const ITfThreadMgrEventSinkVtbl ThreadMgr_ThreadMgrEventSinkVtbl
=
1210 ThreadMgrEventSink_QueryInterface
,
1211 ThreadMgrEventSink_AddRef
,
1212 ThreadMgrEventSink_Release
,
1214 ThreadMgrEventSink_OnInitDocumentMgr
,
1215 ThreadMgrEventSink_OnUninitDocumentMgr
,
1216 ThreadMgrEventSink_OnSetFocus
,
1217 ThreadMgrEventSink_OnPushContext
,
1218 ThreadMgrEventSink_OnPopContext
1221 /*****************************************************
1222 * ITfSourceSingle functions
1223 *****************************************************/
1224 static HRESULT WINAPI
ThreadMgrSourceSingle_QueryInterface(ITfSourceSingle
*iface
, REFIID iid
, LPVOID
*ppvOut
)
1226 ThreadMgr
*This
= impl_from_ITfSourceSingleVtbl(iface
);
1227 return ThreadMgr_QueryInterface((ITfThreadMgr
*)This
, iid
, *ppvOut
);
1230 static ULONG WINAPI
ThreadMgrSourceSingle_AddRef(ITfSourceSingle
*iface
)
1232 ThreadMgr
*This
= impl_from_ITfSourceSingleVtbl(iface
);
1233 return ThreadMgr_AddRef((ITfThreadMgr
*)This
);
1236 static ULONG WINAPI
ThreadMgrSourceSingle_Release(ITfSourceSingle
*iface
)
1238 ThreadMgr
*This
= impl_from_ITfSourceSingleVtbl(iface
);
1239 return ThreadMgr_Release((ITfThreadMgr
*)This
);
1242 static HRESULT WINAPI
ThreadMgrSourceSingle_AdviseSingleSink( ITfSourceSingle
*iface
,
1243 TfClientId tid
, REFIID riid
, IUnknown
*punk
)
1245 ThreadMgr
*This
= impl_from_ITfSourceSingleVtbl(iface
);
1246 FIXME("STUB:(%p) %i %s %p\n",This
, tid
, debugstr_guid(riid
),punk
);
1250 static HRESULT WINAPI
ThreadMgrSourceSingle_UnadviseSingleSink( ITfSourceSingle
*iface
,
1251 TfClientId tid
, REFIID riid
)
1253 ThreadMgr
*This
= impl_from_ITfSourceSingleVtbl(iface
);
1254 FIXME("STUB:(%p) %i %s\n",This
, tid
, debugstr_guid(riid
));
1258 static const ITfSourceSingleVtbl ThreadMgr_SourceSingleVtbl
=
1260 ThreadMgrSourceSingle_QueryInterface
,
1261 ThreadMgrSourceSingle_AddRef
,
1262 ThreadMgrSourceSingle_Release
,
1264 ThreadMgrSourceSingle_AdviseSingleSink
,
1265 ThreadMgrSourceSingle_UnadviseSingleSink
,
1268 HRESULT
ThreadMgr_Constructor(IUnknown
*pUnkOuter
, IUnknown
**ppOut
)
1272 return CLASS_E_NOAGGREGATION
;
1274 /* Only 1 ThreadMgr is created per thread */
1275 This
= TlsGetValue(tlsIndex
);
1278 ThreadMgr_AddRef((ITfThreadMgr
*)This
);
1279 *ppOut
= (IUnknown
*)This
;
1283 This
= HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY
,sizeof(ThreadMgr
));
1285 return E_OUTOFMEMORY
;
1287 This
->ThreadMgrVtbl
= &ThreadMgr_ThreadMgrVtbl
;
1288 This
->SourceVtbl
= &ThreadMgr_SourceVtbl
;
1289 This
->KeystrokeMgrVtbl
= &ThreadMgr_KeystrokeMgrVtbl
;
1290 This
->MessagePumpVtbl
= &ThreadMgr_MessagePumpVtbl
;
1291 This
->ClientIdVtbl
= &ThreadMgr_ClientIdVtbl
;
1292 This
->ThreadMgrEventSinkVtbl
= &ThreadMgr_ThreadMgrEventSinkVtbl
;
1293 This
->SourceSingleVtbl
= &ThreadMgr_SourceSingleVtbl
;
1295 TlsSetValue(tlsIndex
,This
);
1297 CompartmentMgr_Constructor((IUnknown
*)This
, &IID_IUnknown
, (IUnknown
**)&This
->CompartmentMgr
);
1299 list_init(&This
->CurrentPreservedKeys
);
1300 list_init(&This
->CreatedDocumentMgrs
);
1301 list_init(&This
->AssociatedFocusWindows
);
1303 list_init(&This
->ActiveLanguageProfileNotifySink
);
1304 list_init(&This
->DisplayAttributeNotifySink
);
1305 list_init(&This
->KeyTraceEventSink
);
1306 list_init(&This
->PreservedKeyNotifySink
);
1307 list_init(&This
->ThreadFocusSink
);
1308 list_init(&This
->ThreadMgrEventSink
);
1310 TRACE("returning %p\n", This
);
1311 *ppOut
= (IUnknown
*)This
;
1315 /**************************************************
1316 * IEnumTfDocumentMgrs implementation
1317 **************************************************/
1318 static void EnumTfDocumentMgr_Destructor(EnumTfDocumentMgr
*This
)
1320 TRACE("destroying %p\n", This
);
1321 HeapFree(GetProcessHeap(),0,This
);
1324 static HRESULT WINAPI
EnumTfDocumentMgr_QueryInterface(IEnumTfDocumentMgrs
*iface
, REFIID iid
, LPVOID
*ppvOut
)
1326 EnumTfDocumentMgr
*This
= (EnumTfDocumentMgr
*)iface
;
1329 if (IsEqualIID(iid
, &IID_IUnknown
) || IsEqualIID(iid
, &IID_IEnumTfDocumentMgrs
))
1336 IUnknown_AddRef(iface
);
1340 WARN("unsupported interface: %s\n", debugstr_guid(iid
));
1341 return E_NOINTERFACE
;
1344 static ULONG WINAPI
EnumTfDocumentMgr_AddRef(IEnumTfDocumentMgrs
*iface
)
1346 EnumTfDocumentMgr
*This
= (EnumTfDocumentMgr
*)iface
;
1347 return InterlockedIncrement(&This
->refCount
);
1350 static ULONG WINAPI
EnumTfDocumentMgr_Release(IEnumTfDocumentMgrs
*iface
)
1352 EnumTfDocumentMgr
*This
= (EnumTfDocumentMgr
*)iface
;
1355 ret
= InterlockedDecrement(&This
->refCount
);
1357 EnumTfDocumentMgr_Destructor(This
);
1361 static HRESULT WINAPI
EnumTfDocumentMgr_Next(IEnumTfDocumentMgrs
*iface
,
1362 ULONG ulCount
, ITfDocumentMgr
**rgDocumentMgr
, ULONG
*pcFetched
)
1364 EnumTfDocumentMgr
*This
= (EnumTfDocumentMgr
*)iface
;
1367 TRACE("(%p)\n",This
);
1369 if (rgDocumentMgr
== NULL
) return E_POINTER
;
1371 while (fetched
< ulCount
)
1373 DocumentMgrEntry
*mgrentry
;
1374 if (This
->index
== NULL
)
1377 mgrentry
= LIST_ENTRY(This
->index
,DocumentMgrEntry
,entry
);
1378 if (mgrentry
== NULL
)
1381 *rgDocumentMgr
= mgrentry
->docmgr
;
1382 ITfDocumentMgr_AddRef(*rgDocumentMgr
);
1384 This
->index
= list_next(This
->head
, This
->index
);
1389 if (pcFetched
) *pcFetched
= fetched
;
1390 return fetched
== ulCount
? S_OK
: S_FALSE
;
1393 static HRESULT WINAPI
EnumTfDocumentMgr_Skip( IEnumTfDocumentMgrs
* iface
, ULONG celt
)
1396 EnumTfDocumentMgr
*This
= (EnumTfDocumentMgr
*)iface
;
1397 TRACE("(%p)\n",This
);
1398 for(i
= 0; i
< celt
&& This
->index
!= NULL
; i
++)
1399 This
->index
= list_next(This
->head
, This
->index
);
1403 static HRESULT WINAPI
EnumTfDocumentMgr_Reset( IEnumTfDocumentMgrs
* iface
)
1405 EnumTfDocumentMgr
*This
= (EnumTfDocumentMgr
*)iface
;
1406 TRACE("(%p)\n",This
);
1407 This
->index
= list_head(This
->head
);
1411 static HRESULT WINAPI
EnumTfDocumentMgr_Clone( IEnumTfDocumentMgrs
*iface
,
1412 IEnumTfDocumentMgrs
**ppenum
)
1414 EnumTfDocumentMgr
*This
= (EnumTfDocumentMgr
*)iface
;
1417 TRACE("(%p)\n",This
);
1419 if (ppenum
== NULL
) return E_POINTER
;
1421 res
= EnumTfDocumentMgr_Constructor(This
->head
, ppenum
);
1424 EnumTfDocumentMgr
*new_This
= (EnumTfDocumentMgr
*)*ppenum
;
1425 new_This
->index
= This
->index
;
1430 static const IEnumTfDocumentMgrsVtbl IEnumTfDocumentMgrs_Vtbl
={
1431 EnumTfDocumentMgr_QueryInterface
,
1432 EnumTfDocumentMgr_AddRef
,
1433 EnumTfDocumentMgr_Release
,
1435 EnumTfDocumentMgr_Clone
,
1436 EnumTfDocumentMgr_Next
,
1437 EnumTfDocumentMgr_Reset
,
1438 EnumTfDocumentMgr_Skip
1441 static HRESULT
EnumTfDocumentMgr_Constructor(struct list
* head
, IEnumTfDocumentMgrs
**ppOut
)
1443 EnumTfDocumentMgr
*This
;
1445 This
= HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY
,sizeof(EnumTfDocumentMgr
));
1447 return E_OUTOFMEMORY
;
1449 This
->Vtbl
= &IEnumTfDocumentMgrs_Vtbl
;
1452 This
->index
= list_head(This
->head
);
1454 TRACE("returning %p\n", This
);
1455 *ppOut
= (IEnumTfDocumentMgrs
*)This
;
1459 void ThreadMgr_OnDocumentMgrDestruction(ITfThreadMgr
*tm
, ITfDocumentMgr
*mgr
)
1461 ThreadMgr
*This
= (ThreadMgr
*)tm
;
1462 struct list
*cursor
;
1463 LIST_FOR_EACH(cursor
, &This
->CreatedDocumentMgrs
)
1465 DocumentMgrEntry
*mgrentry
= LIST_ENTRY(cursor
,DocumentMgrEntry
,entry
);
1466 if (mgrentry
->docmgr
== mgr
)
1468 list_remove(cursor
);
1469 HeapFree(GetProcessHeap(),0,mgrentry
);
1473 FIXME("ITfDocumentMgr %p not found in this thread\n",mgr
);