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;
74 /* const ITfThreadMgrExVtbl *ThreadMgrExVtbl; */
75 /* const ITfConfigureSystemKeystrokeFeedVtbl *ConfigureSystemKeystrokeFeedVtbl; */
76 /* const ITfLangBarItemMgrVtbl *LangBarItemMgrVtbl; */
77 /* const ITfUIElementMgrVtbl *UIElementMgrVtbl; */
78 /* const ITfSourceSingleVtbl *SourceSingleVtbl; */
81 const ITfThreadMgrEventSinkVtbl *ThreadMgrEventSinkVtbl; /* internal */
83 ITfDocumentMgr *focus;
86 ITfKeyEventSink *forgroundKeyEventSink;
87 CLSID forgroundTextService;
89 struct list CurrentPreservedKeys;
91 /* kept as separate lists to reduce unnecessary iterations */
92 struct list ActiveLanguageProfileNotifySink;
93 struct list DisplayAttributeNotifySink;
94 struct list KeyTraceEventSink;
95 struct list PreservedKeyNotifySink;
96 struct list ThreadFocusSink;
97 struct list ThreadMgrEventSink;
100 static inline ThreadMgr *impl_from_ITfSourceVtbl(ITfSource *iface)
102 return (ThreadMgr *)((char *)iface - FIELD_OFFSET(ThreadMgr,SourceVtbl));
105 static inline ThreadMgr *impl_from_ITfKeystrokeMgrVtbl(ITfKeystrokeMgr *iface)
107 return (ThreadMgr *)((char *)iface - FIELD_OFFSET(ThreadMgr,KeystrokeMgrVtbl));
110 static inline ThreadMgr *impl_from_ITfMessagePumpVtbl(ITfMessagePump *iface)
112 return (ThreadMgr *)((char *)iface - FIELD_OFFSET(ThreadMgr,MessagePumpVtbl));
115 static inline ThreadMgr *impl_from_ITfClientIdVtbl(ITfClientId *iface)
117 return (ThreadMgr *)((char *)iface - FIELD_OFFSET(ThreadMgr,ClientIdVtbl));
120 static inline ThreadMgr *impl_from_ITfThreadMgrEventSink(ITfThreadMgrEventSink *iface)
122 return (ThreadMgr *)((char *)iface - FIELD_OFFSET(ThreadMgr,ThreadMgrEventSinkVtbl));
125 static void free_sink(ThreadMgrSink *sink)
127 IUnknown_Release(sink->interfaces.pIUnknown);
128 HeapFree(GetProcessHeap(),0,sink);
131 static void ThreadMgr_Destructor(ThreadMgr *This)
133 struct list *cursor, *cursor2;
135 TlsSetValue(tlsIndex,NULL);
136 TRACE("destroying %p\n", This);
138 ITfDocumentMgr_Release(This->focus);
141 LIST_FOR_EACH_SAFE(cursor, cursor2, &This->ActiveLanguageProfileNotifySink)
143 ThreadMgrSink* sink = LIST_ENTRY(cursor,ThreadMgrSink,entry);
147 LIST_FOR_EACH_SAFE(cursor, cursor2, &This->DisplayAttributeNotifySink)
149 ThreadMgrSink* sink = LIST_ENTRY(cursor,ThreadMgrSink,entry);
153 LIST_FOR_EACH_SAFE(cursor, cursor2, &This->KeyTraceEventSink)
155 ThreadMgrSink* sink = LIST_ENTRY(cursor,ThreadMgrSink,entry);
159 LIST_FOR_EACH_SAFE(cursor, cursor2, &This->PreservedKeyNotifySink)
161 ThreadMgrSink* sink = LIST_ENTRY(cursor,ThreadMgrSink,entry);
165 LIST_FOR_EACH_SAFE(cursor, cursor2, &This->ThreadFocusSink)
167 ThreadMgrSink* sink = LIST_ENTRY(cursor,ThreadMgrSink,entry);
171 LIST_FOR_EACH_SAFE(cursor, cursor2, &This->ThreadMgrEventSink)
173 ThreadMgrSink* sink = LIST_ENTRY(cursor,ThreadMgrSink,entry);
178 LIST_FOR_EACH_SAFE(cursor, cursor2, &This->CurrentPreservedKeys)
180 PreservedKey* key = LIST_ENTRY(cursor,PreservedKey,entry);
182 HeapFree(GetProcessHeap(),0,key->description);
183 HeapFree(GetProcessHeap(),0,key);
186 HeapFree(GetProcessHeap(),0,This);
189 static HRESULT WINAPI ThreadMgr_QueryInterface(ITfThreadMgr *iface, REFIID iid, LPVOID *ppvOut)
191 ThreadMgr *This = (ThreadMgr *)iface;
194 if (IsEqualIID(iid, &IID_IUnknown) || IsEqualIID(iid, &IID_ITfThreadMgr))
198 else if (IsEqualIID(iid, &IID_ITfSource))
200 *ppvOut = &This->SourceVtbl;
202 else if (IsEqualIID(iid, &IID_ITfKeystrokeMgr))
204 *ppvOut = &This->KeystrokeMgrVtbl;
206 else if (IsEqualIID(iid, &IID_ITfMessagePump))
208 *ppvOut = &This->MessagePumpVtbl;
210 else if (IsEqualIID(iid, &IID_ITfClientId))
212 *ppvOut = &This->ClientIdVtbl;
217 IUnknown_AddRef(iface);
221 WARN("unsupported interface: %s\n", debugstr_guid(iid));
222 return E_NOINTERFACE;
225 static ULONG WINAPI ThreadMgr_AddRef(ITfThreadMgr *iface)
227 ThreadMgr *This = (ThreadMgr *)iface;
228 return InterlockedIncrement(&This->refCount);
231 static ULONG WINAPI ThreadMgr_Release(ITfThreadMgr *iface)
233 ThreadMgr *This = (ThreadMgr *)iface;
236 ret = InterlockedDecrement(&This->refCount);
238 ThreadMgr_Destructor(This);
242 /*****************************************************
243 * ITfThreadMgr functions
244 *****************************************************/
246 static HRESULT WINAPI ThreadMgr_fnActivate( ITfThreadMgr* iface, TfClientId *ptid)
248 ThreadMgr *This = (ThreadMgr *)iface;
250 TRACE("(%p) %p\n",This, ptid);
259 ITfClientId_GetClientId((ITfClientId*)&This->ClientIdVtbl,&guid,&processId);
262 activate_textservices(iface);
263 This->activationCount++;
268 static HRESULT WINAPI ThreadMgr_fnDeactivate( ITfThreadMgr* iface)
270 ThreadMgr *This = (ThreadMgr *)iface;
271 TRACE("(%p)\n",This);
273 if (This->activationCount == 0)
276 This->activationCount --;
278 if (This->activationCount == 0)
282 ITfThreadMgrEventSink_OnSetFocus((ITfThreadMgrEventSink*)&This->ThreadMgrEventSinkVtbl, 0, This->focus);
283 ITfDocumentMgr_Release(This->focus);
288 deactivate_textservices();
293 static HRESULT WINAPI ThreadMgr_CreateDocumentMgr( ITfThreadMgr* iface, ITfDocumentMgr
296 ThreadMgr *This = (ThreadMgr *)iface;
297 TRACE("(%p)\n",iface);
298 return DocumentMgr_Constructor((ITfThreadMgrEventSink*)&This->ThreadMgrEventSinkVtbl, ppdim);
301 static HRESULT WINAPI ThreadMgr_EnumDocumentMgrs( ITfThreadMgr* iface, IEnumTfDocumentMgrs
304 ThreadMgr *This = (ThreadMgr *)iface;
305 FIXME("STUB:(%p)\n",This);
309 static HRESULT WINAPI ThreadMgr_GetFocus( ITfThreadMgr* iface, ITfDocumentMgr
312 ThreadMgr *This = (ThreadMgr *)iface;
313 TRACE("(%p)\n",This);
318 *ppdimFocus = This->focus;
320 TRACE("->%p\n",This->focus);
322 if (This->focus == NULL)
325 ITfDocumentMgr_AddRef(This->focus);
330 static HRESULT WINAPI ThreadMgr_SetFocus( ITfThreadMgr* iface, ITfDocumentMgr *pdimFocus)
332 ITfDocumentMgr *check;
333 ThreadMgr *This = (ThreadMgr *)iface;
335 TRACE("(%p) %p\n",This,pdimFocus);
337 if (!pdimFocus || FAILED(IUnknown_QueryInterface(pdimFocus,&IID_ITfDocumentMgr,(LPVOID*) &check)))
340 ITfThreadMgrEventSink_OnSetFocus((ITfThreadMgrEventSink*)&This->ThreadMgrEventSinkVtbl, check, This->focus);
343 ITfDocumentMgr_Release(This->focus);
349 static HRESULT WINAPI ThreadMgr_AssociateFocus( ITfThreadMgr* iface, HWND hwnd,
350 ITfDocumentMgr *pdimNew, ITfDocumentMgr **ppdimPrev)
352 ThreadMgr *This = (ThreadMgr *)iface;
353 FIXME("STUB:(%p)\n",This);
357 static HRESULT WINAPI ThreadMgr_IsThreadFocus( ITfThreadMgr* iface, BOOL *pfThreadFocus)
359 ThreadMgr *This = (ThreadMgr *)iface;
360 FIXME("STUB:(%p)\n",This);
364 static HRESULT WINAPI ThreadMgr_GetFunctionProvider( ITfThreadMgr* iface, REFCLSID clsid,
365 ITfFunctionProvider **ppFuncProv)
367 ThreadMgr *This = (ThreadMgr *)iface;
368 FIXME("STUB:(%p)\n",This);
372 static HRESULT WINAPI ThreadMgr_EnumFunctionProviders( ITfThreadMgr* iface,
373 IEnumTfFunctionProviders **ppEnum)
375 ThreadMgr *This = (ThreadMgr *)iface;
376 FIXME("STUB:(%p)\n",This);
380 static HRESULT WINAPI ThreadMgr_GetGlobalCompartment( ITfThreadMgr* iface,
381 ITfCompartmentMgr **ppCompMgr)
383 ThreadMgr *This = (ThreadMgr *)iface;
384 FIXME("STUB:(%p)\n",This);
388 static const ITfThreadMgrVtbl ThreadMgr_ThreadMgrVtbl =
390 ThreadMgr_QueryInterface,
394 ThreadMgr_fnActivate,
395 ThreadMgr_fnDeactivate,
396 ThreadMgr_CreateDocumentMgr,
397 ThreadMgr_EnumDocumentMgrs,
400 ThreadMgr_AssociateFocus,
401 ThreadMgr_IsThreadFocus,
402 ThreadMgr_GetFunctionProvider,
403 ThreadMgr_EnumFunctionProviders,
404 ThreadMgr_GetGlobalCompartment
408 static HRESULT WINAPI Source_QueryInterface(ITfSource *iface, REFIID iid, LPVOID *ppvOut)
410 ThreadMgr *This = impl_from_ITfSourceVtbl(iface);
411 return ThreadMgr_QueryInterface((ITfThreadMgr *)This, iid, *ppvOut);
414 static ULONG WINAPI Source_AddRef(ITfSource *iface)
416 ThreadMgr *This = impl_from_ITfSourceVtbl(iface);
417 return ThreadMgr_AddRef((ITfThreadMgr*)This);
420 static ULONG WINAPI Source_Release(ITfSource *iface)
422 ThreadMgr *This = impl_from_ITfSourceVtbl(iface);
423 return ThreadMgr_Release((ITfThreadMgr *)This);
426 /*****************************************************
427 * ITfSource functions
428 *****************************************************/
429 static WINAPI HRESULT ThreadMgrSource_AdviseSink(ITfSource *iface,
430 REFIID riid, IUnknown *punk, DWORD *pdwCookie)
433 ThreadMgr *This = impl_from_ITfSourceVtbl(iface);
435 TRACE("(%p) %s %p %p\n",This,debugstr_guid(riid),punk,pdwCookie);
437 if (!riid || !punk || !pdwCookie)
440 if (IsEqualIID(riid, &IID_ITfThreadMgrEventSink))
442 tms = HeapAlloc(GetProcessHeap(),0,sizeof(ThreadMgrSink));
444 return E_OUTOFMEMORY;
445 if (!SUCCEEDED(IUnknown_QueryInterface(punk, riid, (LPVOID*)&tms->interfaces.pITfThreadMgrEventSink)))
447 HeapFree(GetProcessHeap(),0,tms);
448 return CONNECT_E_CANNOTCONNECT;
450 list_add_head(&This->ThreadMgrEventSink,&tms->entry);
451 *pdwCookie = generate_Cookie(COOKIE_MAGIC_TMSINK, tms);
455 FIXME("(%p) Unhandled Sink: %s\n",This,debugstr_guid(riid));
459 TRACE("cookie %x\n",*pdwCookie);
464 static WINAPI HRESULT ThreadMgrSource_UnadviseSink(ITfSource *iface, DWORD pdwCookie)
467 ThreadMgr *This = impl_from_ITfSourceVtbl(iface);
469 TRACE("(%p) %x\n",This,pdwCookie);
471 if (get_Cookie_magic(pdwCookie)!=COOKIE_MAGIC_TMSINK)
474 sink = (ThreadMgrSink*)remove_Cookie(pdwCookie);
476 return CONNECT_E_NOCONNECTION;
478 list_remove(&sink->entry);
484 static const ITfSourceVtbl ThreadMgr_SourceVtbl =
486 Source_QueryInterface,
490 ThreadMgrSource_AdviseSink,
491 ThreadMgrSource_UnadviseSink,
494 /*****************************************************
495 * ITfKeystrokeMgr functions
496 *****************************************************/
498 static HRESULT WINAPI KeystrokeMgr_QueryInterface(ITfKeystrokeMgr *iface, REFIID iid, LPVOID *ppvOut)
500 ThreadMgr *This = impl_from_ITfKeystrokeMgrVtbl(iface);
501 return ThreadMgr_QueryInterface((ITfThreadMgr *)This, iid, *ppvOut);
504 static ULONG WINAPI KeystrokeMgr_AddRef(ITfKeystrokeMgr *iface)
506 ThreadMgr *This = impl_from_ITfKeystrokeMgrVtbl(iface);
507 return ThreadMgr_AddRef((ITfThreadMgr*)This);
510 static ULONG WINAPI KeystrokeMgr_Release(ITfKeystrokeMgr *iface)
512 ThreadMgr *This = impl_from_ITfKeystrokeMgrVtbl(iface);
513 return ThreadMgr_Release((ITfThreadMgr *)This);
516 static HRESULT WINAPI KeystrokeMgr_AdviseKeyEventSink(ITfKeystrokeMgr *iface,
517 TfClientId tid, ITfKeyEventSink *pSink, BOOL fForeground)
519 ThreadMgr *This = impl_from_ITfKeystrokeMgrVtbl(iface);
521 ITfKeyEventSink *check = NULL;
523 TRACE("(%p) %x %p %i\n",This,tid,pSink,fForeground);
528 textservice = get_textservice_clsid(tid);
529 if (IsEqualCLSID(&GUID_NULL,&textservice))
532 get_textservice_sink(tid, &IID_ITfKeyEventSink, (IUnknown**)&check);
534 return CONNECT_E_ADVISELIMIT;
536 if (FAILED(IUnknown_QueryInterface(pSink,&IID_ITfKeyEventSink,(LPVOID*) &check)))
539 set_textservice_sink(tid, &IID_ITfKeyEventSink, (IUnknown*)check);
543 if (This->forgroundKeyEventSink)
545 ITfKeyEventSink_OnSetFocus(This->forgroundKeyEventSink, FALSE);
546 ITfKeyEventSink_Release(This->forgroundKeyEventSink);
548 ITfKeyEventSink_AddRef(check);
549 ITfKeyEventSink_OnSetFocus(check, TRUE);
550 This->forgroundKeyEventSink = check;
551 This->forgroundTextService = textservice;
556 static HRESULT WINAPI KeystrokeMgr_UnadviseKeyEventSink(ITfKeystrokeMgr *iface,
559 ThreadMgr *This = impl_from_ITfKeystrokeMgrVtbl(iface);
561 ITfKeyEventSink *check = NULL;
562 TRACE("(%p) %x\n",This,tid);
567 textservice = get_textservice_clsid(tid);
568 if (IsEqualCLSID(&GUID_NULL,&textservice))
571 get_textservice_sink(tid, &IID_ITfKeyEventSink, (IUnknown**)&check);
574 return CONNECT_E_NOCONNECTION;
576 set_textservice_sink(tid, &IID_ITfKeyEventSink, NULL);
577 ITfKeyEventSink_Release(check);
579 if (This->forgroundKeyEventSink == check)
581 ITfKeyEventSink_Release(This->forgroundKeyEventSink);
582 This->forgroundKeyEventSink = NULL;
583 This->forgroundTextService = GUID_NULL;
588 static HRESULT WINAPI KeystrokeMgr_GetForeground(ITfKeystrokeMgr *iface,
591 ThreadMgr *This = impl_from_ITfKeystrokeMgrVtbl(iface);
592 TRACE("(%p) %p\n",This,pclsid);
596 if (IsEqualCLSID(&This->forgroundTextService,&GUID_NULL))
599 *pclsid = This->forgroundTextService;
603 static HRESULT WINAPI KeystrokeMgr_TestKeyDown(ITfKeystrokeMgr *iface,
604 WPARAM wParam, LPARAM lParam, BOOL *pfEaten)
606 ThreadMgr *This = impl_from_ITfKeystrokeMgrVtbl(iface);
607 FIXME("STUB:(%p)\n",This);
611 static HRESULT WINAPI KeystrokeMgr_TestKeyUp(ITfKeystrokeMgr *iface,
612 WPARAM wParam, LPARAM lParam, BOOL *pfEaten)
614 ThreadMgr *This = impl_from_ITfKeystrokeMgrVtbl(iface);
615 FIXME("STUB:(%p)\n",This);
619 static HRESULT WINAPI KeystrokeMgr_KeyDown(ITfKeystrokeMgr *iface,
620 WPARAM wParam, LPARAM lParam, BOOL *pfEaten)
622 ThreadMgr *This = impl_from_ITfKeystrokeMgrVtbl(iface);
623 FIXME("STUB:(%p)\n",This);
627 static HRESULT WINAPI KeystrokeMgr_KeyUp(ITfKeystrokeMgr *iface,
628 WPARAM wParam, LPARAM lParam, BOOL *pfEaten)
630 ThreadMgr *This = impl_from_ITfKeystrokeMgrVtbl(iface);
631 FIXME("STUB:(%p)\n",This);
635 static HRESULT WINAPI KeystrokeMgr_GetPreservedKey(ITfKeystrokeMgr *iface,
636 ITfContext *pic, const TF_PRESERVEDKEY *pprekey, GUID *pguid)
638 ThreadMgr *This = impl_from_ITfKeystrokeMgrVtbl(iface);
639 FIXME("STUB:(%p)\n",This);
643 static HRESULT WINAPI KeystrokeMgr_IsPreservedKey(ITfKeystrokeMgr *iface,
644 REFGUID rguid, const TF_PRESERVEDKEY *pprekey, BOOL *pfRegistered)
646 ThreadMgr *This = impl_from_ITfKeystrokeMgrVtbl(iface);
649 TRACE("(%p) %s (%x %x) %p\n",This,debugstr_guid(rguid), (pprekey)?pprekey->uVKey:0, (pprekey)?pprekey->uModifiers:0, pfRegistered);
651 if (!rguid || !pprekey || !pfRegistered)
654 LIST_FOR_EACH(cursor, &This->CurrentPreservedKeys)
656 PreservedKey* key = LIST_ENTRY(cursor,PreservedKey,entry);
657 if (IsEqualGUID(rguid,&key->guid) && pprekey->uVKey == key->prekey.uVKey && pprekey->uModifiers == key->prekey.uModifiers)
659 *pfRegistered = TRUE;
664 *pfRegistered = FALSE;
668 static HRESULT WINAPI KeystrokeMgr_PreserveKey(ITfKeystrokeMgr *iface,
669 TfClientId tid, REFGUID rguid, const TF_PRESERVEDKEY *prekey,
670 const WCHAR *pchDesc, ULONG cchDesc)
672 ThreadMgr *This = impl_from_ITfKeystrokeMgrVtbl(iface);
674 PreservedKey *newkey;
676 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));
678 if (!tid || ! rguid || !prekey || (cchDesc && !pchDesc))
681 LIST_FOR_EACH(cursor, &This->CurrentPreservedKeys)
683 PreservedKey* key = LIST_ENTRY(cursor,PreservedKey,entry);
684 if (IsEqualGUID(rguid,&key->guid) && prekey->uVKey == key->prekey.uVKey && prekey->uModifiers == key->prekey.uModifiers)
685 return TF_E_ALREADY_EXISTS;
688 newkey = HeapAlloc(GetProcessHeap(),0,sizeof(PreservedKey));
690 return E_OUTOFMEMORY;
692 newkey->guid = *rguid;
693 newkey->prekey = *prekey;
697 newkey->description = HeapAlloc(GetProcessHeap(),0,cchDesc * sizeof(WCHAR));
698 if (!newkey->description)
700 HeapFree(GetProcessHeap(),0,newkey);
701 return E_OUTOFMEMORY;
703 memcpy(newkey->description, pchDesc, cchDesc*sizeof(WCHAR));
706 list_add_head(&This->CurrentPreservedKeys,&newkey->entry);
711 static HRESULT WINAPI KeystrokeMgr_UnpreserveKey(ITfKeystrokeMgr *iface,
712 REFGUID rguid, const TF_PRESERVEDKEY *pprekey)
714 ThreadMgr *This = impl_from_ITfKeystrokeMgrVtbl(iface);
715 PreservedKey* key = NULL;
717 TRACE("(%p) %s (%x %x)\n",This,debugstr_guid(rguid),(pprekey)?pprekey->uVKey:0, (pprekey)?pprekey->uModifiers:0);
719 if (!pprekey || !rguid)
722 LIST_FOR_EACH(cursor, &This->CurrentPreservedKeys)
724 key = LIST_ENTRY(cursor,PreservedKey,entry);
725 if (IsEqualGUID(rguid,&key->guid) && pprekey->uVKey == key->prekey.uVKey && pprekey->uModifiers == key->prekey.uModifiers)
731 return CONNECT_E_NOCONNECTION;
733 list_remove(&key->entry);
734 HeapFree(GetProcessHeap(),0,key->description);
735 HeapFree(GetProcessHeap(),0,key);
740 static HRESULT WINAPI KeystrokeMgr_SetPreservedKeyDescription(ITfKeystrokeMgr *iface,
741 REFGUID rguid, const WCHAR *pchDesc, ULONG cchDesc)
743 ThreadMgr *This = impl_from_ITfKeystrokeMgrVtbl(iface);
744 FIXME("STUB:(%p)\n",This);
748 static HRESULT WINAPI KeystrokeMgr_GetPreservedKeyDescription(ITfKeystrokeMgr *iface,
749 REFGUID rguid, BSTR *pbstrDesc)
751 ThreadMgr *This = impl_from_ITfKeystrokeMgrVtbl(iface);
752 FIXME("STUB:(%p)\n",This);
756 static HRESULT WINAPI KeystrokeMgr_SimulatePreservedKey(ITfKeystrokeMgr *iface,
757 ITfContext *pic, REFGUID rguid, BOOL *pfEaten)
759 ThreadMgr *This = impl_from_ITfKeystrokeMgrVtbl(iface);
760 FIXME("STUB:(%p)\n",This);
764 static const ITfKeystrokeMgrVtbl ThreadMgr_KeystrokeMgrVtbl =
766 KeystrokeMgr_QueryInterface,
768 KeystrokeMgr_Release,
770 KeystrokeMgr_AdviseKeyEventSink,
771 KeystrokeMgr_UnadviseKeyEventSink,
772 KeystrokeMgr_GetForeground,
773 KeystrokeMgr_TestKeyDown,
774 KeystrokeMgr_TestKeyUp,
775 KeystrokeMgr_KeyDown,
777 KeystrokeMgr_GetPreservedKey,
778 KeystrokeMgr_IsPreservedKey,
779 KeystrokeMgr_PreserveKey,
780 KeystrokeMgr_UnpreserveKey,
781 KeystrokeMgr_SetPreservedKeyDescription,
782 KeystrokeMgr_GetPreservedKeyDescription,
783 KeystrokeMgr_SimulatePreservedKey
786 /*****************************************************
787 * ITfMessagePump functions
788 *****************************************************/
790 static HRESULT WINAPI MessagePump_QueryInterface(ITfMessagePump *iface, REFIID iid, LPVOID *ppvOut)
792 ThreadMgr *This = impl_from_ITfMessagePumpVtbl(iface);
793 return ThreadMgr_QueryInterface((ITfThreadMgr *)This, iid, *ppvOut);
796 static ULONG WINAPI MessagePump_AddRef(ITfMessagePump *iface)
798 ThreadMgr *This = impl_from_ITfMessagePumpVtbl(iface);
799 return ThreadMgr_AddRef((ITfThreadMgr*)This);
802 static ULONG WINAPI MessagePump_Release(ITfMessagePump *iface)
804 ThreadMgr *This = impl_from_ITfMessagePumpVtbl(iface);
805 return ThreadMgr_Release((ITfThreadMgr *)This);
808 static HRESULT WINAPI MessagePump_PeekMessageA(ITfMessagePump *iface,
809 LPMSG pMsg, HWND hwnd, UINT wMsgFilterMin, UINT wMsgFilterMax,
810 UINT wRemoveMsg, BOOL *pfResult)
814 *pfResult = PeekMessageA(pMsg, hwnd, wMsgFilterMin, wMsgFilterMax, wRemoveMsg);
818 static HRESULT WINAPI MessagePump_GetMessageA(ITfMessagePump *iface,
819 LPMSG pMsg, HWND hwnd, UINT wMsgFilterMin, UINT wMsgFilterMax,
824 *pfResult = GetMessageA(pMsg, hwnd, wMsgFilterMin, wMsgFilterMax);
828 static HRESULT WINAPI MessagePump_PeekMessageW(ITfMessagePump *iface,
829 LPMSG pMsg, HWND hwnd, UINT wMsgFilterMin, UINT wMsgFilterMax,
830 UINT wRemoveMsg, BOOL *pfResult)
834 *pfResult = PeekMessageW(pMsg, hwnd, wMsgFilterMin, wMsgFilterMax, wRemoveMsg);
838 static HRESULT WINAPI MessagePump_GetMessageW(ITfMessagePump *iface,
839 LPMSG pMsg, HWND hwnd, UINT wMsgFilterMin, UINT wMsgFilterMax,
844 *pfResult = GetMessageW(pMsg, hwnd, wMsgFilterMin, wMsgFilterMax);
848 static const ITfMessagePumpVtbl ThreadMgr_MessagePumpVtbl =
850 MessagePump_QueryInterface,
854 MessagePump_PeekMessageA,
855 MessagePump_GetMessageA,
856 MessagePump_PeekMessageW,
857 MessagePump_GetMessageW
860 /*****************************************************
861 * ITfClientId functions
862 *****************************************************/
864 static HRESULT WINAPI ClientId_QueryInterface(ITfClientId *iface, REFIID iid, LPVOID *ppvOut)
866 ThreadMgr *This = impl_from_ITfClientIdVtbl(iface);
867 return ThreadMgr_QueryInterface((ITfThreadMgr *)This, iid, *ppvOut);
870 static ULONG WINAPI ClientId_AddRef(ITfClientId *iface)
872 ThreadMgr *This = impl_from_ITfClientIdVtbl(iface);
873 return ThreadMgr_AddRef((ITfThreadMgr*)This);
876 static ULONG WINAPI ClientId_Release(ITfClientId *iface)
878 ThreadMgr *This = impl_from_ITfClientIdVtbl(iface);
879 return ThreadMgr_Release((ITfThreadMgr *)This);
882 static HRESULT WINAPI ClientId_GetClientId(ITfClientId *iface,
883 REFCLSID rclsid, TfClientId *ptid)
887 ITfCategoryMgr *catmgr;
888 ThreadMgr *This = impl_from_ITfClientIdVtbl(iface);
890 TRACE("(%p) %s\n",This,debugstr_guid(rclsid));
892 CategoryMgr_Constructor(NULL,(IUnknown**)&catmgr);
893 hr = ITfCategoryMgr_RegisterGUID(catmgr,rclsid,ptid);
894 ITfCategoryMgr_Release(catmgr);
899 static const ITfClientIdVtbl ThreadMgr_ClientIdVtbl =
901 ClientId_QueryInterface,
908 /*****************************************************
909 * ITfThreadMgrEventSink functions (internal)
910 *****************************************************/
911 static HRESULT WINAPI ThreadMgrEventSink_QueryInterface(ITfThreadMgrEventSink *iface, REFIID iid, LPVOID *ppvOut)
913 ThreadMgr *This = impl_from_ITfThreadMgrEventSink(iface);
914 return ThreadMgr_QueryInterface((ITfThreadMgr *)This, iid, *ppvOut);
917 static ULONG WINAPI ThreadMgrEventSink_AddRef(ITfThreadMgrEventSink *iface)
919 ThreadMgr *This = impl_from_ITfThreadMgrEventSink(iface);
920 return ThreadMgr_AddRef((ITfThreadMgr*)This);
923 static ULONG WINAPI ThreadMgrEventSink_Release(ITfThreadMgrEventSink *iface)
925 ThreadMgr *This = impl_from_ITfThreadMgrEventSink(iface);
926 return ThreadMgr_Release((ITfThreadMgr *)This);
930 static WINAPI HRESULT ThreadMgrEventSink_OnInitDocumentMgr(
931 ITfThreadMgrEventSink *iface,ITfDocumentMgr *pdim)
934 ThreadMgr *This = impl_from_ITfThreadMgrEventSink(iface);
936 TRACE("(%p) %p\n",This,pdim);
938 LIST_FOR_EACH(cursor, &This->ThreadMgrEventSink)
940 ThreadMgrSink* sink = LIST_ENTRY(cursor,ThreadMgrSink,entry);
941 ITfThreadMgrEventSink_OnInitDocumentMgr(sink->interfaces.pITfThreadMgrEventSink,pdim);
947 static WINAPI HRESULT ThreadMgrEventSink_OnUninitDocumentMgr(
948 ITfThreadMgrEventSink *iface, ITfDocumentMgr *pdim)
951 ThreadMgr *This = impl_from_ITfThreadMgrEventSink(iface);
953 TRACE("(%p) %p\n",This,pdim);
955 LIST_FOR_EACH(cursor, &This->ThreadMgrEventSink)
957 ThreadMgrSink* sink = LIST_ENTRY(cursor,ThreadMgrSink,entry);
958 ITfThreadMgrEventSink_OnUninitDocumentMgr(sink->interfaces.pITfThreadMgrEventSink,pdim);
964 static WINAPI HRESULT ThreadMgrEventSink_OnSetFocus(
965 ITfThreadMgrEventSink *iface, ITfDocumentMgr *pdimFocus,
966 ITfDocumentMgr *pdimPrevFocus)
969 ThreadMgr *This = impl_from_ITfThreadMgrEventSink(iface);
971 TRACE("(%p) %p %p\n",This,pdimFocus, pdimPrevFocus);
973 LIST_FOR_EACH(cursor, &This->ThreadMgrEventSink)
975 ThreadMgrSink* sink = LIST_ENTRY(cursor,ThreadMgrSink,entry);
976 ITfThreadMgrEventSink_OnSetFocus(sink->interfaces.pITfThreadMgrEventSink, pdimFocus, pdimPrevFocus);
982 static WINAPI HRESULT ThreadMgrEventSink_OnPushContext(
983 ITfThreadMgrEventSink *iface, ITfContext *pic)
986 ThreadMgr *This = impl_from_ITfThreadMgrEventSink(iface);
988 TRACE("(%p) %p\n",This,pic);
990 LIST_FOR_EACH(cursor, &This->ThreadMgrEventSink)
992 ThreadMgrSink* sink = LIST_ENTRY(cursor,ThreadMgrSink,entry);
993 ITfThreadMgrEventSink_OnPushContext(sink->interfaces.pITfThreadMgrEventSink,pic);
999 static WINAPI HRESULT ThreadMgrEventSink_OnPopContext(
1000 ITfThreadMgrEventSink *iface, ITfContext *pic)
1002 struct list *cursor;
1003 ThreadMgr *This = impl_from_ITfThreadMgrEventSink(iface);
1005 TRACE("(%p) %p\n",This,pic);
1007 LIST_FOR_EACH(cursor, &This->ThreadMgrEventSink)
1009 ThreadMgrSink* sink = LIST_ENTRY(cursor,ThreadMgrSink,entry);
1010 ITfThreadMgrEventSink_OnPopContext(sink->interfaces.pITfThreadMgrEventSink,pic);
1016 static const ITfThreadMgrEventSinkVtbl ThreadMgr_ThreadMgrEventSinkVtbl =
1018 ThreadMgrEventSink_QueryInterface,
1019 ThreadMgrEventSink_AddRef,
1020 ThreadMgrEventSink_Release,
1022 ThreadMgrEventSink_OnInitDocumentMgr,
1023 ThreadMgrEventSink_OnUninitDocumentMgr,
1024 ThreadMgrEventSink_OnSetFocus,
1025 ThreadMgrEventSink_OnPushContext,
1026 ThreadMgrEventSink_OnPopContext
1029 HRESULT ThreadMgr_Constructor(IUnknown *pUnkOuter, IUnknown **ppOut)
1033 return CLASS_E_NOAGGREGATION;
1035 /* Only 1 ThreadMgr is created per thread */
1036 This = TlsGetValue(tlsIndex);
1039 ThreadMgr_AddRef((ITfThreadMgr*)This);
1040 *ppOut = (IUnknown*)This;
1044 This = HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,sizeof(ThreadMgr));
1046 return E_OUTOFMEMORY;
1048 This->ThreadMgrVtbl= &ThreadMgr_ThreadMgrVtbl;
1049 This->SourceVtbl = &ThreadMgr_SourceVtbl;
1050 This->KeystrokeMgrVtbl= &ThreadMgr_KeystrokeMgrVtbl;
1051 This->MessagePumpVtbl= &ThreadMgr_MessagePumpVtbl;
1052 This->ClientIdVtbl = &ThreadMgr_ClientIdVtbl;
1053 This->ThreadMgrEventSinkVtbl = &ThreadMgr_ThreadMgrEventSinkVtbl;
1055 TlsSetValue(tlsIndex,This);
1057 list_init(&This->CurrentPreservedKeys);
1059 list_init(&This->ActiveLanguageProfileNotifySink);
1060 list_init(&This->DisplayAttributeNotifySink);
1061 list_init(&This->KeyTraceEventSink);
1062 list_init(&This->PreservedKeyNotifySink);
1063 list_init(&This->ThreadFocusSink);
1064 list_init(&This->ThreadMgrEventSink);
1066 TRACE("returning %p\n", This);
1067 *ppOut = (IUnknown *)This;