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 tagACLMulti {
69 const ITfThreadMgrVtbl *ThreadMgrVtbl;
70 const ITfSourceVtbl *SourceVtbl;
71 const ITfKeystrokeMgrVtbl *KeystrokeMgrVtbl;
72 const ITfMessagePumpVtbl *MessagePumpVtbl;
73 const ITfClientIdVtbl *ClientIdVtbl;
76 const ITfThreadMgrEventSinkVtbl *ThreadMgrEventSinkVtbl; /* internal */
78 ITfDocumentMgr *focus;
81 ITfKeyEventSink *forgroundKeyEventSink;
82 CLSID forgroundTextService;
84 struct list CurrentPreservedKeys;
86 /* kept as separate lists to reduce unnecessary iterations */
87 struct list ActiveLanguageProfileNotifySink;
88 struct list DisplayAttributeNotifySink;
89 struct list KeyTraceEventSink;
90 struct list PreservedKeyNotifySink;
91 struct list ThreadFocusSink;
92 struct list ThreadMgrEventSink;
95 static inline ThreadMgr *impl_from_ITfSourceVtbl(ITfSource *iface)
97 return (ThreadMgr *)((char *)iface - FIELD_OFFSET(ThreadMgr,SourceVtbl));
100 static inline ThreadMgr *impl_from_ITfKeystrokeMgrVtbl(ITfKeystrokeMgr *iface)
102 return (ThreadMgr *)((char *)iface - FIELD_OFFSET(ThreadMgr,KeystrokeMgrVtbl));
105 static inline ThreadMgr *impl_from_ITfMessagePumpVtbl(ITfMessagePump *iface)
107 return (ThreadMgr *)((char *)iface - FIELD_OFFSET(ThreadMgr,MessagePumpVtbl));
110 static inline ThreadMgr *impl_from_ITfClientIdVtbl(ITfClientId *iface)
112 return (ThreadMgr *)((char *)iface - FIELD_OFFSET(ThreadMgr,ClientIdVtbl));
115 static inline ThreadMgr *impl_from_ITfThreadMgrEventSink(ITfThreadMgrEventSink *iface)
117 return (ThreadMgr *)((char *)iface - FIELD_OFFSET(ThreadMgr,ThreadMgrEventSinkVtbl));
120 static void free_sink(ThreadMgrSink *sink)
122 IUnknown_Release(sink->interfaces.pIUnknown);
123 HeapFree(GetProcessHeap(),0,sink);
126 static void ThreadMgr_Destructor(ThreadMgr *This)
128 struct list *cursor, *cursor2;
130 TlsSetValue(tlsIndex,NULL);
131 TRACE("destroying %p\n", This);
133 ITfDocumentMgr_Release(This->focus);
136 LIST_FOR_EACH_SAFE(cursor, cursor2, &This->ActiveLanguageProfileNotifySink)
138 ThreadMgrSink* sink = LIST_ENTRY(cursor,ThreadMgrSink,entry);
142 LIST_FOR_EACH_SAFE(cursor, cursor2, &This->DisplayAttributeNotifySink)
144 ThreadMgrSink* sink = LIST_ENTRY(cursor,ThreadMgrSink,entry);
148 LIST_FOR_EACH_SAFE(cursor, cursor2, &This->KeyTraceEventSink)
150 ThreadMgrSink* sink = LIST_ENTRY(cursor,ThreadMgrSink,entry);
154 LIST_FOR_EACH_SAFE(cursor, cursor2, &This->PreservedKeyNotifySink)
156 ThreadMgrSink* sink = LIST_ENTRY(cursor,ThreadMgrSink,entry);
160 LIST_FOR_EACH_SAFE(cursor, cursor2, &This->ThreadFocusSink)
162 ThreadMgrSink* sink = LIST_ENTRY(cursor,ThreadMgrSink,entry);
166 LIST_FOR_EACH_SAFE(cursor, cursor2, &This->ThreadMgrEventSink)
168 ThreadMgrSink* sink = LIST_ENTRY(cursor,ThreadMgrSink,entry);
173 LIST_FOR_EACH_SAFE(cursor, cursor2, &This->CurrentPreservedKeys)
175 PreservedKey* key = LIST_ENTRY(cursor,PreservedKey,entry);
177 HeapFree(GetProcessHeap(),0,key->description);
178 HeapFree(GetProcessHeap(),0,key);
181 HeapFree(GetProcessHeap(),0,This);
184 static HRESULT WINAPI ThreadMgr_QueryInterface(ITfThreadMgr *iface, REFIID iid, LPVOID *ppvOut)
186 ThreadMgr *This = (ThreadMgr *)iface;
189 if (IsEqualIID(iid, &IID_IUnknown) || IsEqualIID(iid, &IID_ITfThreadMgr))
193 else if (IsEqualIID(iid, &IID_ITfSource))
195 *ppvOut = &This->SourceVtbl;
197 else if (IsEqualIID(iid, &IID_ITfKeystrokeMgr))
199 *ppvOut = &This->KeystrokeMgrVtbl;
201 else if (IsEqualIID(iid, &IID_ITfMessagePump))
203 *ppvOut = &This->MessagePumpVtbl;
205 else if (IsEqualIID(iid, &IID_ITfClientId))
207 *ppvOut = &This->ClientIdVtbl;
212 IUnknown_AddRef(iface);
216 WARN("unsupported interface: %s\n", debugstr_guid(iid));
217 return E_NOINTERFACE;
220 static ULONG WINAPI ThreadMgr_AddRef(ITfThreadMgr *iface)
222 ThreadMgr *This = (ThreadMgr *)iface;
223 return InterlockedIncrement(&This->refCount);
226 static ULONG WINAPI ThreadMgr_Release(ITfThreadMgr *iface)
228 ThreadMgr *This = (ThreadMgr *)iface;
231 ret = InterlockedDecrement(&This->refCount);
233 ThreadMgr_Destructor(This);
237 /*****************************************************
238 * ITfThreadMgr functions
239 *****************************************************/
241 static HRESULT WINAPI ThreadMgr_fnActivate( ITfThreadMgr* iface, TfClientId *ptid)
243 ThreadMgr *This = (ThreadMgr *)iface;
245 TRACE("(%p) %p\n",This, ptid);
254 ITfClientId_GetClientId((ITfClientId*)&This->ClientIdVtbl,&guid,&processId);
257 activate_textservices(iface);
258 This->activationCount++;
263 static HRESULT WINAPI ThreadMgr_fnDeactivate( ITfThreadMgr* iface)
265 ThreadMgr *This = (ThreadMgr *)iface;
266 TRACE("(%p)\n",This);
268 if (This->activationCount == 0)
271 This->activationCount --;
273 if (This->activationCount == 0)
277 ITfThreadMgrEventSink_OnSetFocus((ITfThreadMgrEventSink*)&This->ThreadMgrEventSinkVtbl, 0, This->focus);
278 ITfDocumentMgr_Release(This->focus);
283 deactivate_textservices();
288 static HRESULT WINAPI ThreadMgr_CreateDocumentMgr( ITfThreadMgr* iface, ITfDocumentMgr
291 ThreadMgr *This = (ThreadMgr *)iface;
292 TRACE("(%p)\n",iface);
293 return DocumentMgr_Constructor((ITfThreadMgrEventSink*)&This->ThreadMgrEventSinkVtbl, ppdim);
296 static HRESULT WINAPI ThreadMgr_EnumDocumentMgrs( ITfThreadMgr* iface, IEnumTfDocumentMgrs
299 ThreadMgr *This = (ThreadMgr *)iface;
300 FIXME("STUB:(%p)\n",This);
304 static HRESULT WINAPI ThreadMgr_GetFocus( ITfThreadMgr* iface, ITfDocumentMgr
307 ThreadMgr *This = (ThreadMgr *)iface;
308 TRACE("(%p)\n",This);
313 *ppdimFocus = This->focus;
315 TRACE("->%p\n",This->focus);
317 if (This->focus == NULL)
320 ITfDocumentMgr_AddRef(This->focus);
325 static HRESULT WINAPI ThreadMgr_SetFocus( ITfThreadMgr* iface, ITfDocumentMgr *pdimFocus)
327 ITfDocumentMgr *check;
328 ThreadMgr *This = (ThreadMgr *)iface;
330 TRACE("(%p) %p\n",This,pdimFocus);
332 if (!pdimFocus || FAILED(IUnknown_QueryInterface(pdimFocus,&IID_ITfDocumentMgr,(LPVOID*) &check)))
335 ITfThreadMgrEventSink_OnSetFocus((ITfThreadMgrEventSink*)&This->ThreadMgrEventSinkVtbl, check, This->focus);
338 ITfDocumentMgr_Release(This->focus);
344 static HRESULT WINAPI ThreadMgr_AssociateFocus( ITfThreadMgr* iface, HWND hwnd,
345 ITfDocumentMgr *pdimNew, ITfDocumentMgr **ppdimPrev)
347 ThreadMgr *This = (ThreadMgr *)iface;
348 FIXME("STUB:(%p)\n",This);
352 static HRESULT WINAPI ThreadMgr_IsThreadFocus( ITfThreadMgr* iface, BOOL *pfThreadFocus)
354 ThreadMgr *This = (ThreadMgr *)iface;
355 FIXME("STUB:(%p)\n",This);
359 static HRESULT WINAPI ThreadMgr_GetFunctionProvider( ITfThreadMgr* iface, REFCLSID clsid,
360 ITfFunctionProvider **ppFuncProv)
362 ThreadMgr *This = (ThreadMgr *)iface;
363 FIXME("STUB:(%p)\n",This);
367 static HRESULT WINAPI ThreadMgr_EnumFunctionProviders( ITfThreadMgr* iface,
368 IEnumTfFunctionProviders **ppEnum)
370 ThreadMgr *This = (ThreadMgr *)iface;
371 FIXME("STUB:(%p)\n",This);
375 static HRESULT WINAPI ThreadMgr_GetGlobalCompartment( ITfThreadMgr* iface,
376 ITfCompartmentMgr **ppCompMgr)
378 ThreadMgr *This = (ThreadMgr *)iface;
379 FIXME("STUB:(%p)\n",This);
383 static const ITfThreadMgrVtbl ThreadMgr_ThreadMgrVtbl =
385 ThreadMgr_QueryInterface,
389 ThreadMgr_fnActivate,
390 ThreadMgr_fnDeactivate,
391 ThreadMgr_CreateDocumentMgr,
392 ThreadMgr_EnumDocumentMgrs,
395 ThreadMgr_AssociateFocus,
396 ThreadMgr_IsThreadFocus,
397 ThreadMgr_GetFunctionProvider,
398 ThreadMgr_EnumFunctionProviders,
399 ThreadMgr_GetGlobalCompartment
403 static HRESULT WINAPI Source_QueryInterface(ITfSource *iface, REFIID iid, LPVOID *ppvOut)
405 ThreadMgr *This = impl_from_ITfSourceVtbl(iface);
406 return ThreadMgr_QueryInterface((ITfThreadMgr *)This, iid, *ppvOut);
409 static ULONG WINAPI Source_AddRef(ITfSource *iface)
411 ThreadMgr *This = impl_from_ITfSourceVtbl(iface);
412 return ThreadMgr_AddRef((ITfThreadMgr*)This);
415 static ULONG WINAPI Source_Release(ITfSource *iface)
417 ThreadMgr *This = impl_from_ITfSourceVtbl(iface);
418 return ThreadMgr_Release((ITfThreadMgr *)This);
421 /*****************************************************
422 * ITfSource functions
423 *****************************************************/
424 static WINAPI HRESULT ThreadMgrSource_AdviseSink(ITfSource *iface,
425 REFIID riid, IUnknown *punk, DWORD *pdwCookie)
428 ThreadMgr *This = impl_from_ITfSourceVtbl(iface);
430 TRACE("(%p) %s %p %p\n",This,debugstr_guid(riid),punk,pdwCookie);
432 if (!riid || !punk || !pdwCookie)
435 if (IsEqualIID(riid, &IID_ITfThreadMgrEventSink))
437 tms = HeapAlloc(GetProcessHeap(),0,sizeof(ThreadMgrSink));
439 return E_OUTOFMEMORY;
440 if (!SUCCEEDED(IUnknown_QueryInterface(punk, riid, (LPVOID*)&tms->interfaces.pITfThreadMgrEventSink)))
442 HeapFree(GetProcessHeap(),0,tms);
443 return CONNECT_E_CANNOTCONNECT;
445 list_add_head(&This->ThreadMgrEventSink,&tms->entry);
446 *pdwCookie = generate_Cookie(COOKIE_MAGIC_TMSINK, tms);
450 FIXME("(%p) Unhandled Sink: %s\n",This,debugstr_guid(riid));
454 TRACE("cookie %x\n",*pdwCookie);
459 static WINAPI HRESULT ThreadMgrSource_UnadviseSink(ITfSource *iface, DWORD pdwCookie)
462 ThreadMgr *This = impl_from_ITfSourceVtbl(iface);
464 TRACE("(%p) %x\n",This,pdwCookie);
466 if (get_Cookie_magic(pdwCookie)!=COOKIE_MAGIC_TMSINK)
469 sink = (ThreadMgrSink*)remove_Cookie(pdwCookie);
471 return CONNECT_E_NOCONNECTION;
473 list_remove(&sink->entry);
479 static const ITfSourceVtbl ThreadMgr_SourceVtbl =
481 Source_QueryInterface,
485 ThreadMgrSource_AdviseSink,
486 ThreadMgrSource_UnadviseSink,
489 /*****************************************************
490 * ITfKeystrokeMgr functions
491 *****************************************************/
493 static HRESULT WINAPI KeystrokeMgr_QueryInterface(ITfKeystrokeMgr *iface, REFIID iid, LPVOID *ppvOut)
495 ThreadMgr *This = impl_from_ITfKeystrokeMgrVtbl(iface);
496 return ThreadMgr_QueryInterface((ITfThreadMgr *)This, iid, *ppvOut);
499 static ULONG WINAPI KeystrokeMgr_AddRef(ITfKeystrokeMgr *iface)
501 ThreadMgr *This = impl_from_ITfKeystrokeMgrVtbl(iface);
502 return ThreadMgr_AddRef((ITfThreadMgr*)This);
505 static ULONG WINAPI KeystrokeMgr_Release(ITfKeystrokeMgr *iface)
507 ThreadMgr *This = impl_from_ITfKeystrokeMgrVtbl(iface);
508 return ThreadMgr_Release((ITfThreadMgr *)This);
511 static HRESULT WINAPI KeystrokeMgr_AdviseKeyEventSink(ITfKeystrokeMgr *iface,
512 TfClientId tid, ITfKeyEventSink *pSink, BOOL fForeground)
514 ThreadMgr *This = impl_from_ITfKeystrokeMgrVtbl(iface);
516 ITfKeyEventSink *check = NULL;
518 TRACE("(%p) %x %p %i\n",This,tid,pSink,fForeground);
523 textservice = get_textservice_clsid(tid);
524 if (IsEqualCLSID(&GUID_NULL,&textservice))
527 get_textservice_sink(tid, &IID_ITfKeyEventSink, (IUnknown**)&check);
529 return CONNECT_E_ADVISELIMIT;
531 if (FAILED(IUnknown_QueryInterface(pSink,&IID_ITfKeyEventSink,(LPVOID*) &check)))
534 set_textservice_sink(tid, &IID_ITfKeyEventSink, (IUnknown*)check);
538 if (This->forgroundKeyEventSink)
540 ITfKeyEventSink_OnSetFocus(This->forgroundKeyEventSink, FALSE);
541 ITfKeyEventSink_Release(This->forgroundKeyEventSink);
543 ITfKeyEventSink_AddRef(check);
544 ITfKeyEventSink_OnSetFocus(check, TRUE);
545 This->forgroundKeyEventSink = check;
546 This->forgroundTextService = textservice;
551 static HRESULT WINAPI KeystrokeMgr_UnadviseKeyEventSink(ITfKeystrokeMgr *iface,
554 ThreadMgr *This = impl_from_ITfKeystrokeMgrVtbl(iface);
556 ITfKeyEventSink *check = NULL;
557 TRACE("(%p) %x\n",This,tid);
562 textservice = get_textservice_clsid(tid);
563 if (IsEqualCLSID(&GUID_NULL,&textservice))
566 get_textservice_sink(tid, &IID_ITfKeyEventSink, (IUnknown**)&check);
569 return CONNECT_E_NOCONNECTION;
571 set_textservice_sink(tid, &IID_ITfKeyEventSink, NULL);
572 ITfKeyEventSink_Release(check);
574 if (This->forgroundKeyEventSink == check)
576 ITfKeyEventSink_Release(This->forgroundKeyEventSink);
577 This->forgroundKeyEventSink = NULL;
578 This->forgroundTextService = GUID_NULL;
583 static HRESULT WINAPI KeystrokeMgr_GetForeground(ITfKeystrokeMgr *iface,
586 ThreadMgr *This = impl_from_ITfKeystrokeMgrVtbl(iface);
587 TRACE("(%p) %p\n",This,pclsid);
591 if (IsEqualCLSID(&This->forgroundTextService,&GUID_NULL))
594 *pclsid = This->forgroundTextService;
598 static HRESULT WINAPI KeystrokeMgr_TestKeyDown(ITfKeystrokeMgr *iface,
599 WPARAM wParam, LPARAM lParam, BOOL *pfEaten)
601 ThreadMgr *This = impl_from_ITfKeystrokeMgrVtbl(iface);
602 FIXME("STUB:(%p)\n",This);
606 static HRESULT WINAPI KeystrokeMgr_TestKeyUp(ITfKeystrokeMgr *iface,
607 WPARAM wParam, LPARAM lParam, BOOL *pfEaten)
609 ThreadMgr *This = impl_from_ITfKeystrokeMgrVtbl(iface);
610 FIXME("STUB:(%p)\n",This);
614 static HRESULT WINAPI KeystrokeMgr_KeyDown(ITfKeystrokeMgr *iface,
615 WPARAM wParam, LPARAM lParam, BOOL *pfEaten)
617 ThreadMgr *This = impl_from_ITfKeystrokeMgrVtbl(iface);
618 FIXME("STUB:(%p)\n",This);
622 static HRESULT WINAPI KeystrokeMgr_KeyUp(ITfKeystrokeMgr *iface,
623 WPARAM wParam, LPARAM lParam, BOOL *pfEaten)
625 ThreadMgr *This = impl_from_ITfKeystrokeMgrVtbl(iface);
626 FIXME("STUB:(%p)\n",This);
630 static HRESULT WINAPI KeystrokeMgr_GetPreservedKey(ITfKeystrokeMgr *iface,
631 ITfContext *pic, const TF_PRESERVEDKEY *pprekey, GUID *pguid)
633 ThreadMgr *This = impl_from_ITfKeystrokeMgrVtbl(iface);
634 FIXME("STUB:(%p)\n",This);
638 static HRESULT WINAPI KeystrokeMgr_IsPreservedKey(ITfKeystrokeMgr *iface,
639 REFGUID rguid, const TF_PRESERVEDKEY *pprekey, BOOL *pfRegistered)
641 ThreadMgr *This = impl_from_ITfKeystrokeMgrVtbl(iface);
644 TRACE("(%p) %s (%x %x) %p\n",This,debugstr_guid(rguid), (pprekey)?pprekey->uVKey:0, (pprekey)?pprekey->uModifiers:0, pfRegistered);
646 if (!rguid || !pprekey || !pfRegistered)
649 LIST_FOR_EACH(cursor, &This->CurrentPreservedKeys)
651 PreservedKey* key = LIST_ENTRY(cursor,PreservedKey,entry);
652 if (IsEqualGUID(rguid,&key->guid) && pprekey->uVKey == key->prekey.uVKey && pprekey->uModifiers == key->prekey.uModifiers)
654 *pfRegistered = TRUE;
659 *pfRegistered = FALSE;
663 static HRESULT WINAPI KeystrokeMgr_PreserveKey(ITfKeystrokeMgr *iface,
664 TfClientId tid, REFGUID rguid, const TF_PRESERVEDKEY *prekey,
665 const WCHAR *pchDesc, ULONG cchDesc)
667 ThreadMgr *This = impl_from_ITfKeystrokeMgrVtbl(iface);
669 PreservedKey *newkey;
671 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));
673 if (!tid || ! rguid || !prekey || (cchDesc && !pchDesc))
676 LIST_FOR_EACH(cursor, &This->CurrentPreservedKeys)
678 PreservedKey* key = LIST_ENTRY(cursor,PreservedKey,entry);
679 if (IsEqualGUID(rguid,&key->guid) && prekey->uVKey == key->prekey.uVKey && prekey->uModifiers == key->prekey.uModifiers)
680 return TF_E_ALREADY_EXISTS;
683 newkey = HeapAlloc(GetProcessHeap(),0,sizeof(PreservedKey));
685 return E_OUTOFMEMORY;
687 newkey->guid = *rguid;
688 newkey->prekey = *prekey;
692 newkey->description = HeapAlloc(GetProcessHeap(),0,cchDesc * sizeof(WCHAR));
693 if (!newkey->description)
695 HeapFree(GetProcessHeap(),0,newkey);
696 return E_OUTOFMEMORY;
698 memcpy(newkey->description, pchDesc, cchDesc*sizeof(WCHAR));
701 list_add_head(&This->CurrentPreservedKeys,&newkey->entry);
706 static HRESULT WINAPI KeystrokeMgr_UnpreserveKey(ITfKeystrokeMgr *iface,
707 REFGUID rguid, const TF_PRESERVEDKEY *pprekey)
709 ThreadMgr *This = impl_from_ITfKeystrokeMgrVtbl(iface);
710 PreservedKey* key = NULL;
712 TRACE("(%p) %s (%x %x)\n",This,debugstr_guid(rguid),(pprekey)?pprekey->uVKey:0, (pprekey)?pprekey->uModifiers:0);
714 if (!pprekey || !rguid)
717 LIST_FOR_EACH(cursor, &This->CurrentPreservedKeys)
719 key = LIST_ENTRY(cursor,PreservedKey,entry);
720 if (IsEqualGUID(rguid,&key->guid) && pprekey->uVKey == key->prekey.uVKey && pprekey->uModifiers == key->prekey.uModifiers)
726 return CONNECT_E_NOCONNECTION;
728 list_remove(&key->entry);
729 HeapFree(GetProcessHeap(),0,key->description);
730 HeapFree(GetProcessHeap(),0,key);
735 static HRESULT WINAPI KeystrokeMgr_SetPreservedKeyDescription(ITfKeystrokeMgr *iface,
736 REFGUID rguid, const WCHAR *pchDesc, ULONG cchDesc)
738 ThreadMgr *This = impl_from_ITfKeystrokeMgrVtbl(iface);
739 FIXME("STUB:(%p)\n",This);
743 static HRESULT WINAPI KeystrokeMgr_GetPreservedKeyDescription(ITfKeystrokeMgr *iface,
744 REFGUID rguid, BSTR *pbstrDesc)
746 ThreadMgr *This = impl_from_ITfKeystrokeMgrVtbl(iface);
747 FIXME("STUB:(%p)\n",This);
751 static HRESULT WINAPI KeystrokeMgr_SimulatePreservedKey(ITfKeystrokeMgr *iface,
752 ITfContext *pic, REFGUID rguid, BOOL *pfEaten)
754 ThreadMgr *This = impl_from_ITfKeystrokeMgrVtbl(iface);
755 FIXME("STUB:(%p)\n",This);
759 static const ITfKeystrokeMgrVtbl ThreadMgr_KeystrokeMgrVtbl =
761 KeystrokeMgr_QueryInterface,
763 KeystrokeMgr_Release,
765 KeystrokeMgr_AdviseKeyEventSink,
766 KeystrokeMgr_UnadviseKeyEventSink,
767 KeystrokeMgr_GetForeground,
768 KeystrokeMgr_TestKeyDown,
769 KeystrokeMgr_TestKeyUp,
770 KeystrokeMgr_KeyDown,
772 KeystrokeMgr_GetPreservedKey,
773 KeystrokeMgr_IsPreservedKey,
774 KeystrokeMgr_PreserveKey,
775 KeystrokeMgr_UnpreserveKey,
776 KeystrokeMgr_SetPreservedKeyDescription,
777 KeystrokeMgr_GetPreservedKeyDescription,
778 KeystrokeMgr_SimulatePreservedKey
781 /*****************************************************
782 * ITfMessagePump functions
783 *****************************************************/
785 static HRESULT WINAPI MessagePump_QueryInterface(ITfMessagePump *iface, REFIID iid, LPVOID *ppvOut)
787 ThreadMgr *This = impl_from_ITfMessagePumpVtbl(iface);
788 return ThreadMgr_QueryInterface((ITfThreadMgr *)This, iid, *ppvOut);
791 static ULONG WINAPI MessagePump_AddRef(ITfMessagePump *iface)
793 ThreadMgr *This = impl_from_ITfMessagePumpVtbl(iface);
794 return ThreadMgr_AddRef((ITfThreadMgr*)This);
797 static ULONG WINAPI MessagePump_Release(ITfMessagePump *iface)
799 ThreadMgr *This = impl_from_ITfMessagePumpVtbl(iface);
800 return ThreadMgr_Release((ITfThreadMgr *)This);
803 static HRESULT WINAPI MessagePump_PeekMessageA(ITfMessagePump *iface,
804 LPMSG pMsg, HWND hwnd, UINT wMsgFilterMin, UINT wMsgFilterMax,
805 UINT wRemoveMsg, BOOL *pfResult)
809 *pfResult = PeekMessageA(pMsg, hwnd, wMsgFilterMin, wMsgFilterMax, wRemoveMsg);
813 static HRESULT WINAPI MessagePump_GetMessageA(ITfMessagePump *iface,
814 LPMSG pMsg, HWND hwnd, UINT wMsgFilterMin, UINT wMsgFilterMax,
819 *pfResult = GetMessageA(pMsg, hwnd, wMsgFilterMin, wMsgFilterMax);
823 static HRESULT WINAPI MessagePump_PeekMessageW(ITfMessagePump *iface,
824 LPMSG pMsg, HWND hwnd, UINT wMsgFilterMin, UINT wMsgFilterMax,
825 UINT wRemoveMsg, BOOL *pfResult)
829 *pfResult = PeekMessageW(pMsg, hwnd, wMsgFilterMin, wMsgFilterMax, wRemoveMsg);
833 static HRESULT WINAPI MessagePump_GetMessageW(ITfMessagePump *iface,
834 LPMSG pMsg, HWND hwnd, UINT wMsgFilterMin, UINT wMsgFilterMax,
839 *pfResult = GetMessageW(pMsg, hwnd, wMsgFilterMin, wMsgFilterMax);
843 static const ITfMessagePumpVtbl ThreadMgr_MessagePumpVtbl =
845 MessagePump_QueryInterface,
849 MessagePump_PeekMessageA,
850 MessagePump_GetMessageA,
851 MessagePump_PeekMessageW,
852 MessagePump_GetMessageW
855 /*****************************************************
856 * ITfClientId functions
857 *****************************************************/
859 static HRESULT WINAPI ClientId_QueryInterface(ITfClientId *iface, REFIID iid, LPVOID *ppvOut)
861 ThreadMgr *This = impl_from_ITfClientIdVtbl(iface);
862 return ThreadMgr_QueryInterface((ITfThreadMgr *)This, iid, *ppvOut);
865 static ULONG WINAPI ClientId_AddRef(ITfClientId *iface)
867 ThreadMgr *This = impl_from_ITfClientIdVtbl(iface);
868 return ThreadMgr_AddRef((ITfThreadMgr*)This);
871 static ULONG WINAPI ClientId_Release(ITfClientId *iface)
873 ThreadMgr *This = impl_from_ITfClientIdVtbl(iface);
874 return ThreadMgr_Release((ITfThreadMgr *)This);
877 static HRESULT WINAPI ClientId_GetClientId(ITfClientId *iface,
878 REFCLSID rclsid, TfClientId *ptid)
882 ITfCategoryMgr *catmgr;
883 ThreadMgr *This = impl_from_ITfClientIdVtbl(iface);
885 TRACE("(%p) %s\n",This,debugstr_guid(rclsid));
887 CategoryMgr_Constructor(NULL,(IUnknown**)&catmgr);
888 hr = ITfCategoryMgr_RegisterGUID(catmgr,rclsid,ptid);
889 ITfCategoryMgr_Release(catmgr);
894 static const ITfClientIdVtbl ThreadMgr_ClientIdVtbl =
896 ClientId_QueryInterface,
903 /*****************************************************
904 * ITfThreadMgrEventSink functions (internal)
905 *****************************************************/
906 static HRESULT WINAPI ThreadMgrEventSink_QueryInterface(ITfThreadMgrEventSink *iface, REFIID iid, LPVOID *ppvOut)
908 ThreadMgr *This = impl_from_ITfThreadMgrEventSink(iface);
909 return ThreadMgr_QueryInterface((ITfThreadMgr *)This, iid, *ppvOut);
912 static ULONG WINAPI ThreadMgrEventSink_AddRef(ITfThreadMgrEventSink *iface)
914 ThreadMgr *This = impl_from_ITfThreadMgrEventSink(iface);
915 return ThreadMgr_AddRef((ITfThreadMgr*)This);
918 static ULONG WINAPI ThreadMgrEventSink_Release(ITfThreadMgrEventSink *iface)
920 ThreadMgr *This = impl_from_ITfThreadMgrEventSink(iface);
921 return ThreadMgr_Release((ITfThreadMgr *)This);
925 static WINAPI HRESULT ThreadMgrEventSink_OnInitDocumentMgr(
926 ITfThreadMgrEventSink *iface,ITfDocumentMgr *pdim)
929 ThreadMgr *This = impl_from_ITfThreadMgrEventSink(iface);
931 TRACE("(%p) %p\n",This,pdim);
933 LIST_FOR_EACH(cursor, &This->ThreadMgrEventSink)
935 ThreadMgrSink* sink = LIST_ENTRY(cursor,ThreadMgrSink,entry);
936 ITfThreadMgrEventSink_OnInitDocumentMgr(sink->interfaces.pITfThreadMgrEventSink,pdim);
942 static WINAPI HRESULT ThreadMgrEventSink_OnUninitDocumentMgr(
943 ITfThreadMgrEventSink *iface, ITfDocumentMgr *pdim)
946 ThreadMgr *This = impl_from_ITfThreadMgrEventSink(iface);
948 TRACE("(%p) %p\n",This,pdim);
950 LIST_FOR_EACH(cursor, &This->ThreadMgrEventSink)
952 ThreadMgrSink* sink = LIST_ENTRY(cursor,ThreadMgrSink,entry);
953 ITfThreadMgrEventSink_OnUninitDocumentMgr(sink->interfaces.pITfThreadMgrEventSink,pdim);
959 static WINAPI HRESULT ThreadMgrEventSink_OnSetFocus(
960 ITfThreadMgrEventSink *iface, ITfDocumentMgr *pdimFocus,
961 ITfDocumentMgr *pdimPrevFocus)
964 ThreadMgr *This = impl_from_ITfThreadMgrEventSink(iface);
966 TRACE("(%p) %p %p\n",This,pdimFocus, pdimPrevFocus);
968 LIST_FOR_EACH(cursor, &This->ThreadMgrEventSink)
970 ThreadMgrSink* sink = LIST_ENTRY(cursor,ThreadMgrSink,entry);
971 ITfThreadMgrEventSink_OnSetFocus(sink->interfaces.pITfThreadMgrEventSink, pdimFocus, pdimPrevFocus);
977 static WINAPI HRESULT ThreadMgrEventSink_OnPushContext(
978 ITfThreadMgrEventSink *iface, ITfContext *pic)
981 ThreadMgr *This = impl_from_ITfThreadMgrEventSink(iface);
983 TRACE("(%p) %p\n",This,pic);
985 LIST_FOR_EACH(cursor, &This->ThreadMgrEventSink)
987 ThreadMgrSink* sink = LIST_ENTRY(cursor,ThreadMgrSink,entry);
988 ITfThreadMgrEventSink_OnPushContext(sink->interfaces.pITfThreadMgrEventSink,pic);
994 static WINAPI HRESULT ThreadMgrEventSink_OnPopContext(
995 ITfThreadMgrEventSink *iface, ITfContext *pic)
998 ThreadMgr *This = impl_from_ITfThreadMgrEventSink(iface);
1000 TRACE("(%p) %p\n",This,pic);
1002 LIST_FOR_EACH(cursor, &This->ThreadMgrEventSink)
1004 ThreadMgrSink* sink = LIST_ENTRY(cursor,ThreadMgrSink,entry);
1005 ITfThreadMgrEventSink_OnPopContext(sink->interfaces.pITfThreadMgrEventSink,pic);
1011 static const ITfThreadMgrEventSinkVtbl ThreadMgr_ThreadMgrEventSinkVtbl =
1013 ThreadMgrEventSink_QueryInterface,
1014 ThreadMgrEventSink_AddRef,
1015 ThreadMgrEventSink_Release,
1017 ThreadMgrEventSink_OnInitDocumentMgr,
1018 ThreadMgrEventSink_OnUninitDocumentMgr,
1019 ThreadMgrEventSink_OnSetFocus,
1020 ThreadMgrEventSink_OnPushContext,
1021 ThreadMgrEventSink_OnPopContext
1024 HRESULT ThreadMgr_Constructor(IUnknown *pUnkOuter, IUnknown **ppOut)
1028 return CLASS_E_NOAGGREGATION;
1030 /* Only 1 ThreadMgr is created per thread */
1031 This = TlsGetValue(tlsIndex);
1034 ThreadMgr_AddRef((ITfThreadMgr*)This);
1035 *ppOut = (IUnknown*)This;
1039 This = HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,sizeof(ThreadMgr));
1041 return E_OUTOFMEMORY;
1043 This->ThreadMgrVtbl= &ThreadMgr_ThreadMgrVtbl;
1044 This->SourceVtbl = &ThreadMgr_SourceVtbl;
1045 This->KeystrokeMgrVtbl= &ThreadMgr_KeystrokeMgrVtbl;
1046 This->MessagePumpVtbl= &ThreadMgr_MessagePumpVtbl;
1047 This->ClientIdVtbl = &ThreadMgr_ClientIdVtbl;
1048 This->ThreadMgrEventSinkVtbl = &ThreadMgr_ThreadMgrEventSinkVtbl;
1050 TlsSetValue(tlsIndex,This);
1052 list_init(&This->CurrentPreservedKeys);
1054 list_init(&This->ActiveLanguageProfileNotifySink);
1055 list_init(&This->DisplayAttributeNotifySink);
1056 list_init(&This->KeyTraceEventSink);
1057 list_init(&This->PreservedKeyNotifySink);
1058 list_init(&This->ThreadFocusSink);
1059 list_init(&This->ThreadMgrEventSink);
1061 TRACE("returning %p\n", This);
1062 *ppOut = (IUnknown *)This;