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 ITfThreadMgrEx ITfThreadMgrEx_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 ITfUIElementMgr ITfUIElementMgr_iface
;
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_ITfThreadMgrEx(ITfThreadMgrEx
*iface
)
110 return CONTAINING_RECORD(iface
, ThreadMgr
, ITfThreadMgrEx_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_ITfUIElementMgr(ITfUIElementMgr
*iface
)
140 return CONTAINING_RECORD(iface
, ThreadMgr
, ITfUIElementMgr_iface
);
143 static inline ThreadMgr
*impl_from_ITfSourceSingle(ITfSourceSingle
*iface
)
145 return CONTAINING_RECORD(iface
, ThreadMgr
, ITfSourceSingle_iface
);
148 static inline EnumTfDocumentMgr
*impl_from_IEnumTfDocumentMgrs(IEnumTfDocumentMgrs
*iface
)
150 return CONTAINING_RECORD(iface
, EnumTfDocumentMgr
, IEnumTfDocumentMgrs_iface
);
153 static void free_sink(ThreadMgrSink
*sink
)
155 IUnknown_Release(sink
->interfaces
.pIUnknown
);
156 HeapFree(GetProcessHeap(),0,sink
);
159 static void ThreadMgr_Destructor(ThreadMgr
*This
)
161 struct list
*cursor
, *cursor2
;
163 /* unhook right away */
165 UnhookWindowsHookEx(This
->focusHook
);
167 TlsSetValue(tlsIndex
,NULL
);
168 TRACE("destroying %p\n", This
);
170 ITfDocumentMgr_Release(This
->focus
);
173 LIST_FOR_EACH_SAFE(cursor
, cursor2
, &This
->ActiveLanguageProfileNotifySink
)
175 ThreadMgrSink
* sink
= LIST_ENTRY(cursor
,ThreadMgrSink
,entry
);
179 LIST_FOR_EACH_SAFE(cursor
, cursor2
, &This
->DisplayAttributeNotifySink
)
181 ThreadMgrSink
* sink
= LIST_ENTRY(cursor
,ThreadMgrSink
,entry
);
185 LIST_FOR_EACH_SAFE(cursor
, cursor2
, &This
->KeyTraceEventSink
)
187 ThreadMgrSink
* sink
= LIST_ENTRY(cursor
,ThreadMgrSink
,entry
);
191 LIST_FOR_EACH_SAFE(cursor
, cursor2
, &This
->PreservedKeyNotifySink
)
193 ThreadMgrSink
* sink
= LIST_ENTRY(cursor
,ThreadMgrSink
,entry
);
197 LIST_FOR_EACH_SAFE(cursor
, cursor2
, &This
->ThreadFocusSink
)
199 ThreadMgrSink
* sink
= LIST_ENTRY(cursor
,ThreadMgrSink
,entry
);
203 LIST_FOR_EACH_SAFE(cursor
, cursor2
, &This
->ThreadMgrEventSink
)
205 ThreadMgrSink
* sink
= LIST_ENTRY(cursor
,ThreadMgrSink
,entry
);
210 LIST_FOR_EACH_SAFE(cursor
, cursor2
, &This
->CurrentPreservedKeys
)
212 PreservedKey
* key
= LIST_ENTRY(cursor
,PreservedKey
,entry
);
214 HeapFree(GetProcessHeap(),0,key
->description
);
215 HeapFree(GetProcessHeap(),0,key
);
218 LIST_FOR_EACH_SAFE(cursor
, cursor2
, &This
->CreatedDocumentMgrs
)
220 DocumentMgrEntry
*mgr
= LIST_ENTRY(cursor
,DocumentMgrEntry
,entry
);
222 FIXME("Left Over ITfDocumentMgr. Should we do something with it?\n");
223 HeapFree(GetProcessHeap(),0,mgr
);
226 LIST_FOR_EACH_SAFE(cursor
, cursor2
, &This
->AssociatedFocusWindows
)
228 AssociatedWindow
*wnd
= LIST_ENTRY(cursor
,AssociatedWindow
,entry
);
230 HeapFree(GetProcessHeap(),0,wnd
);
233 CompartmentMgr_Destructor(This
->CompartmentMgr
);
235 HeapFree(GetProcessHeap(),0,This
);
238 static HRESULT WINAPI
ThreadMgr_QueryInterface(ITfThreadMgrEx
*iface
, REFIID iid
, LPVOID
*ppvOut
)
240 ThreadMgr
*This
= impl_from_ITfThreadMgrEx(iface
);
243 if (IsEqualIID(iid
, &IID_IUnknown
) || IsEqualIID(iid
, &IID_ITfThreadMgr
)
244 || IsEqualIID(iid
, &IID_ITfThreadMgrEx
))
246 *ppvOut
= &This
->ITfThreadMgrEx_iface
;
248 else if (IsEqualIID(iid
, &IID_ITfSource
))
250 *ppvOut
= &This
->ITfSource_iface
;
252 else if (IsEqualIID(iid
, &IID_ITfKeystrokeMgr
))
254 *ppvOut
= &This
->ITfKeystrokeMgr_iface
;
256 else if (IsEqualIID(iid
, &IID_ITfMessagePump
))
258 *ppvOut
= &This
->ITfMessagePump_iface
;
260 else if (IsEqualIID(iid
, &IID_ITfClientId
))
262 *ppvOut
= &This
->ITfClientId_iface
;
264 else if (IsEqualIID(iid
, &IID_ITfCompartmentMgr
))
266 *ppvOut
= This
->CompartmentMgr
;
268 else if (IsEqualIID(iid
, &IID_ITfUIElementMgr
))
270 *ppvOut
= &This
->ITfUIElementMgr_iface
;
272 else if (IsEqualIID(iid
, &IID_ITfSourceSingle
))
274 *ppvOut
= &This
->ITfSourceSingle_iface
;
279 ITfThreadMgrEx_AddRef(iface
);
283 WARN("unsupported interface: %s\n", debugstr_guid(iid
));
284 return E_NOINTERFACE
;
287 static ULONG WINAPI
ThreadMgr_AddRef(ITfThreadMgrEx
*iface
)
289 ThreadMgr
*This
= impl_from_ITfThreadMgrEx(iface
);
290 return InterlockedIncrement(&This
->refCount
);
293 static ULONG WINAPI
ThreadMgr_Release(ITfThreadMgrEx
*iface
)
295 ThreadMgr
*This
= impl_from_ITfThreadMgrEx(iface
);
298 ret
= InterlockedDecrement(&This
->refCount
);
300 ThreadMgr_Destructor(This
);
304 /*****************************************************
305 * ITfThreadMgr functions
306 *****************************************************/
308 static HRESULT WINAPI
ThreadMgr_Activate(ITfThreadMgrEx
*iface
, TfClientId
*id
)
310 ThreadMgr
*This
= impl_from_ITfThreadMgrEx(iface
);
312 TRACE("(%p) %p\n", This
, id
);
313 return ITfThreadMgrEx_ActivateEx(iface
, id
, 0);
316 static HRESULT WINAPI
ThreadMgr_Deactivate(ITfThreadMgrEx
*iface
)
318 ThreadMgr
*This
= impl_from_ITfThreadMgrEx(iface
);
319 TRACE("(%p)\n",This
);
321 if (This
->activationCount
== 0)
324 This
->activationCount
--;
326 if (This
->activationCount
== 0)
330 ITfThreadMgrEventSink_OnSetFocus(&This
->ITfThreadMgrEventSink_iface
, 0, This
->focus
);
331 ITfDocumentMgr_Release(This
->focus
);
336 deactivate_textservices();
341 static HRESULT WINAPI
ThreadMgr_CreateDocumentMgr(ITfThreadMgrEx
*iface
, ITfDocumentMgr
**ppdim
)
343 ThreadMgr
*This
= impl_from_ITfThreadMgrEx(iface
);
344 DocumentMgrEntry
*mgrentry
;
347 TRACE("(%p)\n",iface
);
348 mgrentry
= HeapAlloc(GetProcessHeap(),0,sizeof(DocumentMgrEntry
));
349 if (mgrentry
== NULL
)
350 return E_OUTOFMEMORY
;
352 hr
= DocumentMgr_Constructor(&This
->ITfThreadMgrEventSink_iface
, ppdim
);
356 mgrentry
->docmgr
= *ppdim
;
357 list_add_head(&This
->CreatedDocumentMgrs
,&mgrentry
->entry
);
360 HeapFree(GetProcessHeap(),0,mgrentry
);
365 static HRESULT WINAPI
ThreadMgr_EnumDocumentMgrs(ITfThreadMgrEx
*iface
, IEnumTfDocumentMgrs
**ppEnum
)
367 ThreadMgr
*This
= impl_from_ITfThreadMgrEx(iface
);
368 TRACE("(%p) %p\n",This
,ppEnum
);
373 return EnumTfDocumentMgr_Constructor(&This
->CreatedDocumentMgrs
, ppEnum
);
376 static HRESULT WINAPI
ThreadMgr_GetFocus(ITfThreadMgrEx
*iface
, ITfDocumentMgr
**ppdimFocus
)
378 ThreadMgr
*This
= impl_from_ITfThreadMgrEx(iface
);
379 TRACE("(%p)\n",This
);
384 *ppdimFocus
= This
->focus
;
386 TRACE("->%p\n",This
->focus
);
388 if (This
->focus
== NULL
)
391 ITfDocumentMgr_AddRef(This
->focus
);
396 static HRESULT WINAPI
ThreadMgr_SetFocus(ITfThreadMgrEx
*iface
, ITfDocumentMgr
*pdimFocus
)
398 ThreadMgr
*This
= impl_from_ITfThreadMgrEx(iface
);
399 ITfDocumentMgr
*check
;
401 TRACE("(%p) %p\n",This
,pdimFocus
);
405 else if (FAILED(ITfDocumentMgr_QueryInterface(pdimFocus
,&IID_ITfDocumentMgr
,(LPVOID
*) &check
)))
408 ITfThreadMgrEventSink_OnSetFocus(&This
->ITfThreadMgrEventSink_iface
, check
, This
->focus
);
411 ITfDocumentMgr_Release(This
->focus
);
417 static LRESULT CALLBACK
ThreadFocusHookProc(int nCode
, WPARAM wParam
, LPARAM lParam
)
421 This
= TlsGetValue(tlsIndex
);
424 ERR("Hook proc but no ThreadMgr for this thread. Serious Error\n");
427 if (!This
->focusHook
)
429 ERR("Hook proc but no ThreadMgr focus Hook. Serious Error\n");
433 if (nCode
== HCBT_SETFOCUS
) /* focus change within our thread */
437 LIST_FOR_EACH(cursor
, &This
->AssociatedFocusWindows
)
439 AssociatedWindow
*wnd
= LIST_ENTRY(cursor
,AssociatedWindow
,entry
);
440 if (wnd
->hwnd
== (HWND
)wParam
)
442 TRACE("Triggering Associated window focus\n");
443 if (This
->focus
!= wnd
->docmgr
)
444 ThreadMgr_SetFocus(&This
->ITfThreadMgrEx_iface
, wnd
->docmgr
);
450 return CallNextHookEx(This
->focusHook
, nCode
, wParam
, lParam
);
453 static HRESULT
SetupWindowsHook(ThreadMgr
*This
)
455 if (!This
->focusHook
)
457 This
->focusHook
= SetWindowsHookExW(WH_CBT
, ThreadFocusHookProc
, 0,
458 GetCurrentThreadId());
459 if (!This
->focusHook
)
461 ERR("Unable to set focus hook\n");
469 static HRESULT WINAPI
ThreadMgr_AssociateFocus(ITfThreadMgrEx
*iface
, HWND hwnd
,
470 ITfDocumentMgr
*pdimNew
, ITfDocumentMgr
**ppdimPrev
)
472 ThreadMgr
*This
= impl_from_ITfThreadMgrEx(iface
);
473 struct list
*cursor
, *cursor2
;
474 AssociatedWindow
*wnd
;
476 TRACE("(%p) %p %p %p\n",This
,hwnd
,pdimNew
,ppdimPrev
);
483 LIST_FOR_EACH_SAFE(cursor
, cursor2
, &This
->AssociatedFocusWindows
)
485 wnd
= LIST_ENTRY(cursor
,AssociatedWindow
,entry
);
486 if (wnd
->hwnd
== hwnd
)
489 ITfDocumentMgr_AddRef(wnd
->docmgr
);
490 *ppdimPrev
= wnd
->docmgr
;
491 wnd
->docmgr
= pdimNew
;
492 if (GetFocus() == hwnd
)
493 ThreadMgr_SetFocus(iface
,pdimNew
);
498 wnd
= HeapAlloc(GetProcessHeap(),0,sizeof(AssociatedWindow
));
500 wnd
->docmgr
= pdimNew
;
501 list_add_head(&This
->AssociatedFocusWindows
,&wnd
->entry
);
503 if (GetFocus() == hwnd
)
504 ThreadMgr_SetFocus(iface
,pdimNew
);
506 SetupWindowsHook(This
);
511 static HRESULT WINAPI
ThreadMgr_IsThreadFocus(ITfThreadMgrEx
*iface
, BOOL
*pfThreadFocus
)
513 ThreadMgr
*This
= impl_from_ITfThreadMgrEx(iface
);
516 TRACE("(%p) %p\n",This
,pfThreadFocus
);
518 *pfThreadFocus
= (focus
== NULL
);
522 static HRESULT WINAPI
ThreadMgr_GetFunctionProvider(ITfThreadMgrEx
*iface
, REFCLSID clsid
,
523 ITfFunctionProvider
**ppFuncProv
)
525 ThreadMgr
*This
= impl_from_ITfThreadMgrEx(iface
);
526 FIXME("STUB:(%p)\n",This
);
530 static HRESULT WINAPI
ThreadMgr_EnumFunctionProviders(ITfThreadMgrEx
*iface
,
531 IEnumTfFunctionProviders
**ppEnum
)
533 ThreadMgr
*This
= impl_from_ITfThreadMgrEx(iface
);
534 FIXME("STUB:(%p)\n",This
);
538 static HRESULT WINAPI
ThreadMgr_GetGlobalCompartment(ITfThreadMgrEx
*iface
,
539 ITfCompartmentMgr
**ppCompMgr
)
541 ThreadMgr
*This
= impl_from_ITfThreadMgrEx(iface
);
543 TRACE("(%p) %p\n",This
, ppCompMgr
);
548 if (!globalCompartmentMgr
)
550 hr
= CompartmentMgr_Constructor(NULL
,&IID_ITfCompartmentMgr
,(IUnknown
**)&globalCompartmentMgr
);
555 ITfCompartmentMgr_AddRef(globalCompartmentMgr
);
556 *ppCompMgr
= globalCompartmentMgr
;
560 static HRESULT WINAPI
ThreadMgr_ActivateEx(ITfThreadMgrEx
*iface
, TfClientId
*id
, DWORD flags
)
562 ThreadMgr
*This
= impl_from_ITfThreadMgrEx(iface
);
564 TRACE("(%p) %p, %#x\n", This
, id
, flags
);
570 FIXME("Unimplemented flags %#x\n", flags
);
576 ITfClientId_GetClientId(&This
->ITfClientId_iface
, &guid
, &processId
);
579 activate_textservices((ITfThreadMgr
*)iface
);
580 This
->activationCount
++;
585 static HRESULT WINAPI
ThreadMgr_GetActiveFlags(ITfThreadMgrEx
*iface
, DWORD
*flags
)
587 ThreadMgr
*This
= impl_from_ITfThreadMgrEx(iface
);
589 FIXME("STUB:(%p)\n", This
);
593 static const ITfThreadMgrExVtbl ThreadMgrExVtbl
=
595 ThreadMgr_QueryInterface
,
599 ThreadMgr_Deactivate
,
600 ThreadMgr_CreateDocumentMgr
,
601 ThreadMgr_EnumDocumentMgrs
,
604 ThreadMgr_AssociateFocus
,
605 ThreadMgr_IsThreadFocus
,
606 ThreadMgr_GetFunctionProvider
,
607 ThreadMgr_EnumFunctionProviders
,
608 ThreadMgr_GetGlobalCompartment
,
610 ThreadMgr_ActivateEx
,
611 ThreadMgr_GetActiveFlags
614 static HRESULT WINAPI
Source_QueryInterface(ITfSource
*iface
, REFIID iid
, LPVOID
*ppvOut
)
616 ThreadMgr
*This
= impl_from_ITfSource(iface
);
617 return ITfThreadMgrEx_QueryInterface(&This
->ITfThreadMgrEx_iface
, iid
, ppvOut
);
620 static ULONG WINAPI
Source_AddRef(ITfSource
*iface
)
622 ThreadMgr
*This
= impl_from_ITfSource(iface
);
623 return ITfThreadMgrEx_AddRef(&This
->ITfThreadMgrEx_iface
);
626 static ULONG WINAPI
Source_Release(ITfSource
*iface
)
628 ThreadMgr
*This
= impl_from_ITfSource(iface
);
629 return ITfThreadMgrEx_Release(&This
->ITfThreadMgrEx_iface
);
632 /*****************************************************
633 * ITfSource functions
634 *****************************************************/
635 static HRESULT WINAPI
ThreadMgrSource_AdviseSink(ITfSource
*iface
,
636 REFIID riid
, IUnknown
*punk
, DWORD
*pdwCookie
)
638 ThreadMgr
*This
= impl_from_ITfSource(iface
);
641 TRACE("(%p) %s %p %p\n",This
,debugstr_guid(riid
),punk
,pdwCookie
);
643 if (!riid
|| !punk
|| !pdwCookie
)
646 if (IsEqualIID(riid
, &IID_ITfThreadMgrEventSink
))
648 tms
= HeapAlloc(GetProcessHeap(),0,sizeof(ThreadMgrSink
));
650 return E_OUTOFMEMORY
;
651 if (FAILED(IUnknown_QueryInterface(punk
, riid
, (LPVOID
*)&tms
->interfaces
.pITfThreadMgrEventSink
)))
653 HeapFree(GetProcessHeap(),0,tms
);
654 return CONNECT_E_CANNOTCONNECT
;
656 list_add_head(&This
->ThreadMgrEventSink
,&tms
->entry
);
657 *pdwCookie
= generate_Cookie(COOKIE_MAGIC_TMSINK
, tms
);
661 FIXME("(%p) Unhandled Sink: %s\n",This
,debugstr_guid(riid
));
665 TRACE("cookie %x\n",*pdwCookie
);
670 static HRESULT WINAPI
ThreadMgrSource_UnadviseSink(ITfSource
*iface
, DWORD pdwCookie
)
672 ThreadMgr
*This
= impl_from_ITfSource(iface
);
675 TRACE("(%p) %x\n",This
,pdwCookie
);
677 if (get_Cookie_magic(pdwCookie
)!=COOKIE_MAGIC_TMSINK
)
680 sink
= remove_Cookie(pdwCookie
);
682 return CONNECT_E_NOCONNECTION
;
684 list_remove(&sink
->entry
);
690 static const ITfSourceVtbl ThreadMgrSourceVtbl
=
692 Source_QueryInterface
,
695 ThreadMgrSource_AdviseSink
,
696 ThreadMgrSource_UnadviseSink
,
699 /*****************************************************
700 * ITfKeystrokeMgr functions
701 *****************************************************/
703 static HRESULT WINAPI
KeystrokeMgr_QueryInterface(ITfKeystrokeMgr
*iface
, REFIID iid
, LPVOID
*ppvOut
)
705 ThreadMgr
*This
= impl_from_ITfKeystrokeMgr(iface
);
706 return ITfThreadMgrEx_QueryInterface(&This
->ITfThreadMgrEx_iface
, iid
, ppvOut
);
709 static ULONG WINAPI
KeystrokeMgr_AddRef(ITfKeystrokeMgr
*iface
)
711 ThreadMgr
*This
= impl_from_ITfKeystrokeMgr(iface
);
712 return ITfThreadMgrEx_AddRef(&This
->ITfThreadMgrEx_iface
);
715 static ULONG WINAPI
KeystrokeMgr_Release(ITfKeystrokeMgr
*iface
)
717 ThreadMgr
*This
= impl_from_ITfKeystrokeMgr(iface
);
718 return ITfThreadMgrEx_Release(&This
->ITfThreadMgrEx_iface
);
721 static HRESULT WINAPI
KeystrokeMgr_AdviseKeyEventSink(ITfKeystrokeMgr
*iface
,
722 TfClientId tid
, ITfKeyEventSink
*pSink
, BOOL fForeground
)
724 ThreadMgr
*This
= impl_from_ITfKeystrokeMgr(iface
);
726 ITfKeyEventSink
*check
= NULL
;
728 TRACE("(%p) %x %p %i\n",This
,tid
,pSink
,fForeground
);
733 textservice
= get_textservice_clsid(tid
);
734 if (IsEqualCLSID(&GUID_NULL
,&textservice
))
737 get_textservice_sink(tid
, &IID_ITfKeyEventSink
, (IUnknown
**)&check
);
739 return CONNECT_E_ADVISELIMIT
;
741 if (FAILED(ITfKeyEventSink_QueryInterface(pSink
,&IID_ITfKeyEventSink
,(LPVOID
*) &check
)))
744 set_textservice_sink(tid
, &IID_ITfKeyEventSink
, (IUnknown
*)check
);
748 if (This
->forgroundKeyEventSink
)
750 ITfKeyEventSink_OnSetFocus(This
->forgroundKeyEventSink
, FALSE
);
751 ITfKeyEventSink_Release(This
->forgroundKeyEventSink
);
753 ITfKeyEventSink_AddRef(check
);
754 ITfKeyEventSink_OnSetFocus(check
, TRUE
);
755 This
->forgroundKeyEventSink
= check
;
756 This
->forgroundTextService
= textservice
;
761 static HRESULT WINAPI
KeystrokeMgr_UnadviseKeyEventSink(ITfKeystrokeMgr
*iface
,
764 ThreadMgr
*This
= impl_from_ITfKeystrokeMgr(iface
);
766 ITfKeyEventSink
*check
= NULL
;
767 TRACE("(%p) %x\n",This
,tid
);
772 textservice
= get_textservice_clsid(tid
);
773 if (IsEqualCLSID(&GUID_NULL
,&textservice
))
776 get_textservice_sink(tid
, &IID_ITfKeyEventSink
, (IUnknown
**)&check
);
779 return CONNECT_E_NOCONNECTION
;
781 set_textservice_sink(tid
, &IID_ITfKeyEventSink
, NULL
);
782 ITfKeyEventSink_Release(check
);
784 if (This
->forgroundKeyEventSink
== check
)
786 ITfKeyEventSink_Release(This
->forgroundKeyEventSink
);
787 This
->forgroundKeyEventSink
= NULL
;
788 This
->forgroundTextService
= GUID_NULL
;
793 static HRESULT WINAPI
KeystrokeMgr_GetForeground(ITfKeystrokeMgr
*iface
,
796 ThreadMgr
*This
= impl_from_ITfKeystrokeMgr(iface
);
797 TRACE("(%p) %p\n",This
,pclsid
);
801 if (IsEqualCLSID(&This
->forgroundTextService
,&GUID_NULL
))
804 *pclsid
= This
->forgroundTextService
;
808 static HRESULT WINAPI
KeystrokeMgr_TestKeyDown(ITfKeystrokeMgr
*iface
,
809 WPARAM wParam
, LPARAM lParam
, BOOL
*pfEaten
)
811 ThreadMgr
*This
= impl_from_ITfKeystrokeMgr(iface
);
812 FIXME("STUB:(%p)\n",This
);
816 static HRESULT WINAPI
KeystrokeMgr_TestKeyUp(ITfKeystrokeMgr
*iface
,
817 WPARAM wParam
, LPARAM lParam
, BOOL
*pfEaten
)
819 ThreadMgr
*This
= impl_from_ITfKeystrokeMgr(iface
);
820 FIXME("STUB:(%p)\n",This
);
824 static HRESULT WINAPI
KeystrokeMgr_KeyDown(ITfKeystrokeMgr
*iface
,
825 WPARAM wParam
, LPARAM lParam
, BOOL
*pfEaten
)
827 ThreadMgr
*This
= impl_from_ITfKeystrokeMgr(iface
);
828 FIXME("STUB:(%p)\n",This
);
832 static HRESULT WINAPI
KeystrokeMgr_KeyUp(ITfKeystrokeMgr
*iface
,
833 WPARAM wParam
, LPARAM lParam
, BOOL
*pfEaten
)
835 ThreadMgr
*This
= impl_from_ITfKeystrokeMgr(iface
);
836 FIXME("STUB:(%p)\n",This
);
840 static HRESULT WINAPI
KeystrokeMgr_GetPreservedKey(ITfKeystrokeMgr
*iface
,
841 ITfContext
*pic
, const TF_PRESERVEDKEY
*pprekey
, GUID
*pguid
)
843 ThreadMgr
*This
= impl_from_ITfKeystrokeMgr(iface
);
844 FIXME("STUB:(%p)\n",This
);
848 static HRESULT WINAPI
KeystrokeMgr_IsPreservedKey(ITfKeystrokeMgr
*iface
,
849 REFGUID rguid
, const TF_PRESERVEDKEY
*pprekey
, BOOL
*pfRegistered
)
851 ThreadMgr
*This
= impl_from_ITfKeystrokeMgr(iface
);
854 TRACE("(%p) %s (%x %x) %p\n",This
,debugstr_guid(rguid
), (pprekey
)?pprekey
->uVKey
:0, (pprekey
)?pprekey
->uModifiers
:0, pfRegistered
);
856 if (!rguid
|| !pprekey
|| !pfRegistered
)
859 LIST_FOR_EACH(cursor
, &This
->CurrentPreservedKeys
)
861 PreservedKey
* key
= LIST_ENTRY(cursor
,PreservedKey
,entry
);
862 if (IsEqualGUID(rguid
,&key
->guid
) && pprekey
->uVKey
== key
->prekey
.uVKey
&& pprekey
->uModifiers
== key
->prekey
.uModifiers
)
864 *pfRegistered
= TRUE
;
869 *pfRegistered
= FALSE
;
873 static HRESULT WINAPI
KeystrokeMgr_PreserveKey(ITfKeystrokeMgr
*iface
,
874 TfClientId tid
, REFGUID rguid
, const TF_PRESERVEDKEY
*prekey
,
875 const WCHAR
*pchDesc
, ULONG cchDesc
)
877 ThreadMgr
*This
= impl_from_ITfKeystrokeMgr(iface
);
879 PreservedKey
*newkey
;
881 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
));
883 if (!tid
|| ! rguid
|| !prekey
|| (cchDesc
&& !pchDesc
))
886 LIST_FOR_EACH(cursor
, &This
->CurrentPreservedKeys
)
888 PreservedKey
* key
= LIST_ENTRY(cursor
,PreservedKey
,entry
);
889 if (IsEqualGUID(rguid
,&key
->guid
) && prekey
->uVKey
== key
->prekey
.uVKey
&& prekey
->uModifiers
== key
->prekey
.uModifiers
)
890 return TF_E_ALREADY_EXISTS
;
893 newkey
= HeapAlloc(GetProcessHeap(),0,sizeof(PreservedKey
));
895 return E_OUTOFMEMORY
;
897 newkey
->guid
= *rguid
;
898 newkey
->prekey
= *prekey
;
900 newkey
->description
= NULL
;
903 newkey
->description
= HeapAlloc(GetProcessHeap(),0,cchDesc
* sizeof(WCHAR
));
904 if (!newkey
->description
)
906 HeapFree(GetProcessHeap(),0,newkey
);
907 return E_OUTOFMEMORY
;
909 memcpy(newkey
->description
, pchDesc
, cchDesc
*sizeof(WCHAR
));
912 list_add_head(&This
->CurrentPreservedKeys
,&newkey
->entry
);
917 static HRESULT WINAPI
KeystrokeMgr_UnpreserveKey(ITfKeystrokeMgr
*iface
,
918 REFGUID rguid
, const TF_PRESERVEDKEY
*pprekey
)
920 ThreadMgr
*This
= impl_from_ITfKeystrokeMgr(iface
);
921 PreservedKey
* key
= NULL
;
923 TRACE("(%p) %s (%x %x)\n",This
,debugstr_guid(rguid
),(pprekey
)?pprekey
->uVKey
:0, (pprekey
)?pprekey
->uModifiers
:0);
925 if (!pprekey
|| !rguid
)
928 LIST_FOR_EACH(cursor
, &This
->CurrentPreservedKeys
)
930 key
= LIST_ENTRY(cursor
,PreservedKey
,entry
);
931 if (IsEqualGUID(rguid
,&key
->guid
) && pprekey
->uVKey
== key
->prekey
.uVKey
&& pprekey
->uModifiers
== key
->prekey
.uModifiers
)
937 return CONNECT_E_NOCONNECTION
;
939 list_remove(&key
->entry
);
940 HeapFree(GetProcessHeap(),0,key
->description
);
941 HeapFree(GetProcessHeap(),0,key
);
946 static HRESULT WINAPI
KeystrokeMgr_SetPreservedKeyDescription(ITfKeystrokeMgr
*iface
,
947 REFGUID rguid
, const WCHAR
*pchDesc
, ULONG cchDesc
)
949 ThreadMgr
*This
= impl_from_ITfKeystrokeMgr(iface
);
950 FIXME("STUB:(%p)\n",This
);
954 static HRESULT WINAPI
KeystrokeMgr_GetPreservedKeyDescription(ITfKeystrokeMgr
*iface
,
955 REFGUID rguid
, BSTR
*pbstrDesc
)
957 ThreadMgr
*This
= impl_from_ITfKeystrokeMgr(iface
);
958 FIXME("STUB:(%p)\n",This
);
962 static HRESULT WINAPI
KeystrokeMgr_SimulatePreservedKey(ITfKeystrokeMgr
*iface
,
963 ITfContext
*pic
, REFGUID rguid
, BOOL
*pfEaten
)
965 ThreadMgr
*This
= impl_from_ITfKeystrokeMgr(iface
);
966 FIXME("STUB:(%p)\n",This
);
970 static const ITfKeystrokeMgrVtbl KeystrokeMgrVtbl
=
972 KeystrokeMgr_QueryInterface
,
974 KeystrokeMgr_Release
,
975 KeystrokeMgr_AdviseKeyEventSink
,
976 KeystrokeMgr_UnadviseKeyEventSink
,
977 KeystrokeMgr_GetForeground
,
978 KeystrokeMgr_TestKeyDown
,
979 KeystrokeMgr_TestKeyUp
,
980 KeystrokeMgr_KeyDown
,
982 KeystrokeMgr_GetPreservedKey
,
983 KeystrokeMgr_IsPreservedKey
,
984 KeystrokeMgr_PreserveKey
,
985 KeystrokeMgr_UnpreserveKey
,
986 KeystrokeMgr_SetPreservedKeyDescription
,
987 KeystrokeMgr_GetPreservedKeyDescription
,
988 KeystrokeMgr_SimulatePreservedKey
991 /*****************************************************
992 * ITfMessagePump functions
993 *****************************************************/
995 static HRESULT WINAPI
MessagePump_QueryInterface(ITfMessagePump
*iface
, REFIID iid
, LPVOID
*ppvOut
)
997 ThreadMgr
*This
= impl_from_ITfMessagePump(iface
);
998 return ITfThreadMgrEx_QueryInterface(&This
->ITfThreadMgrEx_iface
, iid
, ppvOut
);
1001 static ULONG WINAPI
MessagePump_AddRef(ITfMessagePump
*iface
)
1003 ThreadMgr
*This
= impl_from_ITfMessagePump(iface
);
1004 return ITfThreadMgrEx_AddRef(&This
->ITfThreadMgrEx_iface
);
1007 static ULONG WINAPI
MessagePump_Release(ITfMessagePump
*iface
)
1009 ThreadMgr
*This
= impl_from_ITfMessagePump(iface
);
1010 return ITfThreadMgrEx_Release(&This
->ITfThreadMgrEx_iface
);
1013 static HRESULT WINAPI
MessagePump_PeekMessageA(ITfMessagePump
*iface
,
1014 LPMSG pMsg
, HWND hwnd
, UINT wMsgFilterMin
, UINT wMsgFilterMax
,
1015 UINT wRemoveMsg
, BOOL
*pfResult
)
1018 return E_INVALIDARG
;
1019 *pfResult
= PeekMessageA(pMsg
, hwnd
, wMsgFilterMin
, wMsgFilterMax
, wRemoveMsg
);
1023 static HRESULT WINAPI
MessagePump_GetMessageA(ITfMessagePump
*iface
,
1024 LPMSG pMsg
, HWND hwnd
, UINT wMsgFilterMin
, UINT wMsgFilterMax
,
1028 return E_INVALIDARG
;
1029 *pfResult
= GetMessageA(pMsg
, hwnd
, wMsgFilterMin
, wMsgFilterMax
);
1033 static HRESULT WINAPI
MessagePump_PeekMessageW(ITfMessagePump
*iface
,
1034 LPMSG pMsg
, HWND hwnd
, UINT wMsgFilterMin
, UINT wMsgFilterMax
,
1035 UINT wRemoveMsg
, BOOL
*pfResult
)
1038 return E_INVALIDARG
;
1039 *pfResult
= PeekMessageW(pMsg
, hwnd
, wMsgFilterMin
, wMsgFilterMax
, wRemoveMsg
);
1043 static HRESULT WINAPI
MessagePump_GetMessageW(ITfMessagePump
*iface
,
1044 LPMSG pMsg
, HWND hwnd
, UINT wMsgFilterMin
, UINT wMsgFilterMax
,
1048 return E_INVALIDARG
;
1049 *pfResult
= GetMessageW(pMsg
, hwnd
, wMsgFilterMin
, wMsgFilterMax
);
1053 static const ITfMessagePumpVtbl MessagePumpVtbl
=
1055 MessagePump_QueryInterface
,
1057 MessagePump_Release
,
1058 MessagePump_PeekMessageA
,
1059 MessagePump_GetMessageA
,
1060 MessagePump_PeekMessageW
,
1061 MessagePump_GetMessageW
1064 /*****************************************************
1065 * ITfClientId functions
1066 *****************************************************/
1068 static HRESULT WINAPI
ClientId_QueryInterface(ITfClientId
*iface
, REFIID iid
, LPVOID
*ppvOut
)
1070 ThreadMgr
*This
= impl_from_ITfClientId(iface
);
1071 return ITfThreadMgrEx_QueryInterface(&This
->ITfThreadMgrEx_iface
, iid
, ppvOut
);
1074 static ULONG WINAPI
ClientId_AddRef(ITfClientId
*iface
)
1076 ThreadMgr
*This
= impl_from_ITfClientId(iface
);
1077 return ITfThreadMgrEx_AddRef(&This
->ITfThreadMgrEx_iface
);
1080 static ULONG WINAPI
ClientId_Release(ITfClientId
*iface
)
1082 ThreadMgr
*This
= impl_from_ITfClientId(iface
);
1083 return ITfThreadMgrEx_Release(&This
->ITfThreadMgrEx_iface
);
1086 static HRESULT WINAPI
ClientId_GetClientId(ITfClientId
*iface
,
1087 REFCLSID rclsid
, TfClientId
*ptid
)
1090 ThreadMgr
*This
= impl_from_ITfClientId(iface
);
1092 ITfCategoryMgr
*catmgr
;
1094 TRACE("(%p) %s\n",This
,debugstr_guid(rclsid
));
1096 CategoryMgr_Constructor(NULL
,(IUnknown
**)&catmgr
);
1097 hr
= ITfCategoryMgr_RegisterGUID(catmgr
,rclsid
,ptid
);
1098 ITfCategoryMgr_Release(catmgr
);
1103 static const ITfClientIdVtbl ClientIdVtbl
=
1105 ClientId_QueryInterface
,
1108 ClientId_GetClientId
1111 /*****************************************************
1112 * ITfThreadMgrEventSink functions (internal)
1113 *****************************************************/
1114 static HRESULT WINAPI
ThreadMgrEventSink_QueryInterface(ITfThreadMgrEventSink
*iface
, REFIID iid
, LPVOID
*ppvOut
)
1116 ThreadMgr
*This
= impl_from_ITfThreadMgrEventSink(iface
);
1117 return ITfThreadMgrEx_QueryInterface(&This
->ITfThreadMgrEx_iface
, iid
, ppvOut
);
1120 static ULONG WINAPI
ThreadMgrEventSink_AddRef(ITfThreadMgrEventSink
*iface
)
1122 ThreadMgr
*This
= impl_from_ITfThreadMgrEventSink(iface
);
1123 return ITfThreadMgrEx_AddRef(&This
->ITfThreadMgrEx_iface
);
1126 static ULONG WINAPI
ThreadMgrEventSink_Release(ITfThreadMgrEventSink
*iface
)
1128 ThreadMgr
*This
= impl_from_ITfThreadMgrEventSink(iface
);
1129 return ITfThreadMgrEx_Release(&This
->ITfThreadMgrEx_iface
);
1133 static HRESULT WINAPI
ThreadMgrEventSink_OnInitDocumentMgr(
1134 ITfThreadMgrEventSink
*iface
,ITfDocumentMgr
*pdim
)
1136 struct list
*cursor
;
1137 ThreadMgr
*This
= impl_from_ITfThreadMgrEventSink(iface
);
1139 TRACE("(%p) %p\n",This
,pdim
);
1141 LIST_FOR_EACH(cursor
, &This
->ThreadMgrEventSink
)
1143 ThreadMgrSink
* sink
= LIST_ENTRY(cursor
,ThreadMgrSink
,entry
);
1144 ITfThreadMgrEventSink_OnInitDocumentMgr(sink
->interfaces
.pITfThreadMgrEventSink
,pdim
);
1150 static HRESULT WINAPI
ThreadMgrEventSink_OnUninitDocumentMgr(
1151 ITfThreadMgrEventSink
*iface
, ITfDocumentMgr
*pdim
)
1153 struct list
*cursor
;
1154 ThreadMgr
*This
= impl_from_ITfThreadMgrEventSink(iface
);
1156 TRACE("(%p) %p\n",This
,pdim
);
1158 LIST_FOR_EACH(cursor
, &This
->ThreadMgrEventSink
)
1160 ThreadMgrSink
* sink
= LIST_ENTRY(cursor
,ThreadMgrSink
,entry
);
1161 ITfThreadMgrEventSink_OnUninitDocumentMgr(sink
->interfaces
.pITfThreadMgrEventSink
,pdim
);
1167 static HRESULT WINAPI
ThreadMgrEventSink_OnSetFocus(
1168 ITfThreadMgrEventSink
*iface
, ITfDocumentMgr
*pdimFocus
,
1169 ITfDocumentMgr
*pdimPrevFocus
)
1171 struct list
*cursor
;
1172 ThreadMgr
*This
= impl_from_ITfThreadMgrEventSink(iface
);
1174 TRACE("(%p) %p %p\n",This
,pdimFocus
, pdimPrevFocus
);
1176 LIST_FOR_EACH(cursor
, &This
->ThreadMgrEventSink
)
1178 ThreadMgrSink
* sink
= LIST_ENTRY(cursor
,ThreadMgrSink
,entry
);
1179 ITfThreadMgrEventSink_OnSetFocus(sink
->interfaces
.pITfThreadMgrEventSink
, pdimFocus
, pdimPrevFocus
);
1185 static HRESULT WINAPI
ThreadMgrEventSink_OnPushContext(
1186 ITfThreadMgrEventSink
*iface
, ITfContext
*pic
)
1188 struct list
*cursor
;
1189 ThreadMgr
*This
= impl_from_ITfThreadMgrEventSink(iface
);
1191 TRACE("(%p) %p\n",This
,pic
);
1193 LIST_FOR_EACH(cursor
, &This
->ThreadMgrEventSink
)
1195 ThreadMgrSink
* sink
= LIST_ENTRY(cursor
,ThreadMgrSink
,entry
);
1196 ITfThreadMgrEventSink_OnPushContext(sink
->interfaces
.pITfThreadMgrEventSink
,pic
);
1202 static HRESULT WINAPI
ThreadMgrEventSink_OnPopContext(
1203 ITfThreadMgrEventSink
*iface
, ITfContext
*pic
)
1205 struct list
*cursor
;
1206 ThreadMgr
*This
= impl_from_ITfThreadMgrEventSink(iface
);
1208 TRACE("(%p) %p\n",This
,pic
);
1210 LIST_FOR_EACH(cursor
, &This
->ThreadMgrEventSink
)
1212 ThreadMgrSink
* sink
= LIST_ENTRY(cursor
,ThreadMgrSink
,entry
);
1213 ITfThreadMgrEventSink_OnPopContext(sink
->interfaces
.pITfThreadMgrEventSink
,pic
);
1219 static const ITfThreadMgrEventSinkVtbl ThreadMgrEventSinkVtbl
=
1221 ThreadMgrEventSink_QueryInterface
,
1222 ThreadMgrEventSink_AddRef
,
1223 ThreadMgrEventSink_Release
,
1224 ThreadMgrEventSink_OnInitDocumentMgr
,
1225 ThreadMgrEventSink_OnUninitDocumentMgr
,
1226 ThreadMgrEventSink_OnSetFocus
,
1227 ThreadMgrEventSink_OnPushContext
,
1228 ThreadMgrEventSink_OnPopContext
1231 /*****************************************************
1232 * ITfUIElementMgr functions
1233 *****************************************************/
1234 static HRESULT WINAPI
UIElementMgr_QueryInterface(ITfUIElementMgr
*iface
, REFIID iid
, void **ppvOut
)
1236 ThreadMgr
*This
= impl_from_ITfUIElementMgr(iface
);
1238 return ITfThreadMgrEx_QueryInterface(&This
->ITfThreadMgrEx_iface
, iid
, *ppvOut
);
1241 static ULONG WINAPI
UIElementMgr_AddRef(ITfUIElementMgr
*iface
)
1243 ThreadMgr
*This
= impl_from_ITfUIElementMgr(iface
);
1245 return ITfThreadMgrEx_AddRef(&This
->ITfThreadMgrEx_iface
);
1248 static ULONG WINAPI
UIElementMgr_Release(ITfUIElementMgr
*iface
)
1250 ThreadMgr
*This
= impl_from_ITfUIElementMgr(iface
);
1252 return ITfThreadMgrEx_Release(&This
->ITfThreadMgrEx_iface
);
1255 static HRESULT WINAPI
UIElementMgr_BeginUIElement(ITfUIElementMgr
*iface
, ITfUIElement
*element
,
1256 BOOL
*show
, DWORD
*id
)
1258 ThreadMgr
*This
= impl_from_ITfUIElementMgr(iface
);
1260 FIXME("STUB:(%p)\n", This
);
1264 static HRESULT WINAPI
UIElementMgr_UpdateUIElement(ITfUIElementMgr
*iface
, DWORD id
)
1266 ThreadMgr
*This
= impl_from_ITfUIElementMgr(iface
);
1268 FIXME("STUB:(%p)\n", This
);
1272 static HRESULT WINAPI
UIElementMgr_EndUIElement(ITfUIElementMgr
*iface
, DWORD id
)
1274 ThreadMgr
*This
= impl_from_ITfUIElementMgr(iface
);
1276 FIXME("STUB:(%p)\n", This
);
1280 static HRESULT WINAPI
UIElementMgr_GetUIElement(ITfUIElementMgr
*iface
, DWORD id
,
1281 ITfUIElement
**element
)
1283 ThreadMgr
*This
= impl_from_ITfUIElementMgr(iface
);
1285 FIXME("STUB:(%p)\n", This
);
1289 static HRESULT WINAPI
UIElementMgr_EnumUIElements(ITfUIElementMgr
*iface
,
1290 IEnumTfUIElements
**enum_elements
)
1292 ThreadMgr
*This
= impl_from_ITfUIElementMgr(iface
);
1294 FIXME("STUB:(%p)\n", This
);
1298 static const ITfUIElementMgrVtbl ThreadMgrUIElementMgrVtbl
=
1300 UIElementMgr_QueryInterface
,
1301 UIElementMgr_AddRef
,
1302 UIElementMgr_Release
,
1304 UIElementMgr_BeginUIElement
,
1305 UIElementMgr_UpdateUIElement
,
1306 UIElementMgr_EndUIElement
,
1307 UIElementMgr_GetUIElement
,
1308 UIElementMgr_EnumUIElements
1311 /*****************************************************
1312 * ITfSourceSingle functions
1313 *****************************************************/
1314 static HRESULT WINAPI
ThreadMgrSourceSingle_QueryInterface(ITfSourceSingle
*iface
, REFIID iid
, LPVOID
*ppvOut
)
1316 ThreadMgr
*This
= impl_from_ITfSourceSingle(iface
);
1317 return ITfThreadMgrEx_QueryInterface(&This
->ITfThreadMgrEx_iface
, iid
, ppvOut
);
1320 static ULONG WINAPI
ThreadMgrSourceSingle_AddRef(ITfSourceSingle
*iface
)
1322 ThreadMgr
*This
= impl_from_ITfSourceSingle(iface
);
1323 return ITfThreadMgrEx_AddRef(&This
->ITfThreadMgrEx_iface
);
1326 static ULONG WINAPI
ThreadMgrSourceSingle_Release(ITfSourceSingle
*iface
)
1328 ThreadMgr
*This
= impl_from_ITfSourceSingle(iface
);
1329 return ITfThreadMgrEx_Release(&This
->ITfThreadMgrEx_iface
);
1332 static HRESULT WINAPI
ThreadMgrSourceSingle_AdviseSingleSink( ITfSourceSingle
*iface
,
1333 TfClientId tid
, REFIID riid
, IUnknown
*punk
)
1335 ThreadMgr
*This
= impl_from_ITfSourceSingle(iface
);
1336 FIXME("STUB:(%p) %i %s %p\n",This
, tid
, debugstr_guid(riid
),punk
);
1340 static HRESULT WINAPI
ThreadMgrSourceSingle_UnadviseSingleSink( ITfSourceSingle
*iface
,
1341 TfClientId tid
, REFIID riid
)
1343 ThreadMgr
*This
= impl_from_ITfSourceSingle(iface
);
1344 FIXME("STUB:(%p) %i %s\n",This
, tid
, debugstr_guid(riid
));
1348 static const ITfSourceSingleVtbl SourceSingleVtbl
=
1350 ThreadMgrSourceSingle_QueryInterface
,
1351 ThreadMgrSourceSingle_AddRef
,
1352 ThreadMgrSourceSingle_Release
,
1353 ThreadMgrSourceSingle_AdviseSingleSink
,
1354 ThreadMgrSourceSingle_UnadviseSingleSink
1357 HRESULT
ThreadMgr_Constructor(IUnknown
*pUnkOuter
, IUnknown
**ppOut
)
1361 return CLASS_E_NOAGGREGATION
;
1363 /* Only 1 ThreadMgr is created per thread */
1364 This
= TlsGetValue(tlsIndex
);
1367 ThreadMgr_AddRef(&This
->ITfThreadMgrEx_iface
);
1368 *ppOut
= (IUnknown
*)&This
->ITfThreadMgrEx_iface
;
1372 This
= HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY
,sizeof(ThreadMgr
));
1374 return E_OUTOFMEMORY
;
1376 This
->ITfThreadMgrEx_iface
.lpVtbl
= &ThreadMgrExVtbl
;
1377 This
->ITfSource_iface
.lpVtbl
= &ThreadMgrSourceVtbl
;
1378 This
->ITfKeystrokeMgr_iface
.lpVtbl
= &KeystrokeMgrVtbl
;
1379 This
->ITfMessagePump_iface
.lpVtbl
= &MessagePumpVtbl
;
1380 This
->ITfClientId_iface
.lpVtbl
= &ClientIdVtbl
;
1381 This
->ITfThreadMgrEventSink_iface
.lpVtbl
= &ThreadMgrEventSinkVtbl
;
1382 This
->ITfUIElementMgr_iface
.lpVtbl
= &ThreadMgrUIElementMgrVtbl
;
1383 This
->ITfSourceSingle_iface
.lpVtbl
= &SourceSingleVtbl
;
1385 TlsSetValue(tlsIndex
,This
);
1387 CompartmentMgr_Constructor((IUnknown
*)This
, &IID_IUnknown
, (IUnknown
**)&This
->CompartmentMgr
);
1389 list_init(&This
->CurrentPreservedKeys
);
1390 list_init(&This
->CreatedDocumentMgrs
);
1391 list_init(&This
->AssociatedFocusWindows
);
1393 list_init(&This
->ActiveLanguageProfileNotifySink
);
1394 list_init(&This
->DisplayAttributeNotifySink
);
1395 list_init(&This
->KeyTraceEventSink
);
1396 list_init(&This
->PreservedKeyNotifySink
);
1397 list_init(&This
->ThreadFocusSink
);
1398 list_init(&This
->ThreadMgrEventSink
);
1400 TRACE("returning %p\n", This
);
1401 *ppOut
= (IUnknown
*)&This
->ITfThreadMgrEx_iface
;
1405 /**************************************************
1406 * IEnumTfDocumentMgrs implementation
1407 **************************************************/
1408 static void EnumTfDocumentMgr_Destructor(EnumTfDocumentMgr
*This
)
1410 TRACE("destroying %p\n", This
);
1411 HeapFree(GetProcessHeap(),0,This
);
1414 static HRESULT WINAPI
EnumTfDocumentMgr_QueryInterface(IEnumTfDocumentMgrs
*iface
, REFIID iid
, LPVOID
*ppvOut
)
1416 EnumTfDocumentMgr
*This
= impl_from_IEnumTfDocumentMgrs(iface
);
1419 if (IsEqualIID(iid
, &IID_IUnknown
) || IsEqualIID(iid
, &IID_IEnumTfDocumentMgrs
))
1421 *ppvOut
= &This
->IEnumTfDocumentMgrs_iface
;
1426 IEnumTfDocumentMgrs_AddRef(iface
);
1430 WARN("unsupported interface: %s\n", debugstr_guid(iid
));
1431 return E_NOINTERFACE
;
1434 static ULONG WINAPI
EnumTfDocumentMgr_AddRef(IEnumTfDocumentMgrs
*iface
)
1436 EnumTfDocumentMgr
*This
= impl_from_IEnumTfDocumentMgrs(iface
);
1437 return InterlockedIncrement(&This
->refCount
);
1440 static ULONG WINAPI
EnumTfDocumentMgr_Release(IEnumTfDocumentMgrs
*iface
)
1442 EnumTfDocumentMgr
*This
= impl_from_IEnumTfDocumentMgrs(iface
);
1445 ret
= InterlockedDecrement(&This
->refCount
);
1447 EnumTfDocumentMgr_Destructor(This
);
1451 static HRESULT WINAPI
EnumTfDocumentMgr_Next(IEnumTfDocumentMgrs
*iface
,
1452 ULONG ulCount
, ITfDocumentMgr
**rgDocumentMgr
, ULONG
*pcFetched
)
1454 EnumTfDocumentMgr
*This
= impl_from_IEnumTfDocumentMgrs(iface
);
1457 TRACE("(%p)\n",This
);
1459 if (rgDocumentMgr
== NULL
) return E_POINTER
;
1461 while (fetched
< ulCount
)
1463 DocumentMgrEntry
*mgrentry
;
1464 if (This
->index
== NULL
)
1467 mgrentry
= LIST_ENTRY(This
->index
,DocumentMgrEntry
,entry
);
1468 if (mgrentry
== NULL
)
1471 *rgDocumentMgr
= mgrentry
->docmgr
;
1472 ITfDocumentMgr_AddRef(*rgDocumentMgr
);
1474 This
->index
= list_next(This
->head
, This
->index
);
1479 if (pcFetched
) *pcFetched
= fetched
;
1480 return fetched
== ulCount
? S_OK
: S_FALSE
;
1483 static HRESULT WINAPI
EnumTfDocumentMgr_Skip( IEnumTfDocumentMgrs
* iface
, ULONG celt
)
1485 EnumTfDocumentMgr
*This
= impl_from_IEnumTfDocumentMgrs(iface
);
1488 TRACE("(%p)\n",This
);
1489 for(i
= 0; i
< celt
&& This
->index
!= NULL
; i
++)
1490 This
->index
= list_next(This
->head
, This
->index
);
1494 static HRESULT WINAPI
EnumTfDocumentMgr_Reset( IEnumTfDocumentMgrs
* iface
)
1496 EnumTfDocumentMgr
*This
= impl_from_IEnumTfDocumentMgrs(iface
);
1497 TRACE("(%p)\n",This
);
1498 This
->index
= list_head(This
->head
);
1502 static HRESULT WINAPI
EnumTfDocumentMgr_Clone( IEnumTfDocumentMgrs
*iface
,
1503 IEnumTfDocumentMgrs
**ppenum
)
1505 EnumTfDocumentMgr
*This
= impl_from_IEnumTfDocumentMgrs(iface
);
1508 TRACE("(%p)\n",This
);
1510 if (ppenum
== NULL
) return E_POINTER
;
1512 res
= EnumTfDocumentMgr_Constructor(This
->head
, ppenum
);
1515 EnumTfDocumentMgr
*new_This
= impl_from_IEnumTfDocumentMgrs(*ppenum
);
1516 new_This
->index
= This
->index
;
1521 static const IEnumTfDocumentMgrsVtbl EnumTfDocumentMgrsVtbl
=
1523 EnumTfDocumentMgr_QueryInterface
,
1524 EnumTfDocumentMgr_AddRef
,
1525 EnumTfDocumentMgr_Release
,
1526 EnumTfDocumentMgr_Clone
,
1527 EnumTfDocumentMgr_Next
,
1528 EnumTfDocumentMgr_Reset
,
1529 EnumTfDocumentMgr_Skip
1532 static HRESULT
EnumTfDocumentMgr_Constructor(struct list
* head
, IEnumTfDocumentMgrs
**ppOut
)
1534 EnumTfDocumentMgr
*This
;
1536 This
= HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY
,sizeof(EnumTfDocumentMgr
));
1538 return E_OUTOFMEMORY
;
1540 This
->IEnumTfDocumentMgrs_iface
.lpVtbl
= &EnumTfDocumentMgrsVtbl
;
1543 This
->index
= list_head(This
->head
);
1545 TRACE("returning %p\n", This
);
1546 *ppOut
= (IEnumTfDocumentMgrs
*)This
;
1550 void ThreadMgr_OnDocumentMgrDestruction(ITfThreadMgr
*iface
, ITfDocumentMgr
*mgr
)
1552 ThreadMgr
*This
= impl_from_ITfThreadMgrEx((ITfThreadMgrEx
*)iface
);
1553 struct list
*cursor
;
1554 LIST_FOR_EACH(cursor
, &This
->CreatedDocumentMgrs
)
1556 DocumentMgrEntry
*mgrentry
= LIST_ENTRY(cursor
,DocumentMgrEntry
,entry
);
1557 if (mgrentry
->docmgr
== mgr
)
1559 list_remove(cursor
);
1560 HeapFree(GetProcessHeap(),0,mgrentry
);
1564 FIXME("ITfDocumentMgr %p not found in this thread\n",mgr
);