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
;