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; */
82 ITfCompartmentMgr *CompartmentMgr;
84 const ITfThreadMgrEventSinkVtbl *ThreadMgrEventSinkVtbl; /* internal */
86 ITfDocumentMgr *focus;
89 ITfKeyEventSink *forgroundKeyEventSink;
90 CLSID forgroundTextService;
92 struct list CurrentPreservedKeys;
94 /* kept as separate lists to reduce unnecessary iterations */
95 struct list ActiveLanguageProfileNotifySink;
96 struct list DisplayAttributeNotifySink;
97 struct list KeyTraceEventSink;
98 struct list PreservedKeyNotifySink;
99 struct list ThreadFocusSink;
100 struct list ThreadMgrEventSink;
103 static inline ThreadMgr *impl_from_ITfSourceVtbl(ITfSource *iface)
105 return (ThreadMgr *)((char *)iface - FIELD_OFFSET(ThreadMgr,SourceVtbl));
108 static inline ThreadMgr *impl_from_ITfKeystrokeMgrVtbl(ITfKeystrokeMgr *iface)
110 return (ThreadMgr *)((char *)iface - FIELD_OFFSET(ThreadMgr,KeystrokeMgrVtbl));
113 static inline ThreadMgr *impl_from_ITfMessagePumpVtbl(ITfMessagePump *iface)
115 return (ThreadMgr *)((char *)iface - FIELD_OFFSET(ThreadMgr,MessagePumpVtbl));
118 static inline ThreadMgr *impl_from_ITfClientIdVtbl(ITfClientId *iface)
120 return (ThreadMgr *)((char *)iface - FIELD_OFFSET(ThreadMgr,ClientIdVtbl));
123 static inline ThreadMgr *impl_from_ITfThreadMgrEventSink(ITfThreadMgrEventSink *iface)
125 return (ThreadMgr *)((char *)iface - FIELD_OFFSET(ThreadMgr,ThreadMgrEventSinkVtbl));
128 static void free_sink(ThreadMgrSink *sink)
130 IUnknown_Release(sink->interfaces.pIUnknown);
131 HeapFree(GetProcessHeap(),0,sink);
134 static void ThreadMgr_Destructor(ThreadMgr *This)
136 struct list *cursor, *cursor2;
138 TlsSetValue(tlsIndex,NULL);
139 TRACE("destroying %p\n", This);
141 ITfDocumentMgr_Release(This->focus);
144 LIST_FOR_EACH_SAFE(cursor, cursor2, &This->ActiveLanguageProfileNotifySink)
146 ThreadMgrSink* sink = LIST_ENTRY(cursor,ThreadMgrSink,entry);
150 LIST_FOR_EACH_SAFE(cursor, cursor2, &This->DisplayAttributeNotifySink)
152 ThreadMgrSink* sink = LIST_ENTRY(cursor,ThreadMgrSink,entry);
156 LIST_FOR_EACH_SAFE(cursor, cursor2, &This->KeyTraceEventSink)
158 ThreadMgrSink* sink = LIST_ENTRY(cursor,ThreadMgrSink,entry);
162 LIST_FOR_EACH_SAFE(cursor, cursor2, &This->PreservedKeyNotifySink)
164 ThreadMgrSink* sink = LIST_ENTRY(cursor,ThreadMgrSink,entry);
168 LIST_FOR_EACH_SAFE(cursor, cursor2, &This->ThreadFocusSink)
170 ThreadMgrSink* sink = LIST_ENTRY(cursor,ThreadMgrSink,entry);
174 LIST_FOR_EACH_SAFE(cursor, cursor2, &This->ThreadMgrEventSink)
176 ThreadMgrSink* sink = LIST_ENTRY(cursor,ThreadMgrSink,entry);
181 LIST_FOR_EACH_SAFE(cursor, cursor2, &This->CurrentPreservedKeys)
183 PreservedKey* key = LIST_ENTRY(cursor,PreservedKey,entry);
185 HeapFree(GetProcessHeap(),0,key->description);
186 HeapFree(GetProcessHeap(),0,key);
189 CompartmentMgr_Destructor(This->CompartmentMgr);
191 HeapFree(GetProcessHeap(),0,This);
194 static HRESULT WINAPI ThreadMgr_QueryInterface(ITfThreadMgr *iface, REFIID iid, LPVOID *ppvOut)
196 ThreadMgr *This = (ThreadMgr *)iface;
199 if (IsEqualIID(iid, &IID_IUnknown) || IsEqualIID(iid, &IID_ITfThreadMgr))
203 else if (IsEqualIID(iid, &IID_ITfSource))
205 *ppvOut = &This->SourceVtbl;
207 else if (IsEqualIID(iid, &IID_ITfKeystrokeMgr))
209 *ppvOut = &This->KeystrokeMgrVtbl;
211 else if (IsEqualIID(iid, &IID_ITfMessagePump))
213 *ppvOut = &This->MessagePumpVtbl;
215 else if (IsEqualIID(iid, &IID_ITfClientId))
217 *ppvOut = &This->ClientIdVtbl;
219 else if (IsEqualIID(iid, &IID_ITfCompartmentMgr))
221 *ppvOut = This->CompartmentMgr;
226 IUnknown_AddRef(iface);
230 WARN("unsupported interface: %s\n", debugstr_guid(iid));
231 return E_NOINTERFACE;
234 static ULONG WINAPI ThreadMgr_AddRef(ITfThreadMgr *iface)
236 ThreadMgr *This = (ThreadMgr *)iface;
237 return InterlockedIncrement(&This->refCount);
240 static ULONG WINAPI ThreadMgr_Release(ITfThreadMgr *iface)
242 ThreadMgr *This = (ThreadMgr *)iface;
245 ret = InterlockedDecrement(&This->refCount);
247 ThreadMgr_Destructor(This);
251 /*****************************************************
252 * ITfThreadMgr functions
253 *****************************************************/
255 static HRESULT WINAPI ThreadMgr_fnActivate( ITfThreadMgr* iface, TfClientId *ptid)
257 ThreadMgr *This = (ThreadMgr *)iface;
259 TRACE("(%p) %p\n",This, ptid);
268 ITfClientId_GetClientId((ITfClientId*)&This->ClientIdVtbl,&guid,&processId);
271 activate_textservices(iface);
272 This->activationCount++;
277 static HRESULT WINAPI ThreadMgr_fnDeactivate( ITfThreadMgr* iface)
279 ThreadMgr *This = (ThreadMgr *)iface;
280 TRACE("(%p)\n",This);
282 if (This->activationCount == 0)
285 This->activationCount --;
287 if (This->activationCount == 0)
291 ITfThreadMgrEventSink_OnSetFocus((ITfThreadMgrEventSink*)&This->ThreadMgrEventSinkVtbl, 0, This->focus);
292 ITfDocumentMgr_Release(This->focus);
297 deactivate_textservices();
302 static HRESULT WINAPI ThreadMgr_CreateDocumentMgr( ITfThreadMgr* iface, ITfDocumentMgr
305 ThreadMgr *This = (ThreadMgr *)iface;
306 TRACE("(%p)\n",iface);
307 return DocumentMgr_Constructor((ITfThreadMgrEventSink*)&This->ThreadMgrEventSinkVtbl, ppdim);
310 static HRESULT WINAPI ThreadMgr_EnumDocumentMgrs( ITfThreadMgr* iface, IEnumTfDocumentMgrs
313 ThreadMgr *This = (ThreadMgr *)iface;
314 FIXME("STUB:(%p)\n",This);
318 static HRESULT WINAPI ThreadMgr_GetFocus( ITfThreadMgr* iface, ITfDocumentMgr
321 ThreadMgr *This = (ThreadMgr *)iface;
322 TRACE("(%p)\n",This);
327 *ppdimFocus = This->focus;
329 TRACE("->%p\n",This->focus);
331 if (This->focus == NULL)
334 ITfDocumentMgr_AddRef(This->focus);
339 static HRESULT WINAPI ThreadMgr_SetFocus( ITfThreadMgr* iface, ITfDocumentMgr *pdimFocus)
341 ITfDocumentMgr *check;
342 ThreadMgr *This = (ThreadMgr *)iface;
344 TRACE("(%p) %p\n",This,pdimFocus);
346 if (!pdimFocus || FAILED(IUnknown_QueryInterface(pdimFocus,&IID_ITfDocumentMgr,(LPVOID*) &check)))
349 ITfThreadMgrEventSink_OnSetFocus((ITfThreadMgrEventSink*)&This->ThreadMgrEventSinkVtbl, check, This->focus);
352 ITfDocumentMgr_Release(This->focus);
358 static HRESULT WINAPI ThreadMgr_AssociateFocus( ITfThreadMgr* iface, HWND hwnd,
359 ITfDocumentMgr *pdimNew, ITfDocumentMgr **ppdimPrev)
361 ThreadMgr *This = (ThreadMgr *)iface;
362 FIXME("STUB:(%p)\n",This);
366 static HRESULT WINAPI ThreadMgr_IsThreadFocus( ITfThreadMgr* iface, BOOL *pfThreadFocus)
368 ThreadMgr *This = (ThreadMgr *)iface;
369 FIXME("STUB:(%p)\n",This);
373 static HRESULT WINAPI ThreadMgr_GetFunctionProvider( ITfThreadMgr* iface, REFCLSID clsid,
374 ITfFunctionProvider **ppFuncProv)
376 ThreadMgr *This = (ThreadMgr *)iface;
377 FIXME("STUB:(%p)\n",This);
381 static HRESULT WINAPI ThreadMgr_EnumFunctionProviders( ITfThreadMgr* iface,
382 IEnumTfFunctionProviders **ppEnum)
384 ThreadMgr *This = (ThreadMgr *)iface;
385 FIXME("STUB:(%p)\n",This);
389 static HRESULT WINAPI ThreadMgr_GetGlobalCompartment( ITfThreadMgr* iface,
390 ITfCompartmentMgr **ppCompMgr)
392 ThreadMgr *This = (ThreadMgr *)iface;
394 TRACE("(%p) %p\n",This, ppCompMgr);
399 if (!globalCompartmentMgr)
401 hr = CompartmentMgr_Constructor(NULL,&IID_ITfCompartmentMgr,(IUnknown**)&globalCompartmentMgr);
406 ITfCompartmentMgr_AddRef(globalCompartmentMgr);
407 *ppCompMgr = globalCompartmentMgr;
411 static const ITfThreadMgrVtbl ThreadMgr_ThreadMgrVtbl =
413 ThreadMgr_QueryInterface,
417 ThreadMgr_fnActivate,
418 ThreadMgr_fnDeactivate,
419 ThreadMgr_CreateDocumentMgr,
420 ThreadMgr_EnumDocumentMgrs,
423 ThreadMgr_AssociateFocus,
424 ThreadMgr_IsThreadFocus,
425 ThreadMgr_GetFunctionProvider,
426 ThreadMgr_EnumFunctionProviders,
427 ThreadMgr_GetGlobalCompartment
431 static HRESULT WINAPI Source_QueryInterface(ITfSource *iface, REFIID iid, LPVOID *ppvOut)
433 ThreadMgr *This = impl_from_ITfSourceVtbl(iface);
434 return ThreadMgr_QueryInterface((ITfThreadMgr *)This, iid, *ppvOut);
437 static ULONG WINAPI Source_AddRef(ITfSource *iface)
439 ThreadMgr *This = impl_from_ITfSourceVtbl(iface);
440 return ThreadMgr_AddRef((ITfThreadMgr*)This);
443 static ULONG WINAPI Source_Release(ITfSource *iface)
445 ThreadMgr *This = impl_from_ITfSourceVtbl(iface);
446 return ThreadMgr_Release((ITfThreadMgr *)This);
449 /*****************************************************
450 * ITfSource functions
451 *****************************************************/
452 static WINAPI HRESULT ThreadMgrSource_AdviseSink(ITfSource *iface,
453 REFIID riid, IUnknown *punk, DWORD *pdwCookie)
456 ThreadMgr *This = impl_from_ITfSourceVtbl(iface);
458 TRACE("(%p) %s %p %p\n",This,debugstr_guid(riid),punk,pdwCookie);
460 if (!riid || !punk || !pdwCookie)
463 if (IsEqualIID(riid, &IID_ITfThreadMgrEventSink))
465 tms = HeapAlloc(GetProcessHeap(),0,sizeof(ThreadMgrSink));
467 return E_OUTOFMEMORY;
468 if (FAILED(IUnknown_QueryInterface(punk, riid, (LPVOID *)&tms->interfaces.pITfThreadMgrEventSink)))
470 HeapFree(GetProcessHeap(),0,tms);
471 return CONNECT_E_CANNOTCONNECT;
473 list_add_head(&This->ThreadMgrEventSink,&tms->entry);
474 *pdwCookie = generate_Cookie(COOKIE_MAGIC_TMSINK, tms);
478 FIXME("(%p) Unhandled Sink: %s\n",This,debugstr_guid(riid));
482 TRACE("cookie %x\n",*pdwCookie);
487 static WINAPI HRESULT ThreadMgrSource_UnadviseSink(ITfSource *iface, DWORD pdwCookie)
490 ThreadMgr *This = impl_from_ITfSourceVtbl(iface);
492 TRACE("(%p) %x\n",This,pdwCookie);
494 if (get_Cookie_magic(pdwCookie)!=COOKIE_MAGIC_TMSINK)
497 sink = (ThreadMgrSink*)remove_Cookie(pdwCookie);
499 return CONNECT_E_NOCONNECTION;
501 list_remove(&sink->entry);
507 static const ITfSourceVtbl ThreadMgr_SourceVtbl =
509 Source_QueryInterface,
513 ThreadMgrSource_AdviseSink,
514 ThreadMgrSource_UnadviseSink,
517 /*****************************************************
518 * ITfKeystrokeMgr functions
519 *****************************************************/
521 static HRESULT WINAPI KeystrokeMgr_QueryInterface(ITfKeystrokeMgr *iface, REFIID iid, LPVOID *ppvOut)
523 ThreadMgr *This = impl_from_ITfKeystrokeMgrVtbl(iface);
524 return ThreadMgr_QueryInterface((ITfThreadMgr *)This, iid, *ppvOut);
527 static ULONG WINAPI KeystrokeMgr_AddRef(ITfKeystrokeMgr *iface)
529 ThreadMgr *This = impl_from_ITfKeystrokeMgrVtbl(iface);
530 return ThreadMgr_AddRef((ITfThreadMgr*)This);
533 static ULONG WINAPI KeystrokeMgr_Release(ITfKeystrokeMgr *iface)
535 ThreadMgr *This = impl_from_ITfKeystrokeMgrVtbl(iface);
536 return ThreadMgr_Release((ITfThreadMgr *)This);
539 static HRESULT WINAPI KeystrokeMgr_AdviseKeyEventSink(ITfKeystrokeMgr *iface,
540 TfClientId tid, ITfKeyEventSink *pSink, BOOL fForeground)
542 ThreadMgr *This = impl_from_ITfKeystrokeMgrVtbl(iface);
544 ITfKeyEventSink *check = NULL;
546 TRACE("(%p) %x %p %i\n",This,tid,pSink,fForeground);
551 textservice = get_textservice_clsid(tid);
552 if (IsEqualCLSID(&GUID_NULL,&textservice))
555 get_textservice_sink(tid, &IID_ITfKeyEventSink, (IUnknown**)&check);
557 return CONNECT_E_ADVISELIMIT;
559 if (FAILED(IUnknown_QueryInterface(pSink,&IID_ITfKeyEventSink,(LPVOID*) &check)))
562 set_textservice_sink(tid, &IID_ITfKeyEventSink, (IUnknown*)check);
566 if (This->forgroundKeyEventSink)
568 ITfKeyEventSink_OnSetFocus(This->forgroundKeyEventSink, FALSE);
569 ITfKeyEventSink_Release(This->forgroundKeyEventSink);
571 ITfKeyEventSink_AddRef(check);
572 ITfKeyEventSink_OnSetFocus(check, TRUE);
573 This->forgroundKeyEventSink = check;
574 This->forgroundTextService = textservice;
579 static HRESULT WINAPI KeystrokeMgr_UnadviseKeyEventSink(ITfKeystrokeMgr *iface,
582 ThreadMgr *This = impl_from_ITfKeystrokeMgrVtbl(iface);
584 ITfKeyEventSink *check = NULL;
585 TRACE("(%p) %x\n",This,tid);
590 textservice = get_textservice_clsid(tid);
591 if (IsEqualCLSID(&GUID_NULL,&textservice))
594 get_textservice_sink(tid, &IID_ITfKeyEventSink, (IUnknown**)&check);
597 return CONNECT_E_NOCONNECTION;
599 set_textservice_sink(tid, &IID_ITfKeyEventSink, NULL);
600 ITfKeyEventSink_Release(check);
602 if (This->forgroundKeyEventSink == check)
604 ITfKeyEventSink_Release(This->forgroundKeyEventSink);
605 This->forgroundKeyEventSink = NULL;
606 This->forgroundTextService = GUID_NULL;
611 static HRESULT WINAPI KeystrokeMgr_GetForeground(ITfKeystrokeMgr *iface,
614 ThreadMgr *This = impl_from_ITfKeystrokeMgrVtbl(iface);
615 TRACE("(%p) %p\n",This,pclsid);
619 if (IsEqualCLSID(&This->forgroundTextService,&GUID_NULL))
622 *pclsid = This->forgroundTextService;
626 static HRESULT WINAPI KeystrokeMgr_TestKeyDown(ITfKeystrokeMgr *iface,
627 WPARAM wParam, LPARAM lParam, BOOL *pfEaten)
629 ThreadMgr *This = impl_from_ITfKeystrokeMgrVtbl(iface);
630 FIXME("STUB:(%p)\n",This);
634 static HRESULT WINAPI KeystrokeMgr_TestKeyUp(ITfKeystrokeMgr *iface,
635 WPARAM wParam, LPARAM lParam, BOOL *pfEaten)
637 ThreadMgr *This = impl_from_ITfKeystrokeMgrVtbl(iface);
638 FIXME("STUB:(%p)\n",This);
642 static HRESULT WINAPI KeystrokeMgr_KeyDown(ITfKeystrokeMgr *iface,
643 WPARAM wParam, LPARAM lParam, BOOL *pfEaten)
645 ThreadMgr *This = impl_from_ITfKeystrokeMgrVtbl(iface);
646 FIXME("STUB:(%p)\n",This);
650 static HRESULT WINAPI KeystrokeMgr_KeyUp(ITfKeystrokeMgr *iface,
651 WPARAM wParam, LPARAM lParam, BOOL *pfEaten)
653 ThreadMgr *This = impl_from_ITfKeystrokeMgrVtbl(iface);
654 FIXME("STUB:(%p)\n",This);
658 static HRESULT WINAPI KeystrokeMgr_GetPreservedKey(ITfKeystrokeMgr *iface,
659 ITfContext *pic, const TF_PRESERVEDKEY *pprekey, GUID *pguid)
661 ThreadMgr *This = impl_from_ITfKeystrokeMgrVtbl(iface);
662 FIXME("STUB:(%p)\n",This);
666 static HRESULT WINAPI KeystrokeMgr_IsPreservedKey(ITfKeystrokeMgr *iface,
667 REFGUID rguid, const TF_PRESERVEDKEY *pprekey, BOOL *pfRegistered)
669 ThreadMgr *This = impl_from_ITfKeystrokeMgrVtbl(iface);
672 TRACE("(%p) %s (%x %x) %p\n",This,debugstr_guid(rguid), (pprekey)?pprekey->uVKey:0, (pprekey)?pprekey->uModifiers:0, pfRegistered);
674 if (!rguid || !pprekey || !pfRegistered)
677 LIST_FOR_EACH(cursor, &This->CurrentPreservedKeys)
679 PreservedKey* key = LIST_ENTRY(cursor,PreservedKey,entry);
680 if (IsEqualGUID(rguid,&key->guid) && pprekey->uVKey == key->prekey.uVKey && pprekey->uModifiers == key->prekey.uModifiers)
682 *pfRegistered = TRUE;
687 *pfRegistered = FALSE;
691 static HRESULT WINAPI KeystrokeMgr_PreserveKey(ITfKeystrokeMgr *iface,
692 TfClientId tid, REFGUID rguid, const TF_PRESERVEDKEY *prekey,
693 const WCHAR *pchDesc, ULONG cchDesc)
695 ThreadMgr *This = impl_from_ITfKeystrokeMgrVtbl(iface);
697 PreservedKey *newkey;
699 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));
701 if (!tid || ! rguid || !prekey || (cchDesc && !pchDesc))
704 LIST_FOR_EACH(cursor, &This->CurrentPreservedKeys)
706 PreservedKey* key = LIST_ENTRY(cursor,PreservedKey,entry);
707 if (IsEqualGUID(rguid,&key->guid) && prekey->uVKey == key->prekey.uVKey && prekey->uModifiers == key->prekey.uModifiers)
708 return TF_E_ALREADY_EXISTS;
711 newkey = HeapAlloc(GetProcessHeap(),0,sizeof(PreservedKey));
713 return E_OUTOFMEMORY;
715 newkey->guid = *rguid;
716 newkey->prekey = *prekey;
720 newkey->description = HeapAlloc(GetProcessHeap(),0,cchDesc * sizeof(WCHAR));
721 if (!newkey->description)
723 HeapFree(GetProcessHeap(),0,newkey);
724 return E_OUTOFMEMORY;
726 memcpy(newkey->description, pchDesc, cchDesc*sizeof(WCHAR));
729 list_add_head(&This->CurrentPreservedKeys,&newkey->entry);
734 static HRESULT WINAPI KeystrokeMgr_UnpreserveKey(ITfKeystrokeMgr *iface,
735 REFGUID rguid, const TF_PRESERVEDKEY *pprekey)
737 ThreadMgr *This = impl_from_ITfKeystrokeMgrVtbl(iface);
738 PreservedKey* key = NULL;
740 TRACE("(%p) %s (%x %x)\n",This,debugstr_guid(rguid),(pprekey)?pprekey->uVKey:0, (pprekey)?pprekey->uModifiers:0);
742 if (!pprekey || !rguid)
745 LIST_FOR_EACH(cursor, &This->CurrentPreservedKeys)
747 key = LIST_ENTRY(cursor,PreservedKey,entry);
748 if (IsEqualGUID(rguid,&key->guid) && pprekey->uVKey == key->prekey.uVKey && pprekey->uModifiers == key->prekey.uModifiers)
754 return CONNECT_E_NOCONNECTION;
756 list_remove(&key->entry);
757 HeapFree(GetProcessHeap(),0,key->description);
758 HeapFree(GetProcessHeap(),0,key);
763 static HRESULT WINAPI KeystrokeMgr_SetPreservedKeyDescription(ITfKeystrokeMgr *iface,
764 REFGUID rguid, const WCHAR *pchDesc, ULONG cchDesc)
766 ThreadMgr *This = impl_from_ITfKeystrokeMgrVtbl(iface);
767 FIXME("STUB:(%p)\n",This);
771 static HRESULT WINAPI KeystrokeMgr_GetPreservedKeyDescription(ITfKeystrokeMgr *iface,
772 REFGUID rguid, BSTR *pbstrDesc)
774 ThreadMgr *This = impl_from_ITfKeystrokeMgrVtbl(iface);
775 FIXME("STUB:(%p)\n",This);
779 static HRESULT WINAPI KeystrokeMgr_SimulatePreservedKey(ITfKeystrokeMgr *iface,
780 ITfContext *pic, REFGUID rguid, BOOL *pfEaten)
782 ThreadMgr *This = impl_from_ITfKeystrokeMgrVtbl(iface);
783 FIXME("STUB:(%p)\n",This);
787 static const ITfKeystrokeMgrVtbl ThreadMgr_KeystrokeMgrVtbl =
789 KeystrokeMgr_QueryInterface,
791 KeystrokeMgr_Release,
793 KeystrokeMgr_AdviseKeyEventSink,
794 KeystrokeMgr_UnadviseKeyEventSink,
795 KeystrokeMgr_GetForeground,
796 KeystrokeMgr_TestKeyDown,
797 KeystrokeMgr_TestKeyUp,
798 KeystrokeMgr_KeyDown,
800 KeystrokeMgr_GetPreservedKey,
801 KeystrokeMgr_IsPreservedKey,
802 KeystrokeMgr_PreserveKey,
803 KeystrokeMgr_UnpreserveKey,
804 KeystrokeMgr_SetPreservedKeyDescription,
805 KeystrokeMgr_GetPreservedKeyDescription,
806 KeystrokeMgr_SimulatePreservedKey
809 /*****************************************************
810 * ITfMessagePump functions
811 *****************************************************/
813 static HRESULT WINAPI MessagePump_QueryInterface(ITfMessagePump *iface, REFIID iid, LPVOID *ppvOut)
815 ThreadMgr *This = impl_from_ITfMessagePumpVtbl(iface);
816 return ThreadMgr_QueryInterface((ITfThreadMgr *)This, iid, *ppvOut);
819 static ULONG WINAPI MessagePump_AddRef(ITfMessagePump *iface)
821 ThreadMgr *This = impl_from_ITfMessagePumpVtbl(iface);
822 return ThreadMgr_AddRef((ITfThreadMgr*)This);
825 static ULONG WINAPI MessagePump_Release(ITfMessagePump *iface)
827 ThreadMgr *This = impl_from_ITfMessagePumpVtbl(iface);
828 return ThreadMgr_Release((ITfThreadMgr *)This);
831 static HRESULT WINAPI MessagePump_PeekMessageA(ITfMessagePump *iface,
832 LPMSG pMsg, HWND hwnd, UINT wMsgFilterMin, UINT wMsgFilterMax,
833 UINT wRemoveMsg, BOOL *pfResult)
837 *pfResult = PeekMessageA(pMsg, hwnd, wMsgFilterMin, wMsgFilterMax, wRemoveMsg);
841 static HRESULT WINAPI MessagePump_GetMessageA(ITfMessagePump *iface,
842 LPMSG pMsg, HWND hwnd, UINT wMsgFilterMin, UINT wMsgFilterMax,
847 *pfResult = GetMessageA(pMsg, hwnd, wMsgFilterMin, wMsgFilterMax);
851 static HRESULT WINAPI MessagePump_PeekMessageW(ITfMessagePump *iface,
852 LPMSG pMsg, HWND hwnd, UINT wMsgFilterMin, UINT wMsgFilterMax,
853 UINT wRemoveMsg, BOOL *pfResult)
857 *pfResult = PeekMessageW(pMsg, hwnd, wMsgFilterMin, wMsgFilterMax, wRemoveMsg);
861 static HRESULT WINAPI MessagePump_GetMessageW(ITfMessagePump *iface,
862 LPMSG pMsg, HWND hwnd, UINT wMsgFilterMin, UINT wMsgFilterMax,
867 *pfResult = GetMessageW(pMsg, hwnd, wMsgFilterMin, wMsgFilterMax);
871 static const ITfMessagePumpVtbl ThreadMgr_MessagePumpVtbl =
873 MessagePump_QueryInterface,
877 MessagePump_PeekMessageA,
878 MessagePump_GetMessageA,
879 MessagePump_PeekMessageW,
880 MessagePump_GetMessageW
883 /*****************************************************
884 * ITfClientId functions
885 *****************************************************/
887 static HRESULT WINAPI ClientId_QueryInterface(ITfClientId *iface, REFIID iid, LPVOID *ppvOut)
889 ThreadMgr *This = impl_from_ITfClientIdVtbl(iface);
890 return ThreadMgr_QueryInterface((ITfThreadMgr *)This, iid, *ppvOut);
893 static ULONG WINAPI ClientId_AddRef(ITfClientId *iface)
895 ThreadMgr *This = impl_from_ITfClientIdVtbl(iface);
896 return ThreadMgr_AddRef((ITfThreadMgr*)This);
899 static ULONG WINAPI ClientId_Release(ITfClientId *iface)
901 ThreadMgr *This = impl_from_ITfClientIdVtbl(iface);
902 return ThreadMgr_Release((ITfThreadMgr *)This);
905 static HRESULT WINAPI ClientId_GetClientId(ITfClientId *iface,
906 REFCLSID rclsid, TfClientId *ptid)
910 ITfCategoryMgr *catmgr;
911 ThreadMgr *This = impl_from_ITfClientIdVtbl(iface);
913 TRACE("(%p) %s\n",This,debugstr_guid(rclsid));
915 CategoryMgr_Constructor(NULL,(IUnknown**)&catmgr);
916 hr = ITfCategoryMgr_RegisterGUID(catmgr,rclsid,ptid);
917 ITfCategoryMgr_Release(catmgr);
922 static const ITfClientIdVtbl ThreadMgr_ClientIdVtbl =
924 ClientId_QueryInterface,
931 /*****************************************************
932 * ITfThreadMgrEventSink functions (internal)
933 *****************************************************/
934 static HRESULT WINAPI ThreadMgrEventSink_QueryInterface(ITfThreadMgrEventSink *iface, REFIID iid, LPVOID *ppvOut)
936 ThreadMgr *This = impl_from_ITfThreadMgrEventSink(iface);
937 return ThreadMgr_QueryInterface((ITfThreadMgr *)This, iid, *ppvOut);
940 static ULONG WINAPI ThreadMgrEventSink_AddRef(ITfThreadMgrEventSink *iface)
942 ThreadMgr *This = impl_from_ITfThreadMgrEventSink(iface);
943 return ThreadMgr_AddRef((ITfThreadMgr*)This);
946 static ULONG WINAPI ThreadMgrEventSink_Release(ITfThreadMgrEventSink *iface)
948 ThreadMgr *This = impl_from_ITfThreadMgrEventSink(iface);
949 return ThreadMgr_Release((ITfThreadMgr *)This);
953 static WINAPI HRESULT ThreadMgrEventSink_OnInitDocumentMgr(
954 ITfThreadMgrEventSink *iface,ITfDocumentMgr *pdim)
957 ThreadMgr *This = impl_from_ITfThreadMgrEventSink(iface);
959 TRACE("(%p) %p\n",This,pdim);
961 LIST_FOR_EACH(cursor, &This->ThreadMgrEventSink)
963 ThreadMgrSink* sink = LIST_ENTRY(cursor,ThreadMgrSink,entry);
964 ITfThreadMgrEventSink_OnInitDocumentMgr(sink->interfaces.pITfThreadMgrEventSink,pdim);
970 static WINAPI HRESULT ThreadMgrEventSink_OnUninitDocumentMgr(
971 ITfThreadMgrEventSink *iface, ITfDocumentMgr *pdim)
974 ThreadMgr *This = impl_from_ITfThreadMgrEventSink(iface);
976 TRACE("(%p) %p\n",This,pdim);
978 LIST_FOR_EACH(cursor, &This->ThreadMgrEventSink)
980 ThreadMgrSink* sink = LIST_ENTRY(cursor,ThreadMgrSink,entry);
981 ITfThreadMgrEventSink_OnUninitDocumentMgr(sink->interfaces.pITfThreadMgrEventSink,pdim);
987 static WINAPI HRESULT ThreadMgrEventSink_OnSetFocus(
988 ITfThreadMgrEventSink *iface, ITfDocumentMgr *pdimFocus,
989 ITfDocumentMgr *pdimPrevFocus)
992 ThreadMgr *This = impl_from_ITfThreadMgrEventSink(iface);
994 TRACE("(%p) %p %p\n",This,pdimFocus, pdimPrevFocus);
996 LIST_FOR_EACH(cursor, &This->ThreadMgrEventSink)
998 ThreadMgrSink* sink = LIST_ENTRY(cursor,ThreadMgrSink,entry);
999 ITfThreadMgrEventSink_OnSetFocus(sink->interfaces.pITfThreadMgrEventSink, pdimFocus, pdimPrevFocus);
1005 static WINAPI HRESULT ThreadMgrEventSink_OnPushContext(
1006 ITfThreadMgrEventSink *iface, ITfContext *pic)
1008 struct list *cursor;
1009 ThreadMgr *This = impl_from_ITfThreadMgrEventSink(iface);
1011 TRACE("(%p) %p\n",This,pic);
1013 LIST_FOR_EACH(cursor, &This->ThreadMgrEventSink)
1015 ThreadMgrSink* sink = LIST_ENTRY(cursor,ThreadMgrSink,entry);
1016 ITfThreadMgrEventSink_OnPushContext(sink->interfaces.pITfThreadMgrEventSink,pic);
1022 static WINAPI HRESULT ThreadMgrEventSink_OnPopContext(
1023 ITfThreadMgrEventSink *iface, ITfContext *pic)
1025 struct list *cursor;
1026 ThreadMgr *This = impl_from_ITfThreadMgrEventSink(iface);
1028 TRACE("(%p) %p\n",This,pic);
1030 LIST_FOR_EACH(cursor, &This->ThreadMgrEventSink)
1032 ThreadMgrSink* sink = LIST_ENTRY(cursor,ThreadMgrSink,entry);
1033 ITfThreadMgrEventSink_OnPopContext(sink->interfaces.pITfThreadMgrEventSink,pic);
1039 static const ITfThreadMgrEventSinkVtbl ThreadMgr_ThreadMgrEventSinkVtbl =
1041 ThreadMgrEventSink_QueryInterface,
1042 ThreadMgrEventSink_AddRef,
1043 ThreadMgrEventSink_Release,
1045 ThreadMgrEventSink_OnInitDocumentMgr,
1046 ThreadMgrEventSink_OnUninitDocumentMgr,
1047 ThreadMgrEventSink_OnSetFocus,
1048 ThreadMgrEventSink_OnPushContext,
1049 ThreadMgrEventSink_OnPopContext
1052 HRESULT ThreadMgr_Constructor(IUnknown *pUnkOuter, IUnknown **ppOut)
1056 return CLASS_E_NOAGGREGATION;
1058 /* Only 1 ThreadMgr is created per thread */
1059 This = TlsGetValue(tlsIndex);
1062 ThreadMgr_AddRef((ITfThreadMgr*)This);
1063 *ppOut = (IUnknown*)This;
1067 This = HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,sizeof(ThreadMgr));
1069 return E_OUTOFMEMORY;
1071 This->ThreadMgrVtbl= &ThreadMgr_ThreadMgrVtbl;
1072 This->SourceVtbl = &ThreadMgr_SourceVtbl;
1073 This->KeystrokeMgrVtbl= &ThreadMgr_KeystrokeMgrVtbl;
1074 This->MessagePumpVtbl= &ThreadMgr_MessagePumpVtbl;
1075 This->ClientIdVtbl = &ThreadMgr_ClientIdVtbl;
1076 This->ThreadMgrEventSinkVtbl = &ThreadMgr_ThreadMgrEventSinkVtbl;
1078 TlsSetValue(tlsIndex,This);
1080 CompartmentMgr_Constructor((IUnknown*)This, &IID_IUnknown, (IUnknown**)&This->CompartmentMgr);
1082 list_init(&This->CurrentPreservedKeys);
1084 list_init(&This->ActiveLanguageProfileNotifySink);
1085 list_init(&This->DisplayAttributeNotifySink);
1086 list_init(&This->KeyTraceEventSink);
1087 list_init(&This->PreservedKeyNotifySink);
1088 list_init(&This->ThreadFocusSink);
1089 list_init(&This->ThreadMgrEventSink);
1091 TRACE("returning %p\n", This);
1092 *ppOut = (IUnknown *)This;