makefiles: Don't use standard libs for programs that specify -nodefaultlibs.
[wine/zf.git] / dlls / msctf / threadmgr.c
blob77cf47ca4f683c53405d4d5a10c2d561c0d20c5d
1 /*
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
21 #include <stdarg.h>
23 #define COBJMACROS
25 #include "wine/debug.h"
26 #include "windef.h"
27 #include "winbase.h"
28 #include "winreg.h"
29 #include "winuser.h"
30 #include "shlwapi.h"
31 #include "winerror.h"
32 #include "objbase.h"
33 #include "olectl.h"
35 #include "msctf.h"
36 #include "msctf_internal.h"
38 WINE_DEFAULT_DEBUG_CHANNEL(msctf);
40 typedef struct tagPreservedKey
42 struct list entry;
43 GUID guid;
44 TF_PRESERVEDKEY prekey;
45 LPWSTR description;
46 TfClientId tid;
47 } PreservedKey;
49 typedef struct tagDocumentMgrs
51 struct list entry;
52 ITfDocumentMgr *docmgr;
53 } DocumentMgrEntry;
55 typedef struct tagAssociatedWindow
57 struct list entry;
58 HWND hwnd;
59 ITfDocumentMgr *docmgr;
60 } AssociatedWindow;
62 typedef struct tagACLMulti {
63 ITfThreadMgrEx ITfThreadMgrEx_iface;
64 ITfSource ITfSource_iface;
65 ITfKeystrokeMgr ITfKeystrokeMgr_iface;
66 ITfMessagePump ITfMessagePump_iface;
67 ITfClientId ITfClientId_iface;
68 /* const ITfThreadMgrExVtbl *ThreadMgrExVtbl; */
69 /* const ITfConfigureSystemKeystrokeFeedVtbl *ConfigureSystemKeystrokeFeedVtbl; */
70 /* const ITfLangBarItemMgrVtbl *LangBarItemMgrVtbl; */
71 ITfUIElementMgr ITfUIElementMgr_iface;
72 ITfSourceSingle ITfSourceSingle_iface;
73 LONG refCount;
75 /* Aggregation */
76 ITfCompartmentMgr *CompartmentMgr;
78 ITfThreadMgrEventSink ITfThreadMgrEventSink_iface; /* internal */
80 ITfDocumentMgr *focus;
81 LONG activationCount;
83 ITfKeyEventSink *foregroundKeyEventSink;
84 CLSID foregroundTextService;
86 struct list CurrentPreservedKeys;
87 struct list CreatedDocumentMgrs;
89 struct list AssociatedFocusWindows;
90 HHOOK focusHook;
92 /* kept as separate lists to reduce unnecessary iterations */
93 struct list ActiveLanguageProfileNotifySink;
94 struct list DisplayAttributeNotifySink;
95 struct list KeyTraceEventSink;
96 struct list PreservedKeyNotifySink;
97 struct list ThreadFocusSink;
98 struct list ThreadMgrEventSink;
99 struct list UIElementSink;
100 struct list InputProcessorProfileActivationSink;
101 } ThreadMgr;
103 typedef struct tagEnumTfDocumentMgr {
104 IEnumTfDocumentMgrs IEnumTfDocumentMgrs_iface;
105 LONG refCount;
107 struct list *index;
108 struct list *head;
109 } EnumTfDocumentMgr;
111 static HRESULT EnumTfDocumentMgr_Constructor(struct list* head, IEnumTfDocumentMgrs **ppOut);
113 static inline ThreadMgr *impl_from_ITfThreadMgrEx(ITfThreadMgrEx *iface)
115 return CONTAINING_RECORD(iface, ThreadMgr, ITfThreadMgrEx_iface);
118 static inline ThreadMgr *impl_from_ITfSource(ITfSource *iface)
120 return CONTAINING_RECORD(iface, ThreadMgr, ITfSource_iface);
123 static inline ThreadMgr *impl_from_ITfKeystrokeMgr(ITfKeystrokeMgr *iface)
125 return CONTAINING_RECORD(iface, ThreadMgr, ITfKeystrokeMgr_iface);
128 static inline ThreadMgr *impl_from_ITfMessagePump(ITfMessagePump *iface)
130 return CONTAINING_RECORD(iface, ThreadMgr, ITfMessagePump_iface);
133 static inline ThreadMgr *impl_from_ITfClientId(ITfClientId *iface)
135 return CONTAINING_RECORD(iface, ThreadMgr, ITfClientId_iface);
138 static inline ThreadMgr *impl_from_ITfThreadMgrEventSink(ITfThreadMgrEventSink *iface)
140 return CONTAINING_RECORD(iface, ThreadMgr, ITfThreadMgrEventSink_iface);
143 static inline ThreadMgr *impl_from_ITfUIElementMgr(ITfUIElementMgr *iface)
145 return CONTAINING_RECORD(iface, ThreadMgr, ITfUIElementMgr_iface);
148 static inline ThreadMgr *impl_from_ITfSourceSingle(ITfSourceSingle *iface)
150 return CONTAINING_RECORD(iface, ThreadMgr, ITfSourceSingle_iface);
153 static inline EnumTfDocumentMgr *impl_from_IEnumTfDocumentMgrs(IEnumTfDocumentMgrs *iface)
155 return CONTAINING_RECORD(iface, EnumTfDocumentMgr, IEnumTfDocumentMgrs_iface);
158 static void ThreadMgr_Destructor(ThreadMgr *This)
160 struct list *cursor, *cursor2;
162 /* unhook right away */
163 if (This->focusHook)
164 UnhookWindowsHookEx(This->focusHook);
166 TlsSetValue(tlsIndex,NULL);
167 TRACE("destroying %p\n", This);
168 if (This->focus)
169 ITfDocumentMgr_Release(This->focus);
171 free_sinks(&This->ActiveLanguageProfileNotifySink);
172 free_sinks(&This->DisplayAttributeNotifySink);
173 free_sinks(&This->KeyTraceEventSink);
174 free_sinks(&This->PreservedKeyNotifySink);
175 free_sinks(&This->ThreadFocusSink);
176 free_sinks(&This->ThreadMgrEventSink);
177 free_sinks(&This->UIElementSink);
178 free_sinks(&This->InputProcessorProfileActivationSink);
180 LIST_FOR_EACH_SAFE(cursor, cursor2, &This->CurrentPreservedKeys)
182 PreservedKey* key = LIST_ENTRY(cursor,PreservedKey,entry);
183 list_remove(cursor);
184 HeapFree(GetProcessHeap(),0,key->description);
185 HeapFree(GetProcessHeap(),0,key);
188 LIST_FOR_EACH_SAFE(cursor, cursor2, &This->CreatedDocumentMgrs)
190 DocumentMgrEntry *mgr = LIST_ENTRY(cursor,DocumentMgrEntry,entry);
191 list_remove(cursor);
192 FIXME("Left Over ITfDocumentMgr. Should we do something with it?\n");
193 HeapFree(GetProcessHeap(),0,mgr);
196 LIST_FOR_EACH_SAFE(cursor, cursor2, &This->AssociatedFocusWindows)
198 AssociatedWindow *wnd = LIST_ENTRY(cursor,AssociatedWindow,entry);
199 list_remove(cursor);
200 HeapFree(GetProcessHeap(),0,wnd);
203 CompartmentMgr_Destructor(This->CompartmentMgr);
205 HeapFree(GetProcessHeap(),0,This);
208 static HRESULT WINAPI ThreadMgr_QueryInterface(ITfThreadMgrEx *iface, REFIID iid, LPVOID *ppvOut)
210 ThreadMgr *This = impl_from_ITfThreadMgrEx(iface);
211 *ppvOut = NULL;
213 if (IsEqualIID(iid, &IID_IUnknown) || IsEqualIID(iid, &IID_ITfThreadMgr)
214 || IsEqualIID(iid, &IID_ITfThreadMgrEx))
216 *ppvOut = &This->ITfThreadMgrEx_iface;
218 else if (IsEqualIID(iid, &IID_ITfSource))
220 *ppvOut = &This->ITfSource_iface;
222 else if (IsEqualIID(iid, &IID_ITfKeystrokeMgr))
224 *ppvOut = &This->ITfKeystrokeMgr_iface;
226 else if (IsEqualIID(iid, &IID_ITfMessagePump))
228 *ppvOut = &This->ITfMessagePump_iface;
230 else if (IsEqualIID(iid, &IID_ITfClientId))
232 *ppvOut = &This->ITfClientId_iface;
234 else if (IsEqualIID(iid, &IID_ITfCompartmentMgr))
236 *ppvOut = This->CompartmentMgr;
238 else if (IsEqualIID(iid, &IID_ITfUIElementMgr))
240 *ppvOut = &This->ITfUIElementMgr_iface;
242 else if (IsEqualIID(iid, &IID_ITfSourceSingle))
244 *ppvOut = &This->ITfSourceSingle_iface;
247 if (*ppvOut)
249 ITfThreadMgrEx_AddRef(iface);
250 return S_OK;
253 WARN("unsupported interface: %s\n", debugstr_guid(iid));
254 return E_NOINTERFACE;
257 static ULONG WINAPI ThreadMgr_AddRef(ITfThreadMgrEx *iface)
259 ThreadMgr *This = impl_from_ITfThreadMgrEx(iface);
260 return InterlockedIncrement(&This->refCount);
263 static ULONG WINAPI ThreadMgr_Release(ITfThreadMgrEx *iface)
265 ThreadMgr *This = impl_from_ITfThreadMgrEx(iface);
266 ULONG ret;
268 ret = InterlockedDecrement(&This->refCount);
269 if (ret == 0)
270 ThreadMgr_Destructor(This);
271 return ret;
274 /*****************************************************
275 * ITfThreadMgr functions
276 *****************************************************/
278 static HRESULT WINAPI ThreadMgr_Activate(ITfThreadMgrEx *iface, TfClientId *id)
280 ThreadMgr *This = impl_from_ITfThreadMgrEx(iface);
282 TRACE("(%p) %p\n", This, id);
283 return ITfThreadMgrEx_ActivateEx(iface, id, 0);
286 static HRESULT WINAPI ThreadMgr_Deactivate(ITfThreadMgrEx *iface)
288 ThreadMgr *This = impl_from_ITfThreadMgrEx(iface);
289 TRACE("(%p)\n",This);
291 if (This->activationCount == 0)
292 return E_UNEXPECTED;
294 This->activationCount --;
296 if (This->activationCount == 0)
298 if (This->focus)
300 ITfThreadMgrEventSink_OnSetFocus(&This->ITfThreadMgrEventSink_iface, 0, This->focus);
301 ITfDocumentMgr_Release(This->focus);
302 This->focus = 0;
306 deactivate_textservices();
308 return S_OK;
311 static HRESULT WINAPI ThreadMgr_CreateDocumentMgr(ITfThreadMgrEx *iface, ITfDocumentMgr **ppdim)
313 ThreadMgr *This = impl_from_ITfThreadMgrEx(iface);
314 DocumentMgrEntry *mgrentry;
315 HRESULT hr;
317 TRACE("(%p)\n",iface);
318 mgrentry = HeapAlloc(GetProcessHeap(),0,sizeof(DocumentMgrEntry));
319 if (mgrentry == NULL)
320 return E_OUTOFMEMORY;
322 hr = DocumentMgr_Constructor(&This->ITfThreadMgrEventSink_iface, ppdim);
324 if (SUCCEEDED(hr))
326 mgrentry->docmgr = *ppdim;
327 list_add_head(&This->CreatedDocumentMgrs,&mgrentry->entry);
329 else
330 HeapFree(GetProcessHeap(),0,mgrentry);
332 return hr;
335 static HRESULT WINAPI ThreadMgr_EnumDocumentMgrs(ITfThreadMgrEx *iface, IEnumTfDocumentMgrs **ppEnum)
337 ThreadMgr *This = impl_from_ITfThreadMgrEx(iface);
338 TRACE("(%p) %p\n",This,ppEnum);
340 if (!ppEnum)
341 return E_INVALIDARG;
343 return EnumTfDocumentMgr_Constructor(&This->CreatedDocumentMgrs, ppEnum);
346 static HRESULT WINAPI ThreadMgr_GetFocus(ITfThreadMgrEx *iface, ITfDocumentMgr **ppdimFocus)
348 ThreadMgr *This = impl_from_ITfThreadMgrEx(iface);
349 TRACE("(%p)\n",This);
351 if (!ppdimFocus)
352 return E_INVALIDARG;
354 *ppdimFocus = This->focus;
356 TRACE("->%p\n",This->focus);
358 if (This->focus == NULL)
359 return S_FALSE;
361 ITfDocumentMgr_AddRef(This->focus);
363 return S_OK;
366 static HRESULT WINAPI ThreadMgr_SetFocus(ITfThreadMgrEx *iface, ITfDocumentMgr *pdimFocus)
368 ThreadMgr *This = impl_from_ITfThreadMgrEx(iface);
369 ITfDocumentMgr *check;
371 TRACE("(%p) %p\n",This,pdimFocus);
373 if (!pdimFocus)
374 check = NULL;
375 else if (FAILED(ITfDocumentMgr_QueryInterface(pdimFocus,&IID_ITfDocumentMgr,(LPVOID*) &check)))
376 return E_INVALIDARG;
378 ITfThreadMgrEventSink_OnSetFocus(&This->ITfThreadMgrEventSink_iface, check, This->focus);
380 if (This->focus)
381 ITfDocumentMgr_Release(This->focus);
383 This->focus = check;
384 return S_OK;
387 static LRESULT CALLBACK ThreadFocusHookProc(int nCode, WPARAM wParam, LPARAM lParam)
389 ThreadMgr *This;
391 This = TlsGetValue(tlsIndex);
392 if (!This)
394 ERR("Hook proc but no ThreadMgr for this thread. Serious Error\n");
395 return 0;
397 if (!This->focusHook)
399 ERR("Hook proc but no ThreadMgr focus Hook. Serious Error\n");
400 return 0;
403 if (nCode == HCBT_SETFOCUS) /* focus change within our thread */
405 struct list *cursor;
407 LIST_FOR_EACH(cursor, &This->AssociatedFocusWindows)
409 AssociatedWindow *wnd = LIST_ENTRY(cursor,AssociatedWindow,entry);
410 if (wnd->hwnd == (HWND)wParam)
412 TRACE("Triggering Associated window focus\n");
413 if (This->focus != wnd->docmgr)
414 ThreadMgr_SetFocus(&This->ITfThreadMgrEx_iface, wnd->docmgr);
415 break;
420 return CallNextHookEx(This->focusHook, nCode, wParam, lParam);
423 static HRESULT SetupWindowsHook(ThreadMgr *This)
425 if (!This->focusHook)
427 This->focusHook = SetWindowsHookExW(WH_CBT, ThreadFocusHookProc, 0,
428 GetCurrentThreadId());
429 if (!This->focusHook)
431 ERR("Unable to set focus hook\n");
432 return E_FAIL;
434 return S_OK;
436 return S_FALSE;
439 static HRESULT WINAPI ThreadMgr_AssociateFocus(ITfThreadMgrEx *iface, HWND hwnd,
440 ITfDocumentMgr *pdimNew, ITfDocumentMgr **ppdimPrev)
442 ThreadMgr *This = impl_from_ITfThreadMgrEx(iface);
443 struct list *cursor, *cursor2;
444 AssociatedWindow *wnd;
446 TRACE("(%p) %p %p %p\n",This,hwnd,pdimNew,ppdimPrev);
448 if (!ppdimPrev)
449 return E_INVALIDARG;
451 *ppdimPrev = NULL;
453 LIST_FOR_EACH_SAFE(cursor, cursor2, &This->AssociatedFocusWindows)
455 wnd = LIST_ENTRY(cursor,AssociatedWindow,entry);
456 if (wnd->hwnd == hwnd)
458 if (wnd->docmgr)
459 ITfDocumentMgr_AddRef(wnd->docmgr);
460 *ppdimPrev = wnd->docmgr;
461 wnd->docmgr = pdimNew;
462 if (GetFocus() == hwnd)
463 ThreadMgr_SetFocus(iface,pdimNew);
464 return S_OK;
468 wnd = HeapAlloc(GetProcessHeap(),0,sizeof(AssociatedWindow));
469 wnd->hwnd = hwnd;
470 wnd->docmgr = pdimNew;
471 list_add_head(&This->AssociatedFocusWindows,&wnd->entry);
473 if (GetFocus() == hwnd)
474 ThreadMgr_SetFocus(iface,pdimNew);
476 SetupWindowsHook(This);
478 return S_OK;
481 static HRESULT WINAPI ThreadMgr_IsThreadFocus(ITfThreadMgrEx *iface, BOOL *pfThreadFocus)
483 ThreadMgr *This = impl_from_ITfThreadMgrEx(iface);
484 HWND focus;
486 TRACE("(%p) %p\n",This,pfThreadFocus);
487 focus = GetFocus();
488 *pfThreadFocus = (focus == NULL);
489 return S_OK;
492 static HRESULT WINAPI ThreadMgr_GetFunctionProvider(ITfThreadMgrEx *iface, REFCLSID clsid,
493 ITfFunctionProvider **ppFuncProv)
495 ThreadMgr *This = impl_from_ITfThreadMgrEx(iface);
496 FIXME("STUB:(%p)\n",This);
497 return E_NOTIMPL;
500 static HRESULT WINAPI ThreadMgr_EnumFunctionProviders(ITfThreadMgrEx *iface,
501 IEnumTfFunctionProviders **ppEnum)
503 ThreadMgr *This = impl_from_ITfThreadMgrEx(iface);
504 FIXME("STUB:(%p)\n",This);
505 return E_NOTIMPL;
508 static HRESULT WINAPI ThreadMgr_GetGlobalCompartment(ITfThreadMgrEx *iface,
509 ITfCompartmentMgr **ppCompMgr)
511 ThreadMgr *This = impl_from_ITfThreadMgrEx(iface);
512 HRESULT hr;
513 TRACE("(%p) %p\n",This, ppCompMgr);
515 if (!ppCompMgr)
516 return E_INVALIDARG;
518 if (!globalCompartmentMgr)
520 hr = CompartmentMgr_Constructor(NULL,&IID_ITfCompartmentMgr,(IUnknown**)&globalCompartmentMgr);
521 if (FAILED(hr))
522 return hr;
525 ITfCompartmentMgr_AddRef(globalCompartmentMgr);
526 *ppCompMgr = globalCompartmentMgr;
527 return S_OK;
530 static HRESULT WINAPI ThreadMgr_ActivateEx(ITfThreadMgrEx *iface, TfClientId *id, DWORD flags)
532 ThreadMgr *This = impl_from_ITfThreadMgrEx(iface);
534 TRACE("(%p) %p, %#x\n", This, id, flags);
536 if (!id)
537 return E_INVALIDARG;
539 if (flags)
540 FIXME("Unimplemented flags %#x\n", flags);
542 if (!processId)
544 GUID guid;
545 CoCreateGuid(&guid);
546 ITfClientId_GetClientId(&This->ITfClientId_iface, &guid, &processId);
549 activate_textservices(iface);
550 This->activationCount++;
551 *id = processId;
552 return S_OK;
555 static HRESULT WINAPI ThreadMgr_GetActiveFlags(ITfThreadMgrEx *iface, DWORD *flags)
557 ThreadMgr *This = impl_from_ITfThreadMgrEx(iface);
559 FIXME("STUB:(%p)\n", This);
560 return E_NOTIMPL;
563 static const ITfThreadMgrExVtbl ThreadMgrExVtbl =
565 ThreadMgr_QueryInterface,
566 ThreadMgr_AddRef,
567 ThreadMgr_Release,
568 ThreadMgr_Activate,
569 ThreadMgr_Deactivate,
570 ThreadMgr_CreateDocumentMgr,
571 ThreadMgr_EnumDocumentMgrs,
572 ThreadMgr_GetFocus,
573 ThreadMgr_SetFocus,
574 ThreadMgr_AssociateFocus,
575 ThreadMgr_IsThreadFocus,
576 ThreadMgr_GetFunctionProvider,
577 ThreadMgr_EnumFunctionProviders,
578 ThreadMgr_GetGlobalCompartment,
580 ThreadMgr_ActivateEx,
581 ThreadMgr_GetActiveFlags
584 static HRESULT WINAPI Source_QueryInterface(ITfSource *iface, REFIID iid, LPVOID *ppvOut)
586 ThreadMgr *This = impl_from_ITfSource(iface);
587 return ITfThreadMgrEx_QueryInterface(&This->ITfThreadMgrEx_iface, iid, ppvOut);
590 static ULONG WINAPI Source_AddRef(ITfSource *iface)
592 ThreadMgr *This = impl_from_ITfSource(iface);
593 return ITfThreadMgrEx_AddRef(&This->ITfThreadMgrEx_iface);
596 static ULONG WINAPI Source_Release(ITfSource *iface)
598 ThreadMgr *This = impl_from_ITfSource(iface);
599 return ITfThreadMgrEx_Release(&This->ITfThreadMgrEx_iface);
602 /*****************************************************
603 * ITfSource functions
604 *****************************************************/
605 static HRESULT WINAPI ThreadMgrSource_AdviseSink(ITfSource *iface,
606 REFIID riid, IUnknown *punk, DWORD *pdwCookie)
608 ThreadMgr *This = impl_from_ITfSource(iface);
610 TRACE("(%p) %s %p %p\n",This,debugstr_guid(riid),punk,pdwCookie);
612 if (!riid || !punk || !pdwCookie)
613 return E_INVALIDARG;
615 if (IsEqualIID(riid, &IID_ITfThreadMgrEventSink))
616 return advise_sink(&This->ThreadMgrEventSink, &IID_ITfThreadMgrEventSink, COOKIE_MAGIC_TMSINK, punk, pdwCookie);
618 if (IsEqualIID(riid, &IID_ITfThreadFocusSink))
620 WARN("semi-stub for ITfThreadFocusSink: sink won't be used.\n");
621 return advise_sink(&This->ThreadFocusSink, &IID_ITfThreadFocusSink, COOKIE_MAGIC_THREADFOCUSSINK, punk, pdwCookie);
624 if (IsEqualIID(riid, &IID_ITfKeyTraceEventSink))
626 WARN("semi-stub for ITfKeyTraceEventSink: sink won't be used.\n");
627 return advise_sink(&This->KeyTraceEventSink, &IID_ITfKeyTraceEventSink,
628 COOKIE_MAGIC_KEYTRACESINK, punk, pdwCookie);
631 if (IsEqualIID(riid, &IID_ITfUIElementSink))
633 WARN("semi-stub for ITfUIElementSink: sink won't be used.\n");
634 return advise_sink(&This->UIElementSink, &IID_ITfUIElementSink,
635 COOKIE_MAGIC_UIELEMENTSINK, punk, pdwCookie);
638 if (IsEqualIID(riid, &IID_ITfInputProcessorProfileActivationSink))
640 WARN("semi-stub for ITfInputProcessorProfileActivationSink: sink won't be used.\n");
641 return advise_sink(&This->InputProcessorProfileActivationSink, &IID_ITfInputProcessorProfileActivationSink,
642 COOKIE_MAGIC_INPUTPROCESSORPROFILEACTIVATIONSINK, punk, pdwCookie);
645 FIXME("(%p) Unhandled Sink: %s\n",This,debugstr_guid(riid));
646 return E_NOTIMPL;
649 static HRESULT WINAPI ThreadMgrSource_UnadviseSink(ITfSource *iface, DWORD pdwCookie)
651 ThreadMgr *This = impl_from_ITfSource(iface);
652 DWORD magic;
654 TRACE("(%p) %x\n",This,pdwCookie);
656 magic = get_Cookie_magic(pdwCookie);
657 if (magic != COOKIE_MAGIC_TMSINK && magic != COOKIE_MAGIC_THREADFOCUSSINK
658 && magic != COOKIE_MAGIC_KEYTRACESINK && magic != COOKIE_MAGIC_UIELEMENTSINK
659 && magic != COOKIE_MAGIC_INPUTPROCESSORPROFILEACTIVATIONSINK)
660 return E_INVALIDARG;
662 return unadvise_sink(pdwCookie);
665 static const ITfSourceVtbl ThreadMgrSourceVtbl =
667 Source_QueryInterface,
668 Source_AddRef,
669 Source_Release,
670 ThreadMgrSource_AdviseSink,
671 ThreadMgrSource_UnadviseSink,
674 /*****************************************************
675 * ITfKeystrokeMgr functions
676 *****************************************************/
678 static HRESULT WINAPI KeystrokeMgr_QueryInterface(ITfKeystrokeMgr *iface, REFIID iid, LPVOID *ppvOut)
680 ThreadMgr *This = impl_from_ITfKeystrokeMgr(iface);
681 return ITfThreadMgrEx_QueryInterface(&This->ITfThreadMgrEx_iface, iid, ppvOut);
684 static ULONG WINAPI KeystrokeMgr_AddRef(ITfKeystrokeMgr *iface)
686 ThreadMgr *This = impl_from_ITfKeystrokeMgr(iface);
687 return ITfThreadMgrEx_AddRef(&This->ITfThreadMgrEx_iface);
690 static ULONG WINAPI KeystrokeMgr_Release(ITfKeystrokeMgr *iface)
692 ThreadMgr *This = impl_from_ITfKeystrokeMgr(iface);
693 return ITfThreadMgrEx_Release(&This->ITfThreadMgrEx_iface);
696 static HRESULT WINAPI KeystrokeMgr_AdviseKeyEventSink(ITfKeystrokeMgr *iface,
697 TfClientId tid, ITfKeyEventSink *pSink, BOOL fForeground)
699 ThreadMgr *This = impl_from_ITfKeystrokeMgr(iface);
700 CLSID textservice;
701 ITfKeyEventSink *check = NULL;
703 TRACE("(%p) %x %p %i\n",This,tid,pSink,fForeground);
705 if (!tid || !pSink)
706 return E_INVALIDARG;
708 textservice = get_textservice_clsid(tid);
709 if (IsEqualCLSID(&GUID_NULL,&textservice))
710 return E_INVALIDARG;
712 get_textservice_sink(tid, &IID_ITfKeyEventSink, (IUnknown**)&check);
713 if (check != NULL)
714 return CONNECT_E_ADVISELIMIT;
716 if (FAILED(ITfKeyEventSink_QueryInterface(pSink,&IID_ITfKeyEventSink,(LPVOID*) &check)))
717 return E_INVALIDARG;
719 set_textservice_sink(tid, &IID_ITfKeyEventSink, (IUnknown*)check);
721 if (fForeground)
723 if (This->foregroundKeyEventSink)
725 ITfKeyEventSink_OnSetFocus(This->foregroundKeyEventSink, FALSE);
726 ITfKeyEventSink_Release(This->foregroundKeyEventSink);
728 ITfKeyEventSink_AddRef(check);
729 ITfKeyEventSink_OnSetFocus(check, TRUE);
730 This->foregroundKeyEventSink = check;
731 This->foregroundTextService = textservice;
733 return S_OK;
736 static HRESULT WINAPI KeystrokeMgr_UnadviseKeyEventSink(ITfKeystrokeMgr *iface,
737 TfClientId tid)
739 ThreadMgr *This = impl_from_ITfKeystrokeMgr(iface);
740 CLSID textservice;
741 ITfKeyEventSink *check = NULL;
742 TRACE("(%p) %x\n",This,tid);
744 if (!tid)
745 return E_INVALIDARG;
747 textservice = get_textservice_clsid(tid);
748 if (IsEqualCLSID(&GUID_NULL,&textservice))
749 return E_INVALIDARG;
751 get_textservice_sink(tid, &IID_ITfKeyEventSink, (IUnknown**)&check);
753 if (!check)
754 return CONNECT_E_NOCONNECTION;
756 set_textservice_sink(tid, &IID_ITfKeyEventSink, NULL);
757 ITfKeyEventSink_Release(check);
759 if (This->foregroundKeyEventSink == check)
761 ITfKeyEventSink_Release(This->foregroundKeyEventSink);
762 This->foregroundKeyEventSink = NULL;
763 This->foregroundTextService = GUID_NULL;
765 return S_OK;
768 static HRESULT WINAPI KeystrokeMgr_GetForeground(ITfKeystrokeMgr *iface,
769 CLSID *pclsid)
771 ThreadMgr *This = impl_from_ITfKeystrokeMgr(iface);
772 TRACE("(%p) %p\n",This,pclsid);
773 if (!pclsid)
774 return E_INVALIDARG;
776 if (IsEqualCLSID(&This->foregroundTextService,&GUID_NULL))
777 return S_FALSE;
779 *pclsid = This->foregroundTextService;
780 return S_OK;
783 static HRESULT WINAPI KeystrokeMgr_TestKeyDown(ITfKeystrokeMgr *iface,
784 WPARAM wParam, LPARAM lParam, BOOL *pfEaten)
786 ThreadMgr *This = impl_from_ITfKeystrokeMgr(iface);
787 FIXME("STUB:(%p)\n",This);
788 *pfEaten = FALSE;
789 return S_OK;
792 static HRESULT WINAPI KeystrokeMgr_TestKeyUp(ITfKeystrokeMgr *iface,
793 WPARAM wParam, LPARAM lParam, BOOL *pfEaten)
795 ThreadMgr *This = impl_from_ITfKeystrokeMgr(iface);
796 FIXME("STUB:(%p)\n",This);
797 *pfEaten = FALSE;
798 return S_OK;
801 static HRESULT WINAPI KeystrokeMgr_KeyDown(ITfKeystrokeMgr *iface,
802 WPARAM wParam, LPARAM lParam, BOOL *pfEaten)
804 ThreadMgr *This = impl_from_ITfKeystrokeMgr(iface);
805 FIXME("STUB:(%p)\n",This);
806 return E_NOTIMPL;
809 static HRESULT WINAPI KeystrokeMgr_KeyUp(ITfKeystrokeMgr *iface,
810 WPARAM wParam, LPARAM lParam, BOOL *pfEaten)
812 ThreadMgr *This = impl_from_ITfKeystrokeMgr(iface);
813 FIXME("STUB:(%p)\n",This);
814 return E_NOTIMPL;
817 static HRESULT WINAPI KeystrokeMgr_GetPreservedKey(ITfKeystrokeMgr *iface,
818 ITfContext *pic, const TF_PRESERVEDKEY *pprekey, GUID *pguid)
820 ThreadMgr *This = impl_from_ITfKeystrokeMgr(iface);
821 FIXME("STUB:(%p)\n",This);
822 return E_NOTIMPL;
825 static HRESULT WINAPI KeystrokeMgr_IsPreservedKey(ITfKeystrokeMgr *iface,
826 REFGUID rguid, const TF_PRESERVEDKEY *pprekey, BOOL *pfRegistered)
828 ThreadMgr *This = impl_from_ITfKeystrokeMgr(iface);
829 struct list *cursor;
831 TRACE("(%p) %s (%x %x) %p\n",This,debugstr_guid(rguid), (pprekey)?pprekey->uVKey:0, (pprekey)?pprekey->uModifiers:0, pfRegistered);
833 if (!rguid || !pprekey || !pfRegistered)
834 return E_INVALIDARG;
836 LIST_FOR_EACH(cursor, &This->CurrentPreservedKeys)
838 PreservedKey* key = LIST_ENTRY(cursor,PreservedKey,entry);
839 if (IsEqualGUID(rguid,&key->guid) && pprekey->uVKey == key->prekey.uVKey && pprekey->uModifiers == key->prekey.uModifiers)
841 *pfRegistered = TRUE;
842 return S_OK;
846 *pfRegistered = FALSE;
847 return S_FALSE;
850 static HRESULT WINAPI KeystrokeMgr_PreserveKey(ITfKeystrokeMgr *iface,
851 TfClientId tid, REFGUID rguid, const TF_PRESERVEDKEY *prekey,
852 const WCHAR *pchDesc, ULONG cchDesc)
854 ThreadMgr *This = impl_from_ITfKeystrokeMgr(iface);
855 struct list *cursor;
856 PreservedKey *newkey;
858 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));
860 if (!tid || ! rguid || !prekey || (cchDesc && !pchDesc))
861 return E_INVALIDARG;
863 LIST_FOR_EACH(cursor, &This->CurrentPreservedKeys)
865 PreservedKey* key = LIST_ENTRY(cursor,PreservedKey,entry);
866 if (IsEqualGUID(rguid,&key->guid) && prekey->uVKey == key->prekey.uVKey && prekey->uModifiers == key->prekey.uModifiers)
867 return TF_E_ALREADY_EXISTS;
870 newkey = HeapAlloc(GetProcessHeap(),0,sizeof(PreservedKey));
871 if (!newkey)
872 return E_OUTOFMEMORY;
874 newkey->guid = *rguid;
875 newkey->prekey = *prekey;
876 newkey->tid = tid;
877 newkey->description = NULL;
878 if (cchDesc)
880 newkey->description = HeapAlloc(GetProcessHeap(),0,cchDesc * sizeof(WCHAR));
881 if (!newkey->description)
883 HeapFree(GetProcessHeap(),0,newkey);
884 return E_OUTOFMEMORY;
886 memcpy(newkey->description, pchDesc, cchDesc*sizeof(WCHAR));
889 list_add_head(&This->CurrentPreservedKeys,&newkey->entry);
891 return S_OK;
894 static HRESULT WINAPI KeystrokeMgr_UnpreserveKey(ITfKeystrokeMgr *iface,
895 REFGUID rguid, const TF_PRESERVEDKEY *pprekey)
897 ThreadMgr *This = impl_from_ITfKeystrokeMgr(iface);
898 PreservedKey* key = NULL;
899 struct list *cursor;
900 TRACE("(%p) %s (%x %x)\n",This,debugstr_guid(rguid),(pprekey)?pprekey->uVKey:0, (pprekey)?pprekey->uModifiers:0);
902 if (!pprekey || !rguid)
903 return E_INVALIDARG;
905 LIST_FOR_EACH(cursor, &This->CurrentPreservedKeys)
907 key = LIST_ENTRY(cursor,PreservedKey,entry);
908 if (IsEqualGUID(rguid,&key->guid) && pprekey->uVKey == key->prekey.uVKey && pprekey->uModifiers == key->prekey.uModifiers)
909 break;
910 key = NULL;
913 if (!key)
914 return CONNECT_E_NOCONNECTION;
916 list_remove(&key->entry);
917 HeapFree(GetProcessHeap(),0,key->description);
918 HeapFree(GetProcessHeap(),0,key);
920 return S_OK;
923 static HRESULT WINAPI KeystrokeMgr_SetPreservedKeyDescription(ITfKeystrokeMgr *iface,
924 REFGUID rguid, const WCHAR *pchDesc, ULONG cchDesc)
926 ThreadMgr *This = impl_from_ITfKeystrokeMgr(iface);
927 FIXME("STUB:(%p)\n",This);
928 return E_NOTIMPL;
931 static HRESULT WINAPI KeystrokeMgr_GetPreservedKeyDescription(ITfKeystrokeMgr *iface,
932 REFGUID rguid, BSTR *pbstrDesc)
934 ThreadMgr *This = impl_from_ITfKeystrokeMgr(iface);
935 FIXME("STUB:(%p)\n",This);
936 return E_NOTIMPL;
939 static HRESULT WINAPI KeystrokeMgr_SimulatePreservedKey(ITfKeystrokeMgr *iface,
940 ITfContext *pic, REFGUID rguid, BOOL *pfEaten)
942 ThreadMgr *This = impl_from_ITfKeystrokeMgr(iface);
943 FIXME("STUB:(%p)\n",This);
944 return E_NOTIMPL;
947 static const ITfKeystrokeMgrVtbl KeystrokeMgrVtbl =
949 KeystrokeMgr_QueryInterface,
950 KeystrokeMgr_AddRef,
951 KeystrokeMgr_Release,
952 KeystrokeMgr_AdviseKeyEventSink,
953 KeystrokeMgr_UnadviseKeyEventSink,
954 KeystrokeMgr_GetForeground,
955 KeystrokeMgr_TestKeyDown,
956 KeystrokeMgr_TestKeyUp,
957 KeystrokeMgr_KeyDown,
958 KeystrokeMgr_KeyUp,
959 KeystrokeMgr_GetPreservedKey,
960 KeystrokeMgr_IsPreservedKey,
961 KeystrokeMgr_PreserveKey,
962 KeystrokeMgr_UnpreserveKey,
963 KeystrokeMgr_SetPreservedKeyDescription,
964 KeystrokeMgr_GetPreservedKeyDescription,
965 KeystrokeMgr_SimulatePreservedKey
968 /*****************************************************
969 * ITfMessagePump functions
970 *****************************************************/
972 static HRESULT WINAPI MessagePump_QueryInterface(ITfMessagePump *iface, REFIID iid, LPVOID *ppvOut)
974 ThreadMgr *This = impl_from_ITfMessagePump(iface);
975 return ITfThreadMgrEx_QueryInterface(&This->ITfThreadMgrEx_iface, iid, ppvOut);
978 static ULONG WINAPI MessagePump_AddRef(ITfMessagePump *iface)
980 ThreadMgr *This = impl_from_ITfMessagePump(iface);
981 return ITfThreadMgrEx_AddRef(&This->ITfThreadMgrEx_iface);
984 static ULONG WINAPI MessagePump_Release(ITfMessagePump *iface)
986 ThreadMgr *This = impl_from_ITfMessagePump(iface);
987 return ITfThreadMgrEx_Release(&This->ITfThreadMgrEx_iface);
990 static HRESULT WINAPI MessagePump_PeekMessageA(ITfMessagePump *iface,
991 LPMSG pMsg, HWND hwnd, UINT wMsgFilterMin, UINT wMsgFilterMax,
992 UINT wRemoveMsg, BOOL *pfResult)
994 if (!pfResult)
995 return E_INVALIDARG;
996 *pfResult = PeekMessageA(pMsg, hwnd, wMsgFilterMin, wMsgFilterMax, wRemoveMsg);
997 return S_OK;
1000 static HRESULT WINAPI MessagePump_GetMessageA(ITfMessagePump *iface,
1001 LPMSG pMsg, HWND hwnd, UINT wMsgFilterMin, UINT wMsgFilterMax,
1002 BOOL *pfResult)
1004 if (!pfResult)
1005 return E_INVALIDARG;
1006 *pfResult = GetMessageA(pMsg, hwnd, wMsgFilterMin, wMsgFilterMax);
1007 return S_OK;
1010 static HRESULT WINAPI MessagePump_PeekMessageW(ITfMessagePump *iface,
1011 LPMSG pMsg, HWND hwnd, UINT wMsgFilterMin, UINT wMsgFilterMax,
1012 UINT wRemoveMsg, BOOL *pfResult)
1014 if (!pfResult)
1015 return E_INVALIDARG;
1016 *pfResult = PeekMessageW(pMsg, hwnd, wMsgFilterMin, wMsgFilterMax, wRemoveMsg);
1017 return S_OK;
1020 static HRESULT WINAPI MessagePump_GetMessageW(ITfMessagePump *iface,
1021 LPMSG pMsg, HWND hwnd, UINT wMsgFilterMin, UINT wMsgFilterMax,
1022 BOOL *pfResult)
1024 if (!pfResult)
1025 return E_INVALIDARG;
1026 *pfResult = GetMessageW(pMsg, hwnd, wMsgFilterMin, wMsgFilterMax);
1027 return S_OK;
1030 static const ITfMessagePumpVtbl MessagePumpVtbl =
1032 MessagePump_QueryInterface,
1033 MessagePump_AddRef,
1034 MessagePump_Release,
1035 MessagePump_PeekMessageA,
1036 MessagePump_GetMessageA,
1037 MessagePump_PeekMessageW,
1038 MessagePump_GetMessageW
1041 /*****************************************************
1042 * ITfClientId functions
1043 *****************************************************/
1045 static HRESULT WINAPI ClientId_QueryInterface(ITfClientId *iface, REFIID iid, LPVOID *ppvOut)
1047 ThreadMgr *This = impl_from_ITfClientId(iface);
1048 return ITfThreadMgrEx_QueryInterface(&This->ITfThreadMgrEx_iface, iid, ppvOut);
1051 static ULONG WINAPI ClientId_AddRef(ITfClientId *iface)
1053 ThreadMgr *This = impl_from_ITfClientId(iface);
1054 return ITfThreadMgrEx_AddRef(&This->ITfThreadMgrEx_iface);
1057 static ULONG WINAPI ClientId_Release(ITfClientId *iface)
1059 ThreadMgr *This = impl_from_ITfClientId(iface);
1060 return ITfThreadMgrEx_Release(&This->ITfThreadMgrEx_iface);
1063 static HRESULT WINAPI ClientId_GetClientId(ITfClientId *iface,
1064 REFCLSID rclsid, TfClientId *ptid)
1067 ThreadMgr *This = impl_from_ITfClientId(iface);
1068 HRESULT hr;
1069 ITfCategoryMgr *catmgr;
1071 TRACE("(%p) %s\n",This,debugstr_guid(rclsid));
1073 CategoryMgr_Constructor(NULL,(IUnknown**)&catmgr);
1074 hr = ITfCategoryMgr_RegisterGUID(catmgr,rclsid,ptid);
1075 ITfCategoryMgr_Release(catmgr);
1077 return hr;
1080 static const ITfClientIdVtbl ClientIdVtbl =
1082 ClientId_QueryInterface,
1083 ClientId_AddRef,
1084 ClientId_Release,
1085 ClientId_GetClientId
1088 /*****************************************************
1089 * ITfThreadMgrEventSink functions (internal)
1090 *****************************************************/
1091 static HRESULT WINAPI ThreadMgrEventSink_QueryInterface(ITfThreadMgrEventSink *iface, REFIID iid, LPVOID *ppvOut)
1093 ThreadMgr *This = impl_from_ITfThreadMgrEventSink(iface);
1094 return ITfThreadMgrEx_QueryInterface(&This->ITfThreadMgrEx_iface, iid, ppvOut);
1097 static ULONG WINAPI ThreadMgrEventSink_AddRef(ITfThreadMgrEventSink *iface)
1099 ThreadMgr *This = impl_from_ITfThreadMgrEventSink(iface);
1100 return ITfThreadMgrEx_AddRef(&This->ITfThreadMgrEx_iface);
1103 static ULONG WINAPI ThreadMgrEventSink_Release(ITfThreadMgrEventSink *iface)
1105 ThreadMgr *This = impl_from_ITfThreadMgrEventSink(iface);
1106 return ITfThreadMgrEx_Release(&This->ITfThreadMgrEx_iface);
1110 static HRESULT WINAPI ThreadMgrEventSink_OnInitDocumentMgr(
1111 ITfThreadMgrEventSink *iface,ITfDocumentMgr *pdim)
1113 ThreadMgr *This = impl_from_ITfThreadMgrEventSink(iface);
1114 ITfThreadMgrEventSink *sink;
1115 struct list *cursor;
1117 TRACE("(%p) %p\n",This,pdim);
1119 SINK_FOR_EACH(cursor, &This->ThreadMgrEventSink, ITfThreadMgrEventSink, sink)
1121 ITfThreadMgrEventSink_OnInitDocumentMgr(sink, pdim);
1124 return S_OK;
1127 static HRESULT WINAPI ThreadMgrEventSink_OnUninitDocumentMgr(
1128 ITfThreadMgrEventSink *iface, ITfDocumentMgr *pdim)
1130 ThreadMgr *This = impl_from_ITfThreadMgrEventSink(iface);
1131 ITfThreadMgrEventSink *sink;
1132 struct list *cursor;
1134 TRACE("(%p) %p\n",This,pdim);
1136 SINK_FOR_EACH(cursor, &This->ThreadMgrEventSink, ITfThreadMgrEventSink, sink)
1138 ITfThreadMgrEventSink_OnUninitDocumentMgr(sink, pdim);
1141 return S_OK;
1144 static HRESULT WINAPI ThreadMgrEventSink_OnSetFocus(
1145 ITfThreadMgrEventSink *iface, ITfDocumentMgr *pdimFocus,
1146 ITfDocumentMgr *pdimPrevFocus)
1148 ThreadMgr *This = impl_from_ITfThreadMgrEventSink(iface);
1149 ITfThreadMgrEventSink *sink;
1150 struct list *cursor;
1152 TRACE("(%p) %p %p\n",This,pdimFocus, pdimPrevFocus);
1154 SINK_FOR_EACH(cursor, &This->ThreadMgrEventSink, ITfThreadMgrEventSink, sink)
1156 ITfThreadMgrEventSink_OnSetFocus(sink, pdimFocus, pdimPrevFocus);
1159 return S_OK;
1162 static HRESULT WINAPI ThreadMgrEventSink_OnPushContext(
1163 ITfThreadMgrEventSink *iface, ITfContext *pic)
1165 ThreadMgr *This = impl_from_ITfThreadMgrEventSink(iface);
1166 ITfThreadMgrEventSink *sink;
1167 struct list *cursor;
1169 TRACE("(%p) %p\n",This,pic);
1171 SINK_FOR_EACH(cursor, &This->ThreadMgrEventSink, ITfThreadMgrEventSink, sink)
1173 ITfThreadMgrEventSink_OnPushContext(sink, pic);
1176 return S_OK;
1179 static HRESULT WINAPI ThreadMgrEventSink_OnPopContext(
1180 ITfThreadMgrEventSink *iface, ITfContext *pic)
1182 ThreadMgr *This = impl_from_ITfThreadMgrEventSink(iface);
1183 ITfThreadMgrEventSink *sink;
1184 struct list *cursor;
1186 TRACE("(%p) %p\n",This,pic);
1188 SINK_FOR_EACH(cursor, &This->ThreadMgrEventSink, ITfThreadMgrEventSink, sink)
1190 ITfThreadMgrEventSink_OnPopContext(sink, pic);
1193 return S_OK;
1196 static const ITfThreadMgrEventSinkVtbl ThreadMgrEventSinkVtbl =
1198 ThreadMgrEventSink_QueryInterface,
1199 ThreadMgrEventSink_AddRef,
1200 ThreadMgrEventSink_Release,
1201 ThreadMgrEventSink_OnInitDocumentMgr,
1202 ThreadMgrEventSink_OnUninitDocumentMgr,
1203 ThreadMgrEventSink_OnSetFocus,
1204 ThreadMgrEventSink_OnPushContext,
1205 ThreadMgrEventSink_OnPopContext
1208 /*****************************************************
1209 * ITfUIElementMgr functions
1210 *****************************************************/
1211 static HRESULT WINAPI UIElementMgr_QueryInterface(ITfUIElementMgr *iface, REFIID iid, void **ppvOut)
1213 ThreadMgr *This = impl_from_ITfUIElementMgr(iface);
1215 return ITfThreadMgrEx_QueryInterface(&This->ITfThreadMgrEx_iface, iid, ppvOut);
1218 static ULONG WINAPI UIElementMgr_AddRef(ITfUIElementMgr *iface)
1220 ThreadMgr *This = impl_from_ITfUIElementMgr(iface);
1222 return ITfThreadMgrEx_AddRef(&This->ITfThreadMgrEx_iface);
1225 static ULONG WINAPI UIElementMgr_Release(ITfUIElementMgr *iface)
1227 ThreadMgr *This = impl_from_ITfUIElementMgr(iface);
1229 return ITfThreadMgrEx_Release(&This->ITfThreadMgrEx_iface);
1232 static HRESULT WINAPI UIElementMgr_BeginUIElement(ITfUIElementMgr *iface, ITfUIElement *element,
1233 BOOL *show, DWORD *id)
1235 ThreadMgr *This = impl_from_ITfUIElementMgr(iface);
1237 FIXME("STUB:(%p)\n", This);
1238 return E_NOTIMPL;
1241 static HRESULT WINAPI UIElementMgr_UpdateUIElement(ITfUIElementMgr *iface, DWORD id)
1243 ThreadMgr *This = impl_from_ITfUIElementMgr(iface);
1245 FIXME("STUB:(%p)\n", This);
1246 return E_NOTIMPL;
1249 static HRESULT WINAPI UIElementMgr_EndUIElement(ITfUIElementMgr *iface, DWORD id)
1251 ThreadMgr *This = impl_from_ITfUIElementMgr(iface);
1253 FIXME("STUB:(%p)\n", This);
1254 return E_NOTIMPL;
1257 static HRESULT WINAPI UIElementMgr_GetUIElement(ITfUIElementMgr *iface, DWORD id,
1258 ITfUIElement **element)
1260 ThreadMgr *This = impl_from_ITfUIElementMgr(iface);
1262 FIXME("STUB:(%p)\n", This);
1263 return E_NOTIMPL;
1266 static HRESULT WINAPI UIElementMgr_EnumUIElements(ITfUIElementMgr *iface,
1267 IEnumTfUIElements **enum_elements)
1269 ThreadMgr *This = impl_from_ITfUIElementMgr(iface);
1271 FIXME("STUB:(%p)\n", This);
1272 return E_NOTIMPL;
1275 static const ITfUIElementMgrVtbl ThreadMgrUIElementMgrVtbl =
1277 UIElementMgr_QueryInterface,
1278 UIElementMgr_AddRef,
1279 UIElementMgr_Release,
1281 UIElementMgr_BeginUIElement,
1282 UIElementMgr_UpdateUIElement,
1283 UIElementMgr_EndUIElement,
1284 UIElementMgr_GetUIElement,
1285 UIElementMgr_EnumUIElements
1288 /*****************************************************
1289 * ITfSourceSingle functions
1290 *****************************************************/
1291 static HRESULT WINAPI ThreadMgrSourceSingle_QueryInterface(ITfSourceSingle *iface, REFIID iid, LPVOID *ppvOut)
1293 ThreadMgr *This = impl_from_ITfSourceSingle(iface);
1294 return ITfThreadMgrEx_QueryInterface(&This->ITfThreadMgrEx_iface, iid, ppvOut);
1297 static ULONG WINAPI ThreadMgrSourceSingle_AddRef(ITfSourceSingle *iface)
1299 ThreadMgr *This = impl_from_ITfSourceSingle(iface);
1300 return ITfThreadMgrEx_AddRef(&This->ITfThreadMgrEx_iface);
1303 static ULONG WINAPI ThreadMgrSourceSingle_Release(ITfSourceSingle *iface)
1305 ThreadMgr *This = impl_from_ITfSourceSingle(iface);
1306 return ITfThreadMgrEx_Release(&This->ITfThreadMgrEx_iface);
1309 static HRESULT WINAPI ThreadMgrSourceSingle_AdviseSingleSink( ITfSourceSingle *iface,
1310 TfClientId tid, REFIID riid, IUnknown *punk)
1312 ThreadMgr *This = impl_from_ITfSourceSingle(iface);
1313 FIXME("STUB:(%p) %i %s %p\n",This, tid, debugstr_guid(riid),punk);
1314 return E_NOTIMPL;
1317 static HRESULT WINAPI ThreadMgrSourceSingle_UnadviseSingleSink( ITfSourceSingle *iface,
1318 TfClientId tid, REFIID riid)
1320 ThreadMgr *This = impl_from_ITfSourceSingle(iface);
1321 FIXME("STUB:(%p) %i %s\n",This, tid, debugstr_guid(riid));
1322 return E_NOTIMPL;
1325 static const ITfSourceSingleVtbl SourceSingleVtbl =
1327 ThreadMgrSourceSingle_QueryInterface,
1328 ThreadMgrSourceSingle_AddRef,
1329 ThreadMgrSourceSingle_Release,
1330 ThreadMgrSourceSingle_AdviseSingleSink,
1331 ThreadMgrSourceSingle_UnadviseSingleSink
1334 HRESULT ThreadMgr_Constructor(IUnknown *pUnkOuter, IUnknown **ppOut)
1336 ThreadMgr *This;
1337 if (pUnkOuter)
1338 return CLASS_E_NOAGGREGATION;
1340 /* Only 1 ThreadMgr is created per thread */
1341 This = TlsGetValue(tlsIndex);
1342 if (This)
1344 ThreadMgr_AddRef(&This->ITfThreadMgrEx_iface);
1345 *ppOut = (IUnknown*)&This->ITfThreadMgrEx_iface;
1346 return S_OK;
1349 This = HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,sizeof(ThreadMgr));
1350 if (This == NULL)
1351 return E_OUTOFMEMORY;
1353 This->ITfThreadMgrEx_iface.lpVtbl = &ThreadMgrExVtbl;
1354 This->ITfSource_iface.lpVtbl = &ThreadMgrSourceVtbl;
1355 This->ITfKeystrokeMgr_iface.lpVtbl = &KeystrokeMgrVtbl;
1356 This->ITfMessagePump_iface.lpVtbl = &MessagePumpVtbl;
1357 This->ITfClientId_iface.lpVtbl = &ClientIdVtbl;
1358 This->ITfThreadMgrEventSink_iface.lpVtbl = &ThreadMgrEventSinkVtbl;
1359 This->ITfUIElementMgr_iface.lpVtbl = &ThreadMgrUIElementMgrVtbl;
1360 This->ITfSourceSingle_iface.lpVtbl = &SourceSingleVtbl;
1361 This->refCount = 1;
1362 TlsSetValue(tlsIndex,This);
1364 CompartmentMgr_Constructor((IUnknown*)&This->ITfThreadMgrEx_iface, &IID_IUnknown, (IUnknown**)&This->CompartmentMgr);
1366 list_init(&This->CurrentPreservedKeys);
1367 list_init(&This->CreatedDocumentMgrs);
1368 list_init(&This->AssociatedFocusWindows);
1370 list_init(&This->ActiveLanguageProfileNotifySink);
1371 list_init(&This->DisplayAttributeNotifySink);
1372 list_init(&This->KeyTraceEventSink);
1373 list_init(&This->PreservedKeyNotifySink);
1374 list_init(&This->ThreadFocusSink);
1375 list_init(&This->ThreadMgrEventSink);
1376 list_init(&This->UIElementSink);
1377 list_init(&This->InputProcessorProfileActivationSink);
1379 TRACE("returning %p\n", This);
1380 *ppOut = (IUnknown *)&This->ITfThreadMgrEx_iface;
1381 return S_OK;
1384 /**************************************************
1385 * IEnumTfDocumentMgrs implementation
1386 **************************************************/
1387 static void EnumTfDocumentMgr_Destructor(EnumTfDocumentMgr *This)
1389 TRACE("destroying %p\n", This);
1390 HeapFree(GetProcessHeap(),0,This);
1393 static HRESULT WINAPI EnumTfDocumentMgr_QueryInterface(IEnumTfDocumentMgrs *iface, REFIID iid, LPVOID *ppvOut)
1395 EnumTfDocumentMgr *This = impl_from_IEnumTfDocumentMgrs(iface);
1396 *ppvOut = NULL;
1398 if (IsEqualIID(iid, &IID_IUnknown) || IsEqualIID(iid, &IID_IEnumTfDocumentMgrs))
1400 *ppvOut = &This->IEnumTfDocumentMgrs_iface;
1403 if (*ppvOut)
1405 IEnumTfDocumentMgrs_AddRef(iface);
1406 return S_OK;
1409 WARN("unsupported interface: %s\n", debugstr_guid(iid));
1410 return E_NOINTERFACE;
1413 static ULONG WINAPI EnumTfDocumentMgr_AddRef(IEnumTfDocumentMgrs *iface)
1415 EnumTfDocumentMgr *This = impl_from_IEnumTfDocumentMgrs(iface);
1416 return InterlockedIncrement(&This->refCount);
1419 static ULONG WINAPI EnumTfDocumentMgr_Release(IEnumTfDocumentMgrs *iface)
1421 EnumTfDocumentMgr *This = impl_from_IEnumTfDocumentMgrs(iface);
1422 ULONG ret;
1424 ret = InterlockedDecrement(&This->refCount);
1425 if (ret == 0)
1426 EnumTfDocumentMgr_Destructor(This);
1427 return ret;
1430 static HRESULT WINAPI EnumTfDocumentMgr_Next(IEnumTfDocumentMgrs *iface,
1431 ULONG ulCount, ITfDocumentMgr **rgDocumentMgr, ULONG *pcFetched)
1433 EnumTfDocumentMgr *This = impl_from_IEnumTfDocumentMgrs(iface);
1434 ULONG fetched = 0;
1436 TRACE("(%p)\n",This);
1438 if (rgDocumentMgr == NULL) return E_POINTER;
1440 while (fetched < ulCount)
1442 DocumentMgrEntry *mgrentry;
1443 if (This->index == NULL)
1444 break;
1446 mgrentry = LIST_ENTRY(This->index,DocumentMgrEntry,entry);
1447 if (mgrentry == NULL)
1448 break;
1450 *rgDocumentMgr = mgrentry->docmgr;
1451 ITfDocumentMgr_AddRef(*rgDocumentMgr);
1453 This->index = list_next(This->head, This->index);
1454 ++fetched;
1455 ++rgDocumentMgr;
1458 if (pcFetched) *pcFetched = fetched;
1459 return fetched == ulCount ? S_OK : S_FALSE;
1462 static HRESULT WINAPI EnumTfDocumentMgr_Skip( IEnumTfDocumentMgrs* iface, ULONG celt)
1464 EnumTfDocumentMgr *This = impl_from_IEnumTfDocumentMgrs(iface);
1465 ULONG i;
1467 TRACE("(%p)\n",This);
1468 for(i = 0; i < celt && This->index != NULL; i++)
1469 This->index = list_next(This->head, This->index);
1470 return S_OK;
1473 static HRESULT WINAPI EnumTfDocumentMgr_Reset( IEnumTfDocumentMgrs* iface)
1475 EnumTfDocumentMgr *This = impl_from_IEnumTfDocumentMgrs(iface);
1476 TRACE("(%p)\n",This);
1477 This->index = list_head(This->head);
1478 return S_OK;
1481 static HRESULT WINAPI EnumTfDocumentMgr_Clone( IEnumTfDocumentMgrs *iface,
1482 IEnumTfDocumentMgrs **ppenum)
1484 EnumTfDocumentMgr *This = impl_from_IEnumTfDocumentMgrs(iface);
1485 HRESULT res;
1487 TRACE("(%p)\n",This);
1489 if (ppenum == NULL) return E_POINTER;
1491 res = EnumTfDocumentMgr_Constructor(This->head, ppenum);
1492 if (SUCCEEDED(res))
1494 EnumTfDocumentMgr *new_This = impl_from_IEnumTfDocumentMgrs(*ppenum);
1495 new_This->index = This->index;
1497 return res;
1500 static const IEnumTfDocumentMgrsVtbl EnumTfDocumentMgrsVtbl =
1502 EnumTfDocumentMgr_QueryInterface,
1503 EnumTfDocumentMgr_AddRef,
1504 EnumTfDocumentMgr_Release,
1505 EnumTfDocumentMgr_Clone,
1506 EnumTfDocumentMgr_Next,
1507 EnumTfDocumentMgr_Reset,
1508 EnumTfDocumentMgr_Skip
1511 static HRESULT EnumTfDocumentMgr_Constructor(struct list* head, IEnumTfDocumentMgrs **ppOut)
1513 EnumTfDocumentMgr *This;
1515 This = HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,sizeof(EnumTfDocumentMgr));
1516 if (This == NULL)
1517 return E_OUTOFMEMORY;
1519 This->IEnumTfDocumentMgrs_iface.lpVtbl= &EnumTfDocumentMgrsVtbl;
1520 This->refCount = 1;
1521 This->head = head;
1522 This->index = list_head(This->head);
1524 TRACE("returning %p\n", &This->IEnumTfDocumentMgrs_iface);
1525 *ppOut = &This->IEnumTfDocumentMgrs_iface;
1526 return S_OK;
1529 void ThreadMgr_OnDocumentMgrDestruction(ITfThreadMgr *iface, ITfDocumentMgr *mgr)
1531 ThreadMgr *This = impl_from_ITfThreadMgrEx((ITfThreadMgrEx *)iface);
1532 struct list *cursor;
1533 BOOL found = FALSE;
1535 LIST_FOR_EACH(cursor, &This->CreatedDocumentMgrs)
1537 DocumentMgrEntry *mgrentry = LIST_ENTRY(cursor,DocumentMgrEntry,entry);
1538 if (mgrentry->docmgr == mgr)
1540 list_remove(cursor);
1541 HeapFree(GetProcessHeap(),0,mgrentry);
1542 found = TRUE;
1543 break;
1546 if (!found) FIXME("ITfDocumentMgr %p not found in this thread\n",mgr);
1548 LIST_FOR_EACH(cursor, &This->AssociatedFocusWindows)
1550 AssociatedWindow *wnd = LIST_ENTRY(cursor,AssociatedWindow,entry);
1551 if (wnd->docmgr == mgr)
1552 wnd->docmgr = NULL;