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 #define WIN32_NO_STATUS
23 #define COM_NO_WINDOWS_H
31 #include <wine/debug.h>
35 //#include "winuser.h"
36 //#include "shlwapi.h"
37 //#include "winerror.h"
41 //#include "wine/unicode.h"
42 #include <wine/list.h>
45 #include "msctf_internal.h"
47 WINE_DEFAULT_DEBUG_CHANNEL(msctf
);
49 typedef struct tagThreadMgrSink
{
54 /* ITfActiveLanguageProfileNotifySink *pITfActiveLanguageProfileNotifySink; */
55 /* ITfDisplayAttributeNotifySink *pITfDisplayAttributeNotifySink; */
56 /* ITfKeyTraceEventSink *pITfKeyTraceEventSink; */
57 /* ITfPreservedKeyNotifySink *pITfPreservedKeyNotifySink; */
58 /* ITfThreadFocusSink *pITfThreadFocusSink; */
59 ITfThreadMgrEventSink
*pITfThreadMgrEventSink
;
63 typedef struct tagPreservedKey
67 TF_PRESERVEDKEY prekey
;
72 typedef struct tagDocumentMgrs
75 ITfDocumentMgr
*docmgr
;
78 typedef struct tagAssociatedWindow
82 ITfDocumentMgr
*docmgr
;
85 typedef struct tagACLMulti
{
86 const ITfThreadMgrVtbl
*ThreadMgrVtbl
;
87 const ITfSourceVtbl
*SourceVtbl
;
88 const ITfKeystrokeMgrVtbl
*KeystrokeMgrVtbl
;
89 const ITfMessagePumpVtbl
*MessagePumpVtbl
;
90 const ITfClientIdVtbl
*ClientIdVtbl
;
91 /* const ITfThreadMgrExVtbl *ThreadMgrExVtbl; */
92 /* const ITfConfigureSystemKeystrokeFeedVtbl *ConfigureSystemKeystrokeFeedVtbl; */
93 /* const ITfLangBarItemMgrVtbl *LangBarItemMgrVtbl; */
94 /* const ITfUIElementMgrVtbl *UIElementMgrVtbl; */
95 const ITfSourceSingleVtbl
*SourceSingleVtbl
;
99 ITfCompartmentMgr
*CompartmentMgr
;
101 const ITfThreadMgrEventSinkVtbl
*ThreadMgrEventSinkVtbl
; /* internal */
103 ITfDocumentMgr
*focus
;
104 LONG activationCount
;
106 ITfKeyEventSink
*forgroundKeyEventSink
;
107 CLSID forgroundTextService
;
109 struct list CurrentPreservedKeys
;
110 struct list CreatedDocumentMgrs
;
112 struct list AssociatedFocusWindows
;
115 /* kept as separate lists to reduce unnecessary iterations */
116 struct list ActiveLanguageProfileNotifySink
;
117 struct list DisplayAttributeNotifySink
;
118 struct list KeyTraceEventSink
;
119 struct list PreservedKeyNotifySink
;
120 struct list ThreadFocusSink
;
121 struct list ThreadMgrEventSink
;
124 typedef struct tagEnumTfDocumentMgr
{
125 const IEnumTfDocumentMgrsVtbl
*Vtbl
;
132 static HRESULT
EnumTfDocumentMgr_Constructor(struct list
* head
, IEnumTfDocumentMgrs
**ppOut
);
134 static inline ThreadMgr
*impl_from_ITfSourceVtbl(ITfSource
*iface
)
136 return (ThreadMgr
*)((char *)iface
- FIELD_OFFSET(ThreadMgr
,SourceVtbl
));
139 static inline ThreadMgr
*impl_from_ITfKeystrokeMgrVtbl(ITfKeystrokeMgr
*iface
)
141 return (ThreadMgr
*)((char *)iface
- FIELD_OFFSET(ThreadMgr
,KeystrokeMgrVtbl
));
144 static inline ThreadMgr
*impl_from_ITfMessagePumpVtbl(ITfMessagePump
*iface
)
146 return (ThreadMgr
*)((char *)iface
- FIELD_OFFSET(ThreadMgr
,MessagePumpVtbl
));
149 static inline ThreadMgr
*impl_from_ITfClientIdVtbl(ITfClientId
*iface
)
151 return (ThreadMgr
*)((char *)iface
- FIELD_OFFSET(ThreadMgr
,ClientIdVtbl
));
154 static inline ThreadMgr
*impl_from_ITfThreadMgrEventSink(ITfThreadMgrEventSink
*iface
)
156 return (ThreadMgr
*)((char *)iface
- FIELD_OFFSET(ThreadMgr
,ThreadMgrEventSinkVtbl
));
159 static inline ThreadMgr
*impl_from_ITfSourceSingleVtbl(ITfSourceSingle
* iface
)
162 return (ThreadMgr
*)((char *)iface
- FIELD_OFFSET(ThreadMgr
,SourceSingleVtbl
));
165 static void free_sink(ThreadMgrSink
*sink
)
167 IUnknown_Release(sink
->interfaces
.pIUnknown
);
168 HeapFree(GetProcessHeap(),0,sink
);
171 static void ThreadMgr_Destructor(ThreadMgr
*This
)
173 struct list
*cursor
, *cursor2
;
175 /* unhook right away */
177 UnhookWindowsHookEx(This
->focusHook
);
179 TlsSetValue(tlsIndex
,NULL
);
180 TRACE("destroying %p\n", This
);
182 ITfDocumentMgr_Release(This
->focus
);
185 LIST_FOR_EACH_SAFE(cursor
, cursor2
, &This
->ActiveLanguageProfileNotifySink
)
187 ThreadMgrSink
* sink
= LIST_ENTRY(cursor
,ThreadMgrSink
,entry
);
191 LIST_FOR_EACH_SAFE(cursor
, cursor2
, &This
->DisplayAttributeNotifySink
)
193 ThreadMgrSink
* sink
= LIST_ENTRY(cursor
,ThreadMgrSink
,entry
);
197 LIST_FOR_EACH_SAFE(cursor
, cursor2
, &This
->KeyTraceEventSink
)
199 ThreadMgrSink
* sink
= LIST_ENTRY(cursor
,ThreadMgrSink
,entry
);
203 LIST_FOR_EACH_SAFE(cursor
, cursor2
, &This
->PreservedKeyNotifySink
)
205 ThreadMgrSink
* sink
= LIST_ENTRY(cursor
,ThreadMgrSink
,entry
);
209 LIST_FOR_EACH_SAFE(cursor
, cursor2
, &This
->ThreadFocusSink
)
211 ThreadMgrSink
* sink
= LIST_ENTRY(cursor
,ThreadMgrSink
,entry
);
215 LIST_FOR_EACH_SAFE(cursor
, cursor2
, &This
->ThreadMgrEventSink
)
217 ThreadMgrSink
* sink
= LIST_ENTRY(cursor
,ThreadMgrSink
,entry
);
222 LIST_FOR_EACH_SAFE(cursor
, cursor2
, &This
->CurrentPreservedKeys
)
224 PreservedKey
* key
= LIST_ENTRY(cursor
,PreservedKey
,entry
);
226 HeapFree(GetProcessHeap(),0,key
->description
);
227 HeapFree(GetProcessHeap(),0,key
);
230 LIST_FOR_EACH_SAFE(cursor
, cursor2
, &This
->CreatedDocumentMgrs
)
232 DocumentMgrEntry
*mgr
= LIST_ENTRY(cursor
,DocumentMgrEntry
,entry
);
234 FIXME("Left Over ITfDocumentMgr. Should we do something with it?\n");
235 HeapFree(GetProcessHeap(),0,mgr
);
238 LIST_FOR_EACH_SAFE(cursor
, cursor2
, &This
->AssociatedFocusWindows
)
240 AssociatedWindow
*wnd
= LIST_ENTRY(cursor
,AssociatedWindow
,entry
);
242 HeapFree(GetProcessHeap(),0,wnd
);
245 CompartmentMgr_Destructor(This
->CompartmentMgr
);
247 HeapFree(GetProcessHeap(),0,This
);
250 static HRESULT WINAPI
ThreadMgr_QueryInterface(ITfThreadMgr
*iface
, REFIID iid
, LPVOID
*ppvOut
)
252 ThreadMgr
*This
= (ThreadMgr
*)iface
;
255 if (IsEqualIID(iid
, &IID_IUnknown
) || IsEqualIID(iid
, &IID_ITfThreadMgr
))
259 else if (IsEqualIID(iid
, &IID_ITfSource
))
261 *ppvOut
= &This
->SourceVtbl
;
263 else if (IsEqualIID(iid
, &IID_ITfKeystrokeMgr
))
265 *ppvOut
= &This
->KeystrokeMgrVtbl
;
267 else if (IsEqualIID(iid
, &IID_ITfMessagePump
))
269 *ppvOut
= &This
->MessagePumpVtbl
;
271 else if (IsEqualIID(iid
, &IID_ITfClientId
))
273 *ppvOut
= &This
->ClientIdVtbl
;
275 else if (IsEqualIID(iid
, &IID_ITfCompartmentMgr
))
277 *ppvOut
= This
->CompartmentMgr
;
279 else if (IsEqualIID(iid
, &IID_ITfSourceSingle
))
281 *ppvOut
= &This
->SourceSingleVtbl
;
286 ITfThreadMgr_AddRef(iface
);
290 WARN("unsupported interface: %s\n", debugstr_guid(iid
));
291 return E_NOINTERFACE
;
294 static ULONG WINAPI
ThreadMgr_AddRef(ITfThreadMgr
*iface
)
296 ThreadMgr
*This
= (ThreadMgr
*)iface
;
297 return InterlockedIncrement(&This
->refCount
);
300 static ULONG WINAPI
ThreadMgr_Release(ITfThreadMgr
*iface
)
302 ThreadMgr
*This
= (ThreadMgr
*)iface
;
305 ret
= InterlockedDecrement(&This
->refCount
);
307 ThreadMgr_Destructor(This
);
311 /*****************************************************
312 * ITfThreadMgr functions
313 *****************************************************/
315 static HRESULT WINAPI
ThreadMgr_fnActivate( ITfThreadMgr
* iface
, TfClientId
*ptid
)
317 ThreadMgr
*This
= (ThreadMgr
*)iface
;
319 TRACE("(%p) %p\n",This
, ptid
);
328 ITfClientId_GetClientId((ITfClientId
*)&This
->ClientIdVtbl
,&guid
,&processId
);
331 activate_textservices(iface
);
332 This
->activationCount
++;
337 static HRESULT WINAPI
ThreadMgr_fnDeactivate( ITfThreadMgr
* iface
)
339 ThreadMgr
*This
= (ThreadMgr
*)iface
;
340 TRACE("(%p)\n",This
);
342 if (This
->activationCount
== 0)
345 This
->activationCount
--;
347 if (This
->activationCount
== 0)
351 ITfThreadMgrEventSink_OnSetFocus((ITfThreadMgrEventSink
*)&This
->ThreadMgrEventSinkVtbl
, 0, This
->focus
);
352 ITfDocumentMgr_Release(This
->focus
);
357 deactivate_textservices();
362 static HRESULT WINAPI
ThreadMgr_CreateDocumentMgr( ITfThreadMgr
* iface
, ITfDocumentMgr
365 ThreadMgr
*This
= (ThreadMgr
*)iface
;
366 DocumentMgrEntry
*mgrentry
;
369 TRACE("(%p)\n",iface
);
370 mgrentry
= HeapAlloc(GetProcessHeap(),0,sizeof(DocumentMgrEntry
));
371 if (mgrentry
== NULL
)
372 return E_OUTOFMEMORY
;
374 hr
= DocumentMgr_Constructor((ITfThreadMgrEventSink
*)&This
->ThreadMgrEventSinkVtbl
, ppdim
);
378 mgrentry
->docmgr
= *ppdim
;
379 list_add_head(&This
->CreatedDocumentMgrs
,&mgrentry
->entry
);
382 HeapFree(GetProcessHeap(),0,mgrentry
);
387 static HRESULT WINAPI
ThreadMgr_EnumDocumentMgrs( ITfThreadMgr
* iface
, IEnumTfDocumentMgrs
390 ThreadMgr
*This
= (ThreadMgr
*)iface
;
391 TRACE("(%p) %p\n",This
,ppEnum
);
396 return EnumTfDocumentMgr_Constructor(&This
->CreatedDocumentMgrs
, ppEnum
);
399 static HRESULT WINAPI
ThreadMgr_GetFocus( ITfThreadMgr
* iface
, ITfDocumentMgr
402 ThreadMgr
*This
= (ThreadMgr
*)iface
;
403 TRACE("(%p)\n",This
);
408 *ppdimFocus
= This
->focus
;
410 TRACE("->%p\n",This
->focus
);
412 if (This
->focus
== NULL
)
415 ITfDocumentMgr_AddRef(This
->focus
);
420 static HRESULT WINAPI
ThreadMgr_SetFocus( ITfThreadMgr
* iface
, ITfDocumentMgr
*pdimFocus
)
422 ITfDocumentMgr
*check
;
423 ThreadMgr
*This
= (ThreadMgr
*)iface
;
425 TRACE("(%p) %p\n",This
,pdimFocus
);
429 else if (FAILED(ITfDocumentMgr_QueryInterface(pdimFocus
,&IID_ITfDocumentMgr
,(LPVOID
*) &check
)))
432 ITfThreadMgrEventSink_OnSetFocus((ITfThreadMgrEventSink
*)&This
->ThreadMgrEventSinkVtbl
, check
, This
->focus
);
435 ITfDocumentMgr_Release(This
->focus
);
441 static LRESULT CALLBACK
ThreadFocusHookProc(int nCode
, WPARAM wParam
, LPARAM lParam
)
445 This
= TlsGetValue(tlsIndex
);
448 ERR("Hook proc but no ThreadMgr for this thread. Serious Error\n");
451 if (!This
->focusHook
)
453 ERR("Hook proc but no ThreadMgr focus Hook. Serious Error\n");
457 if (nCode
== HCBT_SETFOCUS
) /* focus change within our thread */
461 LIST_FOR_EACH(cursor
, &This
->AssociatedFocusWindows
)
463 AssociatedWindow
*wnd
= LIST_ENTRY(cursor
,AssociatedWindow
,entry
);
464 if (wnd
->hwnd
== (HWND
)wParam
)
466 TRACE("Triggering Associated window focus\n");
467 if (This
->focus
!= wnd
->docmgr
)
468 ThreadMgr_SetFocus((ITfThreadMgr
*)This
, wnd
->docmgr
);
474 return CallNextHookEx(This
->focusHook
, nCode
, wParam
, lParam
);
477 static HRESULT
SetupWindowsHook(ThreadMgr
*This
)
479 if (!This
->focusHook
)
481 This
->focusHook
= SetWindowsHookExW(WH_CBT
, ThreadFocusHookProc
, 0,
482 GetCurrentThreadId());
483 if (!This
->focusHook
)
485 ERR("Unable to set focus hook\n");
493 static HRESULT WINAPI
ThreadMgr_AssociateFocus( ITfThreadMgr
* iface
, HWND hwnd
,
494 ITfDocumentMgr
*pdimNew
, ITfDocumentMgr
**ppdimPrev
)
496 struct list
*cursor
, *cursor2
;
497 ThreadMgr
*This
= (ThreadMgr
*)iface
;
498 AssociatedWindow
*wnd
;
500 TRACE("(%p) %p %p %p\n",This
,hwnd
,pdimNew
,ppdimPrev
);
507 LIST_FOR_EACH_SAFE(cursor
, cursor2
, &This
->AssociatedFocusWindows
)
509 wnd
= LIST_ENTRY(cursor
,AssociatedWindow
,entry
);
510 if (wnd
->hwnd
== hwnd
)
513 ITfDocumentMgr_AddRef(wnd
->docmgr
);
514 *ppdimPrev
= wnd
->docmgr
;
515 wnd
->docmgr
= pdimNew
;
516 if (GetFocus() == hwnd
)
517 ThreadMgr_SetFocus(iface
,pdimNew
);
522 wnd
= HeapAlloc(GetProcessHeap(),0,sizeof(AssociatedWindow
));
524 wnd
->docmgr
= pdimNew
;
525 list_add_head(&This
->AssociatedFocusWindows
,&wnd
->entry
);
527 if (GetFocus() == hwnd
)
528 ThreadMgr_SetFocus(iface
,pdimNew
);
530 SetupWindowsHook(This
);
535 static HRESULT WINAPI
ThreadMgr_IsThreadFocus( ITfThreadMgr
* iface
, BOOL
*pfThreadFocus
)
538 ThreadMgr
*This
= (ThreadMgr
*)iface
;
539 TRACE("(%p) %p\n",This
,pfThreadFocus
);
541 *pfThreadFocus
= (focus
== NULL
);
545 static HRESULT WINAPI
ThreadMgr_GetFunctionProvider( ITfThreadMgr
* iface
, REFCLSID clsid
,
546 ITfFunctionProvider
**ppFuncProv
)
548 ThreadMgr
*This
= (ThreadMgr
*)iface
;
549 FIXME("STUB:(%p)\n",This
);
553 static HRESULT WINAPI
ThreadMgr_EnumFunctionProviders( ITfThreadMgr
* iface
,
554 IEnumTfFunctionProviders
**ppEnum
)
556 ThreadMgr
*This
= (ThreadMgr
*)iface
;
557 FIXME("STUB:(%p)\n",This
);
561 static HRESULT WINAPI
ThreadMgr_GetGlobalCompartment( ITfThreadMgr
* iface
,
562 ITfCompartmentMgr
**ppCompMgr
)
564 ThreadMgr
*This
= (ThreadMgr
*)iface
;
566 TRACE("(%p) %p\n",This
, ppCompMgr
);
571 if (!globalCompartmentMgr
)
573 hr
= CompartmentMgr_Constructor(NULL
,&IID_ITfCompartmentMgr
,(IUnknown
**)&globalCompartmentMgr
);
578 ITfCompartmentMgr_AddRef(globalCompartmentMgr
);
579 *ppCompMgr
= globalCompartmentMgr
;
583 static const ITfThreadMgrVtbl ThreadMgr_ThreadMgrVtbl
=
585 ThreadMgr_QueryInterface
,
589 ThreadMgr_fnActivate
,
590 ThreadMgr_fnDeactivate
,
591 ThreadMgr_CreateDocumentMgr
,
592 ThreadMgr_EnumDocumentMgrs
,
595 ThreadMgr_AssociateFocus
,
596 ThreadMgr_IsThreadFocus
,
597 ThreadMgr_GetFunctionProvider
,
598 ThreadMgr_EnumFunctionProviders
,
599 ThreadMgr_GetGlobalCompartment
603 static HRESULT WINAPI
Source_QueryInterface(ITfSource
*iface
, REFIID iid
, LPVOID
*ppvOut
)
605 ThreadMgr
*This
= impl_from_ITfSourceVtbl(iface
);
606 return ThreadMgr_QueryInterface((ITfThreadMgr
*)This
, iid
, *ppvOut
);
609 static ULONG WINAPI
Source_AddRef(ITfSource
*iface
)
611 ThreadMgr
*This
= impl_from_ITfSourceVtbl(iface
);
612 return ThreadMgr_AddRef((ITfThreadMgr
*)This
);
615 static ULONG WINAPI
Source_Release(ITfSource
*iface
)
617 ThreadMgr
*This
= impl_from_ITfSourceVtbl(iface
);
618 return ThreadMgr_Release((ITfThreadMgr
*)This
);
621 /*****************************************************
622 * ITfSource functions
623 *****************************************************/
624 static HRESULT WINAPI
ThreadMgrSource_AdviseSink(ITfSource
*iface
,
625 REFIID riid
, IUnknown
*punk
, DWORD
*pdwCookie
)
628 ThreadMgr
*This
= impl_from_ITfSourceVtbl(iface
);
630 TRACE("(%p) %s %p %p\n",This
,debugstr_guid(riid
),punk
,pdwCookie
);
632 if (!riid
|| !punk
|| !pdwCookie
)
635 if (IsEqualIID(riid
, &IID_ITfThreadMgrEventSink
))
637 tms
= HeapAlloc(GetProcessHeap(),0,sizeof(ThreadMgrSink
));
639 return E_OUTOFMEMORY
;
640 if (FAILED(IUnknown_QueryInterface(punk
, riid
, (LPVOID
*)&tms
->interfaces
.pITfThreadMgrEventSink
)))
642 HeapFree(GetProcessHeap(),0,tms
);
643 return CONNECT_E_CANNOTCONNECT
;
645 list_add_head(&This
->ThreadMgrEventSink
,&tms
->entry
);
646 *pdwCookie
= generate_Cookie(COOKIE_MAGIC_TMSINK
, tms
);
650 FIXME("(%p) Unhandled Sink: %s\n",This
,debugstr_guid(riid
));
654 TRACE("cookie %x\n",*pdwCookie
);
659 static HRESULT WINAPI
ThreadMgrSource_UnadviseSink(ITfSource
*iface
, DWORD pdwCookie
)
662 ThreadMgr
*This
= impl_from_ITfSourceVtbl(iface
);
664 TRACE("(%p) %x\n",This
,pdwCookie
);
666 if (get_Cookie_magic(pdwCookie
)!=COOKIE_MAGIC_TMSINK
)
669 sink
= remove_Cookie(pdwCookie
);
671 return CONNECT_E_NOCONNECTION
;
673 list_remove(&sink
->entry
);
679 static const ITfSourceVtbl ThreadMgr_SourceVtbl
=
681 Source_QueryInterface
,
685 ThreadMgrSource_AdviseSink
,
686 ThreadMgrSource_UnadviseSink
,
689 /*****************************************************
690 * ITfKeystrokeMgr functions
691 *****************************************************/
693 static HRESULT WINAPI
KeystrokeMgr_QueryInterface(ITfKeystrokeMgr
*iface
, REFIID iid
, LPVOID
*ppvOut
)
695 ThreadMgr
*This
= impl_from_ITfKeystrokeMgrVtbl(iface
);
696 return ThreadMgr_QueryInterface((ITfThreadMgr
*)This
, iid
, *ppvOut
);
699 static ULONG WINAPI
KeystrokeMgr_AddRef(ITfKeystrokeMgr
*iface
)
701 ThreadMgr
*This
= impl_from_ITfKeystrokeMgrVtbl(iface
);
702 return ThreadMgr_AddRef((ITfThreadMgr
*)This
);
705 static ULONG WINAPI
KeystrokeMgr_Release(ITfKeystrokeMgr
*iface
)
707 ThreadMgr
*This
= impl_from_ITfKeystrokeMgrVtbl(iface
);
708 return ThreadMgr_Release((ITfThreadMgr
*)This
);
711 static HRESULT WINAPI
KeystrokeMgr_AdviseKeyEventSink(ITfKeystrokeMgr
*iface
,
712 TfClientId tid
, ITfKeyEventSink
*pSink
, BOOL fForeground
)
714 ThreadMgr
*This
= impl_from_ITfKeystrokeMgrVtbl(iface
);
716 ITfKeyEventSink
*check
= NULL
;
718 TRACE("(%p) %x %p %i\n",This
,tid
,pSink
,fForeground
);
723 textservice
= get_textservice_clsid(tid
);
724 if (IsEqualCLSID(&GUID_NULL
,&textservice
))
727 get_textservice_sink(tid
, &IID_ITfKeyEventSink
, (IUnknown
**)&check
);
729 return CONNECT_E_ADVISELIMIT
;
731 if (FAILED(ITfKeyEventSink_QueryInterface(pSink
,&IID_ITfKeyEventSink
,(LPVOID
*) &check
)))
734 set_textservice_sink(tid
, &IID_ITfKeyEventSink
, (IUnknown
*)check
);
738 if (This
->forgroundKeyEventSink
)
740 ITfKeyEventSink_OnSetFocus(This
->forgroundKeyEventSink
, FALSE
);
741 ITfKeyEventSink_Release(This
->forgroundKeyEventSink
);
743 ITfKeyEventSink_AddRef(check
);
744 ITfKeyEventSink_OnSetFocus(check
, TRUE
);
745 This
->forgroundKeyEventSink
= check
;
746 This
->forgroundTextService
= textservice
;
751 static HRESULT WINAPI
KeystrokeMgr_UnadviseKeyEventSink(ITfKeystrokeMgr
*iface
,
754 ThreadMgr
*This
= impl_from_ITfKeystrokeMgrVtbl(iface
);
756 ITfKeyEventSink
*check
= NULL
;
757 TRACE("(%p) %x\n",This
,tid
);
762 textservice
= get_textservice_clsid(tid
);
763 if (IsEqualCLSID(&GUID_NULL
,&textservice
))
766 get_textservice_sink(tid
, &IID_ITfKeyEventSink
, (IUnknown
**)&check
);
769 return CONNECT_E_NOCONNECTION
;
771 set_textservice_sink(tid
, &IID_ITfKeyEventSink
, NULL
);
772 ITfKeyEventSink_Release(check
);
774 if (This
->forgroundKeyEventSink
== check
)
776 ITfKeyEventSink_Release(This
->forgroundKeyEventSink
);
777 This
->forgroundKeyEventSink
= NULL
;
778 This
->forgroundTextService
= GUID_NULL
;
783 static HRESULT WINAPI
KeystrokeMgr_GetForeground(ITfKeystrokeMgr
*iface
,
786 ThreadMgr
*This
= impl_from_ITfKeystrokeMgrVtbl(iface
);
787 TRACE("(%p) %p\n",This
,pclsid
);
791 if (IsEqualCLSID(&This
->forgroundTextService
,&GUID_NULL
))
794 *pclsid
= This
->forgroundTextService
;
798 static HRESULT WINAPI
KeystrokeMgr_TestKeyDown(ITfKeystrokeMgr
*iface
,
799 WPARAM wParam
, LPARAM lParam
, BOOL
*pfEaten
)
801 ThreadMgr
*This
= impl_from_ITfKeystrokeMgrVtbl(iface
);
802 FIXME("STUB:(%p)\n",This
);
806 static HRESULT WINAPI
KeystrokeMgr_TestKeyUp(ITfKeystrokeMgr
*iface
,
807 WPARAM wParam
, LPARAM lParam
, BOOL
*pfEaten
)
809 ThreadMgr
*This
= impl_from_ITfKeystrokeMgrVtbl(iface
);
810 FIXME("STUB:(%p)\n",This
);
814 static HRESULT WINAPI
KeystrokeMgr_KeyDown(ITfKeystrokeMgr
*iface
,
815 WPARAM wParam
, LPARAM lParam
, BOOL
*pfEaten
)
817 ThreadMgr
*This
= impl_from_ITfKeystrokeMgrVtbl(iface
);
818 FIXME("STUB:(%p)\n",This
);
822 static HRESULT WINAPI
KeystrokeMgr_KeyUp(ITfKeystrokeMgr
*iface
,
823 WPARAM wParam
, LPARAM lParam
, BOOL
*pfEaten
)
825 ThreadMgr
*This
= impl_from_ITfKeystrokeMgrVtbl(iface
);
826 FIXME("STUB:(%p)\n",This
);
830 static HRESULT WINAPI
KeystrokeMgr_GetPreservedKey(ITfKeystrokeMgr
*iface
,
831 ITfContext
*pic
, const TF_PRESERVEDKEY
*pprekey
, GUID
*pguid
)
833 ThreadMgr
*This
= impl_from_ITfKeystrokeMgrVtbl(iface
);
834 FIXME("STUB:(%p)\n",This
);
838 static HRESULT WINAPI
KeystrokeMgr_IsPreservedKey(ITfKeystrokeMgr
*iface
,
839 REFGUID rguid
, const TF_PRESERVEDKEY
*pprekey
, BOOL
*pfRegistered
)
841 ThreadMgr
*This
= impl_from_ITfKeystrokeMgrVtbl(iface
);
844 TRACE("(%p) %s (%x %x) %p\n",This
,debugstr_guid(rguid
), (pprekey
)?pprekey
->uVKey
:0, (pprekey
)?pprekey
->uModifiers
:0, pfRegistered
);
846 if (!rguid
|| !pprekey
|| !pfRegistered
)
849 LIST_FOR_EACH(cursor
, &This
->CurrentPreservedKeys
)
851 PreservedKey
* key
= LIST_ENTRY(cursor
,PreservedKey
,entry
);
852 if (IsEqualGUID(rguid
,&key
->guid
) && pprekey
->uVKey
== key
->prekey
.uVKey
&& pprekey
->uModifiers
== key
->prekey
.uModifiers
)
854 *pfRegistered
= TRUE
;
859 *pfRegistered
= FALSE
;
863 static HRESULT WINAPI
KeystrokeMgr_PreserveKey(ITfKeystrokeMgr
*iface
,
864 TfClientId tid
, REFGUID rguid
, const TF_PRESERVEDKEY
*prekey
,
865 const WCHAR
*pchDesc
, ULONG cchDesc
)
867 ThreadMgr
*This
= impl_from_ITfKeystrokeMgrVtbl(iface
);
869 PreservedKey
*newkey
;
871 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
));
873 if (!tid
|| ! rguid
|| !prekey
|| (cchDesc
&& !pchDesc
))
876 LIST_FOR_EACH(cursor
, &This
->CurrentPreservedKeys
)
878 PreservedKey
* key
= LIST_ENTRY(cursor
,PreservedKey
,entry
);
879 if (IsEqualGUID(rguid
,&key
->guid
) && prekey
->uVKey
== key
->prekey
.uVKey
&& prekey
->uModifiers
== key
->prekey
.uModifiers
)
880 return TF_E_ALREADY_EXISTS
;
883 newkey
= HeapAlloc(GetProcessHeap(),0,sizeof(PreservedKey
));
885 return E_OUTOFMEMORY
;
887 newkey
->guid
= *rguid
;
888 newkey
->prekey
= *prekey
;
890 newkey
->description
= NULL
;
893 newkey
->description
= HeapAlloc(GetProcessHeap(),0,cchDesc
* sizeof(WCHAR
));
894 if (!newkey
->description
)
896 HeapFree(GetProcessHeap(),0,newkey
);
897 return E_OUTOFMEMORY
;
899 memcpy(newkey
->description
, pchDesc
, cchDesc
*sizeof(WCHAR
));
902 list_add_head(&This
->CurrentPreservedKeys
,&newkey
->entry
);
907 static HRESULT WINAPI
KeystrokeMgr_UnpreserveKey(ITfKeystrokeMgr
*iface
,
908 REFGUID rguid
, const TF_PRESERVEDKEY
*pprekey
)
910 ThreadMgr
*This
= impl_from_ITfKeystrokeMgrVtbl(iface
);
911 PreservedKey
* key
= NULL
;
913 TRACE("(%p) %s (%x %x)\n",This
,debugstr_guid(rguid
),(pprekey
)?pprekey
->uVKey
:0, (pprekey
)?pprekey
->uModifiers
:0);
915 if (!pprekey
|| !rguid
)
918 LIST_FOR_EACH(cursor
, &This
->CurrentPreservedKeys
)
920 key
= LIST_ENTRY(cursor
,PreservedKey
,entry
);
921 if (IsEqualGUID(rguid
,&key
->guid
) && pprekey
->uVKey
== key
->prekey
.uVKey
&& pprekey
->uModifiers
== key
->prekey
.uModifiers
)
927 return CONNECT_E_NOCONNECTION
;
929 list_remove(&key
->entry
);
930 HeapFree(GetProcessHeap(),0,key
->description
);
931 HeapFree(GetProcessHeap(),0,key
);
936 static HRESULT WINAPI
KeystrokeMgr_SetPreservedKeyDescription(ITfKeystrokeMgr
*iface
,
937 REFGUID rguid
, const WCHAR
*pchDesc
, ULONG cchDesc
)
939 ThreadMgr
*This
= impl_from_ITfKeystrokeMgrVtbl(iface
);
940 FIXME("STUB:(%p)\n",This
);
944 static HRESULT WINAPI
KeystrokeMgr_GetPreservedKeyDescription(ITfKeystrokeMgr
*iface
,
945 REFGUID rguid
, BSTR
*pbstrDesc
)
947 ThreadMgr
*This
= impl_from_ITfKeystrokeMgrVtbl(iface
);
948 FIXME("STUB:(%p)\n",This
);
952 static HRESULT WINAPI
KeystrokeMgr_SimulatePreservedKey(ITfKeystrokeMgr
*iface
,
953 ITfContext
*pic
, REFGUID rguid
, BOOL
*pfEaten
)
955 ThreadMgr
*This
= impl_from_ITfKeystrokeMgrVtbl(iface
);
956 FIXME("STUB:(%p)\n",This
);
960 static const ITfKeystrokeMgrVtbl ThreadMgr_KeystrokeMgrVtbl
=
962 KeystrokeMgr_QueryInterface
,
964 KeystrokeMgr_Release
,
966 KeystrokeMgr_AdviseKeyEventSink
,
967 KeystrokeMgr_UnadviseKeyEventSink
,
968 KeystrokeMgr_GetForeground
,
969 KeystrokeMgr_TestKeyDown
,
970 KeystrokeMgr_TestKeyUp
,
971 KeystrokeMgr_KeyDown
,
973 KeystrokeMgr_GetPreservedKey
,
974 KeystrokeMgr_IsPreservedKey
,
975 KeystrokeMgr_PreserveKey
,
976 KeystrokeMgr_UnpreserveKey
,
977 KeystrokeMgr_SetPreservedKeyDescription
,
978 KeystrokeMgr_GetPreservedKeyDescription
,
979 KeystrokeMgr_SimulatePreservedKey
982 /*****************************************************
983 * ITfMessagePump functions
984 *****************************************************/
986 static HRESULT WINAPI
MessagePump_QueryInterface(ITfMessagePump
*iface
, REFIID iid
, LPVOID
*ppvOut
)
988 ThreadMgr
*This
= impl_from_ITfMessagePumpVtbl(iface
);
989 return ThreadMgr_QueryInterface((ITfThreadMgr
*)This
, iid
, *ppvOut
);
992 static ULONG WINAPI
MessagePump_AddRef(ITfMessagePump
*iface
)
994 ThreadMgr
*This
= impl_from_ITfMessagePumpVtbl(iface
);
995 return ThreadMgr_AddRef((ITfThreadMgr
*)This
);
998 static ULONG WINAPI
MessagePump_Release(ITfMessagePump
*iface
)
1000 ThreadMgr
*This
= impl_from_ITfMessagePumpVtbl(iface
);
1001 return ThreadMgr_Release((ITfThreadMgr
*)This
);
1004 static HRESULT WINAPI
MessagePump_PeekMessageA(ITfMessagePump
*iface
,
1005 LPMSG pMsg
, HWND hwnd
, UINT wMsgFilterMin
, UINT wMsgFilterMax
,
1006 UINT wRemoveMsg
, BOOL
*pfResult
)
1009 return E_INVALIDARG
;
1010 *pfResult
= PeekMessageA(pMsg
, hwnd
, wMsgFilterMin
, wMsgFilterMax
, wRemoveMsg
);
1014 static HRESULT WINAPI
MessagePump_GetMessageA(ITfMessagePump
*iface
,
1015 LPMSG pMsg
, HWND hwnd
, UINT wMsgFilterMin
, UINT wMsgFilterMax
,
1019 return E_INVALIDARG
;
1020 *pfResult
= GetMessageA(pMsg
, hwnd
, wMsgFilterMin
, wMsgFilterMax
);
1024 static HRESULT WINAPI
MessagePump_PeekMessageW(ITfMessagePump
*iface
,
1025 LPMSG pMsg
, HWND hwnd
, UINT wMsgFilterMin
, UINT wMsgFilterMax
,
1026 UINT wRemoveMsg
, BOOL
*pfResult
)
1029 return E_INVALIDARG
;
1030 *pfResult
= PeekMessageW(pMsg
, hwnd
, wMsgFilterMin
, wMsgFilterMax
, wRemoveMsg
);
1034 static HRESULT WINAPI
MessagePump_GetMessageW(ITfMessagePump
*iface
,
1035 LPMSG pMsg
, HWND hwnd
, UINT wMsgFilterMin
, UINT wMsgFilterMax
,
1039 return E_INVALIDARG
;
1040 *pfResult
= GetMessageW(pMsg
, hwnd
, wMsgFilterMin
, wMsgFilterMax
);
1044 static const ITfMessagePumpVtbl ThreadMgr_MessagePumpVtbl
=
1046 MessagePump_QueryInterface
,
1048 MessagePump_Release
,
1050 MessagePump_PeekMessageA
,
1051 MessagePump_GetMessageA
,
1052 MessagePump_PeekMessageW
,
1053 MessagePump_GetMessageW
1056 /*****************************************************
1057 * ITfClientId functions
1058 *****************************************************/
1060 static HRESULT WINAPI
ClientId_QueryInterface(ITfClientId
*iface
, REFIID iid
, LPVOID
*ppvOut
)
1062 ThreadMgr
*This
= impl_from_ITfClientIdVtbl(iface
);
1063 return ThreadMgr_QueryInterface((ITfThreadMgr
*)This
, iid
, *ppvOut
);
1066 static ULONG WINAPI
ClientId_AddRef(ITfClientId
*iface
)
1068 ThreadMgr
*This
= impl_from_ITfClientIdVtbl(iface
);
1069 return ThreadMgr_AddRef((ITfThreadMgr
*)This
);
1072 static ULONG WINAPI
ClientId_Release(ITfClientId
*iface
)
1074 ThreadMgr
*This
= impl_from_ITfClientIdVtbl(iface
);
1075 return ThreadMgr_Release((ITfThreadMgr
*)This
);
1078 static HRESULT WINAPI
ClientId_GetClientId(ITfClientId
*iface
,
1079 REFCLSID rclsid
, TfClientId
*ptid
)
1083 ITfCategoryMgr
*catmgr
;
1084 ThreadMgr
*This
= impl_from_ITfClientIdVtbl(iface
);
1086 TRACE("(%p) %s\n",This
,debugstr_guid(rclsid
));
1088 CategoryMgr_Constructor(NULL
,(IUnknown
**)&catmgr
);
1089 hr
= ITfCategoryMgr_RegisterGUID(catmgr
,rclsid
,ptid
);
1090 ITfCategoryMgr_Release(catmgr
);
1095 static const ITfClientIdVtbl ThreadMgr_ClientIdVtbl
=
1097 ClientId_QueryInterface
,
1101 ClientId_GetClientId
1104 /*****************************************************
1105 * ITfThreadMgrEventSink functions (internal)
1106 *****************************************************/
1107 static HRESULT WINAPI
ThreadMgrEventSink_QueryInterface(ITfThreadMgrEventSink
*iface
, REFIID iid
, LPVOID
*ppvOut
)
1109 ThreadMgr
*This
= impl_from_ITfThreadMgrEventSink(iface
);
1110 return ThreadMgr_QueryInterface((ITfThreadMgr
*)This
, iid
, *ppvOut
);
1113 static ULONG WINAPI
ThreadMgrEventSink_AddRef(ITfThreadMgrEventSink
*iface
)
1115 ThreadMgr
*This
= impl_from_ITfThreadMgrEventSink(iface
);
1116 return ThreadMgr_AddRef((ITfThreadMgr
*)This
);
1119 static ULONG WINAPI
ThreadMgrEventSink_Release(ITfThreadMgrEventSink
*iface
)
1121 ThreadMgr
*This
= impl_from_ITfThreadMgrEventSink(iface
);
1122 return ThreadMgr_Release((ITfThreadMgr
*)This
);
1126 static HRESULT WINAPI
ThreadMgrEventSink_OnInitDocumentMgr(
1127 ITfThreadMgrEventSink
*iface
,ITfDocumentMgr
*pdim
)
1129 struct list
*cursor
;
1130 ThreadMgr
*This
= impl_from_ITfThreadMgrEventSink(iface
);
1132 TRACE("(%p) %p\n",This
,pdim
);
1134 LIST_FOR_EACH(cursor
, &This
->ThreadMgrEventSink
)
1136 ThreadMgrSink
* sink
= LIST_ENTRY(cursor
,ThreadMgrSink
,entry
);
1137 ITfThreadMgrEventSink_OnInitDocumentMgr(sink
->interfaces
.pITfThreadMgrEventSink
,pdim
);
1143 static HRESULT WINAPI
ThreadMgrEventSink_OnUninitDocumentMgr(
1144 ITfThreadMgrEventSink
*iface
, ITfDocumentMgr
*pdim
)
1146 struct list
*cursor
;
1147 ThreadMgr
*This
= impl_from_ITfThreadMgrEventSink(iface
);
1149 TRACE("(%p) %p\n",This
,pdim
);
1151 LIST_FOR_EACH(cursor
, &This
->ThreadMgrEventSink
)
1153 ThreadMgrSink
* sink
= LIST_ENTRY(cursor
,ThreadMgrSink
,entry
);
1154 ITfThreadMgrEventSink_OnUninitDocumentMgr(sink
->interfaces
.pITfThreadMgrEventSink
,pdim
);
1160 static HRESULT WINAPI
ThreadMgrEventSink_OnSetFocus(
1161 ITfThreadMgrEventSink
*iface
, ITfDocumentMgr
*pdimFocus
,
1162 ITfDocumentMgr
*pdimPrevFocus
)
1164 struct list
*cursor
;
1165 ThreadMgr
*This
= impl_from_ITfThreadMgrEventSink(iface
);
1167 TRACE("(%p) %p %p\n",This
,pdimFocus
, pdimPrevFocus
);
1169 LIST_FOR_EACH(cursor
, &This
->ThreadMgrEventSink
)
1171 ThreadMgrSink
* sink
= LIST_ENTRY(cursor
,ThreadMgrSink
,entry
);
1172 ITfThreadMgrEventSink_OnSetFocus(sink
->interfaces
.pITfThreadMgrEventSink
, pdimFocus
, pdimPrevFocus
);
1178 static HRESULT WINAPI
ThreadMgrEventSink_OnPushContext(
1179 ITfThreadMgrEventSink
*iface
, ITfContext
*pic
)
1181 struct list
*cursor
;
1182 ThreadMgr
*This
= impl_from_ITfThreadMgrEventSink(iface
);
1184 TRACE("(%p) %p\n",This
,pic
);
1186 LIST_FOR_EACH(cursor
, &This
->ThreadMgrEventSink
)
1188 ThreadMgrSink
* sink
= LIST_ENTRY(cursor
,ThreadMgrSink
,entry
);
1189 ITfThreadMgrEventSink_OnPushContext(sink
->interfaces
.pITfThreadMgrEventSink
,pic
);
1195 static HRESULT WINAPI
ThreadMgrEventSink_OnPopContext(
1196 ITfThreadMgrEventSink
*iface
, ITfContext
*pic
)
1198 struct list
*cursor
;
1199 ThreadMgr
*This
= impl_from_ITfThreadMgrEventSink(iface
);
1201 TRACE("(%p) %p\n",This
,pic
);
1203 LIST_FOR_EACH(cursor
, &This
->ThreadMgrEventSink
)
1205 ThreadMgrSink
* sink
= LIST_ENTRY(cursor
,ThreadMgrSink
,entry
);
1206 ITfThreadMgrEventSink_OnPopContext(sink
->interfaces
.pITfThreadMgrEventSink
,pic
);
1212 static const ITfThreadMgrEventSinkVtbl ThreadMgr_ThreadMgrEventSinkVtbl
=
1214 ThreadMgrEventSink_QueryInterface
,
1215 ThreadMgrEventSink_AddRef
,
1216 ThreadMgrEventSink_Release
,
1218 ThreadMgrEventSink_OnInitDocumentMgr
,
1219 ThreadMgrEventSink_OnUninitDocumentMgr
,
1220 ThreadMgrEventSink_OnSetFocus
,
1221 ThreadMgrEventSink_OnPushContext
,
1222 ThreadMgrEventSink_OnPopContext
1225 /*****************************************************
1226 * ITfSourceSingle functions
1227 *****************************************************/
1228 static HRESULT WINAPI
ThreadMgrSourceSingle_QueryInterface(ITfSourceSingle
*iface
, REFIID iid
, LPVOID
*ppvOut
)
1230 ThreadMgr
*This
= impl_from_ITfSourceSingleVtbl(iface
);
1231 return ThreadMgr_QueryInterface((ITfThreadMgr
*)This
, iid
, *ppvOut
);
1234 static ULONG WINAPI
ThreadMgrSourceSingle_AddRef(ITfSourceSingle
*iface
)
1236 ThreadMgr
*This
= impl_from_ITfSourceSingleVtbl(iface
);
1237 return ThreadMgr_AddRef((ITfThreadMgr
*)This
);
1240 static ULONG WINAPI
ThreadMgrSourceSingle_Release(ITfSourceSingle
*iface
)
1242 ThreadMgr
*This
= impl_from_ITfSourceSingleVtbl(iface
);
1243 return ThreadMgr_Release((ITfThreadMgr
*)This
);
1246 static HRESULT WINAPI
ThreadMgrSourceSingle_AdviseSingleSink( ITfSourceSingle
*iface
,
1247 TfClientId tid
, REFIID riid
, IUnknown
*punk
)
1249 ThreadMgr
*This
= impl_from_ITfSourceSingleVtbl(iface
);
1250 FIXME("STUB:(%p) %i %s %p\n",This
, tid
, debugstr_guid(riid
),punk
);
1254 static HRESULT WINAPI
ThreadMgrSourceSingle_UnadviseSingleSink( ITfSourceSingle
*iface
,
1255 TfClientId tid
, REFIID riid
)
1257 ThreadMgr
*This
= impl_from_ITfSourceSingleVtbl(iface
);
1258 FIXME("STUB:(%p) %i %s\n",This
, tid
, debugstr_guid(riid
));
1262 static const ITfSourceSingleVtbl ThreadMgr_SourceSingleVtbl
=
1264 ThreadMgrSourceSingle_QueryInterface
,
1265 ThreadMgrSourceSingle_AddRef
,
1266 ThreadMgrSourceSingle_Release
,
1268 ThreadMgrSourceSingle_AdviseSingleSink
,
1269 ThreadMgrSourceSingle_UnadviseSingleSink
,
1272 HRESULT
ThreadMgr_Constructor(IUnknown
*pUnkOuter
, IUnknown
**ppOut
)
1276 return CLASS_E_NOAGGREGATION
;
1278 /* Only 1 ThreadMgr is created per thread */
1279 This
= TlsGetValue(tlsIndex
);
1282 ThreadMgr_AddRef((ITfThreadMgr
*)This
);
1283 *ppOut
= (IUnknown
*)This
;
1287 This
= HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY
,sizeof(ThreadMgr
));
1289 return E_OUTOFMEMORY
;
1291 This
->ThreadMgrVtbl
= &ThreadMgr_ThreadMgrVtbl
;
1292 This
->SourceVtbl
= &ThreadMgr_SourceVtbl
;
1293 This
->KeystrokeMgrVtbl
= &ThreadMgr_KeystrokeMgrVtbl
;
1294 This
->MessagePumpVtbl
= &ThreadMgr_MessagePumpVtbl
;
1295 This
->ClientIdVtbl
= &ThreadMgr_ClientIdVtbl
;
1296 This
->ThreadMgrEventSinkVtbl
= &ThreadMgr_ThreadMgrEventSinkVtbl
;
1297 This
->SourceSingleVtbl
= &ThreadMgr_SourceSingleVtbl
;
1299 TlsSetValue(tlsIndex
,This
);
1301 CompartmentMgr_Constructor((IUnknown
*)This
, &IID_IUnknown
, (IUnknown
**)&This
->CompartmentMgr
);
1303 list_init(&This
->CurrentPreservedKeys
);
1304 list_init(&This
->CreatedDocumentMgrs
);
1305 list_init(&This
->AssociatedFocusWindows
);
1307 list_init(&This
->ActiveLanguageProfileNotifySink
);
1308 list_init(&This
->DisplayAttributeNotifySink
);
1309 list_init(&This
->KeyTraceEventSink
);
1310 list_init(&This
->PreservedKeyNotifySink
);
1311 list_init(&This
->ThreadFocusSink
);
1312 list_init(&This
->ThreadMgrEventSink
);
1314 TRACE("returning %p\n", This
);
1315 *ppOut
= (IUnknown
*)This
;
1319 /**************************************************
1320 * IEnumTfDocumentMgrs implementation
1321 **************************************************/
1322 static void EnumTfDocumentMgr_Destructor(EnumTfDocumentMgr
*This
)
1324 TRACE("destroying %p\n", This
);
1325 HeapFree(GetProcessHeap(),0,This
);
1328 static HRESULT WINAPI
EnumTfDocumentMgr_QueryInterface(IEnumTfDocumentMgrs
*iface
, REFIID iid
, LPVOID
*ppvOut
)
1330 EnumTfDocumentMgr
*This
= (EnumTfDocumentMgr
*)iface
;
1333 if (IsEqualIID(iid
, &IID_IUnknown
) || IsEqualIID(iid
, &IID_IEnumTfDocumentMgrs
))
1340 IEnumTfDocumentMgrs_AddRef(iface
);
1344 WARN("unsupported interface: %s\n", debugstr_guid(iid
));
1345 return E_NOINTERFACE
;
1348 static ULONG WINAPI
EnumTfDocumentMgr_AddRef(IEnumTfDocumentMgrs
*iface
)
1350 EnumTfDocumentMgr
*This
= (EnumTfDocumentMgr
*)iface
;
1351 return InterlockedIncrement(&This
->refCount
);
1354 static ULONG WINAPI
EnumTfDocumentMgr_Release(IEnumTfDocumentMgrs
*iface
)
1356 EnumTfDocumentMgr
*This
= (EnumTfDocumentMgr
*)iface
;
1359 ret
= InterlockedDecrement(&This
->refCount
);
1361 EnumTfDocumentMgr_Destructor(This
);
1365 static HRESULT WINAPI
EnumTfDocumentMgr_Next(IEnumTfDocumentMgrs
*iface
,
1366 ULONG ulCount
, ITfDocumentMgr
**rgDocumentMgr
, ULONG
*pcFetched
)
1368 EnumTfDocumentMgr
*This
= (EnumTfDocumentMgr
*)iface
;
1371 TRACE("(%p)\n",This
);
1373 if (rgDocumentMgr
== NULL
) return E_POINTER
;
1375 while (fetched
< ulCount
)
1377 DocumentMgrEntry
*mgrentry
;
1378 if (This
->index
== NULL
)
1381 mgrentry
= LIST_ENTRY(This
->index
,DocumentMgrEntry
,entry
);
1382 if (mgrentry
== NULL
)
1385 *rgDocumentMgr
= mgrentry
->docmgr
;
1386 ITfDocumentMgr_AddRef(*rgDocumentMgr
);
1388 This
->index
= list_next(This
->head
, This
->index
);
1393 if (pcFetched
) *pcFetched
= fetched
;
1394 return fetched
== ulCount
? S_OK
: S_FALSE
;
1397 static HRESULT WINAPI
EnumTfDocumentMgr_Skip( IEnumTfDocumentMgrs
* iface
, ULONG celt
)
1400 EnumTfDocumentMgr
*This
= (EnumTfDocumentMgr
*)iface
;
1401 TRACE("(%p)\n",This
);
1402 for(i
= 0; i
< celt
&& This
->index
!= NULL
; i
++)
1403 This
->index
= list_next(This
->head
, This
->index
);
1407 static HRESULT WINAPI
EnumTfDocumentMgr_Reset( IEnumTfDocumentMgrs
* iface
)
1409 EnumTfDocumentMgr
*This
= (EnumTfDocumentMgr
*)iface
;
1410 TRACE("(%p)\n",This
);
1411 This
->index
= list_head(This
->head
);
1415 static HRESULT WINAPI
EnumTfDocumentMgr_Clone( IEnumTfDocumentMgrs
*iface
,
1416 IEnumTfDocumentMgrs
**ppenum
)
1418 EnumTfDocumentMgr
*This
= (EnumTfDocumentMgr
*)iface
;
1421 TRACE("(%p)\n",This
);
1423 if (ppenum
== NULL
) return E_POINTER
;
1425 res
= EnumTfDocumentMgr_Constructor(This
->head
, ppenum
);
1428 EnumTfDocumentMgr
*new_This
= (EnumTfDocumentMgr
*)*ppenum
;
1429 new_This
->index
= This
->index
;
1434 static const IEnumTfDocumentMgrsVtbl IEnumTfDocumentMgrs_Vtbl
={
1435 EnumTfDocumentMgr_QueryInterface
,
1436 EnumTfDocumentMgr_AddRef
,
1437 EnumTfDocumentMgr_Release
,
1439 EnumTfDocumentMgr_Clone
,
1440 EnumTfDocumentMgr_Next
,
1441 EnumTfDocumentMgr_Reset
,
1442 EnumTfDocumentMgr_Skip
1445 static HRESULT
EnumTfDocumentMgr_Constructor(struct list
* head
, IEnumTfDocumentMgrs
**ppOut
)
1447 EnumTfDocumentMgr
*This
;
1449 This
= HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY
,sizeof(EnumTfDocumentMgr
));
1451 return E_OUTOFMEMORY
;
1453 This
->Vtbl
= &IEnumTfDocumentMgrs_Vtbl
;
1456 This
->index
= list_head(This
->head
);
1458 TRACE("returning %p\n", This
);
1459 *ppOut
= (IEnumTfDocumentMgrs
*)This
;
1463 void ThreadMgr_OnDocumentMgrDestruction(ITfThreadMgr
*tm
, ITfDocumentMgr
*mgr
)
1465 ThreadMgr
*This
= (ThreadMgr
*)tm
;
1466 struct list
*cursor
;
1467 LIST_FOR_EACH(cursor
, &This
->CreatedDocumentMgrs
)
1469 DocumentMgrEntry
*mgrentry
= LIST_ENTRY(cursor
,DocumentMgrEntry
,entry
);
1470 if (mgrentry
->docmgr
== mgr
)
1472 list_remove(cursor
);
1473 HeapFree(GetProcessHeap(),0,mgrentry
);
1477 FIXME("ITfDocumentMgr %p not found in this thread\n",mgr
);