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
)
369 ThreadMgr
*This
= (ThreadMgr
*)iface
;
370 TRACE("(%p) %p\n",This
,pfThreadFocus
);
372 *pfThreadFocus
= (focus
== NULL
);
376 static HRESULT WINAPI
ThreadMgr_GetFunctionProvider( ITfThreadMgr
* iface
, REFCLSID clsid
,
377 ITfFunctionProvider
**ppFuncProv
)
379 ThreadMgr
*This
= (ThreadMgr
*)iface
;
380 FIXME("STUB:(%p)\n",This
);
384 static HRESULT WINAPI
ThreadMgr_EnumFunctionProviders( ITfThreadMgr
* iface
,
385 IEnumTfFunctionProviders
**ppEnum
)
387 ThreadMgr
*This
= (ThreadMgr
*)iface
;
388 FIXME("STUB:(%p)\n",This
);
392 static HRESULT WINAPI
ThreadMgr_GetGlobalCompartment( ITfThreadMgr
* iface
,
393 ITfCompartmentMgr
**ppCompMgr
)
395 ThreadMgr
*This
= (ThreadMgr
*)iface
;
397 TRACE("(%p) %p\n",This
, ppCompMgr
);
402 if (!globalCompartmentMgr
)
404 hr
= CompartmentMgr_Constructor(NULL
,&IID_ITfCompartmentMgr
,(IUnknown
**)&globalCompartmentMgr
);
409 ITfCompartmentMgr_AddRef(globalCompartmentMgr
);
410 *ppCompMgr
= globalCompartmentMgr
;
414 static const ITfThreadMgrVtbl ThreadMgr_ThreadMgrVtbl
=
416 ThreadMgr_QueryInterface
,
420 ThreadMgr_fnActivate
,
421 ThreadMgr_fnDeactivate
,
422 ThreadMgr_CreateDocumentMgr
,
423 ThreadMgr_EnumDocumentMgrs
,
426 ThreadMgr_AssociateFocus
,
427 ThreadMgr_IsThreadFocus
,
428 ThreadMgr_GetFunctionProvider
,
429 ThreadMgr_EnumFunctionProviders
,
430 ThreadMgr_GetGlobalCompartment
434 static HRESULT WINAPI
Source_QueryInterface(ITfSource
*iface
, REFIID iid
, LPVOID
*ppvOut
)
436 ThreadMgr
*This
= impl_from_ITfSourceVtbl(iface
);
437 return ThreadMgr_QueryInterface((ITfThreadMgr
*)This
, iid
, *ppvOut
);
440 static ULONG WINAPI
Source_AddRef(ITfSource
*iface
)
442 ThreadMgr
*This
= impl_from_ITfSourceVtbl(iface
);
443 return ThreadMgr_AddRef((ITfThreadMgr
*)This
);
446 static ULONG WINAPI
Source_Release(ITfSource
*iface
)
448 ThreadMgr
*This
= impl_from_ITfSourceVtbl(iface
);
449 return ThreadMgr_Release((ITfThreadMgr
*)This
);
452 /*****************************************************
453 * ITfSource functions
454 *****************************************************/
455 static WINAPI HRESULT
ThreadMgrSource_AdviseSink(ITfSource
*iface
,
456 REFIID riid
, IUnknown
*punk
, DWORD
*pdwCookie
)
459 ThreadMgr
*This
= impl_from_ITfSourceVtbl(iface
);
461 TRACE("(%p) %s %p %p\n",This
,debugstr_guid(riid
),punk
,pdwCookie
);
463 if (!riid
|| !punk
|| !pdwCookie
)
466 if (IsEqualIID(riid
, &IID_ITfThreadMgrEventSink
))
468 tms
= HeapAlloc(GetProcessHeap(),0,sizeof(ThreadMgrSink
));
470 return E_OUTOFMEMORY
;
471 if (FAILED(IUnknown_QueryInterface(punk
, riid
, (LPVOID
*)&tms
->interfaces
.pITfThreadMgrEventSink
)))
473 HeapFree(GetProcessHeap(),0,tms
);
474 return CONNECT_E_CANNOTCONNECT
;
476 list_add_head(&This
->ThreadMgrEventSink
,&tms
->entry
);
477 *pdwCookie
= generate_Cookie(COOKIE_MAGIC_TMSINK
, tms
);
481 FIXME("(%p) Unhandled Sink: %s\n",This
,debugstr_guid(riid
));
485 TRACE("cookie %x\n",*pdwCookie
);
490 static WINAPI HRESULT
ThreadMgrSource_UnadviseSink(ITfSource
*iface
, DWORD pdwCookie
)
493 ThreadMgr
*This
= impl_from_ITfSourceVtbl(iface
);
495 TRACE("(%p) %x\n",This
,pdwCookie
);
497 if (get_Cookie_magic(pdwCookie
)!=COOKIE_MAGIC_TMSINK
)
500 sink
= (ThreadMgrSink
*)remove_Cookie(pdwCookie
);
502 return CONNECT_E_NOCONNECTION
;
504 list_remove(&sink
->entry
);
510 static const ITfSourceVtbl ThreadMgr_SourceVtbl
=
512 Source_QueryInterface
,
516 ThreadMgrSource_AdviseSink
,
517 ThreadMgrSource_UnadviseSink
,
520 /*****************************************************
521 * ITfKeystrokeMgr functions
522 *****************************************************/
524 static HRESULT WINAPI
KeystrokeMgr_QueryInterface(ITfKeystrokeMgr
*iface
, REFIID iid
, LPVOID
*ppvOut
)
526 ThreadMgr
*This
= impl_from_ITfKeystrokeMgrVtbl(iface
);
527 return ThreadMgr_QueryInterface((ITfThreadMgr
*)This
, iid
, *ppvOut
);
530 static ULONG WINAPI
KeystrokeMgr_AddRef(ITfKeystrokeMgr
*iface
)
532 ThreadMgr
*This
= impl_from_ITfKeystrokeMgrVtbl(iface
);
533 return ThreadMgr_AddRef((ITfThreadMgr
*)This
);
536 static ULONG WINAPI
KeystrokeMgr_Release(ITfKeystrokeMgr
*iface
)
538 ThreadMgr
*This
= impl_from_ITfKeystrokeMgrVtbl(iface
);
539 return ThreadMgr_Release((ITfThreadMgr
*)This
);
542 static HRESULT WINAPI
KeystrokeMgr_AdviseKeyEventSink(ITfKeystrokeMgr
*iface
,
543 TfClientId tid
, ITfKeyEventSink
*pSink
, BOOL fForeground
)
545 ThreadMgr
*This
= impl_from_ITfKeystrokeMgrVtbl(iface
);
547 ITfKeyEventSink
*check
= NULL
;
549 TRACE("(%p) %x %p %i\n",This
,tid
,pSink
,fForeground
);
554 textservice
= get_textservice_clsid(tid
);
555 if (IsEqualCLSID(&GUID_NULL
,&textservice
))
558 get_textservice_sink(tid
, &IID_ITfKeyEventSink
, (IUnknown
**)&check
);
560 return CONNECT_E_ADVISELIMIT
;
562 if (FAILED(IUnknown_QueryInterface(pSink
,&IID_ITfKeyEventSink
,(LPVOID
*) &check
)))
565 set_textservice_sink(tid
, &IID_ITfKeyEventSink
, (IUnknown
*)check
);
569 if (This
->forgroundKeyEventSink
)
571 ITfKeyEventSink_OnSetFocus(This
->forgroundKeyEventSink
, FALSE
);
572 ITfKeyEventSink_Release(This
->forgroundKeyEventSink
);
574 ITfKeyEventSink_AddRef(check
);
575 ITfKeyEventSink_OnSetFocus(check
, TRUE
);
576 This
->forgroundKeyEventSink
= check
;
577 This
->forgroundTextService
= textservice
;
582 static HRESULT WINAPI
KeystrokeMgr_UnadviseKeyEventSink(ITfKeystrokeMgr
*iface
,
585 ThreadMgr
*This
= impl_from_ITfKeystrokeMgrVtbl(iface
);
587 ITfKeyEventSink
*check
= NULL
;
588 TRACE("(%p) %x\n",This
,tid
);
593 textservice
= get_textservice_clsid(tid
);
594 if (IsEqualCLSID(&GUID_NULL
,&textservice
))
597 get_textservice_sink(tid
, &IID_ITfKeyEventSink
, (IUnknown
**)&check
);
600 return CONNECT_E_NOCONNECTION
;
602 set_textservice_sink(tid
, &IID_ITfKeyEventSink
, NULL
);
603 ITfKeyEventSink_Release(check
);
605 if (This
->forgroundKeyEventSink
== check
)
607 ITfKeyEventSink_Release(This
->forgroundKeyEventSink
);
608 This
->forgroundKeyEventSink
= NULL
;
609 This
->forgroundTextService
= GUID_NULL
;
614 static HRESULT WINAPI
KeystrokeMgr_GetForeground(ITfKeystrokeMgr
*iface
,
617 ThreadMgr
*This
= impl_from_ITfKeystrokeMgrVtbl(iface
);
618 TRACE("(%p) %p\n",This
,pclsid
);
622 if (IsEqualCLSID(&This
->forgroundTextService
,&GUID_NULL
))
625 *pclsid
= This
->forgroundTextService
;
629 static HRESULT WINAPI
KeystrokeMgr_TestKeyDown(ITfKeystrokeMgr
*iface
,
630 WPARAM wParam
, LPARAM lParam
, BOOL
*pfEaten
)
632 ThreadMgr
*This
= impl_from_ITfKeystrokeMgrVtbl(iface
);
633 FIXME("STUB:(%p)\n",This
);
637 static HRESULT WINAPI
KeystrokeMgr_TestKeyUp(ITfKeystrokeMgr
*iface
,
638 WPARAM wParam
, LPARAM lParam
, BOOL
*pfEaten
)
640 ThreadMgr
*This
= impl_from_ITfKeystrokeMgrVtbl(iface
);
641 FIXME("STUB:(%p)\n",This
);
645 static HRESULT WINAPI
KeystrokeMgr_KeyDown(ITfKeystrokeMgr
*iface
,
646 WPARAM wParam
, LPARAM lParam
, BOOL
*pfEaten
)
648 ThreadMgr
*This
= impl_from_ITfKeystrokeMgrVtbl(iface
);
649 FIXME("STUB:(%p)\n",This
);
653 static HRESULT WINAPI
KeystrokeMgr_KeyUp(ITfKeystrokeMgr
*iface
,
654 WPARAM wParam
, LPARAM lParam
, BOOL
*pfEaten
)
656 ThreadMgr
*This
= impl_from_ITfKeystrokeMgrVtbl(iface
);
657 FIXME("STUB:(%p)\n",This
);
661 static HRESULT WINAPI
KeystrokeMgr_GetPreservedKey(ITfKeystrokeMgr
*iface
,
662 ITfContext
*pic
, const TF_PRESERVEDKEY
*pprekey
, GUID
*pguid
)
664 ThreadMgr
*This
= impl_from_ITfKeystrokeMgrVtbl(iface
);
665 FIXME("STUB:(%p)\n",This
);
669 static HRESULT WINAPI
KeystrokeMgr_IsPreservedKey(ITfKeystrokeMgr
*iface
,
670 REFGUID rguid
, const TF_PRESERVEDKEY
*pprekey
, BOOL
*pfRegistered
)
672 ThreadMgr
*This
= impl_from_ITfKeystrokeMgrVtbl(iface
);
675 TRACE("(%p) %s (%x %x) %p\n",This
,debugstr_guid(rguid
), (pprekey
)?pprekey
->uVKey
:0, (pprekey
)?pprekey
->uModifiers
:0, pfRegistered
);
677 if (!rguid
|| !pprekey
|| !pfRegistered
)
680 LIST_FOR_EACH(cursor
, &This
->CurrentPreservedKeys
)
682 PreservedKey
* key
= LIST_ENTRY(cursor
,PreservedKey
,entry
);
683 if (IsEqualGUID(rguid
,&key
->guid
) && pprekey
->uVKey
== key
->prekey
.uVKey
&& pprekey
->uModifiers
== key
->prekey
.uModifiers
)
685 *pfRegistered
= TRUE
;
690 *pfRegistered
= FALSE
;
694 static HRESULT WINAPI
KeystrokeMgr_PreserveKey(ITfKeystrokeMgr
*iface
,
695 TfClientId tid
, REFGUID rguid
, const TF_PRESERVEDKEY
*prekey
,
696 const WCHAR
*pchDesc
, ULONG cchDesc
)
698 ThreadMgr
*This
= impl_from_ITfKeystrokeMgrVtbl(iface
);
700 PreservedKey
*newkey
;
702 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
));
704 if (!tid
|| ! rguid
|| !prekey
|| (cchDesc
&& !pchDesc
))
707 LIST_FOR_EACH(cursor
, &This
->CurrentPreservedKeys
)
709 PreservedKey
* key
= LIST_ENTRY(cursor
,PreservedKey
,entry
);
710 if (IsEqualGUID(rguid
,&key
->guid
) && prekey
->uVKey
== key
->prekey
.uVKey
&& prekey
->uModifiers
== key
->prekey
.uModifiers
)
711 return TF_E_ALREADY_EXISTS
;
714 newkey
= HeapAlloc(GetProcessHeap(),0,sizeof(PreservedKey
));
716 return E_OUTOFMEMORY
;
718 newkey
->guid
= *rguid
;
719 newkey
->prekey
= *prekey
;
723 newkey
->description
= HeapAlloc(GetProcessHeap(),0,cchDesc
* sizeof(WCHAR
));
724 if (!newkey
->description
)
726 HeapFree(GetProcessHeap(),0,newkey
);
727 return E_OUTOFMEMORY
;
729 memcpy(newkey
->description
, pchDesc
, cchDesc
*sizeof(WCHAR
));
732 list_add_head(&This
->CurrentPreservedKeys
,&newkey
->entry
);
737 static HRESULT WINAPI
KeystrokeMgr_UnpreserveKey(ITfKeystrokeMgr
*iface
,
738 REFGUID rguid
, const TF_PRESERVEDKEY
*pprekey
)
740 ThreadMgr
*This
= impl_from_ITfKeystrokeMgrVtbl(iface
);
741 PreservedKey
* key
= NULL
;
743 TRACE("(%p) %s (%x %x)\n",This
,debugstr_guid(rguid
),(pprekey
)?pprekey
->uVKey
:0, (pprekey
)?pprekey
->uModifiers
:0);
745 if (!pprekey
|| !rguid
)
748 LIST_FOR_EACH(cursor
, &This
->CurrentPreservedKeys
)
750 key
= LIST_ENTRY(cursor
,PreservedKey
,entry
);
751 if (IsEqualGUID(rguid
,&key
->guid
) && pprekey
->uVKey
== key
->prekey
.uVKey
&& pprekey
->uModifiers
== key
->prekey
.uModifiers
)
757 return CONNECT_E_NOCONNECTION
;
759 list_remove(&key
->entry
);
760 HeapFree(GetProcessHeap(),0,key
->description
);
761 HeapFree(GetProcessHeap(),0,key
);
766 static HRESULT WINAPI
KeystrokeMgr_SetPreservedKeyDescription(ITfKeystrokeMgr
*iface
,
767 REFGUID rguid
, const WCHAR
*pchDesc
, ULONG cchDesc
)
769 ThreadMgr
*This
= impl_from_ITfKeystrokeMgrVtbl(iface
);
770 FIXME("STUB:(%p)\n",This
);
774 static HRESULT WINAPI
KeystrokeMgr_GetPreservedKeyDescription(ITfKeystrokeMgr
*iface
,
775 REFGUID rguid
, BSTR
*pbstrDesc
)
777 ThreadMgr
*This
= impl_from_ITfKeystrokeMgrVtbl(iface
);
778 FIXME("STUB:(%p)\n",This
);
782 static HRESULT WINAPI
KeystrokeMgr_SimulatePreservedKey(ITfKeystrokeMgr
*iface
,
783 ITfContext
*pic
, REFGUID rguid
, BOOL
*pfEaten
)
785 ThreadMgr
*This
= impl_from_ITfKeystrokeMgrVtbl(iface
);
786 FIXME("STUB:(%p)\n",This
);
790 static const ITfKeystrokeMgrVtbl ThreadMgr_KeystrokeMgrVtbl
=
792 KeystrokeMgr_QueryInterface
,
794 KeystrokeMgr_Release
,
796 KeystrokeMgr_AdviseKeyEventSink
,
797 KeystrokeMgr_UnadviseKeyEventSink
,
798 KeystrokeMgr_GetForeground
,
799 KeystrokeMgr_TestKeyDown
,
800 KeystrokeMgr_TestKeyUp
,
801 KeystrokeMgr_KeyDown
,
803 KeystrokeMgr_GetPreservedKey
,
804 KeystrokeMgr_IsPreservedKey
,
805 KeystrokeMgr_PreserveKey
,
806 KeystrokeMgr_UnpreserveKey
,
807 KeystrokeMgr_SetPreservedKeyDescription
,
808 KeystrokeMgr_GetPreservedKeyDescription
,
809 KeystrokeMgr_SimulatePreservedKey
812 /*****************************************************
813 * ITfMessagePump functions
814 *****************************************************/
816 static HRESULT WINAPI
MessagePump_QueryInterface(ITfMessagePump
*iface
, REFIID iid
, LPVOID
*ppvOut
)
818 ThreadMgr
*This
= impl_from_ITfMessagePumpVtbl(iface
);
819 return ThreadMgr_QueryInterface((ITfThreadMgr
*)This
, iid
, *ppvOut
);
822 static ULONG WINAPI
MessagePump_AddRef(ITfMessagePump
*iface
)
824 ThreadMgr
*This
= impl_from_ITfMessagePumpVtbl(iface
);
825 return ThreadMgr_AddRef((ITfThreadMgr
*)This
);
828 static ULONG WINAPI
MessagePump_Release(ITfMessagePump
*iface
)
830 ThreadMgr
*This
= impl_from_ITfMessagePumpVtbl(iface
);
831 return ThreadMgr_Release((ITfThreadMgr
*)This
);
834 static HRESULT WINAPI
MessagePump_PeekMessageA(ITfMessagePump
*iface
,
835 LPMSG pMsg
, HWND hwnd
, UINT wMsgFilterMin
, UINT wMsgFilterMax
,
836 UINT wRemoveMsg
, BOOL
*pfResult
)
840 *pfResult
= PeekMessageA(pMsg
, hwnd
, wMsgFilterMin
, wMsgFilterMax
, wRemoveMsg
);
844 static HRESULT WINAPI
MessagePump_GetMessageA(ITfMessagePump
*iface
,
845 LPMSG pMsg
, HWND hwnd
, UINT wMsgFilterMin
, UINT wMsgFilterMax
,
850 *pfResult
= GetMessageA(pMsg
, hwnd
, wMsgFilterMin
, wMsgFilterMax
);
854 static HRESULT WINAPI
MessagePump_PeekMessageW(ITfMessagePump
*iface
,
855 LPMSG pMsg
, HWND hwnd
, UINT wMsgFilterMin
, UINT wMsgFilterMax
,
856 UINT wRemoveMsg
, BOOL
*pfResult
)
860 *pfResult
= PeekMessageW(pMsg
, hwnd
, wMsgFilterMin
, wMsgFilterMax
, wRemoveMsg
);
864 static HRESULT WINAPI
MessagePump_GetMessageW(ITfMessagePump
*iface
,
865 LPMSG pMsg
, HWND hwnd
, UINT wMsgFilterMin
, UINT wMsgFilterMax
,
870 *pfResult
= GetMessageW(pMsg
, hwnd
, wMsgFilterMin
, wMsgFilterMax
);
874 static const ITfMessagePumpVtbl ThreadMgr_MessagePumpVtbl
=
876 MessagePump_QueryInterface
,
880 MessagePump_PeekMessageA
,
881 MessagePump_GetMessageA
,
882 MessagePump_PeekMessageW
,
883 MessagePump_GetMessageW
886 /*****************************************************
887 * ITfClientId functions
888 *****************************************************/
890 static HRESULT WINAPI
ClientId_QueryInterface(ITfClientId
*iface
, REFIID iid
, LPVOID
*ppvOut
)
892 ThreadMgr
*This
= impl_from_ITfClientIdVtbl(iface
);
893 return ThreadMgr_QueryInterface((ITfThreadMgr
*)This
, iid
, *ppvOut
);
896 static ULONG WINAPI
ClientId_AddRef(ITfClientId
*iface
)
898 ThreadMgr
*This
= impl_from_ITfClientIdVtbl(iface
);
899 return ThreadMgr_AddRef((ITfThreadMgr
*)This
);
902 static ULONG WINAPI
ClientId_Release(ITfClientId
*iface
)
904 ThreadMgr
*This
= impl_from_ITfClientIdVtbl(iface
);
905 return ThreadMgr_Release((ITfThreadMgr
*)This
);
908 static HRESULT WINAPI
ClientId_GetClientId(ITfClientId
*iface
,
909 REFCLSID rclsid
, TfClientId
*ptid
)
913 ITfCategoryMgr
*catmgr
;
914 ThreadMgr
*This
= impl_from_ITfClientIdVtbl(iface
);
916 TRACE("(%p) %s\n",This
,debugstr_guid(rclsid
));
918 CategoryMgr_Constructor(NULL
,(IUnknown
**)&catmgr
);
919 hr
= ITfCategoryMgr_RegisterGUID(catmgr
,rclsid
,ptid
);
920 ITfCategoryMgr_Release(catmgr
);
925 static const ITfClientIdVtbl ThreadMgr_ClientIdVtbl
=
927 ClientId_QueryInterface
,
934 /*****************************************************
935 * ITfThreadMgrEventSink functions (internal)
936 *****************************************************/
937 static HRESULT WINAPI
ThreadMgrEventSink_QueryInterface(ITfThreadMgrEventSink
*iface
, REFIID iid
, LPVOID
*ppvOut
)
939 ThreadMgr
*This
= impl_from_ITfThreadMgrEventSink(iface
);
940 return ThreadMgr_QueryInterface((ITfThreadMgr
*)This
, iid
, *ppvOut
);
943 static ULONG WINAPI
ThreadMgrEventSink_AddRef(ITfThreadMgrEventSink
*iface
)
945 ThreadMgr
*This
= impl_from_ITfThreadMgrEventSink(iface
);
946 return ThreadMgr_AddRef((ITfThreadMgr
*)This
);
949 static ULONG WINAPI
ThreadMgrEventSink_Release(ITfThreadMgrEventSink
*iface
)
951 ThreadMgr
*This
= impl_from_ITfThreadMgrEventSink(iface
);
952 return ThreadMgr_Release((ITfThreadMgr
*)This
);
956 static WINAPI HRESULT
ThreadMgrEventSink_OnInitDocumentMgr(
957 ITfThreadMgrEventSink
*iface
,ITfDocumentMgr
*pdim
)
960 ThreadMgr
*This
= impl_from_ITfThreadMgrEventSink(iface
);
962 TRACE("(%p) %p\n",This
,pdim
);
964 LIST_FOR_EACH(cursor
, &This
->ThreadMgrEventSink
)
966 ThreadMgrSink
* sink
= LIST_ENTRY(cursor
,ThreadMgrSink
,entry
);
967 ITfThreadMgrEventSink_OnInitDocumentMgr(sink
->interfaces
.pITfThreadMgrEventSink
,pdim
);
973 static WINAPI HRESULT
ThreadMgrEventSink_OnUninitDocumentMgr(
974 ITfThreadMgrEventSink
*iface
, ITfDocumentMgr
*pdim
)
977 ThreadMgr
*This
= impl_from_ITfThreadMgrEventSink(iface
);
979 TRACE("(%p) %p\n",This
,pdim
);
981 LIST_FOR_EACH(cursor
, &This
->ThreadMgrEventSink
)
983 ThreadMgrSink
* sink
= LIST_ENTRY(cursor
,ThreadMgrSink
,entry
);
984 ITfThreadMgrEventSink_OnUninitDocumentMgr(sink
->interfaces
.pITfThreadMgrEventSink
,pdim
);
990 static WINAPI HRESULT
ThreadMgrEventSink_OnSetFocus(
991 ITfThreadMgrEventSink
*iface
, ITfDocumentMgr
*pdimFocus
,
992 ITfDocumentMgr
*pdimPrevFocus
)
995 ThreadMgr
*This
= impl_from_ITfThreadMgrEventSink(iface
);
997 TRACE("(%p) %p %p\n",This
,pdimFocus
, pdimPrevFocus
);
999 LIST_FOR_EACH(cursor
, &This
->ThreadMgrEventSink
)
1001 ThreadMgrSink
* sink
= LIST_ENTRY(cursor
,ThreadMgrSink
,entry
);
1002 ITfThreadMgrEventSink_OnSetFocus(sink
->interfaces
.pITfThreadMgrEventSink
, pdimFocus
, pdimPrevFocus
);
1008 static WINAPI HRESULT
ThreadMgrEventSink_OnPushContext(
1009 ITfThreadMgrEventSink
*iface
, ITfContext
*pic
)
1011 struct list
*cursor
;
1012 ThreadMgr
*This
= impl_from_ITfThreadMgrEventSink(iface
);
1014 TRACE("(%p) %p\n",This
,pic
);
1016 LIST_FOR_EACH(cursor
, &This
->ThreadMgrEventSink
)
1018 ThreadMgrSink
* sink
= LIST_ENTRY(cursor
,ThreadMgrSink
,entry
);
1019 ITfThreadMgrEventSink_OnPushContext(sink
->interfaces
.pITfThreadMgrEventSink
,pic
);
1025 static WINAPI HRESULT
ThreadMgrEventSink_OnPopContext(
1026 ITfThreadMgrEventSink
*iface
, ITfContext
*pic
)
1028 struct list
*cursor
;
1029 ThreadMgr
*This
= impl_from_ITfThreadMgrEventSink(iface
);
1031 TRACE("(%p) %p\n",This
,pic
);
1033 LIST_FOR_EACH(cursor
, &This
->ThreadMgrEventSink
)
1035 ThreadMgrSink
* sink
= LIST_ENTRY(cursor
,ThreadMgrSink
,entry
);
1036 ITfThreadMgrEventSink_OnPopContext(sink
->interfaces
.pITfThreadMgrEventSink
,pic
);
1042 static const ITfThreadMgrEventSinkVtbl ThreadMgr_ThreadMgrEventSinkVtbl
=
1044 ThreadMgrEventSink_QueryInterface
,
1045 ThreadMgrEventSink_AddRef
,
1046 ThreadMgrEventSink_Release
,
1048 ThreadMgrEventSink_OnInitDocumentMgr
,
1049 ThreadMgrEventSink_OnUninitDocumentMgr
,
1050 ThreadMgrEventSink_OnSetFocus
,
1051 ThreadMgrEventSink_OnPushContext
,
1052 ThreadMgrEventSink_OnPopContext
1055 HRESULT
ThreadMgr_Constructor(IUnknown
*pUnkOuter
, IUnknown
**ppOut
)
1059 return CLASS_E_NOAGGREGATION
;
1061 /* Only 1 ThreadMgr is created per thread */
1062 This
= TlsGetValue(tlsIndex
);
1065 ThreadMgr_AddRef((ITfThreadMgr
*)This
);
1066 *ppOut
= (IUnknown
*)This
;
1070 This
= HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY
,sizeof(ThreadMgr
));
1072 return E_OUTOFMEMORY
;
1074 This
->ThreadMgrVtbl
= &ThreadMgr_ThreadMgrVtbl
;
1075 This
->SourceVtbl
= &ThreadMgr_SourceVtbl
;
1076 This
->KeystrokeMgrVtbl
= &ThreadMgr_KeystrokeMgrVtbl
;
1077 This
->MessagePumpVtbl
= &ThreadMgr_MessagePumpVtbl
;
1078 This
->ClientIdVtbl
= &ThreadMgr_ClientIdVtbl
;
1079 This
->ThreadMgrEventSinkVtbl
= &ThreadMgr_ThreadMgrEventSinkVtbl
;
1081 TlsSetValue(tlsIndex
,This
);
1083 CompartmentMgr_Constructor((IUnknown
*)This
, &IID_IUnknown
, (IUnknown
**)&This
->CompartmentMgr
);
1085 list_init(&This
->CurrentPreservedKeys
);
1087 list_init(&This
->ActiveLanguageProfileNotifySink
);
1088 list_init(&This
->DisplayAttributeNotifySink
);
1089 list_init(&This
->KeyTraceEventSink
);
1090 list_init(&This
->PreservedKeyNotifySink
);
1091 list_init(&This
->ThreadFocusSink
);
1092 list_init(&This
->ThreadMgrEventSink
);
1094 TRACE("returning %p\n", This
);
1095 *ppOut
= (IUnknown
*)This
;