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 ITfThreadMgrEx ITfThreadMgrEx_iface
;
83 ITfSource ITfSource_iface
;
84 ITfKeystrokeMgr ITfKeystrokeMgr_iface
;
85 ITfMessagePump ITfMessagePump_iface
;
86 ITfClientId ITfClientId_iface
;
87 /* const ITfThreadMgrExVtbl *ThreadMgrExVtbl; */
88 /* const ITfConfigureSystemKeystrokeFeedVtbl *ConfigureSystemKeystrokeFeedVtbl; */
89 /* const ITfLangBarItemMgrVtbl *LangBarItemMgrVtbl; */
90 ITfUIElementMgr ITfUIElementMgr_iface
;
91 ITfSourceSingle ITfSourceSingle_iface
;
95 ITfCompartmentMgr
*CompartmentMgr
;
97 ITfThreadMgrEventSink ITfThreadMgrEventSink_iface
; /* 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 IEnumTfDocumentMgrs IEnumTfDocumentMgrs_iface
;
128 static HRESULT
EnumTfDocumentMgr_Constructor(struct list
* head
, IEnumTfDocumentMgrs
**ppOut
);
130 static inline ThreadMgr
*impl_from_ITfThreadMgrEx(ITfThreadMgrEx
*iface
)
132 return CONTAINING_RECORD(iface
, ThreadMgr
, ITfThreadMgrEx_iface
);
135 static inline ThreadMgr
*impl_from_ITfSource(ITfSource
*iface
)
137 return CONTAINING_RECORD(iface
, ThreadMgr
, ITfSource_iface
);
140 static inline ThreadMgr
*impl_from_ITfKeystrokeMgr(ITfKeystrokeMgr
*iface
)
142 return CONTAINING_RECORD(iface
, ThreadMgr
, ITfKeystrokeMgr_iface
);
145 static inline ThreadMgr
*impl_from_ITfMessagePump(ITfMessagePump
*iface
)
147 return CONTAINING_RECORD(iface
, ThreadMgr
, ITfMessagePump_iface
);
150 static inline ThreadMgr
*impl_from_ITfClientId(ITfClientId
*iface
)
152 return CONTAINING_RECORD(iface
, ThreadMgr
, ITfClientId_iface
);
155 static inline ThreadMgr
*impl_from_ITfThreadMgrEventSink(ITfThreadMgrEventSink
*iface
)
157 return CONTAINING_RECORD(iface
, ThreadMgr
, ITfThreadMgrEventSink_iface
);
160 static inline ThreadMgr
*impl_from_ITfUIElementMgr(ITfUIElementMgr
*iface
)
162 return CONTAINING_RECORD(iface
, ThreadMgr
, ITfUIElementMgr_iface
);
165 static inline ThreadMgr
*impl_from_ITfSourceSingle(ITfSourceSingle
*iface
)
167 return CONTAINING_RECORD(iface
, ThreadMgr
, ITfSourceSingle_iface
);
170 static inline EnumTfDocumentMgr
*impl_from_IEnumTfDocumentMgrs(IEnumTfDocumentMgrs
*iface
)
172 return CONTAINING_RECORD(iface
, EnumTfDocumentMgr
, IEnumTfDocumentMgrs_iface
);
175 static void free_sink(ThreadMgrSink
*sink
)
177 IUnknown_Release(sink
->interfaces
.pIUnknown
);
178 HeapFree(GetProcessHeap(),0,sink
);
181 static void ThreadMgr_Destructor(ThreadMgr
*This
)
183 struct list
*cursor
, *cursor2
;
185 /* unhook right away */
187 UnhookWindowsHookEx(This
->focusHook
);
189 TlsSetValue(tlsIndex
,NULL
);
190 TRACE("destroying %p\n", This
);
192 ITfDocumentMgr_Release(This
->focus
);
195 LIST_FOR_EACH_SAFE(cursor
, cursor2
, &This
->ActiveLanguageProfileNotifySink
)
197 ThreadMgrSink
* sink
= LIST_ENTRY(cursor
,ThreadMgrSink
,entry
);
201 LIST_FOR_EACH_SAFE(cursor
, cursor2
, &This
->DisplayAttributeNotifySink
)
203 ThreadMgrSink
* sink
= LIST_ENTRY(cursor
,ThreadMgrSink
,entry
);
207 LIST_FOR_EACH_SAFE(cursor
, cursor2
, &This
->KeyTraceEventSink
)
209 ThreadMgrSink
* sink
= LIST_ENTRY(cursor
,ThreadMgrSink
,entry
);
213 LIST_FOR_EACH_SAFE(cursor
, cursor2
, &This
->PreservedKeyNotifySink
)
215 ThreadMgrSink
* sink
= LIST_ENTRY(cursor
,ThreadMgrSink
,entry
);
219 LIST_FOR_EACH_SAFE(cursor
, cursor2
, &This
->ThreadFocusSink
)
221 ThreadMgrSink
* sink
= LIST_ENTRY(cursor
,ThreadMgrSink
,entry
);
225 LIST_FOR_EACH_SAFE(cursor
, cursor2
, &This
->ThreadMgrEventSink
)
227 ThreadMgrSink
* sink
= LIST_ENTRY(cursor
,ThreadMgrSink
,entry
);
232 LIST_FOR_EACH_SAFE(cursor
, cursor2
, &This
->CurrentPreservedKeys
)
234 PreservedKey
* key
= LIST_ENTRY(cursor
,PreservedKey
,entry
);
236 HeapFree(GetProcessHeap(),0,key
->description
);
237 HeapFree(GetProcessHeap(),0,key
);
240 LIST_FOR_EACH_SAFE(cursor
, cursor2
, &This
->CreatedDocumentMgrs
)
242 DocumentMgrEntry
*mgr
= LIST_ENTRY(cursor
,DocumentMgrEntry
,entry
);
244 FIXME("Left Over ITfDocumentMgr. Should we do something with it?\n");
245 HeapFree(GetProcessHeap(),0,mgr
);
248 LIST_FOR_EACH_SAFE(cursor
, cursor2
, &This
->AssociatedFocusWindows
)
250 AssociatedWindow
*wnd
= LIST_ENTRY(cursor
,AssociatedWindow
,entry
);
252 HeapFree(GetProcessHeap(),0,wnd
);
255 CompartmentMgr_Destructor(This
->CompartmentMgr
);
257 HeapFree(GetProcessHeap(),0,This
);
260 static HRESULT WINAPI
ThreadMgr_QueryInterface(ITfThreadMgrEx
*iface
, REFIID iid
, LPVOID
*ppvOut
)
262 ThreadMgr
*This
= impl_from_ITfThreadMgrEx(iface
);
265 if (IsEqualIID(iid
, &IID_IUnknown
) || IsEqualIID(iid
, &IID_ITfThreadMgr
)
266 || IsEqualIID(iid
, &IID_ITfThreadMgrEx
))
268 *ppvOut
= &This
->ITfThreadMgrEx_iface
;
270 else if (IsEqualIID(iid
, &IID_ITfSource
))
272 *ppvOut
= &This
->ITfSource_iface
;
274 else if (IsEqualIID(iid
, &IID_ITfKeystrokeMgr
))
276 *ppvOut
= &This
->ITfKeystrokeMgr_iface
;
278 else if (IsEqualIID(iid
, &IID_ITfMessagePump
))
280 *ppvOut
= &This
->ITfMessagePump_iface
;
282 else if (IsEqualIID(iid
, &IID_ITfClientId
))
284 *ppvOut
= &This
->ITfClientId_iface
;
286 else if (IsEqualIID(iid
, &IID_ITfCompartmentMgr
))
288 *ppvOut
= This
->CompartmentMgr
;
290 else if (IsEqualIID(iid
, &IID_ITfUIElementMgr
))
292 *ppvOut
= &This
->ITfUIElementMgr_iface
;
294 else if (IsEqualIID(iid
, &IID_ITfSourceSingle
))
296 *ppvOut
= &This
->ITfSourceSingle_iface
;
301 ITfThreadMgrEx_AddRef(iface
);
305 WARN("unsupported interface: %s\n", debugstr_guid(iid
));
306 return E_NOINTERFACE
;
309 static ULONG WINAPI
ThreadMgr_AddRef(ITfThreadMgrEx
*iface
)
311 ThreadMgr
*This
= impl_from_ITfThreadMgrEx(iface
);
312 return InterlockedIncrement(&This
->refCount
);
315 static ULONG WINAPI
ThreadMgr_Release(ITfThreadMgrEx
*iface
)
317 ThreadMgr
*This
= impl_from_ITfThreadMgrEx(iface
);
320 ret
= InterlockedDecrement(&This
->refCount
);
322 ThreadMgr_Destructor(This
);
326 /*****************************************************
327 * ITfThreadMgr functions
328 *****************************************************/
330 static HRESULT WINAPI
ThreadMgr_Activate(ITfThreadMgrEx
*iface
, TfClientId
*id
)
332 ThreadMgr
*This
= impl_from_ITfThreadMgrEx(iface
);
334 TRACE("(%p) %p\n", This
, id
);
335 return ITfThreadMgrEx_ActivateEx(iface
, id
, 0);
338 static HRESULT WINAPI
ThreadMgr_Deactivate(ITfThreadMgrEx
*iface
)
340 ThreadMgr
*This
= impl_from_ITfThreadMgrEx(iface
);
341 TRACE("(%p)\n",This
);
343 if (This
->activationCount
== 0)
346 This
->activationCount
--;
348 if (This
->activationCount
== 0)
352 ITfThreadMgrEventSink_OnSetFocus(&This
->ITfThreadMgrEventSink_iface
, 0, This
->focus
);
353 ITfDocumentMgr_Release(This
->focus
);
358 deactivate_textservices();
363 static HRESULT WINAPI
ThreadMgr_CreateDocumentMgr(ITfThreadMgrEx
*iface
, ITfDocumentMgr
**ppdim
)
365 ThreadMgr
*This
= impl_from_ITfThreadMgrEx(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(&This
->ITfThreadMgrEventSink_iface
, ppdim
);
378 mgrentry
->docmgr
= *ppdim
;
379 list_add_head(&This
->CreatedDocumentMgrs
,&mgrentry
->entry
);
382 HeapFree(GetProcessHeap(),0,mgrentry
);
387 static HRESULT WINAPI
ThreadMgr_EnumDocumentMgrs(ITfThreadMgrEx
*iface
, IEnumTfDocumentMgrs
**ppEnum
)
389 ThreadMgr
*This
= impl_from_ITfThreadMgrEx(iface
);
390 TRACE("(%p) %p\n",This
,ppEnum
);
395 return EnumTfDocumentMgr_Constructor(&This
->CreatedDocumentMgrs
, ppEnum
);
398 static HRESULT WINAPI
ThreadMgr_GetFocus(ITfThreadMgrEx
*iface
, ITfDocumentMgr
**ppdimFocus
)
400 ThreadMgr
*This
= impl_from_ITfThreadMgrEx(iface
);
401 TRACE("(%p)\n",This
);
406 *ppdimFocus
= This
->focus
;
408 TRACE("->%p\n",This
->focus
);
410 if (This
->focus
== NULL
)
413 ITfDocumentMgr_AddRef(This
->focus
);
418 static HRESULT WINAPI
ThreadMgr_SetFocus(ITfThreadMgrEx
*iface
, ITfDocumentMgr
*pdimFocus
)
420 ThreadMgr
*This
= impl_from_ITfThreadMgrEx(iface
);
421 ITfDocumentMgr
*check
;
423 TRACE("(%p) %p\n",This
,pdimFocus
);
427 else if (FAILED(ITfDocumentMgr_QueryInterface(pdimFocus
,&IID_ITfDocumentMgr
,(LPVOID
*) &check
)))
430 ITfThreadMgrEventSink_OnSetFocus(&This
->ITfThreadMgrEventSink_iface
, check
, This
->focus
);
433 ITfDocumentMgr_Release(This
->focus
);
439 static LRESULT CALLBACK
ThreadFocusHookProc(int nCode
, WPARAM wParam
, LPARAM lParam
)
443 This
= TlsGetValue(tlsIndex
);
446 ERR("Hook proc but no ThreadMgr for this thread. Serious Error\n");
449 if (!This
->focusHook
)
451 ERR("Hook proc but no ThreadMgr focus Hook. Serious Error\n");
455 if (nCode
== HCBT_SETFOCUS
) /* focus change within our thread */
459 LIST_FOR_EACH(cursor
, &This
->AssociatedFocusWindows
)
461 AssociatedWindow
*wnd
= LIST_ENTRY(cursor
,AssociatedWindow
,entry
);
462 if (wnd
->hwnd
== (HWND
)wParam
)
464 TRACE("Triggering Associated window focus\n");
465 if (This
->focus
!= wnd
->docmgr
)
466 ThreadMgr_SetFocus(&This
->ITfThreadMgrEx_iface
, wnd
->docmgr
);
472 return CallNextHookEx(This
->focusHook
, nCode
, wParam
, lParam
);
475 static HRESULT
SetupWindowsHook(ThreadMgr
*This
)
477 if (!This
->focusHook
)
479 This
->focusHook
= SetWindowsHookExW(WH_CBT
, ThreadFocusHookProc
, 0,
480 GetCurrentThreadId());
481 if (!This
->focusHook
)
483 ERR("Unable to set focus hook\n");
491 static HRESULT WINAPI
ThreadMgr_AssociateFocus(ITfThreadMgrEx
*iface
, HWND hwnd
,
492 ITfDocumentMgr
*pdimNew
, ITfDocumentMgr
**ppdimPrev
)
494 ThreadMgr
*This
= impl_from_ITfThreadMgrEx(iface
);
495 struct list
*cursor
, *cursor2
;
496 AssociatedWindow
*wnd
;
498 TRACE("(%p) %p %p %p\n",This
,hwnd
,pdimNew
,ppdimPrev
);
505 LIST_FOR_EACH_SAFE(cursor
, cursor2
, &This
->AssociatedFocusWindows
)
507 wnd
= LIST_ENTRY(cursor
,AssociatedWindow
,entry
);
508 if (wnd
->hwnd
== hwnd
)
511 ITfDocumentMgr_AddRef(wnd
->docmgr
);
512 *ppdimPrev
= wnd
->docmgr
;
513 wnd
->docmgr
= pdimNew
;
514 if (GetFocus() == hwnd
)
515 ThreadMgr_SetFocus(iface
,pdimNew
);
520 wnd
= HeapAlloc(GetProcessHeap(),0,sizeof(AssociatedWindow
));
522 wnd
->docmgr
= pdimNew
;
523 list_add_head(&This
->AssociatedFocusWindows
,&wnd
->entry
);
525 if (GetFocus() == hwnd
)
526 ThreadMgr_SetFocus(iface
,pdimNew
);
528 SetupWindowsHook(This
);
533 static HRESULT WINAPI
ThreadMgr_IsThreadFocus(ITfThreadMgrEx
*iface
, BOOL
*pfThreadFocus
)
535 ThreadMgr
*This
= impl_from_ITfThreadMgrEx(iface
);
538 TRACE("(%p) %p\n",This
,pfThreadFocus
);
540 *pfThreadFocus
= (focus
== NULL
);
544 static HRESULT WINAPI
ThreadMgr_GetFunctionProvider(ITfThreadMgrEx
*iface
, REFCLSID clsid
,
545 ITfFunctionProvider
**ppFuncProv
)
547 ThreadMgr
*This
= impl_from_ITfThreadMgrEx(iface
);
548 FIXME("STUB:(%p)\n",This
);
552 static HRESULT WINAPI
ThreadMgr_EnumFunctionProviders(ITfThreadMgrEx
*iface
,
553 IEnumTfFunctionProviders
**ppEnum
)
555 ThreadMgr
*This
= impl_from_ITfThreadMgrEx(iface
);
556 FIXME("STUB:(%p)\n",This
);
560 static HRESULT WINAPI
ThreadMgr_GetGlobalCompartment(ITfThreadMgrEx
*iface
,
561 ITfCompartmentMgr
**ppCompMgr
)
563 ThreadMgr
*This
= impl_from_ITfThreadMgrEx(iface
);
565 TRACE("(%p) %p\n",This
, ppCompMgr
);
570 if (!globalCompartmentMgr
)
572 hr
= CompartmentMgr_Constructor(NULL
,&IID_ITfCompartmentMgr
,(IUnknown
**)&globalCompartmentMgr
);
577 ITfCompartmentMgr_AddRef(globalCompartmentMgr
);
578 *ppCompMgr
= globalCompartmentMgr
;
582 static HRESULT WINAPI
ThreadMgr_ActivateEx(ITfThreadMgrEx
*iface
, TfClientId
*id
, DWORD flags
)
584 ThreadMgr
*This
= impl_from_ITfThreadMgrEx(iface
);
586 TRACE("(%p) %p, %#x\n", This
, id
, flags
);
592 FIXME("Unimplemented flags %#x\n", flags
);
598 ITfClientId_GetClientId(&This
->ITfClientId_iface
, &guid
, &processId
);
601 activate_textservices(iface
);
602 This
->activationCount
++;
607 static HRESULT WINAPI
ThreadMgr_GetActiveFlags(ITfThreadMgrEx
*iface
, DWORD
*flags
)
609 ThreadMgr
*This
= impl_from_ITfThreadMgrEx(iface
);
611 FIXME("STUB:(%p)\n", This
);
615 static const ITfThreadMgrExVtbl ThreadMgrExVtbl
=
617 ThreadMgr_QueryInterface
,
621 ThreadMgr_Deactivate
,
622 ThreadMgr_CreateDocumentMgr
,
623 ThreadMgr_EnumDocumentMgrs
,
626 ThreadMgr_AssociateFocus
,
627 ThreadMgr_IsThreadFocus
,
628 ThreadMgr_GetFunctionProvider
,
629 ThreadMgr_EnumFunctionProviders
,
630 ThreadMgr_GetGlobalCompartment
,
632 ThreadMgr_ActivateEx
,
633 ThreadMgr_GetActiveFlags
636 static HRESULT WINAPI
Source_QueryInterface(ITfSource
*iface
, REFIID iid
, LPVOID
*ppvOut
)
638 ThreadMgr
*This
= impl_from_ITfSource(iface
);
639 return ITfThreadMgrEx_QueryInterface(&This
->ITfThreadMgrEx_iface
, iid
, ppvOut
);
642 static ULONG WINAPI
Source_AddRef(ITfSource
*iface
)
644 ThreadMgr
*This
= impl_from_ITfSource(iface
);
645 return ITfThreadMgrEx_AddRef(&This
->ITfThreadMgrEx_iface
);
648 static ULONG WINAPI
Source_Release(ITfSource
*iface
)
650 ThreadMgr
*This
= impl_from_ITfSource(iface
);
651 return ITfThreadMgrEx_Release(&This
->ITfThreadMgrEx_iface
);
654 /*****************************************************
655 * ITfSource functions
656 *****************************************************/
657 static HRESULT WINAPI
ThreadMgrSource_AdviseSink(ITfSource
*iface
,
658 REFIID riid
, IUnknown
*punk
, DWORD
*pdwCookie
)
660 ThreadMgr
*This
= impl_from_ITfSource(iface
);
663 TRACE("(%p) %s %p %p\n",This
,debugstr_guid(riid
),punk
,pdwCookie
);
665 if (!riid
|| !punk
|| !pdwCookie
)
668 if (IsEqualIID(riid
, &IID_ITfThreadMgrEventSink
))
670 tms
= HeapAlloc(GetProcessHeap(),0,sizeof(ThreadMgrSink
));
672 return E_OUTOFMEMORY
;
673 if (FAILED(IUnknown_QueryInterface(punk
, riid
, (LPVOID
*)&tms
->interfaces
.pITfThreadMgrEventSink
)))
675 HeapFree(GetProcessHeap(),0,tms
);
676 return CONNECT_E_CANNOTCONNECT
;
678 list_add_head(&This
->ThreadMgrEventSink
,&tms
->entry
);
679 *pdwCookie
= generate_Cookie(COOKIE_MAGIC_TMSINK
, tms
);
683 FIXME("(%p) Unhandled Sink: %s\n",This
,debugstr_guid(riid
));
687 TRACE("cookie %x\n",*pdwCookie
);
692 static HRESULT WINAPI
ThreadMgrSource_UnadviseSink(ITfSource
*iface
, DWORD pdwCookie
)
694 ThreadMgr
*This
= impl_from_ITfSource(iface
);
697 TRACE("(%p) %x\n",This
,pdwCookie
);
699 if (get_Cookie_magic(pdwCookie
)!=COOKIE_MAGIC_TMSINK
)
702 sink
= remove_Cookie(pdwCookie
);
704 return CONNECT_E_NOCONNECTION
;
706 list_remove(&sink
->entry
);
712 static const ITfSourceVtbl ThreadMgrSourceVtbl
=
714 Source_QueryInterface
,
717 ThreadMgrSource_AdviseSink
,
718 ThreadMgrSource_UnadviseSink
,
721 /*****************************************************
722 * ITfKeystrokeMgr functions
723 *****************************************************/
725 static HRESULT WINAPI
KeystrokeMgr_QueryInterface(ITfKeystrokeMgr
*iface
, REFIID iid
, LPVOID
*ppvOut
)
727 ThreadMgr
*This
= impl_from_ITfKeystrokeMgr(iface
);
728 return ITfThreadMgrEx_QueryInterface(&This
->ITfThreadMgrEx_iface
, iid
, ppvOut
);
731 static ULONG WINAPI
KeystrokeMgr_AddRef(ITfKeystrokeMgr
*iface
)
733 ThreadMgr
*This
= impl_from_ITfKeystrokeMgr(iface
);
734 return ITfThreadMgrEx_AddRef(&This
->ITfThreadMgrEx_iface
);
737 static ULONG WINAPI
KeystrokeMgr_Release(ITfKeystrokeMgr
*iface
)
739 ThreadMgr
*This
= impl_from_ITfKeystrokeMgr(iface
);
740 return ITfThreadMgrEx_Release(&This
->ITfThreadMgrEx_iface
);
743 static HRESULT WINAPI
KeystrokeMgr_AdviseKeyEventSink(ITfKeystrokeMgr
*iface
,
744 TfClientId tid
, ITfKeyEventSink
*pSink
, BOOL fForeground
)
746 ThreadMgr
*This
= impl_from_ITfKeystrokeMgr(iface
);
748 ITfKeyEventSink
*check
= NULL
;
750 TRACE("(%p) %x %p %i\n",This
,tid
,pSink
,fForeground
);
755 textservice
= get_textservice_clsid(tid
);
756 if (IsEqualCLSID(&GUID_NULL
,&textservice
))
759 get_textservice_sink(tid
, &IID_ITfKeyEventSink
, (IUnknown
**)&check
);
761 return CONNECT_E_ADVISELIMIT
;
763 if (FAILED(ITfKeyEventSink_QueryInterface(pSink
,&IID_ITfKeyEventSink
,(LPVOID
*) &check
)))
766 set_textservice_sink(tid
, &IID_ITfKeyEventSink
, (IUnknown
*)check
);
770 if (This
->forgroundKeyEventSink
)
772 ITfKeyEventSink_OnSetFocus(This
->forgroundKeyEventSink
, FALSE
);
773 ITfKeyEventSink_Release(This
->forgroundKeyEventSink
);
775 ITfKeyEventSink_AddRef(check
);
776 ITfKeyEventSink_OnSetFocus(check
, TRUE
);
777 This
->forgroundKeyEventSink
= check
;
778 This
->forgroundTextService
= textservice
;
783 static HRESULT WINAPI
KeystrokeMgr_UnadviseKeyEventSink(ITfKeystrokeMgr
*iface
,
786 ThreadMgr
*This
= impl_from_ITfKeystrokeMgr(iface
);
788 ITfKeyEventSink
*check
= NULL
;
789 TRACE("(%p) %x\n",This
,tid
);
794 textservice
= get_textservice_clsid(tid
);
795 if (IsEqualCLSID(&GUID_NULL
,&textservice
))
798 get_textservice_sink(tid
, &IID_ITfKeyEventSink
, (IUnknown
**)&check
);
801 return CONNECT_E_NOCONNECTION
;
803 set_textservice_sink(tid
, &IID_ITfKeyEventSink
, NULL
);
804 ITfKeyEventSink_Release(check
);
806 if (This
->forgroundKeyEventSink
== check
)
808 ITfKeyEventSink_Release(This
->forgroundKeyEventSink
);
809 This
->forgroundKeyEventSink
= NULL
;
810 This
->forgroundTextService
= GUID_NULL
;
815 static HRESULT WINAPI
KeystrokeMgr_GetForeground(ITfKeystrokeMgr
*iface
,
818 ThreadMgr
*This
= impl_from_ITfKeystrokeMgr(iface
);
819 TRACE("(%p) %p\n",This
,pclsid
);
823 if (IsEqualCLSID(&This
->forgroundTextService
,&GUID_NULL
))
826 *pclsid
= This
->forgroundTextService
;
830 static HRESULT WINAPI
KeystrokeMgr_TestKeyDown(ITfKeystrokeMgr
*iface
,
831 WPARAM wParam
, LPARAM lParam
, BOOL
*pfEaten
)
833 ThreadMgr
*This
= impl_from_ITfKeystrokeMgr(iface
);
834 FIXME("STUB:(%p)\n",This
);
838 static HRESULT WINAPI
KeystrokeMgr_TestKeyUp(ITfKeystrokeMgr
*iface
,
839 WPARAM wParam
, LPARAM lParam
, BOOL
*pfEaten
)
841 ThreadMgr
*This
= impl_from_ITfKeystrokeMgr(iface
);
842 FIXME("STUB:(%p)\n",This
);
846 static HRESULT WINAPI
KeystrokeMgr_KeyDown(ITfKeystrokeMgr
*iface
,
847 WPARAM wParam
, LPARAM lParam
, BOOL
*pfEaten
)
849 ThreadMgr
*This
= impl_from_ITfKeystrokeMgr(iface
);
850 FIXME("STUB:(%p)\n",This
);
854 static HRESULT WINAPI
KeystrokeMgr_KeyUp(ITfKeystrokeMgr
*iface
,
855 WPARAM wParam
, LPARAM lParam
, BOOL
*pfEaten
)
857 ThreadMgr
*This
= impl_from_ITfKeystrokeMgr(iface
);
858 FIXME("STUB:(%p)\n",This
);
862 static HRESULT WINAPI
KeystrokeMgr_GetPreservedKey(ITfKeystrokeMgr
*iface
,
863 ITfContext
*pic
, const TF_PRESERVEDKEY
*pprekey
, GUID
*pguid
)
865 ThreadMgr
*This
= impl_from_ITfKeystrokeMgr(iface
);
866 FIXME("STUB:(%p)\n",This
);
870 static HRESULT WINAPI
KeystrokeMgr_IsPreservedKey(ITfKeystrokeMgr
*iface
,
871 REFGUID rguid
, const TF_PRESERVEDKEY
*pprekey
, BOOL
*pfRegistered
)
873 ThreadMgr
*This
= impl_from_ITfKeystrokeMgr(iface
);
876 TRACE("(%p) %s (%x %x) %p\n",This
,debugstr_guid(rguid
), (pprekey
)?pprekey
->uVKey
:0, (pprekey
)?pprekey
->uModifiers
:0, pfRegistered
);
878 if (!rguid
|| !pprekey
|| !pfRegistered
)
881 LIST_FOR_EACH(cursor
, &This
->CurrentPreservedKeys
)
883 PreservedKey
* key
= LIST_ENTRY(cursor
,PreservedKey
,entry
);
884 if (IsEqualGUID(rguid
,&key
->guid
) && pprekey
->uVKey
== key
->prekey
.uVKey
&& pprekey
->uModifiers
== key
->prekey
.uModifiers
)
886 *pfRegistered
= TRUE
;
891 *pfRegistered
= FALSE
;
895 static HRESULT WINAPI
KeystrokeMgr_PreserveKey(ITfKeystrokeMgr
*iface
,
896 TfClientId tid
, REFGUID rguid
, const TF_PRESERVEDKEY
*prekey
,
897 const WCHAR
*pchDesc
, ULONG cchDesc
)
899 ThreadMgr
*This
= impl_from_ITfKeystrokeMgr(iface
);
901 PreservedKey
*newkey
;
903 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
));
905 if (!tid
|| ! rguid
|| !prekey
|| (cchDesc
&& !pchDesc
))
908 LIST_FOR_EACH(cursor
, &This
->CurrentPreservedKeys
)
910 PreservedKey
* key
= LIST_ENTRY(cursor
,PreservedKey
,entry
);
911 if (IsEqualGUID(rguid
,&key
->guid
) && prekey
->uVKey
== key
->prekey
.uVKey
&& prekey
->uModifiers
== key
->prekey
.uModifiers
)
912 return TF_E_ALREADY_EXISTS
;
915 newkey
= HeapAlloc(GetProcessHeap(),0,sizeof(PreservedKey
));
917 return E_OUTOFMEMORY
;
919 newkey
->guid
= *rguid
;
920 newkey
->prekey
= *prekey
;
922 newkey
->description
= NULL
;
925 newkey
->description
= HeapAlloc(GetProcessHeap(),0,cchDesc
* sizeof(WCHAR
));
926 if (!newkey
->description
)
928 HeapFree(GetProcessHeap(),0,newkey
);
929 return E_OUTOFMEMORY
;
931 memcpy(newkey
->description
, pchDesc
, cchDesc
*sizeof(WCHAR
));
934 list_add_head(&This
->CurrentPreservedKeys
,&newkey
->entry
);
939 static HRESULT WINAPI
KeystrokeMgr_UnpreserveKey(ITfKeystrokeMgr
*iface
,
940 REFGUID rguid
, const TF_PRESERVEDKEY
*pprekey
)
942 ThreadMgr
*This
= impl_from_ITfKeystrokeMgr(iface
);
943 PreservedKey
* key
= NULL
;
945 TRACE("(%p) %s (%x %x)\n",This
,debugstr_guid(rguid
),(pprekey
)?pprekey
->uVKey
:0, (pprekey
)?pprekey
->uModifiers
:0);
947 if (!pprekey
|| !rguid
)
950 LIST_FOR_EACH(cursor
, &This
->CurrentPreservedKeys
)
952 key
= LIST_ENTRY(cursor
,PreservedKey
,entry
);
953 if (IsEqualGUID(rguid
,&key
->guid
) && pprekey
->uVKey
== key
->prekey
.uVKey
&& pprekey
->uModifiers
== key
->prekey
.uModifiers
)
959 return CONNECT_E_NOCONNECTION
;
961 list_remove(&key
->entry
);
962 HeapFree(GetProcessHeap(),0,key
->description
);
963 HeapFree(GetProcessHeap(),0,key
);
968 static HRESULT WINAPI
KeystrokeMgr_SetPreservedKeyDescription(ITfKeystrokeMgr
*iface
,
969 REFGUID rguid
, const WCHAR
*pchDesc
, ULONG cchDesc
)
971 ThreadMgr
*This
= impl_from_ITfKeystrokeMgr(iface
);
972 FIXME("STUB:(%p)\n",This
);
976 static HRESULT WINAPI
KeystrokeMgr_GetPreservedKeyDescription(ITfKeystrokeMgr
*iface
,
977 REFGUID rguid
, BSTR
*pbstrDesc
)
979 ThreadMgr
*This
= impl_from_ITfKeystrokeMgr(iface
);
980 FIXME("STUB:(%p)\n",This
);
984 static HRESULT WINAPI
KeystrokeMgr_SimulatePreservedKey(ITfKeystrokeMgr
*iface
,
985 ITfContext
*pic
, REFGUID rguid
, BOOL
*pfEaten
)
987 ThreadMgr
*This
= impl_from_ITfKeystrokeMgr(iface
);
988 FIXME("STUB:(%p)\n",This
);
992 static const ITfKeystrokeMgrVtbl KeystrokeMgrVtbl
=
994 KeystrokeMgr_QueryInterface
,
996 KeystrokeMgr_Release
,
997 KeystrokeMgr_AdviseKeyEventSink
,
998 KeystrokeMgr_UnadviseKeyEventSink
,
999 KeystrokeMgr_GetForeground
,
1000 KeystrokeMgr_TestKeyDown
,
1001 KeystrokeMgr_TestKeyUp
,
1002 KeystrokeMgr_KeyDown
,
1004 KeystrokeMgr_GetPreservedKey
,
1005 KeystrokeMgr_IsPreservedKey
,
1006 KeystrokeMgr_PreserveKey
,
1007 KeystrokeMgr_UnpreserveKey
,
1008 KeystrokeMgr_SetPreservedKeyDescription
,
1009 KeystrokeMgr_GetPreservedKeyDescription
,
1010 KeystrokeMgr_SimulatePreservedKey
1013 /*****************************************************
1014 * ITfMessagePump functions
1015 *****************************************************/
1017 static HRESULT WINAPI
MessagePump_QueryInterface(ITfMessagePump
*iface
, REFIID iid
, LPVOID
*ppvOut
)
1019 ThreadMgr
*This
= impl_from_ITfMessagePump(iface
);
1020 return ITfThreadMgrEx_QueryInterface(&This
->ITfThreadMgrEx_iface
, iid
, ppvOut
);
1023 static ULONG WINAPI
MessagePump_AddRef(ITfMessagePump
*iface
)
1025 ThreadMgr
*This
= impl_from_ITfMessagePump(iface
);
1026 return ITfThreadMgrEx_AddRef(&This
->ITfThreadMgrEx_iface
);
1029 static ULONG WINAPI
MessagePump_Release(ITfMessagePump
*iface
)
1031 ThreadMgr
*This
= impl_from_ITfMessagePump(iface
);
1032 return ITfThreadMgrEx_Release(&This
->ITfThreadMgrEx_iface
);
1035 static HRESULT WINAPI
MessagePump_PeekMessageA(ITfMessagePump
*iface
,
1036 LPMSG pMsg
, HWND hwnd
, UINT wMsgFilterMin
, UINT wMsgFilterMax
,
1037 UINT wRemoveMsg
, BOOL
*pfResult
)
1040 return E_INVALIDARG
;
1041 *pfResult
= PeekMessageA(pMsg
, hwnd
, wMsgFilterMin
, wMsgFilterMax
, wRemoveMsg
);
1045 static HRESULT WINAPI
MessagePump_GetMessageA(ITfMessagePump
*iface
,
1046 LPMSG pMsg
, HWND hwnd
, UINT wMsgFilterMin
, UINT wMsgFilterMax
,
1050 return E_INVALIDARG
;
1051 *pfResult
= GetMessageA(pMsg
, hwnd
, wMsgFilterMin
, wMsgFilterMax
);
1055 static HRESULT WINAPI
MessagePump_PeekMessageW(ITfMessagePump
*iface
,
1056 LPMSG pMsg
, HWND hwnd
, UINT wMsgFilterMin
, UINT wMsgFilterMax
,
1057 UINT wRemoveMsg
, BOOL
*pfResult
)
1060 return E_INVALIDARG
;
1061 *pfResult
= PeekMessageW(pMsg
, hwnd
, wMsgFilterMin
, wMsgFilterMax
, wRemoveMsg
);
1065 static HRESULT WINAPI
MessagePump_GetMessageW(ITfMessagePump
*iface
,
1066 LPMSG pMsg
, HWND hwnd
, UINT wMsgFilterMin
, UINT wMsgFilterMax
,
1070 return E_INVALIDARG
;
1071 *pfResult
= GetMessageW(pMsg
, hwnd
, wMsgFilterMin
, wMsgFilterMax
);
1075 static const ITfMessagePumpVtbl MessagePumpVtbl
=
1077 MessagePump_QueryInterface
,
1079 MessagePump_Release
,
1080 MessagePump_PeekMessageA
,
1081 MessagePump_GetMessageA
,
1082 MessagePump_PeekMessageW
,
1083 MessagePump_GetMessageW
1086 /*****************************************************
1087 * ITfClientId functions
1088 *****************************************************/
1090 static HRESULT WINAPI
ClientId_QueryInterface(ITfClientId
*iface
, REFIID iid
, LPVOID
*ppvOut
)
1092 ThreadMgr
*This
= impl_from_ITfClientId(iface
);
1093 return ITfThreadMgrEx_QueryInterface(&This
->ITfThreadMgrEx_iface
, iid
, ppvOut
);
1096 static ULONG WINAPI
ClientId_AddRef(ITfClientId
*iface
)
1098 ThreadMgr
*This
= impl_from_ITfClientId(iface
);
1099 return ITfThreadMgrEx_AddRef(&This
->ITfThreadMgrEx_iface
);
1102 static ULONG WINAPI
ClientId_Release(ITfClientId
*iface
)
1104 ThreadMgr
*This
= impl_from_ITfClientId(iface
);
1105 return ITfThreadMgrEx_Release(&This
->ITfThreadMgrEx_iface
);
1108 static HRESULT WINAPI
ClientId_GetClientId(ITfClientId
*iface
,
1109 REFCLSID rclsid
, TfClientId
*ptid
)
1112 ThreadMgr
*This
= impl_from_ITfClientId(iface
);
1114 ITfCategoryMgr
*catmgr
;
1116 TRACE("(%p) %s\n",This
,debugstr_guid(rclsid
));
1118 CategoryMgr_Constructor(NULL
,(IUnknown
**)&catmgr
);
1119 hr
= ITfCategoryMgr_RegisterGUID(catmgr
,rclsid
,ptid
);
1120 ITfCategoryMgr_Release(catmgr
);
1125 static const ITfClientIdVtbl ClientIdVtbl
=
1127 ClientId_QueryInterface
,
1130 ClientId_GetClientId
1133 /*****************************************************
1134 * ITfThreadMgrEventSink functions (internal)
1135 *****************************************************/
1136 static HRESULT WINAPI
ThreadMgrEventSink_QueryInterface(ITfThreadMgrEventSink
*iface
, REFIID iid
, LPVOID
*ppvOut
)
1138 ThreadMgr
*This
= impl_from_ITfThreadMgrEventSink(iface
);
1139 return ITfThreadMgrEx_QueryInterface(&This
->ITfThreadMgrEx_iface
, iid
, ppvOut
);
1142 static ULONG WINAPI
ThreadMgrEventSink_AddRef(ITfThreadMgrEventSink
*iface
)
1144 ThreadMgr
*This
= impl_from_ITfThreadMgrEventSink(iface
);
1145 return ITfThreadMgrEx_AddRef(&This
->ITfThreadMgrEx_iface
);
1148 static ULONG WINAPI
ThreadMgrEventSink_Release(ITfThreadMgrEventSink
*iface
)
1150 ThreadMgr
*This
= impl_from_ITfThreadMgrEventSink(iface
);
1151 return ITfThreadMgrEx_Release(&This
->ITfThreadMgrEx_iface
);
1155 static HRESULT WINAPI
ThreadMgrEventSink_OnInitDocumentMgr(
1156 ITfThreadMgrEventSink
*iface
,ITfDocumentMgr
*pdim
)
1158 struct list
*cursor
;
1159 ThreadMgr
*This
= impl_from_ITfThreadMgrEventSink(iface
);
1161 TRACE("(%p) %p\n",This
,pdim
);
1163 LIST_FOR_EACH(cursor
, &This
->ThreadMgrEventSink
)
1165 ThreadMgrSink
* sink
= LIST_ENTRY(cursor
,ThreadMgrSink
,entry
);
1166 ITfThreadMgrEventSink_OnInitDocumentMgr(sink
->interfaces
.pITfThreadMgrEventSink
,pdim
);
1172 static HRESULT WINAPI
ThreadMgrEventSink_OnUninitDocumentMgr(
1173 ITfThreadMgrEventSink
*iface
, ITfDocumentMgr
*pdim
)
1175 struct list
*cursor
;
1176 ThreadMgr
*This
= impl_from_ITfThreadMgrEventSink(iface
);
1178 TRACE("(%p) %p\n",This
,pdim
);
1180 LIST_FOR_EACH(cursor
, &This
->ThreadMgrEventSink
)
1182 ThreadMgrSink
* sink
= LIST_ENTRY(cursor
,ThreadMgrSink
,entry
);
1183 ITfThreadMgrEventSink_OnUninitDocumentMgr(sink
->interfaces
.pITfThreadMgrEventSink
,pdim
);
1189 static HRESULT WINAPI
ThreadMgrEventSink_OnSetFocus(
1190 ITfThreadMgrEventSink
*iface
, ITfDocumentMgr
*pdimFocus
,
1191 ITfDocumentMgr
*pdimPrevFocus
)
1193 struct list
*cursor
;
1194 ThreadMgr
*This
= impl_from_ITfThreadMgrEventSink(iface
);
1196 TRACE("(%p) %p %p\n",This
,pdimFocus
, pdimPrevFocus
);
1198 LIST_FOR_EACH(cursor
, &This
->ThreadMgrEventSink
)
1200 ThreadMgrSink
* sink
= LIST_ENTRY(cursor
,ThreadMgrSink
,entry
);
1201 ITfThreadMgrEventSink_OnSetFocus(sink
->interfaces
.pITfThreadMgrEventSink
, pdimFocus
, pdimPrevFocus
);
1207 static HRESULT WINAPI
ThreadMgrEventSink_OnPushContext(
1208 ITfThreadMgrEventSink
*iface
, ITfContext
*pic
)
1210 struct list
*cursor
;
1211 ThreadMgr
*This
= impl_from_ITfThreadMgrEventSink(iface
);
1213 TRACE("(%p) %p\n",This
,pic
);
1215 LIST_FOR_EACH(cursor
, &This
->ThreadMgrEventSink
)
1217 ThreadMgrSink
* sink
= LIST_ENTRY(cursor
,ThreadMgrSink
,entry
);
1218 ITfThreadMgrEventSink_OnPushContext(sink
->interfaces
.pITfThreadMgrEventSink
,pic
);
1224 static HRESULT WINAPI
ThreadMgrEventSink_OnPopContext(
1225 ITfThreadMgrEventSink
*iface
, ITfContext
*pic
)
1227 struct list
*cursor
;
1228 ThreadMgr
*This
= impl_from_ITfThreadMgrEventSink(iface
);
1230 TRACE("(%p) %p\n",This
,pic
);
1232 LIST_FOR_EACH(cursor
, &This
->ThreadMgrEventSink
)
1234 ThreadMgrSink
* sink
= LIST_ENTRY(cursor
,ThreadMgrSink
,entry
);
1235 ITfThreadMgrEventSink_OnPopContext(sink
->interfaces
.pITfThreadMgrEventSink
,pic
);
1241 static const ITfThreadMgrEventSinkVtbl ThreadMgrEventSinkVtbl
=
1243 ThreadMgrEventSink_QueryInterface
,
1244 ThreadMgrEventSink_AddRef
,
1245 ThreadMgrEventSink_Release
,
1246 ThreadMgrEventSink_OnInitDocumentMgr
,
1247 ThreadMgrEventSink_OnUninitDocumentMgr
,
1248 ThreadMgrEventSink_OnSetFocus
,
1249 ThreadMgrEventSink_OnPushContext
,
1250 ThreadMgrEventSink_OnPopContext
1253 /*****************************************************
1254 * ITfUIElementMgr functions
1255 *****************************************************/
1256 static HRESULT WINAPI
UIElementMgr_QueryInterface(ITfUIElementMgr
*iface
, REFIID iid
, void **ppvOut
)
1258 ThreadMgr
*This
= impl_from_ITfUIElementMgr(iface
);
1260 return ITfThreadMgrEx_QueryInterface(&This
->ITfThreadMgrEx_iface
, iid
, *ppvOut
);
1263 static ULONG WINAPI
UIElementMgr_AddRef(ITfUIElementMgr
*iface
)
1265 ThreadMgr
*This
= impl_from_ITfUIElementMgr(iface
);
1267 return ITfThreadMgrEx_AddRef(&This
->ITfThreadMgrEx_iface
);
1270 static ULONG WINAPI
UIElementMgr_Release(ITfUIElementMgr
*iface
)
1272 ThreadMgr
*This
= impl_from_ITfUIElementMgr(iface
);
1274 return ITfThreadMgrEx_Release(&This
->ITfThreadMgrEx_iface
);
1277 static HRESULT WINAPI
UIElementMgr_BeginUIElement(ITfUIElementMgr
*iface
, ITfUIElement
*element
,
1278 BOOL
*show
, DWORD
*id
)
1280 ThreadMgr
*This
= impl_from_ITfUIElementMgr(iface
);
1282 FIXME("STUB:(%p)\n", This
);
1286 static HRESULT WINAPI
UIElementMgr_UpdateUIElement(ITfUIElementMgr
*iface
, DWORD id
)
1288 ThreadMgr
*This
= impl_from_ITfUIElementMgr(iface
);
1290 FIXME("STUB:(%p)\n", This
);
1294 static HRESULT WINAPI
UIElementMgr_EndUIElement(ITfUIElementMgr
*iface
, DWORD id
)
1296 ThreadMgr
*This
= impl_from_ITfUIElementMgr(iface
);
1298 FIXME("STUB:(%p)\n", This
);
1302 static HRESULT WINAPI
UIElementMgr_GetUIElement(ITfUIElementMgr
*iface
, DWORD id
,
1303 ITfUIElement
**element
)
1305 ThreadMgr
*This
= impl_from_ITfUIElementMgr(iface
);
1307 FIXME("STUB:(%p)\n", This
);
1311 static HRESULT WINAPI
UIElementMgr_EnumUIElements(ITfUIElementMgr
*iface
,
1312 IEnumTfUIElements
**enum_elements
)
1314 ThreadMgr
*This
= impl_from_ITfUIElementMgr(iface
);
1316 FIXME("STUB:(%p)\n", This
);
1320 static const ITfUIElementMgrVtbl ThreadMgrUIElementMgrVtbl
=
1322 UIElementMgr_QueryInterface
,
1323 UIElementMgr_AddRef
,
1324 UIElementMgr_Release
,
1326 UIElementMgr_BeginUIElement
,
1327 UIElementMgr_UpdateUIElement
,
1328 UIElementMgr_EndUIElement
,
1329 UIElementMgr_GetUIElement
,
1330 UIElementMgr_EnumUIElements
1333 /*****************************************************
1334 * ITfSourceSingle functions
1335 *****************************************************/
1336 static HRESULT WINAPI
ThreadMgrSourceSingle_QueryInterface(ITfSourceSingle
*iface
, REFIID iid
, LPVOID
*ppvOut
)
1338 ThreadMgr
*This
= impl_from_ITfSourceSingle(iface
);
1339 return ITfThreadMgrEx_QueryInterface(&This
->ITfThreadMgrEx_iface
, iid
, ppvOut
);
1342 static ULONG WINAPI
ThreadMgrSourceSingle_AddRef(ITfSourceSingle
*iface
)
1344 ThreadMgr
*This
= impl_from_ITfSourceSingle(iface
);
1345 return ITfThreadMgrEx_AddRef(&This
->ITfThreadMgrEx_iface
);
1348 static ULONG WINAPI
ThreadMgrSourceSingle_Release(ITfSourceSingle
*iface
)
1350 ThreadMgr
*This
= impl_from_ITfSourceSingle(iface
);
1351 return ITfThreadMgrEx_Release(&This
->ITfThreadMgrEx_iface
);
1354 static HRESULT WINAPI
ThreadMgrSourceSingle_AdviseSingleSink( ITfSourceSingle
*iface
,
1355 TfClientId tid
, REFIID riid
, IUnknown
*punk
)
1357 ThreadMgr
*This
= impl_from_ITfSourceSingle(iface
);
1358 FIXME("STUB:(%p) %i %s %p\n",This
, tid
, debugstr_guid(riid
),punk
);
1362 static HRESULT WINAPI
ThreadMgrSourceSingle_UnadviseSingleSink( ITfSourceSingle
*iface
,
1363 TfClientId tid
, REFIID riid
)
1365 ThreadMgr
*This
= impl_from_ITfSourceSingle(iface
);
1366 FIXME("STUB:(%p) %i %s\n",This
, tid
, debugstr_guid(riid
));
1370 static const ITfSourceSingleVtbl SourceSingleVtbl
=
1372 ThreadMgrSourceSingle_QueryInterface
,
1373 ThreadMgrSourceSingle_AddRef
,
1374 ThreadMgrSourceSingle_Release
,
1375 ThreadMgrSourceSingle_AdviseSingleSink
,
1376 ThreadMgrSourceSingle_UnadviseSingleSink
1379 HRESULT
ThreadMgr_Constructor(IUnknown
*pUnkOuter
, IUnknown
**ppOut
)
1383 return CLASS_E_NOAGGREGATION
;
1385 /* Only 1 ThreadMgr is created per thread */
1386 This
= TlsGetValue(tlsIndex
);
1389 ThreadMgr_AddRef(&This
->ITfThreadMgrEx_iface
);
1390 *ppOut
= (IUnknown
*)&This
->ITfThreadMgrEx_iface
;
1394 This
= HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY
,sizeof(ThreadMgr
));
1396 return E_OUTOFMEMORY
;
1398 This
->ITfThreadMgrEx_iface
.lpVtbl
= &ThreadMgrExVtbl
;
1399 This
->ITfSource_iface
.lpVtbl
= &ThreadMgrSourceVtbl
;
1400 This
->ITfKeystrokeMgr_iface
.lpVtbl
= &KeystrokeMgrVtbl
;
1401 This
->ITfMessagePump_iface
.lpVtbl
= &MessagePumpVtbl
;
1402 This
->ITfClientId_iface
.lpVtbl
= &ClientIdVtbl
;
1403 This
->ITfThreadMgrEventSink_iface
.lpVtbl
= &ThreadMgrEventSinkVtbl
;
1404 This
->ITfUIElementMgr_iface
.lpVtbl
= &ThreadMgrUIElementMgrVtbl
;
1405 This
->ITfSourceSingle_iface
.lpVtbl
= &SourceSingleVtbl
;
1407 TlsSetValue(tlsIndex
,This
);
1409 CompartmentMgr_Constructor((IUnknown
*)This
, &IID_IUnknown
, (IUnknown
**)&This
->CompartmentMgr
);
1411 list_init(&This
->CurrentPreservedKeys
);
1412 list_init(&This
->CreatedDocumentMgrs
);
1413 list_init(&This
->AssociatedFocusWindows
);
1415 list_init(&This
->ActiveLanguageProfileNotifySink
);
1416 list_init(&This
->DisplayAttributeNotifySink
);
1417 list_init(&This
->KeyTraceEventSink
);
1418 list_init(&This
->PreservedKeyNotifySink
);
1419 list_init(&This
->ThreadFocusSink
);
1420 list_init(&This
->ThreadMgrEventSink
);
1422 TRACE("returning %p\n", This
);
1423 *ppOut
= (IUnknown
*)&This
->ITfThreadMgrEx_iface
;
1427 /**************************************************
1428 * IEnumTfDocumentMgrs implementation
1429 **************************************************/
1430 static void EnumTfDocumentMgr_Destructor(EnumTfDocumentMgr
*This
)
1432 TRACE("destroying %p\n", This
);
1433 HeapFree(GetProcessHeap(),0,This
);
1436 static HRESULT WINAPI
EnumTfDocumentMgr_QueryInterface(IEnumTfDocumentMgrs
*iface
, REFIID iid
, LPVOID
*ppvOut
)
1438 EnumTfDocumentMgr
*This
= impl_from_IEnumTfDocumentMgrs(iface
);
1441 if (IsEqualIID(iid
, &IID_IUnknown
) || IsEqualIID(iid
, &IID_IEnumTfDocumentMgrs
))
1443 *ppvOut
= &This
->IEnumTfDocumentMgrs_iface
;
1448 IEnumTfDocumentMgrs_AddRef(iface
);
1452 WARN("unsupported interface: %s\n", debugstr_guid(iid
));
1453 return E_NOINTERFACE
;
1456 static ULONG WINAPI
EnumTfDocumentMgr_AddRef(IEnumTfDocumentMgrs
*iface
)
1458 EnumTfDocumentMgr
*This
= impl_from_IEnumTfDocumentMgrs(iface
);
1459 return InterlockedIncrement(&This
->refCount
);
1462 static ULONG WINAPI
EnumTfDocumentMgr_Release(IEnumTfDocumentMgrs
*iface
)
1464 EnumTfDocumentMgr
*This
= impl_from_IEnumTfDocumentMgrs(iface
);
1467 ret
= InterlockedDecrement(&This
->refCount
);
1469 EnumTfDocumentMgr_Destructor(This
);
1473 static HRESULT WINAPI
EnumTfDocumentMgr_Next(IEnumTfDocumentMgrs
*iface
,
1474 ULONG ulCount
, ITfDocumentMgr
**rgDocumentMgr
, ULONG
*pcFetched
)
1476 EnumTfDocumentMgr
*This
= impl_from_IEnumTfDocumentMgrs(iface
);
1479 TRACE("(%p)\n",This
);
1481 if (rgDocumentMgr
== NULL
) return E_POINTER
;
1483 while (fetched
< ulCount
)
1485 DocumentMgrEntry
*mgrentry
;
1486 if (This
->index
== NULL
)
1489 mgrentry
= LIST_ENTRY(This
->index
,DocumentMgrEntry
,entry
);
1490 if (mgrentry
== NULL
)
1493 *rgDocumentMgr
= mgrentry
->docmgr
;
1494 ITfDocumentMgr_AddRef(*rgDocumentMgr
);
1496 This
->index
= list_next(This
->head
, This
->index
);
1501 if (pcFetched
) *pcFetched
= fetched
;
1502 return fetched
== ulCount
? S_OK
: S_FALSE
;
1505 static HRESULT WINAPI
EnumTfDocumentMgr_Skip( IEnumTfDocumentMgrs
* iface
, ULONG celt
)
1507 EnumTfDocumentMgr
*This
= impl_from_IEnumTfDocumentMgrs(iface
);
1510 TRACE("(%p)\n",This
);
1511 for(i
= 0; i
< celt
&& This
->index
!= NULL
; i
++)
1512 This
->index
= list_next(This
->head
, This
->index
);
1516 static HRESULT WINAPI
EnumTfDocumentMgr_Reset( IEnumTfDocumentMgrs
* iface
)
1518 EnumTfDocumentMgr
*This
= impl_from_IEnumTfDocumentMgrs(iface
);
1519 TRACE("(%p)\n",This
);
1520 This
->index
= list_head(This
->head
);
1524 static HRESULT WINAPI
EnumTfDocumentMgr_Clone( IEnumTfDocumentMgrs
*iface
,
1525 IEnumTfDocumentMgrs
**ppenum
)
1527 EnumTfDocumentMgr
*This
= impl_from_IEnumTfDocumentMgrs(iface
);
1530 TRACE("(%p)\n",This
);
1532 if (ppenum
== NULL
) return E_POINTER
;
1534 res
= EnumTfDocumentMgr_Constructor(This
->head
, ppenum
);
1537 EnumTfDocumentMgr
*new_This
= impl_from_IEnumTfDocumentMgrs(*ppenum
);
1538 new_This
->index
= This
->index
;
1543 static const IEnumTfDocumentMgrsVtbl EnumTfDocumentMgrsVtbl
=
1545 EnumTfDocumentMgr_QueryInterface
,
1546 EnumTfDocumentMgr_AddRef
,
1547 EnumTfDocumentMgr_Release
,
1548 EnumTfDocumentMgr_Clone
,
1549 EnumTfDocumentMgr_Next
,
1550 EnumTfDocumentMgr_Reset
,
1551 EnumTfDocumentMgr_Skip
1554 static HRESULT
EnumTfDocumentMgr_Constructor(struct list
* head
, IEnumTfDocumentMgrs
**ppOut
)
1556 EnumTfDocumentMgr
*This
;
1558 This
= HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY
,sizeof(EnumTfDocumentMgr
));
1560 return E_OUTOFMEMORY
;
1562 This
->IEnumTfDocumentMgrs_iface
.lpVtbl
= &EnumTfDocumentMgrsVtbl
;
1565 This
->index
= list_head(This
->head
);
1567 TRACE("returning %p\n", This
);
1568 *ppOut
= (IEnumTfDocumentMgrs
*)This
;
1572 void ThreadMgr_OnDocumentMgrDestruction(ITfThreadMgr
*iface
, ITfDocumentMgr
*mgr
)
1574 ThreadMgr
*This
= impl_from_ITfThreadMgrEx((ITfThreadMgrEx
*)iface
);
1575 struct list
*cursor
;
1576 LIST_FOR_EACH(cursor
, &This
->CreatedDocumentMgrs
)
1578 DocumentMgrEntry
*mgrentry
= LIST_ENTRY(cursor
,DocumentMgrEntry
,entry
);
1579 if (mgrentry
->docmgr
== mgr
)
1581 list_remove(cursor
);
1582 HeapFree(GetProcessHeap(),0,mgrentry
);
1586 FIXME("ITfDocumentMgr %p not found in this thread\n",mgr
);