2 * ITfThreadMgr implementation
4 * Copyright 2008 Aric Stewart, CodeWeavers
6 * This library is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Lesser General Public
8 * License as published by the Free Software Foundation; either
9 * version 2.1 of the License, or (at your option) any later version.
11 * This library is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Lesser General Public License for more details.
16 * You should have received a copy of the GNU Lesser General Public
17 * License along with this library; if not, write to the Free Software
18 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
27 #include "wine/debug.h"
37 #include "wine/unicode.h"
38 #include "wine/list.h"
41 #include "msctf_internal.h"
43 WINE_DEFAULT_DEBUG_CHANNEL(msctf
);
45 typedef struct tagThreadMgrSink
{
50 /* ITfActiveLanguageProfileNotifySink *pITfActiveLanguageProfileNotifySink; */
51 /* ITfDisplayAttributeNotifySink *pITfDisplayAttributeNotifySink; */
52 /* ITfKeyTraceEventSink *pITfKeyTraceEventSink; */
53 /* ITfPreservedKeyNotifySink *pITfPreservedKeyNotifySink; */
54 /* ITfThreadFocusSink *pITfThreadFocusSink; */
55 ITfThreadMgrEventSink
*pITfThreadMgrEventSink
;
59 typedef struct tagPreservedKey
63 TF_PRESERVEDKEY prekey
;
68 typedef struct tagDocumentMgrs
71 ITfDocumentMgr
*docmgr
;
74 typedef struct tagACLMulti
{
75 const ITfThreadMgrVtbl
*ThreadMgrVtbl
;
76 const ITfSourceVtbl
*SourceVtbl
;
77 const ITfKeystrokeMgrVtbl
*KeystrokeMgrVtbl
;
78 const ITfMessagePumpVtbl
*MessagePumpVtbl
;
79 const ITfClientIdVtbl
*ClientIdVtbl
;
80 /* const ITfThreadMgrExVtbl *ThreadMgrExVtbl; */
81 /* const ITfConfigureSystemKeystrokeFeedVtbl *ConfigureSystemKeystrokeFeedVtbl; */
82 /* const ITfLangBarItemMgrVtbl *LangBarItemMgrVtbl; */
83 /* const ITfUIElementMgrVtbl *UIElementMgrVtbl; */
84 /* const ITfSourceSingleVtbl *SourceSingleVtbl; */
88 ITfCompartmentMgr
*CompartmentMgr
;
90 const ITfThreadMgrEventSinkVtbl
*ThreadMgrEventSinkVtbl
; /* internal */
92 ITfDocumentMgr
*focus
;
95 ITfKeyEventSink
*forgroundKeyEventSink
;
96 CLSID forgroundTextService
;
98 struct list CurrentPreservedKeys
;
99 struct list CreatedDocumentMgrs
;
101 /* kept as separate lists to reduce unnecessary iterations */
102 struct list ActiveLanguageProfileNotifySink
;
103 struct list DisplayAttributeNotifySink
;
104 struct list KeyTraceEventSink
;
105 struct list PreservedKeyNotifySink
;
106 struct list ThreadFocusSink
;
107 struct list ThreadMgrEventSink
;
110 typedef struct tagEnumTfDocumentMgr
{
111 const IEnumTfDocumentMgrsVtbl
*Vtbl
;
118 static HRESULT
EnumTfDocumentMgr_Constructor(struct list
* head
, IEnumTfDocumentMgrs
**ppOut
);
120 static inline ThreadMgr
*impl_from_ITfSourceVtbl(ITfSource
*iface
)
122 return (ThreadMgr
*)((char *)iface
- FIELD_OFFSET(ThreadMgr
,SourceVtbl
));
125 static inline ThreadMgr
*impl_from_ITfKeystrokeMgrVtbl(ITfKeystrokeMgr
*iface
)
127 return (ThreadMgr
*)((char *)iface
- FIELD_OFFSET(ThreadMgr
,KeystrokeMgrVtbl
));
130 static inline ThreadMgr
*impl_from_ITfMessagePumpVtbl(ITfMessagePump
*iface
)
132 return (ThreadMgr
*)((char *)iface
- FIELD_OFFSET(ThreadMgr
,MessagePumpVtbl
));
135 static inline ThreadMgr
*impl_from_ITfClientIdVtbl(ITfClientId
*iface
)
137 return (ThreadMgr
*)((char *)iface
- FIELD_OFFSET(ThreadMgr
,ClientIdVtbl
));
140 static inline ThreadMgr
*impl_from_ITfThreadMgrEventSink(ITfThreadMgrEventSink
*iface
)
142 return (ThreadMgr
*)((char *)iface
- FIELD_OFFSET(ThreadMgr
,ThreadMgrEventSinkVtbl
));
145 static void free_sink(ThreadMgrSink
*sink
)
147 IUnknown_Release(sink
->interfaces
.pIUnknown
);
148 HeapFree(GetProcessHeap(),0,sink
);
151 static void ThreadMgr_Destructor(ThreadMgr
*This
)
153 struct list
*cursor
, *cursor2
;
155 TlsSetValue(tlsIndex
,NULL
);
156 TRACE("destroying %p\n", This
);
158 ITfDocumentMgr_Release(This
->focus
);
161 LIST_FOR_EACH_SAFE(cursor
, cursor2
, &This
->ActiveLanguageProfileNotifySink
)
163 ThreadMgrSink
* sink
= LIST_ENTRY(cursor
,ThreadMgrSink
,entry
);
167 LIST_FOR_EACH_SAFE(cursor
, cursor2
, &This
->DisplayAttributeNotifySink
)
169 ThreadMgrSink
* sink
= LIST_ENTRY(cursor
,ThreadMgrSink
,entry
);
173 LIST_FOR_EACH_SAFE(cursor
, cursor2
, &This
->KeyTraceEventSink
)
175 ThreadMgrSink
* sink
= LIST_ENTRY(cursor
,ThreadMgrSink
,entry
);
179 LIST_FOR_EACH_SAFE(cursor
, cursor2
, &This
->PreservedKeyNotifySink
)
181 ThreadMgrSink
* sink
= LIST_ENTRY(cursor
,ThreadMgrSink
,entry
);
185 LIST_FOR_EACH_SAFE(cursor
, cursor2
, &This
->ThreadFocusSink
)
187 ThreadMgrSink
* sink
= LIST_ENTRY(cursor
,ThreadMgrSink
,entry
);
191 LIST_FOR_EACH_SAFE(cursor
, cursor2
, &This
->ThreadMgrEventSink
)
193 ThreadMgrSink
* sink
= LIST_ENTRY(cursor
,ThreadMgrSink
,entry
);
198 LIST_FOR_EACH_SAFE(cursor
, cursor2
, &This
->CurrentPreservedKeys
)
200 PreservedKey
* key
= LIST_ENTRY(cursor
,PreservedKey
,entry
);
202 HeapFree(GetProcessHeap(),0,key
->description
);
203 HeapFree(GetProcessHeap(),0,key
);
206 LIST_FOR_EACH_SAFE(cursor
, cursor2
, &This
->CreatedDocumentMgrs
)
208 DocumentMgrEntry
*mgr
= LIST_ENTRY(cursor
,DocumentMgrEntry
,entry
);
210 FIXME("Left Over ITfDocumentMgr. Should we do something with it?\n");
211 HeapFree(GetProcessHeap(),0,mgr
);
214 CompartmentMgr_Destructor(This
->CompartmentMgr
);
216 HeapFree(GetProcessHeap(),0,This
);
219 static HRESULT WINAPI
ThreadMgr_QueryInterface(ITfThreadMgr
*iface
, REFIID iid
, LPVOID
*ppvOut
)
221 ThreadMgr
*This
= (ThreadMgr
*)iface
;
224 if (IsEqualIID(iid
, &IID_IUnknown
) || IsEqualIID(iid
, &IID_ITfThreadMgr
))
228 else if (IsEqualIID(iid
, &IID_ITfSource
))
230 *ppvOut
= &This
->SourceVtbl
;
232 else if (IsEqualIID(iid
, &IID_ITfKeystrokeMgr
))
234 *ppvOut
= &This
->KeystrokeMgrVtbl
;
236 else if (IsEqualIID(iid
, &IID_ITfMessagePump
))
238 *ppvOut
= &This
->MessagePumpVtbl
;
240 else if (IsEqualIID(iid
, &IID_ITfClientId
))
242 *ppvOut
= &This
->ClientIdVtbl
;
244 else if (IsEqualIID(iid
, &IID_ITfCompartmentMgr
))
246 *ppvOut
= This
->CompartmentMgr
;
251 IUnknown_AddRef(iface
);
255 WARN("unsupported interface: %s\n", debugstr_guid(iid
));
256 return E_NOINTERFACE
;
259 static ULONG WINAPI
ThreadMgr_AddRef(ITfThreadMgr
*iface
)
261 ThreadMgr
*This
= (ThreadMgr
*)iface
;
262 return InterlockedIncrement(&This
->refCount
);
265 static ULONG WINAPI
ThreadMgr_Release(ITfThreadMgr
*iface
)
267 ThreadMgr
*This
= (ThreadMgr
*)iface
;
270 ret
= InterlockedDecrement(&This
->refCount
);
272 ThreadMgr_Destructor(This
);
276 /*****************************************************
277 * ITfThreadMgr functions
278 *****************************************************/
280 static HRESULT WINAPI
ThreadMgr_fnActivate( ITfThreadMgr
* iface
, TfClientId
*ptid
)
282 ThreadMgr
*This
= (ThreadMgr
*)iface
;
284 TRACE("(%p) %p\n",This
, ptid
);
293 ITfClientId_GetClientId((ITfClientId
*)&This
->ClientIdVtbl
,&guid
,&processId
);
296 activate_textservices(iface
);
297 This
->activationCount
++;
302 static HRESULT WINAPI
ThreadMgr_fnDeactivate( ITfThreadMgr
* iface
)
304 ThreadMgr
*This
= (ThreadMgr
*)iface
;
305 TRACE("(%p)\n",This
);
307 if (This
->activationCount
== 0)
310 This
->activationCount
--;
312 if (This
->activationCount
== 0)
316 ITfThreadMgrEventSink_OnSetFocus((ITfThreadMgrEventSink
*)&This
->ThreadMgrEventSinkVtbl
, 0, This
->focus
);
317 ITfDocumentMgr_Release(This
->focus
);
322 deactivate_textservices();
327 static HRESULT WINAPI
ThreadMgr_CreateDocumentMgr( ITfThreadMgr
* iface
, ITfDocumentMgr
330 ThreadMgr
*This
= (ThreadMgr
*)iface
;
331 DocumentMgrEntry
*mgrentry
;
334 TRACE("(%p)\n",iface
);
335 mgrentry
= HeapAlloc(GetProcessHeap(),0,sizeof(DocumentMgrEntry
));
336 if (mgrentry
== NULL
)
337 return E_OUTOFMEMORY
;
339 hr
= DocumentMgr_Constructor((ITfThreadMgrEventSink
*)&This
->ThreadMgrEventSinkVtbl
, ppdim
);
343 mgrentry
->docmgr
= *ppdim
;
344 list_add_head(&This
->CreatedDocumentMgrs
,&mgrentry
->entry
);
347 HeapFree(GetProcessHeap(),0,mgrentry
);
352 static HRESULT WINAPI
ThreadMgr_EnumDocumentMgrs( ITfThreadMgr
* iface
, IEnumTfDocumentMgrs
355 ThreadMgr
*This
= (ThreadMgr
*)iface
;
356 TRACE("(%p) %p\n",This
,ppEnum
);
361 return EnumTfDocumentMgr_Constructor(&This
->CreatedDocumentMgrs
, ppEnum
);
364 static HRESULT WINAPI
ThreadMgr_GetFocus( ITfThreadMgr
* iface
, ITfDocumentMgr
367 ThreadMgr
*This
= (ThreadMgr
*)iface
;
368 TRACE("(%p)\n",This
);
373 *ppdimFocus
= This
->focus
;
375 TRACE("->%p\n",This
->focus
);
377 if (This
->focus
== NULL
)
380 ITfDocumentMgr_AddRef(This
->focus
);
385 static HRESULT WINAPI
ThreadMgr_SetFocus( ITfThreadMgr
* iface
, ITfDocumentMgr
*pdimFocus
)
387 ITfDocumentMgr
*check
;
388 ThreadMgr
*This
= (ThreadMgr
*)iface
;
390 TRACE("(%p) %p\n",This
,pdimFocus
);
392 if (!pdimFocus
|| FAILED(IUnknown_QueryInterface(pdimFocus
,&IID_ITfDocumentMgr
,(LPVOID
*) &check
)))
395 ITfThreadMgrEventSink_OnSetFocus((ITfThreadMgrEventSink
*)&This
->ThreadMgrEventSinkVtbl
, check
, This
->focus
);
398 ITfDocumentMgr_Release(This
->focus
);
404 static HRESULT WINAPI
ThreadMgr_AssociateFocus( ITfThreadMgr
* iface
, HWND hwnd
,
405 ITfDocumentMgr
*pdimNew
, ITfDocumentMgr
**ppdimPrev
)
407 ThreadMgr
*This
= (ThreadMgr
*)iface
;
408 FIXME("STUB:(%p)\n",This
);
412 static HRESULT WINAPI
ThreadMgr_IsThreadFocus( ITfThreadMgr
* iface
, BOOL
*pfThreadFocus
)
415 ThreadMgr
*This
= (ThreadMgr
*)iface
;
416 TRACE("(%p) %p\n",This
,pfThreadFocus
);
418 *pfThreadFocus
= (focus
== NULL
);
422 static HRESULT WINAPI
ThreadMgr_GetFunctionProvider( ITfThreadMgr
* iface
, REFCLSID clsid
,
423 ITfFunctionProvider
**ppFuncProv
)
425 ThreadMgr
*This
= (ThreadMgr
*)iface
;
426 FIXME("STUB:(%p)\n",This
);
430 static HRESULT WINAPI
ThreadMgr_EnumFunctionProviders( ITfThreadMgr
* iface
,
431 IEnumTfFunctionProviders
**ppEnum
)
433 ThreadMgr
*This
= (ThreadMgr
*)iface
;
434 FIXME("STUB:(%p)\n",This
);
438 static HRESULT WINAPI
ThreadMgr_GetGlobalCompartment( ITfThreadMgr
* iface
,
439 ITfCompartmentMgr
**ppCompMgr
)
441 ThreadMgr
*This
= (ThreadMgr
*)iface
;
443 TRACE("(%p) %p\n",This
, ppCompMgr
);
448 if (!globalCompartmentMgr
)
450 hr
= CompartmentMgr_Constructor(NULL
,&IID_ITfCompartmentMgr
,(IUnknown
**)&globalCompartmentMgr
);
455 ITfCompartmentMgr_AddRef(globalCompartmentMgr
);
456 *ppCompMgr
= globalCompartmentMgr
;
460 static const ITfThreadMgrVtbl ThreadMgr_ThreadMgrVtbl
=
462 ThreadMgr_QueryInterface
,
466 ThreadMgr_fnActivate
,
467 ThreadMgr_fnDeactivate
,
468 ThreadMgr_CreateDocumentMgr
,
469 ThreadMgr_EnumDocumentMgrs
,
472 ThreadMgr_AssociateFocus
,
473 ThreadMgr_IsThreadFocus
,
474 ThreadMgr_GetFunctionProvider
,
475 ThreadMgr_EnumFunctionProviders
,
476 ThreadMgr_GetGlobalCompartment
480 static HRESULT WINAPI
Source_QueryInterface(ITfSource
*iface
, REFIID iid
, LPVOID
*ppvOut
)
482 ThreadMgr
*This
= impl_from_ITfSourceVtbl(iface
);
483 return ThreadMgr_QueryInterface((ITfThreadMgr
*)This
, iid
, *ppvOut
);
486 static ULONG WINAPI
Source_AddRef(ITfSource
*iface
)
488 ThreadMgr
*This
= impl_from_ITfSourceVtbl(iface
);
489 return ThreadMgr_AddRef((ITfThreadMgr
*)This
);
492 static ULONG WINAPI
Source_Release(ITfSource
*iface
)
494 ThreadMgr
*This
= impl_from_ITfSourceVtbl(iface
);
495 return ThreadMgr_Release((ITfThreadMgr
*)This
);
498 /*****************************************************
499 * ITfSource functions
500 *****************************************************/
501 static WINAPI HRESULT
ThreadMgrSource_AdviseSink(ITfSource
*iface
,
502 REFIID riid
, IUnknown
*punk
, DWORD
*pdwCookie
)
505 ThreadMgr
*This
= impl_from_ITfSourceVtbl(iface
);
507 TRACE("(%p) %s %p %p\n",This
,debugstr_guid(riid
),punk
,pdwCookie
);
509 if (!riid
|| !punk
|| !pdwCookie
)
512 if (IsEqualIID(riid
, &IID_ITfThreadMgrEventSink
))
514 tms
= HeapAlloc(GetProcessHeap(),0,sizeof(ThreadMgrSink
));
516 return E_OUTOFMEMORY
;
517 if (FAILED(IUnknown_QueryInterface(punk
, riid
, (LPVOID
*)&tms
->interfaces
.pITfThreadMgrEventSink
)))
519 HeapFree(GetProcessHeap(),0,tms
);
520 return CONNECT_E_CANNOTCONNECT
;
522 list_add_head(&This
->ThreadMgrEventSink
,&tms
->entry
);
523 *pdwCookie
= generate_Cookie(COOKIE_MAGIC_TMSINK
, tms
);
527 FIXME("(%p) Unhandled Sink: %s\n",This
,debugstr_guid(riid
));
531 TRACE("cookie %x\n",*pdwCookie
);
536 static WINAPI HRESULT
ThreadMgrSource_UnadviseSink(ITfSource
*iface
, DWORD pdwCookie
)
539 ThreadMgr
*This
= impl_from_ITfSourceVtbl(iface
);
541 TRACE("(%p) %x\n",This
,pdwCookie
);
543 if (get_Cookie_magic(pdwCookie
)!=COOKIE_MAGIC_TMSINK
)
546 sink
= (ThreadMgrSink
*)remove_Cookie(pdwCookie
);
548 return CONNECT_E_NOCONNECTION
;
550 list_remove(&sink
->entry
);
556 static const ITfSourceVtbl ThreadMgr_SourceVtbl
=
558 Source_QueryInterface
,
562 ThreadMgrSource_AdviseSink
,
563 ThreadMgrSource_UnadviseSink
,
566 /*****************************************************
567 * ITfKeystrokeMgr functions
568 *****************************************************/
570 static HRESULT WINAPI
KeystrokeMgr_QueryInterface(ITfKeystrokeMgr
*iface
, REFIID iid
, LPVOID
*ppvOut
)
572 ThreadMgr
*This
= impl_from_ITfKeystrokeMgrVtbl(iface
);
573 return ThreadMgr_QueryInterface((ITfThreadMgr
*)This
, iid
, *ppvOut
);
576 static ULONG WINAPI
KeystrokeMgr_AddRef(ITfKeystrokeMgr
*iface
)
578 ThreadMgr
*This
= impl_from_ITfKeystrokeMgrVtbl(iface
);
579 return ThreadMgr_AddRef((ITfThreadMgr
*)This
);
582 static ULONG WINAPI
KeystrokeMgr_Release(ITfKeystrokeMgr
*iface
)
584 ThreadMgr
*This
= impl_from_ITfKeystrokeMgrVtbl(iface
);
585 return ThreadMgr_Release((ITfThreadMgr
*)This
);
588 static HRESULT WINAPI
KeystrokeMgr_AdviseKeyEventSink(ITfKeystrokeMgr
*iface
,
589 TfClientId tid
, ITfKeyEventSink
*pSink
, BOOL fForeground
)
591 ThreadMgr
*This
= impl_from_ITfKeystrokeMgrVtbl(iface
);
593 ITfKeyEventSink
*check
= NULL
;
595 TRACE("(%p) %x %p %i\n",This
,tid
,pSink
,fForeground
);
600 textservice
= get_textservice_clsid(tid
);
601 if (IsEqualCLSID(&GUID_NULL
,&textservice
))
604 get_textservice_sink(tid
, &IID_ITfKeyEventSink
, (IUnknown
**)&check
);
606 return CONNECT_E_ADVISELIMIT
;
608 if (FAILED(IUnknown_QueryInterface(pSink
,&IID_ITfKeyEventSink
,(LPVOID
*) &check
)))
611 set_textservice_sink(tid
, &IID_ITfKeyEventSink
, (IUnknown
*)check
);
615 if (This
->forgroundKeyEventSink
)
617 ITfKeyEventSink_OnSetFocus(This
->forgroundKeyEventSink
, FALSE
);
618 ITfKeyEventSink_Release(This
->forgroundKeyEventSink
);
620 ITfKeyEventSink_AddRef(check
);
621 ITfKeyEventSink_OnSetFocus(check
, TRUE
);
622 This
->forgroundKeyEventSink
= check
;
623 This
->forgroundTextService
= textservice
;
628 static HRESULT WINAPI
KeystrokeMgr_UnadviseKeyEventSink(ITfKeystrokeMgr
*iface
,
631 ThreadMgr
*This
= impl_from_ITfKeystrokeMgrVtbl(iface
);
633 ITfKeyEventSink
*check
= NULL
;
634 TRACE("(%p) %x\n",This
,tid
);
639 textservice
= get_textservice_clsid(tid
);
640 if (IsEqualCLSID(&GUID_NULL
,&textservice
))
643 get_textservice_sink(tid
, &IID_ITfKeyEventSink
, (IUnknown
**)&check
);
646 return CONNECT_E_NOCONNECTION
;
648 set_textservice_sink(tid
, &IID_ITfKeyEventSink
, NULL
);
649 ITfKeyEventSink_Release(check
);
651 if (This
->forgroundKeyEventSink
== check
)
653 ITfKeyEventSink_Release(This
->forgroundKeyEventSink
);
654 This
->forgroundKeyEventSink
= NULL
;
655 This
->forgroundTextService
= GUID_NULL
;
660 static HRESULT WINAPI
KeystrokeMgr_GetForeground(ITfKeystrokeMgr
*iface
,
663 ThreadMgr
*This
= impl_from_ITfKeystrokeMgrVtbl(iface
);
664 TRACE("(%p) %p\n",This
,pclsid
);
668 if (IsEqualCLSID(&This
->forgroundTextService
,&GUID_NULL
))
671 *pclsid
= This
->forgroundTextService
;
675 static HRESULT WINAPI
KeystrokeMgr_TestKeyDown(ITfKeystrokeMgr
*iface
,
676 WPARAM wParam
, LPARAM lParam
, BOOL
*pfEaten
)
678 ThreadMgr
*This
= impl_from_ITfKeystrokeMgrVtbl(iface
);
679 FIXME("STUB:(%p)\n",This
);
683 static HRESULT WINAPI
KeystrokeMgr_TestKeyUp(ITfKeystrokeMgr
*iface
,
684 WPARAM wParam
, LPARAM lParam
, BOOL
*pfEaten
)
686 ThreadMgr
*This
= impl_from_ITfKeystrokeMgrVtbl(iface
);
687 FIXME("STUB:(%p)\n",This
);
691 static HRESULT WINAPI
KeystrokeMgr_KeyDown(ITfKeystrokeMgr
*iface
,
692 WPARAM wParam
, LPARAM lParam
, BOOL
*pfEaten
)
694 ThreadMgr
*This
= impl_from_ITfKeystrokeMgrVtbl(iface
);
695 FIXME("STUB:(%p)\n",This
);
699 static HRESULT WINAPI
KeystrokeMgr_KeyUp(ITfKeystrokeMgr
*iface
,
700 WPARAM wParam
, LPARAM lParam
, BOOL
*pfEaten
)
702 ThreadMgr
*This
= impl_from_ITfKeystrokeMgrVtbl(iface
);
703 FIXME("STUB:(%p)\n",This
);
707 static HRESULT WINAPI
KeystrokeMgr_GetPreservedKey(ITfKeystrokeMgr
*iface
,
708 ITfContext
*pic
, const TF_PRESERVEDKEY
*pprekey
, GUID
*pguid
)
710 ThreadMgr
*This
= impl_from_ITfKeystrokeMgrVtbl(iface
);
711 FIXME("STUB:(%p)\n",This
);
715 static HRESULT WINAPI
KeystrokeMgr_IsPreservedKey(ITfKeystrokeMgr
*iface
,
716 REFGUID rguid
, const TF_PRESERVEDKEY
*pprekey
, BOOL
*pfRegistered
)
718 ThreadMgr
*This
= impl_from_ITfKeystrokeMgrVtbl(iface
);
721 TRACE("(%p) %s (%x %x) %p\n",This
,debugstr_guid(rguid
), (pprekey
)?pprekey
->uVKey
:0, (pprekey
)?pprekey
->uModifiers
:0, pfRegistered
);
723 if (!rguid
|| !pprekey
|| !pfRegistered
)
726 LIST_FOR_EACH(cursor
, &This
->CurrentPreservedKeys
)
728 PreservedKey
* key
= LIST_ENTRY(cursor
,PreservedKey
,entry
);
729 if (IsEqualGUID(rguid
,&key
->guid
) && pprekey
->uVKey
== key
->prekey
.uVKey
&& pprekey
->uModifiers
== key
->prekey
.uModifiers
)
731 *pfRegistered
= TRUE
;
736 *pfRegistered
= FALSE
;
740 static HRESULT WINAPI
KeystrokeMgr_PreserveKey(ITfKeystrokeMgr
*iface
,
741 TfClientId tid
, REFGUID rguid
, const TF_PRESERVEDKEY
*prekey
,
742 const WCHAR
*pchDesc
, ULONG cchDesc
)
744 ThreadMgr
*This
= impl_from_ITfKeystrokeMgrVtbl(iface
);
746 PreservedKey
*newkey
;
748 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
));
750 if (!tid
|| ! rguid
|| !prekey
|| (cchDesc
&& !pchDesc
))
753 LIST_FOR_EACH(cursor
, &This
->CurrentPreservedKeys
)
755 PreservedKey
* key
= LIST_ENTRY(cursor
,PreservedKey
,entry
);
756 if (IsEqualGUID(rguid
,&key
->guid
) && prekey
->uVKey
== key
->prekey
.uVKey
&& prekey
->uModifiers
== key
->prekey
.uModifiers
)
757 return TF_E_ALREADY_EXISTS
;
760 newkey
= HeapAlloc(GetProcessHeap(),0,sizeof(PreservedKey
));
762 return E_OUTOFMEMORY
;
764 newkey
->guid
= *rguid
;
765 newkey
->prekey
= *prekey
;
769 newkey
->description
= HeapAlloc(GetProcessHeap(),0,cchDesc
* sizeof(WCHAR
));
770 if (!newkey
->description
)
772 HeapFree(GetProcessHeap(),0,newkey
);
773 return E_OUTOFMEMORY
;
775 memcpy(newkey
->description
, pchDesc
, cchDesc
*sizeof(WCHAR
));
778 list_add_head(&This
->CurrentPreservedKeys
,&newkey
->entry
);
783 static HRESULT WINAPI
KeystrokeMgr_UnpreserveKey(ITfKeystrokeMgr
*iface
,
784 REFGUID rguid
, const TF_PRESERVEDKEY
*pprekey
)
786 ThreadMgr
*This
= impl_from_ITfKeystrokeMgrVtbl(iface
);
787 PreservedKey
* key
= NULL
;
789 TRACE("(%p) %s (%x %x)\n",This
,debugstr_guid(rguid
),(pprekey
)?pprekey
->uVKey
:0, (pprekey
)?pprekey
->uModifiers
:0);
791 if (!pprekey
|| !rguid
)
794 LIST_FOR_EACH(cursor
, &This
->CurrentPreservedKeys
)
796 key
= LIST_ENTRY(cursor
,PreservedKey
,entry
);
797 if (IsEqualGUID(rguid
,&key
->guid
) && pprekey
->uVKey
== key
->prekey
.uVKey
&& pprekey
->uModifiers
== key
->prekey
.uModifiers
)
803 return CONNECT_E_NOCONNECTION
;
805 list_remove(&key
->entry
);
806 HeapFree(GetProcessHeap(),0,key
->description
);
807 HeapFree(GetProcessHeap(),0,key
);
812 static HRESULT WINAPI
KeystrokeMgr_SetPreservedKeyDescription(ITfKeystrokeMgr
*iface
,
813 REFGUID rguid
, const WCHAR
*pchDesc
, ULONG cchDesc
)
815 ThreadMgr
*This
= impl_from_ITfKeystrokeMgrVtbl(iface
);
816 FIXME("STUB:(%p)\n",This
);
820 static HRESULT WINAPI
KeystrokeMgr_GetPreservedKeyDescription(ITfKeystrokeMgr
*iface
,
821 REFGUID rguid
, BSTR
*pbstrDesc
)
823 ThreadMgr
*This
= impl_from_ITfKeystrokeMgrVtbl(iface
);
824 FIXME("STUB:(%p)\n",This
);
828 static HRESULT WINAPI
KeystrokeMgr_SimulatePreservedKey(ITfKeystrokeMgr
*iface
,
829 ITfContext
*pic
, REFGUID rguid
, BOOL
*pfEaten
)
831 ThreadMgr
*This
= impl_from_ITfKeystrokeMgrVtbl(iface
);
832 FIXME("STUB:(%p)\n",This
);
836 static const ITfKeystrokeMgrVtbl ThreadMgr_KeystrokeMgrVtbl
=
838 KeystrokeMgr_QueryInterface
,
840 KeystrokeMgr_Release
,
842 KeystrokeMgr_AdviseKeyEventSink
,
843 KeystrokeMgr_UnadviseKeyEventSink
,
844 KeystrokeMgr_GetForeground
,
845 KeystrokeMgr_TestKeyDown
,
846 KeystrokeMgr_TestKeyUp
,
847 KeystrokeMgr_KeyDown
,
849 KeystrokeMgr_GetPreservedKey
,
850 KeystrokeMgr_IsPreservedKey
,
851 KeystrokeMgr_PreserveKey
,
852 KeystrokeMgr_UnpreserveKey
,
853 KeystrokeMgr_SetPreservedKeyDescription
,
854 KeystrokeMgr_GetPreservedKeyDescription
,
855 KeystrokeMgr_SimulatePreservedKey
858 /*****************************************************
859 * ITfMessagePump functions
860 *****************************************************/
862 static HRESULT WINAPI
MessagePump_QueryInterface(ITfMessagePump
*iface
, REFIID iid
, LPVOID
*ppvOut
)
864 ThreadMgr
*This
= impl_from_ITfMessagePumpVtbl(iface
);
865 return ThreadMgr_QueryInterface((ITfThreadMgr
*)This
, iid
, *ppvOut
);
868 static ULONG WINAPI
MessagePump_AddRef(ITfMessagePump
*iface
)
870 ThreadMgr
*This
= impl_from_ITfMessagePumpVtbl(iface
);
871 return ThreadMgr_AddRef((ITfThreadMgr
*)This
);
874 static ULONG WINAPI
MessagePump_Release(ITfMessagePump
*iface
)
876 ThreadMgr
*This
= impl_from_ITfMessagePumpVtbl(iface
);
877 return ThreadMgr_Release((ITfThreadMgr
*)This
);
880 static HRESULT WINAPI
MessagePump_PeekMessageA(ITfMessagePump
*iface
,
881 LPMSG pMsg
, HWND hwnd
, UINT wMsgFilterMin
, UINT wMsgFilterMax
,
882 UINT wRemoveMsg
, BOOL
*pfResult
)
886 *pfResult
= PeekMessageA(pMsg
, hwnd
, wMsgFilterMin
, wMsgFilterMax
, wRemoveMsg
);
890 static HRESULT WINAPI
MessagePump_GetMessageA(ITfMessagePump
*iface
,
891 LPMSG pMsg
, HWND hwnd
, UINT wMsgFilterMin
, UINT wMsgFilterMax
,
896 *pfResult
= GetMessageA(pMsg
, hwnd
, wMsgFilterMin
, wMsgFilterMax
);
900 static HRESULT WINAPI
MessagePump_PeekMessageW(ITfMessagePump
*iface
,
901 LPMSG pMsg
, HWND hwnd
, UINT wMsgFilterMin
, UINT wMsgFilterMax
,
902 UINT wRemoveMsg
, BOOL
*pfResult
)
906 *pfResult
= PeekMessageW(pMsg
, hwnd
, wMsgFilterMin
, wMsgFilterMax
, wRemoveMsg
);
910 static HRESULT WINAPI
MessagePump_GetMessageW(ITfMessagePump
*iface
,
911 LPMSG pMsg
, HWND hwnd
, UINT wMsgFilterMin
, UINT wMsgFilterMax
,
916 *pfResult
= GetMessageW(pMsg
, hwnd
, wMsgFilterMin
, wMsgFilterMax
);
920 static const ITfMessagePumpVtbl ThreadMgr_MessagePumpVtbl
=
922 MessagePump_QueryInterface
,
926 MessagePump_PeekMessageA
,
927 MessagePump_GetMessageA
,
928 MessagePump_PeekMessageW
,
929 MessagePump_GetMessageW
932 /*****************************************************
933 * ITfClientId functions
934 *****************************************************/
936 static HRESULT WINAPI
ClientId_QueryInterface(ITfClientId
*iface
, REFIID iid
, LPVOID
*ppvOut
)
938 ThreadMgr
*This
= impl_from_ITfClientIdVtbl(iface
);
939 return ThreadMgr_QueryInterface((ITfThreadMgr
*)This
, iid
, *ppvOut
);
942 static ULONG WINAPI
ClientId_AddRef(ITfClientId
*iface
)
944 ThreadMgr
*This
= impl_from_ITfClientIdVtbl(iface
);
945 return ThreadMgr_AddRef((ITfThreadMgr
*)This
);
948 static ULONG WINAPI
ClientId_Release(ITfClientId
*iface
)
950 ThreadMgr
*This
= impl_from_ITfClientIdVtbl(iface
);
951 return ThreadMgr_Release((ITfThreadMgr
*)This
);
954 static HRESULT WINAPI
ClientId_GetClientId(ITfClientId
*iface
,
955 REFCLSID rclsid
, TfClientId
*ptid
)
959 ITfCategoryMgr
*catmgr
;
960 ThreadMgr
*This
= impl_from_ITfClientIdVtbl(iface
);
962 TRACE("(%p) %s\n",This
,debugstr_guid(rclsid
));
964 CategoryMgr_Constructor(NULL
,(IUnknown
**)&catmgr
);
965 hr
= ITfCategoryMgr_RegisterGUID(catmgr
,rclsid
,ptid
);
966 ITfCategoryMgr_Release(catmgr
);
971 static const ITfClientIdVtbl ThreadMgr_ClientIdVtbl
=
973 ClientId_QueryInterface
,
980 /*****************************************************
981 * ITfThreadMgrEventSink functions (internal)
982 *****************************************************/
983 static HRESULT WINAPI
ThreadMgrEventSink_QueryInterface(ITfThreadMgrEventSink
*iface
, REFIID iid
, LPVOID
*ppvOut
)
985 ThreadMgr
*This
= impl_from_ITfThreadMgrEventSink(iface
);
986 return ThreadMgr_QueryInterface((ITfThreadMgr
*)This
, iid
, *ppvOut
);
989 static ULONG WINAPI
ThreadMgrEventSink_AddRef(ITfThreadMgrEventSink
*iface
)
991 ThreadMgr
*This
= impl_from_ITfThreadMgrEventSink(iface
);
992 return ThreadMgr_AddRef((ITfThreadMgr
*)This
);
995 static ULONG WINAPI
ThreadMgrEventSink_Release(ITfThreadMgrEventSink
*iface
)
997 ThreadMgr
*This
= impl_from_ITfThreadMgrEventSink(iface
);
998 return ThreadMgr_Release((ITfThreadMgr
*)This
);
1002 static WINAPI HRESULT
ThreadMgrEventSink_OnInitDocumentMgr(
1003 ITfThreadMgrEventSink
*iface
,ITfDocumentMgr
*pdim
)
1005 struct list
*cursor
;
1006 ThreadMgr
*This
= impl_from_ITfThreadMgrEventSink(iface
);
1008 TRACE("(%p) %p\n",This
,pdim
);
1010 LIST_FOR_EACH(cursor
, &This
->ThreadMgrEventSink
)
1012 ThreadMgrSink
* sink
= LIST_ENTRY(cursor
,ThreadMgrSink
,entry
);
1013 ITfThreadMgrEventSink_OnInitDocumentMgr(sink
->interfaces
.pITfThreadMgrEventSink
,pdim
);
1019 static WINAPI HRESULT
ThreadMgrEventSink_OnUninitDocumentMgr(
1020 ITfThreadMgrEventSink
*iface
, ITfDocumentMgr
*pdim
)
1022 struct list
*cursor
;
1023 ThreadMgr
*This
= impl_from_ITfThreadMgrEventSink(iface
);
1025 TRACE("(%p) %p\n",This
,pdim
);
1027 LIST_FOR_EACH(cursor
, &This
->ThreadMgrEventSink
)
1029 ThreadMgrSink
* sink
= LIST_ENTRY(cursor
,ThreadMgrSink
,entry
);
1030 ITfThreadMgrEventSink_OnUninitDocumentMgr(sink
->interfaces
.pITfThreadMgrEventSink
,pdim
);
1036 static WINAPI HRESULT
ThreadMgrEventSink_OnSetFocus(
1037 ITfThreadMgrEventSink
*iface
, ITfDocumentMgr
*pdimFocus
,
1038 ITfDocumentMgr
*pdimPrevFocus
)
1040 struct list
*cursor
;
1041 ThreadMgr
*This
= impl_from_ITfThreadMgrEventSink(iface
);
1043 TRACE("(%p) %p %p\n",This
,pdimFocus
, pdimPrevFocus
);
1045 LIST_FOR_EACH(cursor
, &This
->ThreadMgrEventSink
)
1047 ThreadMgrSink
* sink
= LIST_ENTRY(cursor
,ThreadMgrSink
,entry
);
1048 ITfThreadMgrEventSink_OnSetFocus(sink
->interfaces
.pITfThreadMgrEventSink
, pdimFocus
, pdimPrevFocus
);
1054 static WINAPI HRESULT
ThreadMgrEventSink_OnPushContext(
1055 ITfThreadMgrEventSink
*iface
, ITfContext
*pic
)
1057 struct list
*cursor
;
1058 ThreadMgr
*This
= impl_from_ITfThreadMgrEventSink(iface
);
1060 TRACE("(%p) %p\n",This
,pic
);
1062 LIST_FOR_EACH(cursor
, &This
->ThreadMgrEventSink
)
1064 ThreadMgrSink
* sink
= LIST_ENTRY(cursor
,ThreadMgrSink
,entry
);
1065 ITfThreadMgrEventSink_OnPushContext(sink
->interfaces
.pITfThreadMgrEventSink
,pic
);
1071 static WINAPI HRESULT
ThreadMgrEventSink_OnPopContext(
1072 ITfThreadMgrEventSink
*iface
, ITfContext
*pic
)
1074 struct list
*cursor
;
1075 ThreadMgr
*This
= impl_from_ITfThreadMgrEventSink(iface
);
1077 TRACE("(%p) %p\n",This
,pic
);
1079 LIST_FOR_EACH(cursor
, &This
->ThreadMgrEventSink
)
1081 ThreadMgrSink
* sink
= LIST_ENTRY(cursor
,ThreadMgrSink
,entry
);
1082 ITfThreadMgrEventSink_OnPopContext(sink
->interfaces
.pITfThreadMgrEventSink
,pic
);
1088 static const ITfThreadMgrEventSinkVtbl ThreadMgr_ThreadMgrEventSinkVtbl
=
1090 ThreadMgrEventSink_QueryInterface
,
1091 ThreadMgrEventSink_AddRef
,
1092 ThreadMgrEventSink_Release
,
1094 ThreadMgrEventSink_OnInitDocumentMgr
,
1095 ThreadMgrEventSink_OnUninitDocumentMgr
,
1096 ThreadMgrEventSink_OnSetFocus
,
1097 ThreadMgrEventSink_OnPushContext
,
1098 ThreadMgrEventSink_OnPopContext
1101 HRESULT
ThreadMgr_Constructor(IUnknown
*pUnkOuter
, IUnknown
**ppOut
)
1105 return CLASS_E_NOAGGREGATION
;
1107 /* Only 1 ThreadMgr is created per thread */
1108 This
= TlsGetValue(tlsIndex
);
1111 ThreadMgr_AddRef((ITfThreadMgr
*)This
);
1112 *ppOut
= (IUnknown
*)This
;
1116 This
= HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY
,sizeof(ThreadMgr
));
1118 return E_OUTOFMEMORY
;
1120 This
->ThreadMgrVtbl
= &ThreadMgr_ThreadMgrVtbl
;
1121 This
->SourceVtbl
= &ThreadMgr_SourceVtbl
;
1122 This
->KeystrokeMgrVtbl
= &ThreadMgr_KeystrokeMgrVtbl
;
1123 This
->MessagePumpVtbl
= &ThreadMgr_MessagePumpVtbl
;
1124 This
->ClientIdVtbl
= &ThreadMgr_ClientIdVtbl
;
1125 This
->ThreadMgrEventSinkVtbl
= &ThreadMgr_ThreadMgrEventSinkVtbl
;
1127 TlsSetValue(tlsIndex
,This
);
1129 CompartmentMgr_Constructor((IUnknown
*)This
, &IID_IUnknown
, (IUnknown
**)&This
->CompartmentMgr
);
1131 list_init(&This
->CurrentPreservedKeys
);
1132 list_init(&This
->CreatedDocumentMgrs
);
1134 list_init(&This
->ActiveLanguageProfileNotifySink
);
1135 list_init(&This
->DisplayAttributeNotifySink
);
1136 list_init(&This
->KeyTraceEventSink
);
1137 list_init(&This
->PreservedKeyNotifySink
);
1138 list_init(&This
->ThreadFocusSink
);
1139 list_init(&This
->ThreadMgrEventSink
);
1141 TRACE("returning %p\n", This
);
1142 *ppOut
= (IUnknown
*)This
;
1146 /**************************************************
1147 * IEnumTfDocumentMgrs implementaion
1148 **************************************************/
1149 static void EnumTfDocumentMgr_Destructor(EnumTfDocumentMgr
*This
)
1151 TRACE("destroying %p\n", This
);
1152 HeapFree(GetProcessHeap(),0,This
);
1155 static HRESULT WINAPI
EnumTfDocumentMgr_QueryInterface(IEnumTfDocumentMgrs
*iface
, REFIID iid
, LPVOID
*ppvOut
)
1157 EnumTfDocumentMgr
*This
= (EnumTfDocumentMgr
*)iface
;
1160 if (IsEqualIID(iid
, &IID_IUnknown
) || IsEqualIID(iid
, &IID_IEnumTfDocumentMgrs
))
1167 IUnknown_AddRef(iface
);
1171 WARN("unsupported interface: %s\n", debugstr_guid(iid
));
1172 return E_NOINTERFACE
;
1175 static ULONG WINAPI
EnumTfDocumentMgr_AddRef(IEnumTfDocumentMgrs
*iface
)
1177 EnumTfDocumentMgr
*This
= (EnumTfDocumentMgr
*)iface
;
1178 return InterlockedIncrement(&This
->refCount
);
1181 static ULONG WINAPI
EnumTfDocumentMgr_Release(IEnumTfDocumentMgrs
*iface
)
1183 EnumTfDocumentMgr
*This
= (EnumTfDocumentMgr
*)iface
;
1186 ret
= InterlockedDecrement(&This
->refCount
);
1188 EnumTfDocumentMgr_Destructor(This
);
1192 static HRESULT WINAPI
EnumTfDocumentMgr_Next(IEnumTfDocumentMgrs
*iface
,
1193 ULONG ulCount
, ITfDocumentMgr
**rgDocumentMgr
, ULONG
*pcFetched
)
1195 EnumTfDocumentMgr
*This
= (EnumTfDocumentMgr
*)iface
;
1198 TRACE("(%p)\n",This
);
1200 if (rgDocumentMgr
== NULL
) return E_POINTER
;
1202 while (fetched
< ulCount
)
1204 DocumentMgrEntry
*mgrentry
;
1205 if (This
->index
== NULL
)
1208 mgrentry
= LIST_ENTRY(This
->index
,DocumentMgrEntry
,entry
);
1209 if (mgrentry
== NULL
)
1212 *rgDocumentMgr
= mgrentry
->docmgr
;
1213 ITfDocumentMgr_AddRef(*rgDocumentMgr
);
1215 This
->index
= list_next(This
->head
, This
->index
);
1220 if (pcFetched
) *pcFetched
= fetched
;
1221 return fetched
== ulCount
? S_OK
: S_FALSE
;
1224 static HRESULT WINAPI
EnumTfDocumentMgr_Skip( IEnumTfDocumentMgrs
* iface
, ULONG celt
)
1227 EnumTfDocumentMgr
*This
= (EnumTfDocumentMgr
*)iface
;
1228 TRACE("(%p)\n",This
);
1229 for(i
= 0; i
< celt
&& This
->index
!= NULL
; i
++)
1230 This
->index
= list_next(This
->head
, This
->index
);
1234 static HRESULT WINAPI
EnumTfDocumentMgr_Reset( IEnumTfDocumentMgrs
* iface
)
1236 EnumTfDocumentMgr
*This
= (EnumTfDocumentMgr
*)iface
;
1237 TRACE("(%p)\n",This
);
1238 This
->index
= list_head(This
->head
);
1242 static HRESULT WINAPI
EnumTfDocumentMgr_Clone( IEnumTfDocumentMgrs
*iface
,
1243 IEnumTfDocumentMgrs
**ppenum
)
1245 EnumTfDocumentMgr
*This
= (EnumTfDocumentMgr
*)iface
;
1248 TRACE("(%p)\n",This
);
1250 if (ppenum
== NULL
) return E_POINTER
;
1252 res
= EnumTfDocumentMgr_Constructor(This
->head
, ppenum
);
1255 EnumTfDocumentMgr
*new_This
= (EnumTfDocumentMgr
*)*ppenum
;
1256 new_This
->index
= This
->index
;
1261 static const IEnumTfDocumentMgrsVtbl IEnumTfDocumentMgrs_Vtbl
={
1262 EnumTfDocumentMgr_QueryInterface
,
1263 EnumTfDocumentMgr_AddRef
,
1264 EnumTfDocumentMgr_Release
,
1266 EnumTfDocumentMgr_Clone
,
1267 EnumTfDocumentMgr_Next
,
1268 EnumTfDocumentMgr_Reset
,
1269 EnumTfDocumentMgr_Skip
1272 static HRESULT
EnumTfDocumentMgr_Constructor(struct list
* head
, IEnumTfDocumentMgrs
**ppOut
)
1274 EnumTfDocumentMgr
*This
;
1276 This
= HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY
,sizeof(EnumTfDocumentMgr
));
1278 return E_OUTOFMEMORY
;
1280 This
->Vtbl
= &IEnumTfDocumentMgrs_Vtbl
;
1283 This
->index
= list_head(This
->head
);
1285 TRACE("returning %p\n", This
);
1286 *ppOut
= (IEnumTfDocumentMgrs
*)This
;
1290 void ThreadMgr_OnDocumentMgrDestruction(ITfThreadMgr
*tm
, ITfDocumentMgr
*mgr
)
1292 ThreadMgr
*This
= (ThreadMgr
*)tm
;
1293 struct list
*cursor
;
1294 LIST_FOR_EACH(cursor
, &This
->CreatedDocumentMgrs
)
1296 DocumentMgrEntry
*mgrentry
= LIST_ENTRY(cursor
,DocumentMgrEntry
,entry
);
1297 if (mgrentry
->docmgr
== mgr
)
1299 list_remove(cursor
);
1300 HeapFree(GetProcessHeap(),0,mgrentry
);
1304 FIXME("ITfDocumenMgr %p not found in this thread\n",mgr
);