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
21 #include "msctf_internal.h"
23 typedef struct tagThreadMgrSink
{
28 /* ITfActiveLanguageProfileNotifySink *pITfActiveLanguageProfileNotifySink; */
29 /* ITfDisplayAttributeNotifySink *pITfDisplayAttributeNotifySink; */
30 /* ITfKeyTraceEventSink *pITfKeyTraceEventSink; */
31 /* ITfPreservedKeyNotifySink *pITfPreservedKeyNotifySink; */
32 /* ITfThreadFocusSink *pITfThreadFocusSink; */
33 ITfThreadMgrEventSink
*pITfThreadMgrEventSink
;
37 typedef struct tagPreservedKey
41 TF_PRESERVEDKEY prekey
;
46 typedef struct tagDocumentMgrs
49 ITfDocumentMgr
*docmgr
;
52 typedef struct tagAssociatedWindow
56 ITfDocumentMgr
*docmgr
;
59 typedef struct tagACLMulti
{
60 ITfThreadMgr ITfThreadMgr_iface
;
61 ITfSource ITfSource_iface
;
62 ITfKeystrokeMgr ITfKeystrokeMgr_iface
;
63 ITfMessagePump ITfMessagePump_iface
;
64 ITfClientId ITfClientId_iface
;
65 /* const ITfThreadMgrExVtbl *ThreadMgrExVtbl; */
66 /* const ITfConfigureSystemKeystrokeFeedVtbl *ConfigureSystemKeystrokeFeedVtbl; */
67 /* const ITfLangBarItemMgrVtbl *LangBarItemMgrVtbl; */
68 /* const ITfUIElementMgrVtbl *UIElementMgrVtbl; */
69 ITfSourceSingle ITfSourceSingle_iface
;
73 ITfCompartmentMgr
*CompartmentMgr
;
75 ITfThreadMgrEventSink ITfThreadMgrEventSink_iface
; /* internal */
77 ITfDocumentMgr
*focus
;
80 ITfKeyEventSink
*forgroundKeyEventSink
;
81 CLSID forgroundTextService
;
83 struct list CurrentPreservedKeys
;
84 struct list CreatedDocumentMgrs
;
86 struct list AssociatedFocusWindows
;
89 /* kept as separate lists to reduce unnecessary iterations */
90 struct list ActiveLanguageProfileNotifySink
;
91 struct list DisplayAttributeNotifySink
;
92 struct list KeyTraceEventSink
;
93 struct list PreservedKeyNotifySink
;
94 struct list ThreadFocusSink
;
95 struct list ThreadMgrEventSink
;
98 typedef struct tagEnumTfDocumentMgr
{
99 IEnumTfDocumentMgrs IEnumTfDocumentMgrs_iface
;
106 static HRESULT
EnumTfDocumentMgr_Constructor(struct list
* head
, IEnumTfDocumentMgrs
**ppOut
);
108 static inline ThreadMgr
*impl_from_ITfThreadMgr(ITfThreadMgr
*iface
)
110 return CONTAINING_RECORD(iface
, ThreadMgr
, ITfThreadMgr_iface
);
113 static inline ThreadMgr
*impl_from_ITfSource(ITfSource
*iface
)
115 return CONTAINING_RECORD(iface
, ThreadMgr
, ITfSource_iface
);
118 static inline ThreadMgr
*impl_from_ITfKeystrokeMgr(ITfKeystrokeMgr
*iface
)
120 return CONTAINING_RECORD(iface
, ThreadMgr
, ITfKeystrokeMgr_iface
);
123 static inline ThreadMgr
*impl_from_ITfMessagePump(ITfMessagePump
*iface
)
125 return CONTAINING_RECORD(iface
, ThreadMgr
, ITfMessagePump_iface
);
128 static inline ThreadMgr
*impl_from_ITfClientId(ITfClientId
*iface
)
130 return CONTAINING_RECORD(iface
, ThreadMgr
, ITfClientId_iface
);
133 static inline ThreadMgr
*impl_from_ITfThreadMgrEventSink(ITfThreadMgrEventSink
*iface
)
135 return CONTAINING_RECORD(iface
, ThreadMgr
, ITfThreadMgrEventSink_iface
);
138 static inline ThreadMgr
*impl_from_ITfSourceSingle(ITfSourceSingle
*iface
)
140 return CONTAINING_RECORD(iface
, ThreadMgr
, ITfSourceSingle_iface
);
143 static inline EnumTfDocumentMgr
*impl_from_IEnumTfDocumentMgrs(IEnumTfDocumentMgrs
*iface
)
145 return CONTAINING_RECORD(iface
, EnumTfDocumentMgr
, IEnumTfDocumentMgrs_iface
);
148 static void free_sink(ThreadMgrSink
*sink
)
150 IUnknown_Release(sink
->interfaces
.pIUnknown
);
151 HeapFree(GetProcessHeap(),0,sink
);
154 static void ThreadMgr_Destructor(ThreadMgr
*This
)
156 struct list
*cursor
, *cursor2
;
158 /* unhook right away */
160 UnhookWindowsHookEx(This
->focusHook
);
162 TlsSetValue(tlsIndex
,NULL
);
163 TRACE("destroying %p\n", This
);
165 ITfDocumentMgr_Release(This
->focus
);
168 LIST_FOR_EACH_SAFE(cursor
, cursor2
, &This
->ActiveLanguageProfileNotifySink
)
170 ThreadMgrSink
* sink
= LIST_ENTRY(cursor
,ThreadMgrSink
,entry
);
174 LIST_FOR_EACH_SAFE(cursor
, cursor2
, &This
->DisplayAttributeNotifySink
)
176 ThreadMgrSink
* sink
= LIST_ENTRY(cursor
,ThreadMgrSink
,entry
);
180 LIST_FOR_EACH_SAFE(cursor
, cursor2
, &This
->KeyTraceEventSink
)
182 ThreadMgrSink
* sink
= LIST_ENTRY(cursor
,ThreadMgrSink
,entry
);
186 LIST_FOR_EACH_SAFE(cursor
, cursor2
, &This
->PreservedKeyNotifySink
)
188 ThreadMgrSink
* sink
= LIST_ENTRY(cursor
,ThreadMgrSink
,entry
);
192 LIST_FOR_EACH_SAFE(cursor
, cursor2
, &This
->ThreadFocusSink
)
194 ThreadMgrSink
* sink
= LIST_ENTRY(cursor
,ThreadMgrSink
,entry
);
198 LIST_FOR_EACH_SAFE(cursor
, cursor2
, &This
->ThreadMgrEventSink
)
200 ThreadMgrSink
* sink
= LIST_ENTRY(cursor
,ThreadMgrSink
,entry
);
205 LIST_FOR_EACH_SAFE(cursor
, cursor2
, &This
->CurrentPreservedKeys
)
207 PreservedKey
* key
= LIST_ENTRY(cursor
,PreservedKey
,entry
);
209 HeapFree(GetProcessHeap(),0,key
->description
);
210 HeapFree(GetProcessHeap(),0,key
);
213 LIST_FOR_EACH_SAFE(cursor
, cursor2
, &This
->CreatedDocumentMgrs
)
215 DocumentMgrEntry
*mgr
= LIST_ENTRY(cursor
,DocumentMgrEntry
,entry
);
217 FIXME("Left Over ITfDocumentMgr. Should we do something with it?\n");
218 HeapFree(GetProcessHeap(),0,mgr
);
221 LIST_FOR_EACH_SAFE(cursor
, cursor2
, &This
->AssociatedFocusWindows
)
223 AssociatedWindow
*wnd
= LIST_ENTRY(cursor
,AssociatedWindow
,entry
);
225 HeapFree(GetProcessHeap(),0,wnd
);
228 CompartmentMgr_Destructor(This
->CompartmentMgr
);
230 HeapFree(GetProcessHeap(),0,This
);
233 static HRESULT WINAPI
ThreadMgr_QueryInterface(ITfThreadMgr
*iface
, REFIID iid
, LPVOID
*ppvOut
)
235 ThreadMgr
*This
= impl_from_ITfThreadMgr(iface
);
238 if (IsEqualIID(iid
, &IID_IUnknown
) || IsEqualIID(iid
, &IID_ITfThreadMgr
))
240 *ppvOut
= &This
->ITfThreadMgr_iface
;
242 else if (IsEqualIID(iid
, &IID_ITfSource
))
244 *ppvOut
= &This
->ITfSource_iface
;
246 else if (IsEqualIID(iid
, &IID_ITfKeystrokeMgr
))
248 *ppvOut
= &This
->ITfKeystrokeMgr_iface
;
250 else if (IsEqualIID(iid
, &IID_ITfMessagePump
))
252 *ppvOut
= &This
->ITfMessagePump_iface
;
254 else if (IsEqualIID(iid
, &IID_ITfClientId
))
256 *ppvOut
= &This
->ITfClientId_iface
;
258 else if (IsEqualIID(iid
, &IID_ITfCompartmentMgr
))
260 *ppvOut
= This
->CompartmentMgr
;
262 else if (IsEqualIID(iid
, &IID_ITfSourceSingle
))
264 *ppvOut
= &This
->ITfSourceSingle_iface
;
269 ITfThreadMgr_AddRef(iface
);
273 WARN("unsupported interface: %s\n", debugstr_guid(iid
));
274 return E_NOINTERFACE
;
277 static ULONG WINAPI
ThreadMgr_AddRef(ITfThreadMgr
*iface
)
279 ThreadMgr
*This
= impl_from_ITfThreadMgr(iface
);
280 return InterlockedIncrement(&This
->refCount
);
283 static ULONG WINAPI
ThreadMgr_Release(ITfThreadMgr
*iface
)
285 ThreadMgr
*This
= impl_from_ITfThreadMgr(iface
);
288 ret
= InterlockedDecrement(&This
->refCount
);
290 ThreadMgr_Destructor(This
);
294 /*****************************************************
295 * ITfThreadMgr functions
296 *****************************************************/
298 static HRESULT WINAPI
ThreadMgr_fnActivate( ITfThreadMgr
* iface
, TfClientId
*ptid
)
300 ThreadMgr
*This
= impl_from_ITfThreadMgr(iface
);
302 TRACE("(%p) %p\n",This
, ptid
);
311 ITfClientId_GetClientId(&This
->ITfClientId_iface
, &guid
, &processId
);
314 activate_textservices(iface
);
315 This
->activationCount
++;
320 static HRESULT WINAPI
ThreadMgr_fnDeactivate( ITfThreadMgr
* iface
)
322 ThreadMgr
*This
= impl_from_ITfThreadMgr(iface
);
323 TRACE("(%p)\n",This
);
325 if (This
->activationCount
== 0)
328 This
->activationCount
--;
330 if (This
->activationCount
== 0)
334 ITfThreadMgrEventSink_OnSetFocus(&This
->ITfThreadMgrEventSink_iface
, 0, This
->focus
);
335 ITfDocumentMgr_Release(This
->focus
);
340 deactivate_textservices();
345 static HRESULT WINAPI
ThreadMgr_CreateDocumentMgr(ITfThreadMgr
* iface
, ITfDocumentMgr
**ppdim
)
347 ThreadMgr
*This
= impl_from_ITfThreadMgr(iface
);
348 DocumentMgrEntry
*mgrentry
;
351 TRACE("(%p)\n",iface
);
352 mgrentry
= HeapAlloc(GetProcessHeap(),0,sizeof(DocumentMgrEntry
));
353 if (mgrentry
== NULL
)
354 return E_OUTOFMEMORY
;
356 hr
= DocumentMgr_Constructor(&This
->ITfThreadMgrEventSink_iface
, ppdim
);
360 mgrentry
->docmgr
= *ppdim
;
361 list_add_head(&This
->CreatedDocumentMgrs
,&mgrentry
->entry
);
364 HeapFree(GetProcessHeap(),0,mgrentry
);
369 static HRESULT WINAPI
ThreadMgr_EnumDocumentMgrs( ITfThreadMgr
* iface
, IEnumTfDocumentMgrs
**ppEnum
)
371 ThreadMgr
*This
= impl_from_ITfThreadMgr(iface
);
372 TRACE("(%p) %p\n",This
,ppEnum
);
377 return EnumTfDocumentMgr_Constructor(&This
->CreatedDocumentMgrs
, ppEnum
);
380 static HRESULT WINAPI
ThreadMgr_GetFocus( ITfThreadMgr
* iface
, ITfDocumentMgr
383 ThreadMgr
*This
= impl_from_ITfThreadMgr(iface
);
384 TRACE("(%p)\n",This
);
389 *ppdimFocus
= This
->focus
;
391 TRACE("->%p\n",This
->focus
);
393 if (This
->focus
== NULL
)
396 ITfDocumentMgr_AddRef(This
->focus
);
401 static HRESULT WINAPI
ThreadMgr_SetFocus( ITfThreadMgr
* iface
, ITfDocumentMgr
*pdimFocus
)
403 ThreadMgr
*This
= impl_from_ITfThreadMgr(iface
);
404 ITfDocumentMgr
*check
;
406 TRACE("(%p) %p\n",This
,pdimFocus
);
410 else if (FAILED(ITfDocumentMgr_QueryInterface(pdimFocus
,&IID_ITfDocumentMgr
,(LPVOID
*) &check
)))
413 ITfThreadMgrEventSink_OnSetFocus(&This
->ITfThreadMgrEventSink_iface
, check
, This
->focus
);
416 ITfDocumentMgr_Release(This
->focus
);
422 static LRESULT CALLBACK
ThreadFocusHookProc(int nCode
, WPARAM wParam
, LPARAM lParam
)
426 This
= TlsGetValue(tlsIndex
);
429 ERR("Hook proc but no ThreadMgr for this thread. Serious Error\n");
432 if (!This
->focusHook
)
434 ERR("Hook proc but no ThreadMgr focus Hook. Serious Error\n");
438 if (nCode
== HCBT_SETFOCUS
) /* focus change within our thread */
442 LIST_FOR_EACH(cursor
, &This
->AssociatedFocusWindows
)
444 AssociatedWindow
*wnd
= LIST_ENTRY(cursor
,AssociatedWindow
,entry
);
445 if (wnd
->hwnd
== (HWND
)wParam
)
447 TRACE("Triggering Associated window focus\n");
448 if (This
->focus
!= wnd
->docmgr
)
449 ThreadMgr_SetFocus((ITfThreadMgr
*)This
, wnd
->docmgr
);
455 return CallNextHookEx(This
->focusHook
, nCode
, wParam
, lParam
);
458 static HRESULT
SetupWindowsHook(ThreadMgr
*This
)
460 if (!This
->focusHook
)
462 This
->focusHook
= SetWindowsHookExW(WH_CBT
, ThreadFocusHookProc
, 0,
463 GetCurrentThreadId());
464 if (!This
->focusHook
)
466 ERR("Unable to set focus hook\n");
474 static HRESULT WINAPI
ThreadMgr_AssociateFocus( ITfThreadMgr
* iface
, HWND hwnd
,
475 ITfDocumentMgr
*pdimNew
, ITfDocumentMgr
**ppdimPrev
)
477 ThreadMgr
*This
= impl_from_ITfThreadMgr(iface
);
478 struct list
*cursor
, *cursor2
;
479 AssociatedWindow
*wnd
;
481 TRACE("(%p) %p %p %p\n",This
,hwnd
,pdimNew
,ppdimPrev
);
488 LIST_FOR_EACH_SAFE(cursor
, cursor2
, &This
->AssociatedFocusWindows
)
490 wnd
= LIST_ENTRY(cursor
,AssociatedWindow
,entry
);
491 if (wnd
->hwnd
== hwnd
)
494 ITfDocumentMgr_AddRef(wnd
->docmgr
);
495 *ppdimPrev
= wnd
->docmgr
;
496 wnd
->docmgr
= pdimNew
;
497 if (GetFocus() == hwnd
)
498 ThreadMgr_SetFocus(iface
,pdimNew
);
503 wnd
= HeapAlloc(GetProcessHeap(),0,sizeof(AssociatedWindow
));
505 wnd
->docmgr
= pdimNew
;
506 list_add_head(&This
->AssociatedFocusWindows
,&wnd
->entry
);
508 if (GetFocus() == hwnd
)
509 ThreadMgr_SetFocus(iface
,pdimNew
);
511 SetupWindowsHook(This
);
516 static HRESULT WINAPI
ThreadMgr_IsThreadFocus( ITfThreadMgr
* iface
, BOOL
*pfThreadFocus
)
518 ThreadMgr
*This
= impl_from_ITfThreadMgr(iface
);
521 TRACE("(%p) %p\n",This
,pfThreadFocus
);
523 *pfThreadFocus
= (focus
== NULL
);
527 static HRESULT WINAPI
ThreadMgr_GetFunctionProvider( ITfThreadMgr
* iface
, REFCLSID clsid
,
528 ITfFunctionProvider
**ppFuncProv
)
530 ThreadMgr
*This
= impl_from_ITfThreadMgr(iface
);
531 FIXME("STUB:(%p)\n",This
);
535 static HRESULT WINAPI
ThreadMgr_EnumFunctionProviders( ITfThreadMgr
* iface
,
536 IEnumTfFunctionProviders
**ppEnum
)
538 ThreadMgr
*This
= impl_from_ITfThreadMgr(iface
);
539 FIXME("STUB:(%p)\n",This
);
543 static HRESULT WINAPI
ThreadMgr_GetGlobalCompartment( ITfThreadMgr
* iface
,
544 ITfCompartmentMgr
**ppCompMgr
)
546 ThreadMgr
*This
= impl_from_ITfThreadMgr(iface
);
548 TRACE("(%p) %p\n",This
, ppCompMgr
);
553 if (!globalCompartmentMgr
)
555 hr
= CompartmentMgr_Constructor(NULL
,&IID_ITfCompartmentMgr
,(IUnknown
**)&globalCompartmentMgr
);
560 ITfCompartmentMgr_AddRef(globalCompartmentMgr
);
561 *ppCompMgr
= globalCompartmentMgr
;
565 static const ITfThreadMgrVtbl ThreadMgrVtbl
=
567 ThreadMgr_QueryInterface
,
570 ThreadMgr_fnActivate
,
571 ThreadMgr_fnDeactivate
,
572 ThreadMgr_CreateDocumentMgr
,
573 ThreadMgr_EnumDocumentMgrs
,
576 ThreadMgr_AssociateFocus
,
577 ThreadMgr_IsThreadFocus
,
578 ThreadMgr_GetFunctionProvider
,
579 ThreadMgr_EnumFunctionProviders
,
580 ThreadMgr_GetGlobalCompartment
583 static HRESULT WINAPI
Source_QueryInterface(ITfSource
*iface
, REFIID iid
, LPVOID
*ppvOut
)
585 ThreadMgr
*This
= impl_from_ITfSource(iface
);
586 return ITfThreadMgr_QueryInterface(&This
->ITfThreadMgr_iface
, iid
, ppvOut
);
589 static ULONG WINAPI
Source_AddRef(ITfSource
*iface
)
591 ThreadMgr
*This
= impl_from_ITfSource(iface
);
592 return ITfThreadMgr_AddRef(&This
->ITfThreadMgr_iface
);
595 static ULONG WINAPI
Source_Release(ITfSource
*iface
)
597 ThreadMgr
*This
= impl_from_ITfSource(iface
);
598 return ITfThreadMgr_Release(&This
->ITfThreadMgr_iface
);
601 /*****************************************************
602 * ITfSource functions
603 *****************************************************/
604 static HRESULT WINAPI
ThreadMgrSource_AdviseSink(ITfSource
*iface
,
605 REFIID riid
, IUnknown
*punk
, DWORD
*pdwCookie
)
607 ThreadMgr
*This
= impl_from_ITfSource(iface
);
610 TRACE("(%p) %s %p %p\n",This
,debugstr_guid(riid
),punk
,pdwCookie
);
612 if (!riid
|| !punk
|| !pdwCookie
)
615 if (IsEqualIID(riid
, &IID_ITfThreadMgrEventSink
))
617 tms
= HeapAlloc(GetProcessHeap(),0,sizeof(ThreadMgrSink
));
619 return E_OUTOFMEMORY
;
620 if (FAILED(IUnknown_QueryInterface(punk
, riid
, (LPVOID
*)&tms
->interfaces
.pITfThreadMgrEventSink
)))
622 HeapFree(GetProcessHeap(),0,tms
);
623 return CONNECT_E_CANNOTCONNECT
;
625 list_add_head(&This
->ThreadMgrEventSink
,&tms
->entry
);
626 *pdwCookie
= generate_Cookie(COOKIE_MAGIC_TMSINK
, tms
);
630 FIXME("(%p) Unhandled Sink: %s\n",This
,debugstr_guid(riid
));
634 TRACE("cookie %x\n",*pdwCookie
);
639 static HRESULT WINAPI
ThreadMgrSource_UnadviseSink(ITfSource
*iface
, DWORD pdwCookie
)
641 ThreadMgr
*This
= impl_from_ITfSource(iface
);
644 TRACE("(%p) %x\n",This
,pdwCookie
);
646 if (get_Cookie_magic(pdwCookie
)!=COOKIE_MAGIC_TMSINK
)
649 sink
= remove_Cookie(pdwCookie
);
651 return CONNECT_E_NOCONNECTION
;
653 list_remove(&sink
->entry
);
659 static const ITfSourceVtbl ThreadMgrSourceVtbl
=
661 Source_QueryInterface
,
664 ThreadMgrSource_AdviseSink
,
665 ThreadMgrSource_UnadviseSink
,
668 /*****************************************************
669 * ITfKeystrokeMgr functions
670 *****************************************************/
672 static HRESULT WINAPI
KeystrokeMgr_QueryInterface(ITfKeystrokeMgr
*iface
, REFIID iid
, LPVOID
*ppvOut
)
674 ThreadMgr
*This
= impl_from_ITfKeystrokeMgr(iface
);
675 return ITfThreadMgr_QueryInterface(&This
->ITfThreadMgr_iface
, iid
, ppvOut
);
678 static ULONG WINAPI
KeystrokeMgr_AddRef(ITfKeystrokeMgr
*iface
)
680 ThreadMgr
*This
= impl_from_ITfKeystrokeMgr(iface
);
681 return ITfThreadMgr_AddRef(&This
->ITfThreadMgr_iface
);
684 static ULONG WINAPI
KeystrokeMgr_Release(ITfKeystrokeMgr
*iface
)
686 ThreadMgr
*This
= impl_from_ITfKeystrokeMgr(iface
);
687 return ITfThreadMgr_Release(&This
->ITfThreadMgr_iface
);
690 static HRESULT WINAPI
KeystrokeMgr_AdviseKeyEventSink(ITfKeystrokeMgr
*iface
,
691 TfClientId tid
, ITfKeyEventSink
*pSink
, BOOL fForeground
)
693 ThreadMgr
*This
= impl_from_ITfKeystrokeMgr(iface
);
695 ITfKeyEventSink
*check
= NULL
;
697 TRACE("(%p) %x %p %i\n",This
,tid
,pSink
,fForeground
);
702 textservice
= get_textservice_clsid(tid
);
703 if (IsEqualCLSID(&GUID_NULL
,&textservice
))
706 get_textservice_sink(tid
, &IID_ITfKeyEventSink
, (IUnknown
**)&check
);
708 return CONNECT_E_ADVISELIMIT
;
710 if (FAILED(ITfKeyEventSink_QueryInterface(pSink
,&IID_ITfKeyEventSink
,(LPVOID
*) &check
)))
713 set_textservice_sink(tid
, &IID_ITfKeyEventSink
, (IUnknown
*)check
);
717 if (This
->forgroundKeyEventSink
)
719 ITfKeyEventSink_OnSetFocus(This
->forgroundKeyEventSink
, FALSE
);
720 ITfKeyEventSink_Release(This
->forgroundKeyEventSink
);
722 ITfKeyEventSink_AddRef(check
);
723 ITfKeyEventSink_OnSetFocus(check
, TRUE
);
724 This
->forgroundKeyEventSink
= check
;
725 This
->forgroundTextService
= textservice
;
730 static HRESULT WINAPI
KeystrokeMgr_UnadviseKeyEventSink(ITfKeystrokeMgr
*iface
,
733 ThreadMgr
*This
= impl_from_ITfKeystrokeMgr(iface
);
735 ITfKeyEventSink
*check
= NULL
;
736 TRACE("(%p) %x\n",This
,tid
);
741 textservice
= get_textservice_clsid(tid
);
742 if (IsEqualCLSID(&GUID_NULL
,&textservice
))
745 get_textservice_sink(tid
, &IID_ITfKeyEventSink
, (IUnknown
**)&check
);
748 return CONNECT_E_NOCONNECTION
;
750 set_textservice_sink(tid
, &IID_ITfKeyEventSink
, NULL
);
751 ITfKeyEventSink_Release(check
);
753 if (This
->forgroundKeyEventSink
== check
)
755 ITfKeyEventSink_Release(This
->forgroundKeyEventSink
);
756 This
->forgroundKeyEventSink
= NULL
;
757 This
->forgroundTextService
= GUID_NULL
;
762 static HRESULT WINAPI
KeystrokeMgr_GetForeground(ITfKeystrokeMgr
*iface
,
765 ThreadMgr
*This
= impl_from_ITfKeystrokeMgr(iface
);
766 TRACE("(%p) %p\n",This
,pclsid
);
770 if (IsEqualCLSID(&This
->forgroundTextService
,&GUID_NULL
))
773 *pclsid
= This
->forgroundTextService
;
777 static HRESULT WINAPI
KeystrokeMgr_TestKeyDown(ITfKeystrokeMgr
*iface
,
778 WPARAM wParam
, LPARAM lParam
, BOOL
*pfEaten
)
780 ThreadMgr
*This
= impl_from_ITfKeystrokeMgr(iface
);
781 FIXME("STUB:(%p)\n",This
);
785 static HRESULT WINAPI
KeystrokeMgr_TestKeyUp(ITfKeystrokeMgr
*iface
,
786 WPARAM wParam
, LPARAM lParam
, BOOL
*pfEaten
)
788 ThreadMgr
*This
= impl_from_ITfKeystrokeMgr(iface
);
789 FIXME("STUB:(%p)\n",This
);
793 static HRESULT WINAPI
KeystrokeMgr_KeyDown(ITfKeystrokeMgr
*iface
,
794 WPARAM wParam
, LPARAM lParam
, BOOL
*pfEaten
)
796 ThreadMgr
*This
= impl_from_ITfKeystrokeMgr(iface
);
797 FIXME("STUB:(%p)\n",This
);
801 static HRESULT WINAPI
KeystrokeMgr_KeyUp(ITfKeystrokeMgr
*iface
,
802 WPARAM wParam
, LPARAM lParam
, BOOL
*pfEaten
)
804 ThreadMgr
*This
= impl_from_ITfKeystrokeMgr(iface
);
805 FIXME("STUB:(%p)\n",This
);
809 static HRESULT WINAPI
KeystrokeMgr_GetPreservedKey(ITfKeystrokeMgr
*iface
,
810 ITfContext
*pic
, const TF_PRESERVEDKEY
*pprekey
, GUID
*pguid
)
812 ThreadMgr
*This
= impl_from_ITfKeystrokeMgr(iface
);
813 FIXME("STUB:(%p)\n",This
);
817 static HRESULT WINAPI
KeystrokeMgr_IsPreservedKey(ITfKeystrokeMgr
*iface
,
818 REFGUID rguid
, const TF_PRESERVEDKEY
*pprekey
, BOOL
*pfRegistered
)
820 ThreadMgr
*This
= impl_from_ITfKeystrokeMgr(iface
);
823 TRACE("(%p) %s (%x %x) %p\n",This
,debugstr_guid(rguid
), (pprekey
)?pprekey
->uVKey
:0, (pprekey
)?pprekey
->uModifiers
:0, pfRegistered
);
825 if (!rguid
|| !pprekey
|| !pfRegistered
)
828 LIST_FOR_EACH(cursor
, &This
->CurrentPreservedKeys
)
830 PreservedKey
* key
= LIST_ENTRY(cursor
,PreservedKey
,entry
);
831 if (IsEqualGUID(rguid
,&key
->guid
) && pprekey
->uVKey
== key
->prekey
.uVKey
&& pprekey
->uModifiers
== key
->prekey
.uModifiers
)
833 *pfRegistered
= TRUE
;
838 *pfRegistered
= FALSE
;
842 static HRESULT WINAPI
KeystrokeMgr_PreserveKey(ITfKeystrokeMgr
*iface
,
843 TfClientId tid
, REFGUID rguid
, const TF_PRESERVEDKEY
*prekey
,
844 const WCHAR
*pchDesc
, ULONG cchDesc
)
846 ThreadMgr
*This
= impl_from_ITfKeystrokeMgr(iface
);
848 PreservedKey
*newkey
;
850 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
));
852 if (!tid
|| ! rguid
|| !prekey
|| (cchDesc
&& !pchDesc
))
855 LIST_FOR_EACH(cursor
, &This
->CurrentPreservedKeys
)
857 PreservedKey
* key
= LIST_ENTRY(cursor
,PreservedKey
,entry
);
858 if (IsEqualGUID(rguid
,&key
->guid
) && prekey
->uVKey
== key
->prekey
.uVKey
&& prekey
->uModifiers
== key
->prekey
.uModifiers
)
859 return TF_E_ALREADY_EXISTS
;
862 newkey
= HeapAlloc(GetProcessHeap(),0,sizeof(PreservedKey
));
864 return E_OUTOFMEMORY
;
866 newkey
->guid
= *rguid
;
867 newkey
->prekey
= *prekey
;
869 newkey
->description
= NULL
;
872 newkey
->description
= HeapAlloc(GetProcessHeap(),0,cchDesc
* sizeof(WCHAR
));
873 if (!newkey
->description
)
875 HeapFree(GetProcessHeap(),0,newkey
);
876 return E_OUTOFMEMORY
;
878 memcpy(newkey
->description
, pchDesc
, cchDesc
*sizeof(WCHAR
));
881 list_add_head(&This
->CurrentPreservedKeys
,&newkey
->entry
);
886 static HRESULT WINAPI
KeystrokeMgr_UnpreserveKey(ITfKeystrokeMgr
*iface
,
887 REFGUID rguid
, const TF_PRESERVEDKEY
*pprekey
)
889 ThreadMgr
*This
= impl_from_ITfKeystrokeMgr(iface
);
890 PreservedKey
* key
= NULL
;
892 TRACE("(%p) %s (%x %x)\n",This
,debugstr_guid(rguid
),(pprekey
)?pprekey
->uVKey
:0, (pprekey
)?pprekey
->uModifiers
:0);
894 if (!pprekey
|| !rguid
)
897 LIST_FOR_EACH(cursor
, &This
->CurrentPreservedKeys
)
899 key
= LIST_ENTRY(cursor
,PreservedKey
,entry
);
900 if (IsEqualGUID(rguid
,&key
->guid
) && pprekey
->uVKey
== key
->prekey
.uVKey
&& pprekey
->uModifiers
== key
->prekey
.uModifiers
)
906 return CONNECT_E_NOCONNECTION
;
908 list_remove(&key
->entry
);
909 HeapFree(GetProcessHeap(),0,key
->description
);
910 HeapFree(GetProcessHeap(),0,key
);
915 static HRESULT WINAPI
KeystrokeMgr_SetPreservedKeyDescription(ITfKeystrokeMgr
*iface
,
916 REFGUID rguid
, const WCHAR
*pchDesc
, ULONG cchDesc
)
918 ThreadMgr
*This
= impl_from_ITfKeystrokeMgr(iface
);
919 FIXME("STUB:(%p)\n",This
);
923 static HRESULT WINAPI
KeystrokeMgr_GetPreservedKeyDescription(ITfKeystrokeMgr
*iface
,
924 REFGUID rguid
, BSTR
*pbstrDesc
)
926 ThreadMgr
*This
= impl_from_ITfKeystrokeMgr(iface
);
927 FIXME("STUB:(%p)\n",This
);
931 static HRESULT WINAPI
KeystrokeMgr_SimulatePreservedKey(ITfKeystrokeMgr
*iface
,
932 ITfContext
*pic
, REFGUID rguid
, BOOL
*pfEaten
)
934 ThreadMgr
*This
= impl_from_ITfKeystrokeMgr(iface
);
935 FIXME("STUB:(%p)\n",This
);
939 static const ITfKeystrokeMgrVtbl KeystrokeMgrVtbl
=
941 KeystrokeMgr_QueryInterface
,
943 KeystrokeMgr_Release
,
944 KeystrokeMgr_AdviseKeyEventSink
,
945 KeystrokeMgr_UnadviseKeyEventSink
,
946 KeystrokeMgr_GetForeground
,
947 KeystrokeMgr_TestKeyDown
,
948 KeystrokeMgr_TestKeyUp
,
949 KeystrokeMgr_KeyDown
,
951 KeystrokeMgr_GetPreservedKey
,
952 KeystrokeMgr_IsPreservedKey
,
953 KeystrokeMgr_PreserveKey
,
954 KeystrokeMgr_UnpreserveKey
,
955 KeystrokeMgr_SetPreservedKeyDescription
,
956 KeystrokeMgr_GetPreservedKeyDescription
,
957 KeystrokeMgr_SimulatePreservedKey
960 /*****************************************************
961 * ITfMessagePump functions
962 *****************************************************/
964 static HRESULT WINAPI
MessagePump_QueryInterface(ITfMessagePump
*iface
, REFIID iid
, LPVOID
*ppvOut
)
966 ThreadMgr
*This
= impl_from_ITfMessagePump(iface
);
967 return ITfThreadMgr_QueryInterface(&This
->ITfThreadMgr_iface
, iid
, ppvOut
);
970 static ULONG WINAPI
MessagePump_AddRef(ITfMessagePump
*iface
)
972 ThreadMgr
*This
= impl_from_ITfMessagePump(iface
);
973 return ITfThreadMgr_AddRef(&This
->ITfThreadMgr_iface
);
976 static ULONG WINAPI
MessagePump_Release(ITfMessagePump
*iface
)
978 ThreadMgr
*This
= impl_from_ITfMessagePump(iface
);
979 return ITfThreadMgr_Release(&This
->ITfThreadMgr_iface
);
982 static HRESULT WINAPI
MessagePump_PeekMessageA(ITfMessagePump
*iface
,
983 LPMSG pMsg
, HWND hwnd
, UINT wMsgFilterMin
, UINT wMsgFilterMax
,
984 UINT wRemoveMsg
, BOOL
*pfResult
)
988 *pfResult
= PeekMessageA(pMsg
, hwnd
, wMsgFilterMin
, wMsgFilterMax
, wRemoveMsg
);
992 static HRESULT WINAPI
MessagePump_GetMessageA(ITfMessagePump
*iface
,
993 LPMSG pMsg
, HWND hwnd
, UINT wMsgFilterMin
, UINT wMsgFilterMax
,
998 *pfResult
= GetMessageA(pMsg
, hwnd
, wMsgFilterMin
, wMsgFilterMax
);
1002 static HRESULT WINAPI
MessagePump_PeekMessageW(ITfMessagePump
*iface
,
1003 LPMSG pMsg
, HWND hwnd
, UINT wMsgFilterMin
, UINT wMsgFilterMax
,
1004 UINT wRemoveMsg
, BOOL
*pfResult
)
1007 return E_INVALIDARG
;
1008 *pfResult
= PeekMessageW(pMsg
, hwnd
, wMsgFilterMin
, wMsgFilterMax
, wRemoveMsg
);
1012 static HRESULT WINAPI
MessagePump_GetMessageW(ITfMessagePump
*iface
,
1013 LPMSG pMsg
, HWND hwnd
, UINT wMsgFilterMin
, UINT wMsgFilterMax
,
1017 return E_INVALIDARG
;
1018 *pfResult
= GetMessageW(pMsg
, hwnd
, wMsgFilterMin
, wMsgFilterMax
);
1022 static const ITfMessagePumpVtbl MessagePumpVtbl
=
1024 MessagePump_QueryInterface
,
1026 MessagePump_Release
,
1027 MessagePump_PeekMessageA
,
1028 MessagePump_GetMessageA
,
1029 MessagePump_PeekMessageW
,
1030 MessagePump_GetMessageW
1033 /*****************************************************
1034 * ITfClientId functions
1035 *****************************************************/
1037 static HRESULT WINAPI
ClientId_QueryInterface(ITfClientId
*iface
, REFIID iid
, LPVOID
*ppvOut
)
1039 ThreadMgr
*This
= impl_from_ITfClientId(iface
);
1040 return ITfThreadMgr_QueryInterface(&This
->ITfThreadMgr_iface
, iid
, ppvOut
);
1043 static ULONG WINAPI
ClientId_AddRef(ITfClientId
*iface
)
1045 ThreadMgr
*This
= impl_from_ITfClientId(iface
);
1046 return ITfThreadMgr_AddRef(&This
->ITfThreadMgr_iface
);
1049 static ULONG WINAPI
ClientId_Release(ITfClientId
*iface
)
1051 ThreadMgr
*This
= impl_from_ITfClientId(iface
);
1052 return ITfThreadMgr_Release(&This
->ITfThreadMgr_iface
);
1055 static HRESULT WINAPI
ClientId_GetClientId(ITfClientId
*iface
,
1056 REFCLSID rclsid
, TfClientId
*ptid
)
1059 ThreadMgr
*This
= impl_from_ITfClientId(iface
);
1061 ITfCategoryMgr
*catmgr
;
1063 TRACE("(%p) %s\n",This
,debugstr_guid(rclsid
));
1065 CategoryMgr_Constructor(NULL
,(IUnknown
**)&catmgr
);
1066 hr
= ITfCategoryMgr_RegisterGUID(catmgr
,rclsid
,ptid
);
1067 ITfCategoryMgr_Release(catmgr
);
1072 static const ITfClientIdVtbl ClientIdVtbl
=
1074 ClientId_QueryInterface
,
1077 ClientId_GetClientId
1080 /*****************************************************
1081 * ITfThreadMgrEventSink functions (internal)
1082 *****************************************************/
1083 static HRESULT WINAPI
ThreadMgrEventSink_QueryInterface(ITfThreadMgrEventSink
*iface
, REFIID iid
, LPVOID
*ppvOut
)
1085 ThreadMgr
*This
= impl_from_ITfThreadMgrEventSink(iface
);
1086 return ITfThreadMgr_QueryInterface(&This
->ITfThreadMgr_iface
, iid
, ppvOut
);
1089 static ULONG WINAPI
ThreadMgrEventSink_AddRef(ITfThreadMgrEventSink
*iface
)
1091 ThreadMgr
*This
= impl_from_ITfThreadMgrEventSink(iface
);
1092 return ITfThreadMgr_AddRef(&This
->ITfThreadMgr_iface
);
1095 static ULONG WINAPI
ThreadMgrEventSink_Release(ITfThreadMgrEventSink
*iface
)
1097 ThreadMgr
*This
= impl_from_ITfThreadMgrEventSink(iface
);
1098 return ITfThreadMgr_Release(&This
->ITfThreadMgr_iface
);
1102 static HRESULT WINAPI
ThreadMgrEventSink_OnInitDocumentMgr(
1103 ITfThreadMgrEventSink
*iface
,ITfDocumentMgr
*pdim
)
1105 struct list
*cursor
;
1106 ThreadMgr
*This
= impl_from_ITfThreadMgrEventSink(iface
);
1108 TRACE("(%p) %p\n",This
,pdim
);
1110 LIST_FOR_EACH(cursor
, &This
->ThreadMgrEventSink
)
1112 ThreadMgrSink
* sink
= LIST_ENTRY(cursor
,ThreadMgrSink
,entry
);
1113 ITfThreadMgrEventSink_OnInitDocumentMgr(sink
->interfaces
.pITfThreadMgrEventSink
,pdim
);
1119 static HRESULT WINAPI
ThreadMgrEventSink_OnUninitDocumentMgr(
1120 ITfThreadMgrEventSink
*iface
, ITfDocumentMgr
*pdim
)
1122 struct list
*cursor
;
1123 ThreadMgr
*This
= impl_from_ITfThreadMgrEventSink(iface
);
1125 TRACE("(%p) %p\n",This
,pdim
);
1127 LIST_FOR_EACH(cursor
, &This
->ThreadMgrEventSink
)
1129 ThreadMgrSink
* sink
= LIST_ENTRY(cursor
,ThreadMgrSink
,entry
);
1130 ITfThreadMgrEventSink_OnUninitDocumentMgr(sink
->interfaces
.pITfThreadMgrEventSink
,pdim
);
1136 static HRESULT WINAPI
ThreadMgrEventSink_OnSetFocus(
1137 ITfThreadMgrEventSink
*iface
, ITfDocumentMgr
*pdimFocus
,
1138 ITfDocumentMgr
*pdimPrevFocus
)
1140 struct list
*cursor
;
1141 ThreadMgr
*This
= impl_from_ITfThreadMgrEventSink(iface
);
1143 TRACE("(%p) %p %p\n",This
,pdimFocus
, pdimPrevFocus
);
1145 LIST_FOR_EACH(cursor
, &This
->ThreadMgrEventSink
)
1147 ThreadMgrSink
* sink
= LIST_ENTRY(cursor
,ThreadMgrSink
,entry
);
1148 ITfThreadMgrEventSink_OnSetFocus(sink
->interfaces
.pITfThreadMgrEventSink
, pdimFocus
, pdimPrevFocus
);
1154 static HRESULT WINAPI
ThreadMgrEventSink_OnPushContext(
1155 ITfThreadMgrEventSink
*iface
, ITfContext
*pic
)
1157 struct list
*cursor
;
1158 ThreadMgr
*This
= impl_from_ITfThreadMgrEventSink(iface
);
1160 TRACE("(%p) %p\n",This
,pic
);
1162 LIST_FOR_EACH(cursor
, &This
->ThreadMgrEventSink
)
1164 ThreadMgrSink
* sink
= LIST_ENTRY(cursor
,ThreadMgrSink
,entry
);
1165 ITfThreadMgrEventSink_OnPushContext(sink
->interfaces
.pITfThreadMgrEventSink
,pic
);
1171 static HRESULT WINAPI
ThreadMgrEventSink_OnPopContext(
1172 ITfThreadMgrEventSink
*iface
, ITfContext
*pic
)
1174 struct list
*cursor
;
1175 ThreadMgr
*This
= impl_from_ITfThreadMgrEventSink(iface
);
1177 TRACE("(%p) %p\n",This
,pic
);
1179 LIST_FOR_EACH(cursor
, &This
->ThreadMgrEventSink
)
1181 ThreadMgrSink
* sink
= LIST_ENTRY(cursor
,ThreadMgrSink
,entry
);
1182 ITfThreadMgrEventSink_OnPopContext(sink
->interfaces
.pITfThreadMgrEventSink
,pic
);
1188 static const ITfThreadMgrEventSinkVtbl ThreadMgrEventSinkVtbl
=
1190 ThreadMgrEventSink_QueryInterface
,
1191 ThreadMgrEventSink_AddRef
,
1192 ThreadMgrEventSink_Release
,
1193 ThreadMgrEventSink_OnInitDocumentMgr
,
1194 ThreadMgrEventSink_OnUninitDocumentMgr
,
1195 ThreadMgrEventSink_OnSetFocus
,
1196 ThreadMgrEventSink_OnPushContext
,
1197 ThreadMgrEventSink_OnPopContext
1200 /*****************************************************
1201 * ITfSourceSingle functions
1202 *****************************************************/
1203 static HRESULT WINAPI
ThreadMgrSourceSingle_QueryInterface(ITfSourceSingle
*iface
, REFIID iid
, LPVOID
*ppvOut
)
1205 ThreadMgr
*This
= impl_from_ITfSourceSingle(iface
);
1206 return ITfThreadMgr_QueryInterface(&This
->ITfThreadMgr_iface
, iid
, ppvOut
);
1209 static ULONG WINAPI
ThreadMgrSourceSingle_AddRef(ITfSourceSingle
*iface
)
1211 ThreadMgr
*This
= impl_from_ITfSourceSingle(iface
);
1212 return ITfThreadMgr_AddRef(&This
->ITfThreadMgr_iface
);
1215 static ULONG WINAPI
ThreadMgrSourceSingle_Release(ITfSourceSingle
*iface
)
1217 ThreadMgr
*This
= impl_from_ITfSourceSingle(iface
);
1218 return ITfThreadMgr_Release(&This
->ITfThreadMgr_iface
);
1221 static HRESULT WINAPI
ThreadMgrSourceSingle_AdviseSingleSink( ITfSourceSingle
*iface
,
1222 TfClientId tid
, REFIID riid
, IUnknown
*punk
)
1224 ThreadMgr
*This
= impl_from_ITfSourceSingle(iface
);
1225 FIXME("STUB:(%p) %i %s %p\n",This
, tid
, debugstr_guid(riid
),punk
);
1229 static HRESULT WINAPI
ThreadMgrSourceSingle_UnadviseSingleSink( ITfSourceSingle
*iface
,
1230 TfClientId tid
, REFIID riid
)
1232 ThreadMgr
*This
= impl_from_ITfSourceSingle(iface
);
1233 FIXME("STUB:(%p) %i %s\n",This
, tid
, debugstr_guid(riid
));
1237 static const ITfSourceSingleVtbl SourceSingleVtbl
=
1239 ThreadMgrSourceSingle_QueryInterface
,
1240 ThreadMgrSourceSingle_AddRef
,
1241 ThreadMgrSourceSingle_Release
,
1242 ThreadMgrSourceSingle_AdviseSingleSink
,
1243 ThreadMgrSourceSingle_UnadviseSingleSink
1246 HRESULT
ThreadMgr_Constructor(IUnknown
*pUnkOuter
, IUnknown
**ppOut
)
1250 return CLASS_E_NOAGGREGATION
;
1252 /* Only 1 ThreadMgr is created per thread */
1253 This
= TlsGetValue(tlsIndex
);
1256 ThreadMgr_AddRef(&This
->ITfThreadMgr_iface
);
1257 *ppOut
= (IUnknown
*)&This
->ITfThreadMgr_iface
;
1261 This
= HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY
,sizeof(ThreadMgr
));
1263 return E_OUTOFMEMORY
;
1265 This
->ITfThreadMgr_iface
.lpVtbl
= &ThreadMgrVtbl
;
1266 This
->ITfSource_iface
.lpVtbl
= &ThreadMgrSourceVtbl
;
1267 This
->ITfKeystrokeMgr_iface
.lpVtbl
= &KeystrokeMgrVtbl
;
1268 This
->ITfMessagePump_iface
.lpVtbl
= &MessagePumpVtbl
;
1269 This
->ITfClientId_iface
.lpVtbl
= &ClientIdVtbl
;
1270 This
->ITfThreadMgrEventSink_iface
.lpVtbl
= &ThreadMgrEventSinkVtbl
;
1271 This
->ITfSourceSingle_iface
.lpVtbl
= &SourceSingleVtbl
;
1273 TlsSetValue(tlsIndex
,This
);
1275 CompartmentMgr_Constructor((IUnknown
*)This
, &IID_IUnknown
, (IUnknown
**)&This
->CompartmentMgr
);
1277 list_init(&This
->CurrentPreservedKeys
);
1278 list_init(&This
->CreatedDocumentMgrs
);
1279 list_init(&This
->AssociatedFocusWindows
);
1281 list_init(&This
->ActiveLanguageProfileNotifySink
);
1282 list_init(&This
->DisplayAttributeNotifySink
);
1283 list_init(&This
->KeyTraceEventSink
);
1284 list_init(&This
->PreservedKeyNotifySink
);
1285 list_init(&This
->ThreadFocusSink
);
1286 list_init(&This
->ThreadMgrEventSink
);
1288 TRACE("returning %p\n", This
);
1289 *ppOut
= (IUnknown
*)&This
->ITfThreadMgr_iface
;
1293 /**************************************************
1294 * IEnumTfDocumentMgrs implementation
1295 **************************************************/
1296 static void EnumTfDocumentMgr_Destructor(EnumTfDocumentMgr
*This
)
1298 TRACE("destroying %p\n", This
);
1299 HeapFree(GetProcessHeap(),0,This
);
1302 static HRESULT WINAPI
EnumTfDocumentMgr_QueryInterface(IEnumTfDocumentMgrs
*iface
, REFIID iid
, LPVOID
*ppvOut
)
1304 EnumTfDocumentMgr
*This
= impl_from_IEnumTfDocumentMgrs(iface
);
1307 if (IsEqualIID(iid
, &IID_IUnknown
) || IsEqualIID(iid
, &IID_IEnumTfDocumentMgrs
))
1309 *ppvOut
= &This
->IEnumTfDocumentMgrs_iface
;
1314 IEnumTfDocumentMgrs_AddRef(iface
);
1318 WARN("unsupported interface: %s\n", debugstr_guid(iid
));
1319 return E_NOINTERFACE
;
1322 static ULONG WINAPI
EnumTfDocumentMgr_AddRef(IEnumTfDocumentMgrs
*iface
)
1324 EnumTfDocumentMgr
*This
= impl_from_IEnumTfDocumentMgrs(iface
);
1325 return InterlockedIncrement(&This
->refCount
);
1328 static ULONG WINAPI
EnumTfDocumentMgr_Release(IEnumTfDocumentMgrs
*iface
)
1330 EnumTfDocumentMgr
*This
= impl_from_IEnumTfDocumentMgrs(iface
);
1333 ret
= InterlockedDecrement(&This
->refCount
);
1335 EnumTfDocumentMgr_Destructor(This
);
1339 static HRESULT WINAPI
EnumTfDocumentMgr_Next(IEnumTfDocumentMgrs
*iface
,
1340 ULONG ulCount
, ITfDocumentMgr
**rgDocumentMgr
, ULONG
*pcFetched
)
1342 EnumTfDocumentMgr
*This
= impl_from_IEnumTfDocumentMgrs(iface
);
1345 TRACE("(%p)\n",This
);
1347 if (rgDocumentMgr
== NULL
) return E_POINTER
;
1349 while (fetched
< ulCount
)
1351 DocumentMgrEntry
*mgrentry
;
1352 if (This
->index
== NULL
)
1355 mgrentry
= LIST_ENTRY(This
->index
,DocumentMgrEntry
,entry
);
1356 if (mgrentry
== NULL
)
1359 *rgDocumentMgr
= mgrentry
->docmgr
;
1360 ITfDocumentMgr_AddRef(*rgDocumentMgr
);
1362 This
->index
= list_next(This
->head
, This
->index
);
1367 if (pcFetched
) *pcFetched
= fetched
;
1368 return fetched
== ulCount
? S_OK
: S_FALSE
;
1371 static HRESULT WINAPI
EnumTfDocumentMgr_Skip( IEnumTfDocumentMgrs
* iface
, ULONG celt
)
1373 EnumTfDocumentMgr
*This
= impl_from_IEnumTfDocumentMgrs(iface
);
1376 TRACE("(%p)\n",This
);
1377 for(i
= 0; i
< celt
&& This
->index
!= NULL
; i
++)
1378 This
->index
= list_next(This
->head
, This
->index
);
1382 static HRESULT WINAPI
EnumTfDocumentMgr_Reset( IEnumTfDocumentMgrs
* iface
)
1384 EnumTfDocumentMgr
*This
= impl_from_IEnumTfDocumentMgrs(iface
);
1385 TRACE("(%p)\n",This
);
1386 This
->index
= list_head(This
->head
);
1390 static HRESULT WINAPI
EnumTfDocumentMgr_Clone( IEnumTfDocumentMgrs
*iface
,
1391 IEnumTfDocumentMgrs
**ppenum
)
1393 EnumTfDocumentMgr
*This
= impl_from_IEnumTfDocumentMgrs(iface
);
1396 TRACE("(%p)\n",This
);
1398 if (ppenum
== NULL
) return E_POINTER
;
1400 res
= EnumTfDocumentMgr_Constructor(This
->head
, ppenum
);
1403 EnumTfDocumentMgr
*new_This
= impl_from_IEnumTfDocumentMgrs(*ppenum
);
1404 new_This
->index
= This
->index
;
1409 static const IEnumTfDocumentMgrsVtbl EnumTfDocumentMgrsVtbl
=
1411 EnumTfDocumentMgr_QueryInterface
,
1412 EnumTfDocumentMgr_AddRef
,
1413 EnumTfDocumentMgr_Release
,
1414 EnumTfDocumentMgr_Clone
,
1415 EnumTfDocumentMgr_Next
,
1416 EnumTfDocumentMgr_Reset
,
1417 EnumTfDocumentMgr_Skip
1420 static HRESULT
EnumTfDocumentMgr_Constructor(struct list
* head
, IEnumTfDocumentMgrs
**ppOut
)
1422 EnumTfDocumentMgr
*This
;
1424 This
= HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY
,sizeof(EnumTfDocumentMgr
));
1426 return E_OUTOFMEMORY
;
1428 This
->IEnumTfDocumentMgrs_iface
.lpVtbl
= &EnumTfDocumentMgrsVtbl
;
1431 This
->index
= list_head(This
->head
);
1433 TRACE("returning %p\n", This
);
1434 *ppOut
= (IEnumTfDocumentMgrs
*)This
;
1438 void ThreadMgr_OnDocumentMgrDestruction(ITfThreadMgr
*iface
, ITfDocumentMgr
*mgr
)
1440 ThreadMgr
*This
= impl_from_ITfThreadMgr(iface
);
1441 struct list
*cursor
;
1442 LIST_FOR_EACH(cursor
, &This
->CreatedDocumentMgrs
)
1444 DocumentMgrEntry
*mgrentry
= LIST_ENTRY(cursor
,DocumentMgrEntry
,entry
);
1445 if (mgrentry
->docmgr
== mgr
)
1447 list_remove(cursor
);
1448 HeapFree(GetProcessHeap(),0,mgrentry
);
1452 FIXME("ITfDocumentMgr %p not found in this thread\n",mgr
);