Home | Info | Community | Development | myReactOS | Contact Us
ReactOS Development > Doxygenthreadmgr.c
Go to the documentation of this file.
00001 /* 00002 * ITfThreadMgr implementation 00003 * 00004 * Copyright 2008 Aric Stewart, CodeWeavers 00005 * 00006 * This library is free software; you can redistribute it and/or 00007 * modify it under the terms of the GNU Lesser General Public 00008 * License as published by the Free Software Foundation; either 00009 * version 2.1 of the License, or (at your option) any later version. 00010 * 00011 * This library is distributed in the hope that it will be useful, 00012 * but WITHOUT ANY WARRANTY; without even the implied warranty of 00013 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 00014 * Lesser General Public License for more details. 00015 * 00016 * You should have received a copy of the GNU Lesser General Public 00017 * License along with this library; if not, write to the Free Software 00018 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA 00019 */ 00020 00021 #include "config.h" 00022 00023 #include <stdarg.h> 00024 00025 #define COBJMACROS 00026 00027 #include "wine/debug.h" 00028 #include "windef.h" 00029 #include "winbase.h" 00030 #include "winreg.h" 00031 #include "winuser.h" 00032 #include "shlwapi.h" 00033 #include "winerror.h" 00034 #include "objbase.h" 00035 #include "olectl.h" 00036 00037 #include "wine/unicode.h" 00038 #include "wine/list.h" 00039 00040 #include "msctf.h" 00041 #include "msctf_internal.h" 00042 00043 WINE_DEFAULT_DEBUG_CHANNEL(msctf); 00044 00045 typedef struct tagThreadMgrSink { 00046 struct list entry; 00047 union { 00048 /* ThreadMgr Sinks */ 00049 IUnknown *pIUnknown; 00050 /* ITfActiveLanguageProfileNotifySink *pITfActiveLanguageProfileNotifySink; */ 00051 /* ITfDisplayAttributeNotifySink *pITfDisplayAttributeNotifySink; */ 00052 /* ITfKeyTraceEventSink *pITfKeyTraceEventSink; */ 00053 /* ITfPreservedKeyNotifySink *pITfPreservedKeyNotifySink; */ 00054 /* ITfThreadFocusSink *pITfThreadFocusSink; */ 00055 ITfThreadMgrEventSink *pITfThreadMgrEventSink; 00056 } interfaces; 00057 } ThreadMgrSink; 00058 00059 typedef struct tagPreservedKey 00060 { 00061 struct list entry; 00062 GUID guid; 00063 TF_PRESERVEDKEY prekey; 00064 LPWSTR description; 00065 TfClientId tid; 00066 } PreservedKey; 00067 00068 typedef struct tagDocumentMgrs 00069 { 00070 struct list entry; 00071 ITfDocumentMgr *docmgr; 00072 } DocumentMgrEntry; 00073 00074 typedef struct tagAssociatedWindow 00075 { 00076 struct list entry; 00077 HWND hwnd; 00078 ITfDocumentMgr *docmgr; 00079 } AssociatedWindow; 00080 00081 typedef struct tagACLMulti { 00082 const ITfThreadMgrVtbl *ThreadMgrVtbl; 00083 const ITfSourceVtbl *SourceVtbl; 00084 const ITfKeystrokeMgrVtbl *KeystrokeMgrVtbl; 00085 const ITfMessagePumpVtbl *MessagePumpVtbl; 00086 const ITfClientIdVtbl *ClientIdVtbl; 00087 /* const ITfThreadMgrExVtbl *ThreadMgrExVtbl; */ 00088 /* const ITfConfigureSystemKeystrokeFeedVtbl *ConfigureSystemKeystrokeFeedVtbl; */ 00089 /* const ITfLangBarItemMgrVtbl *LangBarItemMgrVtbl; */ 00090 /* const ITfUIElementMgrVtbl *UIElementMgrVtbl; */ 00091 const ITfSourceSingleVtbl *SourceSingleVtbl; 00092 LONG refCount; 00093 00094 /* Aggregation */ 00095 ITfCompartmentMgr *CompartmentMgr; 00096 00097 const ITfThreadMgrEventSinkVtbl *ThreadMgrEventSinkVtbl; /* internal */ 00098 00099 ITfDocumentMgr *focus; 00100 LONG activationCount; 00101 00102 ITfKeyEventSink *forgroundKeyEventSink; 00103 CLSID forgroundTextService; 00104 00105 struct list CurrentPreservedKeys; 00106 struct list CreatedDocumentMgrs; 00107 00108 struct list AssociatedFocusWindows; 00109 HHOOK focusHook; 00110 00111 /* kept as separate lists to reduce unnecessary iterations */ 00112 struct list ActiveLanguageProfileNotifySink; 00113 struct list DisplayAttributeNotifySink; 00114 struct list KeyTraceEventSink; 00115 struct list PreservedKeyNotifySink; 00116 struct list ThreadFocusSink; 00117 struct list ThreadMgrEventSink; 00118 } ThreadMgr; 00119 00120 typedef struct tagEnumTfDocumentMgr { 00121 const IEnumTfDocumentMgrsVtbl *Vtbl; 00122 LONG refCount; 00123 00124 struct list *index; 00125 struct list *head; 00126 } EnumTfDocumentMgr; 00127 00128 static HRESULT EnumTfDocumentMgr_Constructor(struct list* head, IEnumTfDocumentMgrs **ppOut); 00129 00130 static inline ThreadMgr *impl_from_ITfSourceVtbl(ITfSource *iface) 00131 { 00132 return (ThreadMgr *)((char *)iface - FIELD_OFFSET(ThreadMgr,SourceVtbl)); 00133 } 00134 00135 static inline ThreadMgr *impl_from_ITfKeystrokeMgrVtbl(ITfKeystrokeMgr *iface) 00136 { 00137 return (ThreadMgr *)((char *)iface - FIELD_OFFSET(ThreadMgr,KeystrokeMgrVtbl)); 00138 } 00139 00140 static inline ThreadMgr *impl_from_ITfMessagePumpVtbl(ITfMessagePump *iface) 00141 { 00142 return (ThreadMgr *)((char *)iface - FIELD_OFFSET(ThreadMgr,MessagePumpVtbl)); 00143 } 00144 00145 static inline ThreadMgr *impl_from_ITfClientIdVtbl(ITfClientId *iface) 00146 { 00147 return (ThreadMgr *)((char *)iface - FIELD_OFFSET(ThreadMgr,ClientIdVtbl)); 00148 } 00149 00150 static inline ThreadMgr *impl_from_ITfThreadMgrEventSink(ITfThreadMgrEventSink *iface) 00151 { 00152 return (ThreadMgr *)((char *)iface - FIELD_OFFSET(ThreadMgr,ThreadMgrEventSinkVtbl)); 00153 } 00154 00155 static inline ThreadMgr *impl_from_ITfSourceSingleVtbl(ITfSourceSingle* iface) 00156 00157 { 00158 return (ThreadMgr *)((char *)iface - FIELD_OFFSET(ThreadMgr,SourceSingleVtbl)); 00159 } 00160 00161 static void free_sink(ThreadMgrSink *sink) 00162 { 00163 IUnknown_Release(sink->interfaces.pIUnknown); 00164 HeapFree(GetProcessHeap(),0,sink); 00165 } 00166 00167 static void ThreadMgr_Destructor(ThreadMgr *This) 00168 { 00169 struct list *cursor, *cursor2; 00170 00171 /* unhook right away */ 00172 if (This->focusHook) 00173 UnhookWindowsHookEx(This->focusHook); 00174 00175 TlsSetValue(tlsIndex,NULL); 00176 TRACE("destroying %p\n", This); 00177 if (This->focus) 00178 ITfDocumentMgr_Release(This->focus); 00179 00180 /* free sinks */ 00181 LIST_FOR_EACH_SAFE(cursor, cursor2, &This->ActiveLanguageProfileNotifySink) 00182 { 00183 ThreadMgrSink* sink = LIST_ENTRY(cursor,ThreadMgrSink,entry); 00184 list_remove(cursor); 00185 free_sink(sink); 00186 } 00187 LIST_FOR_EACH_SAFE(cursor, cursor2, &This->DisplayAttributeNotifySink) 00188 { 00189 ThreadMgrSink* sink = LIST_ENTRY(cursor,ThreadMgrSink,entry); 00190 list_remove(cursor); 00191 free_sink(sink); 00192 } 00193 LIST_FOR_EACH_SAFE(cursor, cursor2, &This->KeyTraceEventSink) 00194 { 00195 ThreadMgrSink* sink = LIST_ENTRY(cursor,ThreadMgrSink,entry); 00196 list_remove(cursor); 00197 free_sink(sink); 00198 } 00199 LIST_FOR_EACH_SAFE(cursor, cursor2, &This->PreservedKeyNotifySink) 00200 { 00201 ThreadMgrSink* sink = LIST_ENTRY(cursor,ThreadMgrSink,entry); 00202 list_remove(cursor); 00203 free_sink(sink); 00204 } 00205 LIST_FOR_EACH_SAFE(cursor, cursor2, &This->ThreadFocusSink) 00206 { 00207 ThreadMgrSink* sink = LIST_ENTRY(cursor,ThreadMgrSink,entry); 00208 list_remove(cursor); 00209 free_sink(sink); 00210 } 00211 LIST_FOR_EACH_SAFE(cursor, cursor2, &This->ThreadMgrEventSink) 00212 { 00213 ThreadMgrSink* sink = LIST_ENTRY(cursor,ThreadMgrSink,entry); 00214 list_remove(cursor); 00215 free_sink(sink); 00216 } 00217 00218 LIST_FOR_EACH_SAFE(cursor, cursor2, &This->CurrentPreservedKeys) 00219 { 00220 PreservedKey* key = LIST_ENTRY(cursor,PreservedKey,entry); 00221 list_remove(cursor); 00222 HeapFree(GetProcessHeap(),0,key->description); 00223 HeapFree(GetProcessHeap(),0,key); 00224 } 00225 00226 LIST_FOR_EACH_SAFE(cursor, cursor2, &This->CreatedDocumentMgrs) 00227 { 00228 DocumentMgrEntry *mgr = LIST_ENTRY(cursor,DocumentMgrEntry,entry); 00229 list_remove(cursor); 00230 FIXME("Left Over ITfDocumentMgr. Should we do something with it?\n"); 00231 HeapFree(GetProcessHeap(),0,mgr); 00232 } 00233 00234 LIST_FOR_EACH_SAFE(cursor, cursor2, &This->AssociatedFocusWindows) 00235 { 00236 AssociatedWindow *wnd = LIST_ENTRY(cursor,AssociatedWindow,entry); 00237 list_remove(cursor); 00238 HeapFree(GetProcessHeap(),0,wnd); 00239 } 00240 00241 CompartmentMgr_Destructor(This->CompartmentMgr); 00242 00243 HeapFree(GetProcessHeap(),0,This); 00244 } 00245 00246 static HRESULT WINAPI ThreadMgr_QueryInterface(ITfThreadMgr *iface, REFIID iid, LPVOID *ppvOut) 00247 { 00248 ThreadMgr *This = (ThreadMgr *)iface; 00249 *ppvOut = NULL; 00250 00251 if (IsEqualIID(iid, &IID_IUnknown) || IsEqualIID(iid, &IID_ITfThreadMgr)) 00252 { 00253 *ppvOut = This; 00254 } 00255 else if (IsEqualIID(iid, &IID_ITfSource)) 00256 { 00257 *ppvOut = &This->SourceVtbl; 00258 } 00259 else if (IsEqualIID(iid, &IID_ITfKeystrokeMgr)) 00260 { 00261 *ppvOut = &This->KeystrokeMgrVtbl; 00262 } 00263 else if (IsEqualIID(iid, &IID_ITfMessagePump)) 00264 { 00265 *ppvOut = &This->MessagePumpVtbl; 00266 } 00267 else if (IsEqualIID(iid, &IID_ITfClientId)) 00268 { 00269 *ppvOut = &This->ClientIdVtbl; 00270 } 00271 else if (IsEqualIID(iid, &IID_ITfCompartmentMgr)) 00272 { 00273 *ppvOut = This->CompartmentMgr; 00274 } 00275 else if (IsEqualIID(iid, &IID_ITfSourceSingle)) 00276 { 00277 *ppvOut = &This->SourceSingleVtbl; 00278 } 00279 00280 if (*ppvOut) 00281 { 00282 IUnknown_AddRef(iface); 00283 return S_OK; 00284 } 00285 00286 WARN("unsupported interface: %s\n", debugstr_guid(iid)); 00287 return E_NOINTERFACE; 00288 } 00289 00290 static ULONG WINAPI ThreadMgr_AddRef(ITfThreadMgr *iface) 00291 { 00292 ThreadMgr *This = (ThreadMgr *)iface; 00293 return InterlockedIncrement(&This->refCount); 00294 } 00295 00296 static ULONG WINAPI ThreadMgr_Release(ITfThreadMgr *iface) 00297 { 00298 ThreadMgr *This = (ThreadMgr *)iface; 00299 ULONG ret; 00300 00301 ret = InterlockedDecrement(&This->refCount); 00302 if (ret == 0) 00303 ThreadMgr_Destructor(This); 00304 return ret; 00305 } 00306 00307 /***************************************************** 00308 * ITfThreadMgr functions 00309 *****************************************************/ 00310 00311 static HRESULT WINAPI ThreadMgr_fnActivate( ITfThreadMgr* iface, TfClientId *ptid) 00312 { 00313 ThreadMgr *This = (ThreadMgr *)iface; 00314 00315 TRACE("(%p) %p\n",This, ptid); 00316 00317 if (!ptid) 00318 return E_INVALIDARG; 00319 00320 if (!processId) 00321 { 00322 GUID guid; 00323 CoCreateGuid(&guid); 00324 ITfClientId_GetClientId((ITfClientId*)&This->ClientIdVtbl,&guid,&processId); 00325 } 00326 00327 activate_textservices(iface); 00328 This->activationCount++; 00329 *ptid = processId; 00330 return S_OK; 00331 } 00332 00333 static HRESULT WINAPI ThreadMgr_fnDeactivate( ITfThreadMgr* iface) 00334 { 00335 ThreadMgr *This = (ThreadMgr *)iface; 00336 TRACE("(%p)\n",This); 00337 00338 if (This->activationCount == 0) 00339 return E_UNEXPECTED; 00340 00341 This->activationCount --; 00342 00343 if (This->activationCount == 0) 00344 { 00345 if (This->focus) 00346 { 00347 ITfThreadMgrEventSink_OnSetFocus((ITfThreadMgrEventSink*)&This->ThreadMgrEventSinkVtbl, 0, This->focus); 00348 ITfDocumentMgr_Release(This->focus); 00349 This->focus = 0; 00350 } 00351 } 00352 00353 deactivate_textservices(); 00354 00355 return S_OK; 00356 } 00357 00358 static HRESULT WINAPI ThreadMgr_CreateDocumentMgr( ITfThreadMgr* iface, ITfDocumentMgr 00359 **ppdim) 00360 { 00361 ThreadMgr *This = (ThreadMgr *)iface; 00362 DocumentMgrEntry *mgrentry; 00363 HRESULT hr; 00364 00365 TRACE("(%p)\n",iface); 00366 mgrentry = HeapAlloc(GetProcessHeap(),0,sizeof(DocumentMgrEntry)); 00367 if (mgrentry == NULL) 00368 return E_OUTOFMEMORY; 00369 00370 hr = DocumentMgr_Constructor((ITfThreadMgrEventSink*)&This->ThreadMgrEventSinkVtbl, ppdim); 00371 00372 if (SUCCEEDED(hr)) 00373 { 00374 mgrentry->docmgr = *ppdim; 00375 list_add_head(&This->CreatedDocumentMgrs,&mgrentry->entry); 00376 } 00377 else 00378 HeapFree(GetProcessHeap(),0,mgrentry); 00379 00380 return hr; 00381 } 00382 00383 static HRESULT WINAPI ThreadMgr_EnumDocumentMgrs( ITfThreadMgr* iface, IEnumTfDocumentMgrs 00384 **ppEnum) 00385 { 00386 ThreadMgr *This = (ThreadMgr *)iface; 00387 TRACE("(%p) %p\n",This,ppEnum); 00388 00389 if (!ppEnum) 00390 return E_INVALIDARG; 00391 00392 return EnumTfDocumentMgr_Constructor(&This->CreatedDocumentMgrs, ppEnum); 00393 } 00394 00395 static HRESULT WINAPI ThreadMgr_GetFocus( ITfThreadMgr* iface, ITfDocumentMgr 00396 **ppdimFocus) 00397 { 00398 ThreadMgr *This = (ThreadMgr *)iface; 00399 TRACE("(%p)\n",This); 00400 00401 if (!ppdimFocus) 00402 return E_INVALIDARG; 00403 00404 *ppdimFocus = This->focus; 00405 00406 TRACE("->%p\n",This->focus); 00407 00408 if (This->focus == NULL) 00409 return S_FALSE; 00410 00411 ITfDocumentMgr_AddRef(This->focus); 00412 00413 return S_OK; 00414 } 00415 00416 static HRESULT WINAPI ThreadMgr_SetFocus( ITfThreadMgr* iface, ITfDocumentMgr *pdimFocus) 00417 { 00418 ITfDocumentMgr *check; 00419 ThreadMgr *This = (ThreadMgr *)iface; 00420 00421 TRACE("(%p) %p\n",This,pdimFocus); 00422 00423 if (!pdimFocus) 00424 check = NULL; 00425 else if (FAILED(IUnknown_QueryInterface(pdimFocus,&IID_ITfDocumentMgr,(LPVOID*) &check))) 00426 return E_INVALIDARG; 00427 00428 ITfThreadMgrEventSink_OnSetFocus((ITfThreadMgrEventSink*)&This->ThreadMgrEventSinkVtbl, check, This->focus); 00429 00430 if (This->focus) 00431 ITfDocumentMgr_Release(This->focus); 00432 00433 This->focus = check; 00434 return S_OK; 00435 } 00436 00437 static LRESULT CALLBACK ThreadFocusHookProc(int nCode, WPARAM wParam, LPARAM lParam) 00438 { 00439 ThreadMgr *This; 00440 00441 This = TlsGetValue(tlsIndex); 00442 if (!This) 00443 { 00444 ERR("Hook proc but no ThreadMgr for this thread. Serious Error\n"); 00445 return 0; 00446 } 00447 if (!This->focusHook) 00448 { 00449 ERR("Hook proc but no ThreadMgr focus Hook. Serious Error\n"); 00450 return 0; 00451 } 00452 00453 if (nCode == HCBT_SETFOCUS) /* focus change within our thread */ 00454 { 00455 struct list *cursor; 00456 00457 LIST_FOR_EACH(cursor, &This->AssociatedFocusWindows) 00458 { 00459 AssociatedWindow *wnd = LIST_ENTRY(cursor,AssociatedWindow,entry); 00460 if (wnd->hwnd == (HWND)wParam) 00461 { 00462 TRACE("Triggering Associated window focus\n"); 00463 if (This->focus != wnd->docmgr) 00464 ThreadMgr_SetFocus((ITfThreadMgr*)This, wnd->docmgr); 00465 break; 00466 } 00467 } 00468 } 00469 00470 return CallNextHookEx(This->focusHook, nCode, wParam, lParam); 00471 } 00472 00473 static HRESULT SetupWindowsHook(ThreadMgr *This) 00474 { 00475 if (!This->focusHook) 00476 { 00477 This->focusHook = SetWindowsHookExW(WH_CBT, ThreadFocusHookProc, 0, 00478 GetCurrentThreadId()); 00479 if (!This->focusHook) 00480 { 00481 ERR("Unable to set focus hook\n"); 00482 return E_FAIL; 00483 } 00484 return S_OK; 00485 } 00486 return S_FALSE; 00487 } 00488 00489 static HRESULT WINAPI ThreadMgr_AssociateFocus( ITfThreadMgr* iface, HWND hwnd, 00490 ITfDocumentMgr *pdimNew, ITfDocumentMgr **ppdimPrev) 00491 { 00492 struct list *cursor, *cursor2; 00493 ThreadMgr *This = (ThreadMgr *)iface; 00494 AssociatedWindow *wnd; 00495 00496 TRACE("(%p) %p %p %p\n",This,hwnd,pdimNew,ppdimPrev); 00497 00498 if (!ppdimPrev) 00499 return E_INVALIDARG; 00500 00501 *ppdimPrev = NULL; 00502 00503 LIST_FOR_EACH_SAFE(cursor, cursor2, &This->AssociatedFocusWindows) 00504 { 00505 wnd = LIST_ENTRY(cursor,AssociatedWindow,entry); 00506 if (wnd->hwnd == hwnd) 00507 { 00508 if (wnd->docmgr) 00509 ITfDocumentMgr_AddRef(wnd->docmgr); 00510 *ppdimPrev = wnd->docmgr; 00511 wnd->docmgr = pdimNew; 00512 if (GetFocus() == hwnd) 00513 ThreadMgr_SetFocus(iface,pdimNew); 00514 return S_OK; 00515 } 00516 } 00517 00518 wnd = HeapAlloc(GetProcessHeap(),0,sizeof(AssociatedWindow)); 00519 wnd->hwnd = hwnd; 00520 wnd->docmgr = pdimNew; 00521 list_add_head(&This->AssociatedFocusWindows,&wnd->entry); 00522 00523 if (GetFocus() == hwnd) 00524 ThreadMgr_SetFocus(iface,pdimNew); 00525 00526 SetupWindowsHook(This); 00527 00528 return S_OK; 00529 } 00530 00531 static HRESULT WINAPI ThreadMgr_IsThreadFocus( ITfThreadMgr* iface, BOOL *pfThreadFocus) 00532 { 00533 HWND focus; 00534 ThreadMgr *This = (ThreadMgr *)iface; 00535 TRACE("(%p) %p\n",This,pfThreadFocus); 00536 focus = GetFocus(); 00537 *pfThreadFocus = (focus == NULL); 00538 return S_OK; 00539 } 00540 00541 static HRESULT WINAPI ThreadMgr_GetFunctionProvider( ITfThreadMgr* iface, REFCLSID clsid, 00542 ITfFunctionProvider **ppFuncProv) 00543 { 00544 ThreadMgr *This = (ThreadMgr *)iface; 00545 FIXME("STUB:(%p)\n",This); 00546 return E_NOTIMPL; 00547 } 00548 00549 static HRESULT WINAPI ThreadMgr_EnumFunctionProviders( ITfThreadMgr* iface, 00550 IEnumTfFunctionProviders **ppEnum) 00551 { 00552 ThreadMgr *This = (ThreadMgr *)iface; 00553 FIXME("STUB:(%p)\n",This); 00554 return E_NOTIMPL; 00555 } 00556 00557 static HRESULT WINAPI ThreadMgr_GetGlobalCompartment( ITfThreadMgr* iface, 00558 ITfCompartmentMgr **ppCompMgr) 00559 { 00560 ThreadMgr *This = (ThreadMgr *)iface; 00561 HRESULT hr; 00562 TRACE("(%p) %p\n",This, ppCompMgr); 00563 00564 if (!ppCompMgr) 00565 return E_INVALIDARG; 00566 00567 if (!globalCompartmentMgr) 00568 { 00569 hr = CompartmentMgr_Constructor(NULL,&IID_ITfCompartmentMgr,(IUnknown**)&globalCompartmentMgr); 00570 if (FAILED(hr)) 00571 return hr; 00572 } 00573 00574 ITfCompartmentMgr_AddRef(globalCompartmentMgr); 00575 *ppCompMgr = globalCompartmentMgr; 00576 return S_OK; 00577 } 00578 00579 static const ITfThreadMgrVtbl ThreadMgr_ThreadMgrVtbl = 00580 { 00581 ThreadMgr_QueryInterface, 00582 ThreadMgr_AddRef, 00583 ThreadMgr_Release, 00584 00585 ThreadMgr_fnActivate, 00586 ThreadMgr_fnDeactivate, 00587 ThreadMgr_CreateDocumentMgr, 00588 ThreadMgr_EnumDocumentMgrs, 00589 ThreadMgr_GetFocus, 00590 ThreadMgr_SetFocus, 00591 ThreadMgr_AssociateFocus, 00592 ThreadMgr_IsThreadFocus, 00593 ThreadMgr_GetFunctionProvider, 00594 ThreadMgr_EnumFunctionProviders, 00595 ThreadMgr_GetGlobalCompartment 00596 }; 00597 00598 00599 static HRESULT WINAPI Source_QueryInterface(ITfSource *iface, REFIID iid, LPVOID *ppvOut) 00600 { 00601 ThreadMgr *This = impl_from_ITfSourceVtbl(iface); 00602 return ThreadMgr_QueryInterface((ITfThreadMgr *)This, iid, *ppvOut); 00603 } 00604 00605 static ULONG WINAPI Source_AddRef(ITfSource *iface) 00606 { 00607 ThreadMgr *This = impl_from_ITfSourceVtbl(iface); 00608 return ThreadMgr_AddRef((ITfThreadMgr*)This); 00609 } 00610 00611 static ULONG WINAPI Source_Release(ITfSource *iface) 00612 { 00613 ThreadMgr *This = impl_from_ITfSourceVtbl(iface); 00614 return ThreadMgr_Release((ITfThreadMgr *)This); 00615 } 00616 00617 /***************************************************** 00618 * ITfSource functions 00619 *****************************************************/ 00620 static HRESULT WINAPI ThreadMgrSource_AdviseSink(ITfSource *iface, 00621 REFIID riid, IUnknown *punk, DWORD *pdwCookie) 00622 { 00623 ThreadMgrSink *tms; 00624 ThreadMgr *This = impl_from_ITfSourceVtbl(iface); 00625 00626 TRACE("(%p) %s %p %p\n",This,debugstr_guid(riid),punk,pdwCookie); 00627 00628 if (!riid || !punk || !pdwCookie) 00629 return E_INVALIDARG; 00630 00631 if (IsEqualIID(riid, &IID_ITfThreadMgrEventSink)) 00632 { 00633 tms = HeapAlloc(GetProcessHeap(),0,sizeof(ThreadMgrSink)); 00634 if (!tms) 00635 return E_OUTOFMEMORY; 00636 if (FAILED(IUnknown_QueryInterface(punk, riid, (LPVOID *)&tms->interfaces.pITfThreadMgrEventSink))) 00637 { 00638 HeapFree(GetProcessHeap(),0,tms); 00639 return CONNECT_E_CANNOTCONNECT; 00640 } 00641 list_add_head(&This->ThreadMgrEventSink,&tms->entry); 00642 *pdwCookie = generate_Cookie(COOKIE_MAGIC_TMSINK, tms); 00643 } 00644 else 00645 { 00646 FIXME("(%p) Unhandled Sink: %s\n",This,debugstr_guid(riid)); 00647 return E_NOTIMPL; 00648 } 00649 00650 TRACE("cookie %x\n",*pdwCookie); 00651 00652 return S_OK; 00653 } 00654 00655 static HRESULT WINAPI ThreadMgrSource_UnadviseSink(ITfSource *iface, DWORD pdwCookie) 00656 { 00657 ThreadMgrSink *sink; 00658 ThreadMgr *This = impl_from_ITfSourceVtbl(iface); 00659 00660 TRACE("(%p) %x\n",This,pdwCookie); 00661 00662 if (get_Cookie_magic(pdwCookie)!=COOKIE_MAGIC_TMSINK) 00663 return E_INVALIDARG; 00664 00665 sink = (ThreadMgrSink*)remove_Cookie(pdwCookie); 00666 if (!sink) 00667 return CONNECT_E_NOCONNECTION; 00668 00669 list_remove(&sink->entry); 00670 free_sink(sink); 00671 00672 return S_OK; 00673 } 00674 00675 static const ITfSourceVtbl ThreadMgr_SourceVtbl = 00676 { 00677 Source_QueryInterface, 00678 Source_AddRef, 00679 Source_Release, 00680 00681 ThreadMgrSource_AdviseSink, 00682 ThreadMgrSource_UnadviseSink, 00683 }; 00684 00685 /***************************************************** 00686 * ITfKeystrokeMgr functions 00687 *****************************************************/ 00688 00689 static HRESULT WINAPI KeystrokeMgr_QueryInterface(ITfKeystrokeMgr *iface, REFIID iid, LPVOID *ppvOut) 00690 { 00691 ThreadMgr *This = impl_from_ITfKeystrokeMgrVtbl(iface); 00692 return ThreadMgr_QueryInterface((ITfThreadMgr *)This, iid, *ppvOut); 00693 } 00694 00695 static ULONG WINAPI KeystrokeMgr_AddRef(ITfKeystrokeMgr *iface) 00696 { 00697 ThreadMgr *This = impl_from_ITfKeystrokeMgrVtbl(iface); 00698 return ThreadMgr_AddRef((ITfThreadMgr*)This); 00699 } 00700 00701 static ULONG WINAPI KeystrokeMgr_Release(ITfKeystrokeMgr *iface) 00702 { 00703 ThreadMgr *This = impl_from_ITfKeystrokeMgrVtbl(iface); 00704 return ThreadMgr_Release((ITfThreadMgr *)This); 00705 } 00706 00707 static HRESULT WINAPI KeystrokeMgr_AdviseKeyEventSink(ITfKeystrokeMgr *iface, 00708 TfClientId tid, ITfKeyEventSink *pSink, BOOL fForeground) 00709 { 00710 ThreadMgr *This = impl_from_ITfKeystrokeMgrVtbl(iface); 00711 CLSID textservice; 00712 ITfKeyEventSink *check = NULL; 00713 00714 TRACE("(%p) %x %p %i\n",This,tid,pSink,fForeground); 00715 00716 if (!tid || !pSink) 00717 return E_INVALIDARG; 00718 00719 textservice = get_textservice_clsid(tid); 00720 if (IsEqualCLSID(&GUID_NULL,&textservice)) 00721 return E_INVALIDARG; 00722 00723 get_textservice_sink(tid, &IID_ITfKeyEventSink, (IUnknown**)&check); 00724 if (check != NULL) 00725 return CONNECT_E_ADVISELIMIT; 00726 00727 if (FAILED(IUnknown_QueryInterface(pSink,&IID_ITfKeyEventSink,(LPVOID*) &check))) 00728 return E_INVALIDARG; 00729 00730 set_textservice_sink(tid, &IID_ITfKeyEventSink, (IUnknown*)check); 00731 00732 if (fForeground) 00733 { 00734 if (This->forgroundKeyEventSink) 00735 { 00736 ITfKeyEventSink_OnSetFocus(This->forgroundKeyEventSink, FALSE); 00737 ITfKeyEventSink_Release(This->forgroundKeyEventSink); 00738 } 00739 ITfKeyEventSink_AddRef(check); 00740 ITfKeyEventSink_OnSetFocus(check, TRUE); 00741 This->forgroundKeyEventSink = check; 00742 This->forgroundTextService = textservice; 00743 } 00744 return S_OK; 00745 } 00746 00747 static HRESULT WINAPI KeystrokeMgr_UnadviseKeyEventSink(ITfKeystrokeMgr *iface, 00748 TfClientId tid) 00749 { 00750 ThreadMgr *This = impl_from_ITfKeystrokeMgrVtbl(iface); 00751 CLSID textservice; 00752 ITfKeyEventSink *check = NULL; 00753 TRACE("(%p) %x\n",This,tid); 00754 00755 if (!tid) 00756 return E_INVALIDARG; 00757 00758 textservice = get_textservice_clsid(tid); 00759 if (IsEqualCLSID(&GUID_NULL,&textservice)) 00760 return E_INVALIDARG; 00761 00762 get_textservice_sink(tid, &IID_ITfKeyEventSink, (IUnknown**)&check); 00763 00764 if (!check) 00765 return CONNECT_E_NOCONNECTION; 00766 00767 set_textservice_sink(tid, &IID_ITfKeyEventSink, NULL); 00768 ITfKeyEventSink_Release(check); 00769 00770 if (This->forgroundKeyEventSink == check) 00771 { 00772 ITfKeyEventSink_Release(This->forgroundKeyEventSink); 00773 This->forgroundKeyEventSink = NULL; 00774 This->forgroundTextService = GUID_NULL; 00775 } 00776 return S_OK; 00777 } 00778 00779 static HRESULT WINAPI KeystrokeMgr_GetForeground(ITfKeystrokeMgr *iface, 00780 CLSID *pclsid) 00781 { 00782 ThreadMgr *This = impl_from_ITfKeystrokeMgrVtbl(iface); 00783 TRACE("(%p) %p\n",This,pclsid); 00784 if (!pclsid) 00785 return E_INVALIDARG; 00786 00787 if (IsEqualCLSID(&This->forgroundTextService,&GUID_NULL)) 00788 return S_FALSE; 00789 00790 *pclsid = This->forgroundTextService; 00791 return S_OK; 00792 } 00793 00794 static HRESULT WINAPI KeystrokeMgr_TestKeyDown(ITfKeystrokeMgr *iface, 00795 WPARAM wParam, LPARAM lParam, BOOL *pfEaten) 00796 { 00797 ThreadMgr *This = impl_from_ITfKeystrokeMgrVtbl(iface); 00798 FIXME("STUB:(%p)\n",This); 00799 return E_NOTIMPL; 00800 } 00801 00802 static HRESULT WINAPI KeystrokeMgr_TestKeyUp(ITfKeystrokeMgr *iface, 00803 WPARAM wParam, LPARAM lParam, BOOL *pfEaten) 00804 { 00805 ThreadMgr *This = impl_from_ITfKeystrokeMgrVtbl(iface); 00806 FIXME("STUB:(%p)\n",This); 00807 return E_NOTIMPL; 00808 } 00809 00810 static HRESULT WINAPI KeystrokeMgr_KeyDown(ITfKeystrokeMgr *iface, 00811 WPARAM wParam, LPARAM lParam, BOOL *pfEaten) 00812 { 00813 ThreadMgr *This = impl_from_ITfKeystrokeMgrVtbl(iface); 00814 FIXME("STUB:(%p)\n",This); 00815 return E_NOTIMPL; 00816 } 00817 00818 static HRESULT WINAPI KeystrokeMgr_KeyUp(ITfKeystrokeMgr *iface, 00819 WPARAM wParam, LPARAM lParam, BOOL *pfEaten) 00820 { 00821 ThreadMgr *This = impl_from_ITfKeystrokeMgrVtbl(iface); 00822 FIXME("STUB:(%p)\n",This); 00823 return E_NOTIMPL; 00824 } 00825 00826 static HRESULT WINAPI KeystrokeMgr_GetPreservedKey(ITfKeystrokeMgr *iface, 00827 ITfContext *pic, const TF_PRESERVEDKEY *pprekey, GUID *pguid) 00828 { 00829 ThreadMgr *This = impl_from_ITfKeystrokeMgrVtbl(iface); 00830 FIXME("STUB:(%p)\n",This); 00831 return E_NOTIMPL; 00832 } 00833 00834 static HRESULT WINAPI KeystrokeMgr_IsPreservedKey(ITfKeystrokeMgr *iface, 00835 REFGUID rguid, const TF_PRESERVEDKEY *pprekey, BOOL *pfRegistered) 00836 { 00837 ThreadMgr *This = impl_from_ITfKeystrokeMgrVtbl(iface); 00838 struct list *cursor; 00839 00840 TRACE("(%p) %s (%x %x) %p\n",This,debugstr_guid(rguid), (pprekey)?pprekey->uVKey:0, (pprekey)?pprekey->uModifiers:0, pfRegistered); 00841 00842 if (!rguid || !pprekey || !pfRegistered) 00843 return E_INVALIDARG; 00844 00845 LIST_FOR_EACH(cursor, &This->CurrentPreservedKeys) 00846 { 00847 PreservedKey* key = LIST_ENTRY(cursor,PreservedKey,entry); 00848 if (IsEqualGUID(rguid,&key->guid) && pprekey->uVKey == key->prekey.uVKey && pprekey->uModifiers == key->prekey.uModifiers) 00849 { 00850 *pfRegistered = TRUE; 00851 return S_OK; 00852 } 00853 } 00854 00855 *pfRegistered = FALSE; 00856 return S_FALSE; 00857 } 00858 00859 static HRESULT WINAPI KeystrokeMgr_PreserveKey(ITfKeystrokeMgr *iface, 00860 TfClientId tid, REFGUID rguid, const TF_PRESERVEDKEY *prekey, 00861 const WCHAR *pchDesc, ULONG cchDesc) 00862 { 00863 ThreadMgr *This = impl_from_ITfKeystrokeMgrVtbl(iface); 00864 struct list *cursor; 00865 PreservedKey *newkey; 00866 00867 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)); 00868 00869 if (!tid || ! rguid || !prekey || (cchDesc && !pchDesc)) 00870 return E_INVALIDARG; 00871 00872 LIST_FOR_EACH(cursor, &This->CurrentPreservedKeys) 00873 { 00874 PreservedKey* key = LIST_ENTRY(cursor,PreservedKey,entry); 00875 if (IsEqualGUID(rguid,&key->guid) && prekey->uVKey == key->prekey.uVKey && prekey->uModifiers == key->prekey.uModifiers) 00876 return TF_E_ALREADY_EXISTS; 00877 } 00878 00879 newkey = HeapAlloc(GetProcessHeap(),0,sizeof(PreservedKey)); 00880 if (!newkey) 00881 return E_OUTOFMEMORY; 00882 00883 newkey->guid = *rguid; 00884 newkey->prekey = *prekey; 00885 newkey->tid = tid; 00886 newkey->description = NULL; 00887 if (cchDesc) 00888 { 00889 newkey->description = HeapAlloc(GetProcessHeap(),0,cchDesc * sizeof(WCHAR)); 00890 if (!newkey->description) 00891 { 00892 HeapFree(GetProcessHeap(),0,newkey); 00893 return E_OUTOFMEMORY; 00894 } 00895 memcpy(newkey->description, pchDesc, cchDesc*sizeof(WCHAR)); 00896 } 00897 00898 list_add_head(&This->CurrentPreservedKeys,&newkey->entry); 00899 00900 return S_OK; 00901 } 00902 00903 static HRESULT WINAPI KeystrokeMgr_UnpreserveKey(ITfKeystrokeMgr *iface, 00904 REFGUID rguid, const TF_PRESERVEDKEY *pprekey) 00905 { 00906 ThreadMgr *This = impl_from_ITfKeystrokeMgrVtbl(iface); 00907 PreservedKey* key = NULL; 00908 struct list *cursor; 00909 TRACE("(%p) %s (%x %x)\n",This,debugstr_guid(rguid),(pprekey)?pprekey->uVKey:0, (pprekey)?pprekey->uModifiers:0); 00910 00911 if (!pprekey || !rguid) 00912 return E_INVALIDARG; 00913 00914 LIST_FOR_EACH(cursor, &This->CurrentPreservedKeys) 00915 { 00916 key = LIST_ENTRY(cursor,PreservedKey,entry); 00917 if (IsEqualGUID(rguid,&key->guid) && pprekey->uVKey == key->prekey.uVKey && pprekey->uModifiers == key->prekey.uModifiers) 00918 break; 00919 key = NULL; 00920 } 00921 00922 if (!key) 00923 return CONNECT_E_NOCONNECTION; 00924 00925 list_remove(&key->entry); 00926 HeapFree(GetProcessHeap(),0,key->description); 00927 HeapFree(GetProcessHeap(),0,key); 00928 00929 return S_OK; 00930 } 00931 00932 static HRESULT WINAPI KeystrokeMgr_SetPreservedKeyDescription(ITfKeystrokeMgr *iface, 00933 REFGUID rguid, const WCHAR *pchDesc, ULONG cchDesc) 00934 { 00935 ThreadMgr *This = impl_from_ITfKeystrokeMgrVtbl(iface); 00936 FIXME("STUB:(%p)\n",This); 00937 return E_NOTIMPL; 00938 } 00939 00940 static HRESULT WINAPI KeystrokeMgr_GetPreservedKeyDescription(ITfKeystrokeMgr *iface, 00941 REFGUID rguid, BSTR *pbstrDesc) 00942 { 00943 ThreadMgr *This = impl_from_ITfKeystrokeMgrVtbl(iface); 00944 FIXME("STUB:(%p)\n",This); 00945 return E_NOTIMPL; 00946 } 00947 00948 static HRESULT WINAPI KeystrokeMgr_SimulatePreservedKey(ITfKeystrokeMgr *iface, 00949 ITfContext *pic, REFGUID rguid, BOOL *pfEaten) 00950 { 00951 ThreadMgr *This = impl_from_ITfKeystrokeMgrVtbl(iface); 00952 FIXME("STUB:(%p)\n",This); 00953 return E_NOTIMPL; 00954 } 00955 00956 static const ITfKeystrokeMgrVtbl ThreadMgr_KeystrokeMgrVtbl = 00957 { 00958 KeystrokeMgr_QueryInterface, 00959 KeystrokeMgr_AddRef, 00960 KeystrokeMgr_Release, 00961 00962 KeystrokeMgr_AdviseKeyEventSink, 00963 KeystrokeMgr_UnadviseKeyEventSink, 00964 KeystrokeMgr_GetForeground, 00965 KeystrokeMgr_TestKeyDown, 00966 KeystrokeMgr_TestKeyUp, 00967 KeystrokeMgr_KeyDown, 00968 KeystrokeMgr_KeyUp, 00969 KeystrokeMgr_GetPreservedKey, 00970 KeystrokeMgr_IsPreservedKey, 00971 KeystrokeMgr_PreserveKey, 00972 KeystrokeMgr_UnpreserveKey, 00973 KeystrokeMgr_SetPreservedKeyDescription, 00974 KeystrokeMgr_GetPreservedKeyDescription, 00975 KeystrokeMgr_SimulatePreservedKey 00976 }; 00977 00978 /***************************************************** 00979 * ITfMessagePump functions 00980 *****************************************************/ 00981 00982 static HRESULT WINAPI MessagePump_QueryInterface(ITfMessagePump *iface, REFIID iid, LPVOID *ppvOut) 00983 { 00984 ThreadMgr *This = impl_from_ITfMessagePumpVtbl(iface); 00985 return ThreadMgr_QueryInterface((ITfThreadMgr *)This, iid, *ppvOut); 00986 } 00987 00988 static ULONG WINAPI MessagePump_AddRef(ITfMessagePump *iface) 00989 { 00990 ThreadMgr *This = impl_from_ITfMessagePumpVtbl(iface); 00991 return ThreadMgr_AddRef((ITfThreadMgr*)This); 00992 } 00993 00994 static ULONG WINAPI MessagePump_Release(ITfMessagePump *iface) 00995 { 00996 ThreadMgr *This = impl_from_ITfMessagePumpVtbl(iface); 00997 return ThreadMgr_Release((ITfThreadMgr *)This); 00998 } 00999 01000 static HRESULT WINAPI MessagePump_PeekMessageA(ITfMessagePump *iface, 01001 LPMSG pMsg, HWND hwnd, UINT wMsgFilterMin, UINT wMsgFilterMax, 01002 UINT wRemoveMsg, BOOL *pfResult) 01003 { 01004 if (!pfResult) 01005 return E_INVALIDARG; 01006 *pfResult = PeekMessageA(pMsg, hwnd, wMsgFilterMin, wMsgFilterMax, wRemoveMsg); 01007 return S_OK; 01008 } 01009 01010 static HRESULT WINAPI MessagePump_GetMessageA(ITfMessagePump *iface, 01011 LPMSG pMsg, HWND hwnd, UINT wMsgFilterMin, UINT wMsgFilterMax, 01012 BOOL *pfResult) 01013 { 01014 if (!pfResult) 01015 return E_INVALIDARG; 01016 *pfResult = GetMessageA(pMsg, hwnd, wMsgFilterMin, wMsgFilterMax); 01017 return S_OK; 01018 } 01019 01020 static HRESULT WINAPI MessagePump_PeekMessageW(ITfMessagePump *iface, 01021 LPMSG pMsg, HWND hwnd, UINT wMsgFilterMin, UINT wMsgFilterMax, 01022 UINT wRemoveMsg, BOOL *pfResult) 01023 { 01024 if (!pfResult) 01025 return E_INVALIDARG; 01026 *pfResult = PeekMessageW(pMsg, hwnd, wMsgFilterMin, wMsgFilterMax, wRemoveMsg); 01027 return S_OK; 01028 } 01029 01030 static HRESULT WINAPI MessagePump_GetMessageW(ITfMessagePump *iface, 01031 LPMSG pMsg, HWND hwnd, UINT wMsgFilterMin, UINT wMsgFilterMax, 01032 BOOL *pfResult) 01033 { 01034 if (!pfResult) 01035 return E_INVALIDARG; 01036 *pfResult = GetMessageW(pMsg, hwnd, wMsgFilterMin, wMsgFilterMax); 01037 return S_OK; 01038 } 01039 01040 static const ITfMessagePumpVtbl ThreadMgr_MessagePumpVtbl = 01041 { 01042 MessagePump_QueryInterface, 01043 MessagePump_AddRef, 01044 MessagePump_Release, 01045 01046 MessagePump_PeekMessageA, 01047 MessagePump_GetMessageA, 01048 MessagePump_PeekMessageW, 01049 MessagePump_GetMessageW 01050 }; 01051 01052 /***************************************************** 01053 * ITfClientId functions 01054 *****************************************************/ 01055 01056 static HRESULT WINAPI ClientId_QueryInterface(ITfClientId *iface, REFIID iid, LPVOID *ppvOut) 01057 { 01058 ThreadMgr *This = impl_from_ITfClientIdVtbl(iface); 01059 return ThreadMgr_QueryInterface((ITfThreadMgr *)This, iid, *ppvOut); 01060 } 01061 01062 static ULONG WINAPI ClientId_AddRef(ITfClientId *iface) 01063 { 01064 ThreadMgr *This = impl_from_ITfClientIdVtbl(iface); 01065 return ThreadMgr_AddRef((ITfThreadMgr*)This); 01066 } 01067 01068 static ULONG WINAPI ClientId_Release(ITfClientId *iface) 01069 { 01070 ThreadMgr *This = impl_from_ITfClientIdVtbl(iface); 01071 return ThreadMgr_Release((ITfThreadMgr *)This); 01072 } 01073 01074 static HRESULT WINAPI ClientId_GetClientId(ITfClientId *iface, 01075 REFCLSID rclsid, TfClientId *ptid) 01076 01077 { 01078 HRESULT hr; 01079 ITfCategoryMgr *catmgr; 01080 ThreadMgr *This = impl_from_ITfClientIdVtbl(iface); 01081 01082 TRACE("(%p) %s\n",This,debugstr_guid(rclsid)); 01083 01084 CategoryMgr_Constructor(NULL,(IUnknown**)&catmgr); 01085 hr = ITfCategoryMgr_RegisterGUID(catmgr,rclsid,ptid); 01086 ITfCategoryMgr_Release(catmgr); 01087 01088 return hr; 01089 } 01090 01091 static const ITfClientIdVtbl ThreadMgr_ClientIdVtbl = 01092 { 01093 ClientId_QueryInterface, 01094 ClientId_AddRef, 01095 ClientId_Release, 01096 01097 ClientId_GetClientId 01098 }; 01099 01100 /***************************************************** 01101 * ITfThreadMgrEventSink functions (internal) 01102 *****************************************************/ 01103 static HRESULT WINAPI ThreadMgrEventSink_QueryInterface(ITfThreadMgrEventSink *iface, REFIID iid, LPVOID *ppvOut) 01104 { 01105 ThreadMgr *This = impl_from_ITfThreadMgrEventSink(iface); 01106 return ThreadMgr_QueryInterface((ITfThreadMgr *)This, iid, *ppvOut); 01107 } 01108 01109 static ULONG WINAPI ThreadMgrEventSink_AddRef(ITfThreadMgrEventSink *iface) 01110 { 01111 ThreadMgr *This = impl_from_ITfThreadMgrEventSink(iface); 01112 return ThreadMgr_AddRef((ITfThreadMgr*)This); 01113 } 01114 01115 static ULONG WINAPI ThreadMgrEventSink_Release(ITfThreadMgrEventSink *iface) 01116 { 01117 ThreadMgr *This = impl_from_ITfThreadMgrEventSink(iface); 01118 return ThreadMgr_Release((ITfThreadMgr *)This); 01119 } 01120 01121 01122 static HRESULT WINAPI ThreadMgrEventSink_OnInitDocumentMgr( 01123 ITfThreadMgrEventSink *iface,ITfDocumentMgr *pdim) 01124 { 01125 struct list *cursor; 01126 ThreadMgr *This = impl_from_ITfThreadMgrEventSink(iface); 01127 01128 TRACE("(%p) %p\n",This,pdim); 01129 01130 LIST_FOR_EACH(cursor, &This->ThreadMgrEventSink) 01131 { 01132 ThreadMgrSink* sink = LIST_ENTRY(cursor,ThreadMgrSink,entry); 01133 ITfThreadMgrEventSink_OnInitDocumentMgr(sink->interfaces.pITfThreadMgrEventSink,pdim); 01134 } 01135 01136 return S_OK; 01137 } 01138 01139 static HRESULT WINAPI ThreadMgrEventSink_OnUninitDocumentMgr( 01140 ITfThreadMgrEventSink *iface, ITfDocumentMgr *pdim) 01141 { 01142 struct list *cursor; 01143 ThreadMgr *This = impl_from_ITfThreadMgrEventSink(iface); 01144 01145 TRACE("(%p) %p\n",This,pdim); 01146 01147 LIST_FOR_EACH(cursor, &This->ThreadMgrEventSink) 01148 { 01149 ThreadMgrSink* sink = LIST_ENTRY(cursor,ThreadMgrSink,entry); 01150 ITfThreadMgrEventSink_OnUninitDocumentMgr(sink->interfaces.pITfThreadMgrEventSink,pdim); 01151 } 01152 01153 return S_OK; 01154 } 01155 01156 static HRESULT WINAPI ThreadMgrEventSink_OnSetFocus( 01157 ITfThreadMgrEventSink *iface, ITfDocumentMgr *pdimFocus, 01158 ITfDocumentMgr *pdimPrevFocus) 01159 { 01160 struct list *cursor; 01161 ThreadMgr *This = impl_from_ITfThreadMgrEventSink(iface); 01162 01163 TRACE("(%p) %p %p\n",This,pdimFocus, pdimPrevFocus); 01164 01165 LIST_FOR_EACH(cursor, &This->ThreadMgrEventSink) 01166 { 01167 ThreadMgrSink* sink = LIST_ENTRY(cursor,ThreadMgrSink,entry); 01168 ITfThreadMgrEventSink_OnSetFocus(sink->interfaces.pITfThreadMgrEventSink, pdimFocus, pdimPrevFocus); 01169 } 01170 01171 return S_OK; 01172 } 01173 01174 static HRESULT WINAPI ThreadMgrEventSink_OnPushContext( 01175 ITfThreadMgrEventSink *iface, ITfContext *pic) 01176 { 01177 struct list *cursor; 01178 ThreadMgr *This = impl_from_ITfThreadMgrEventSink(iface); 01179 01180 TRACE("(%p) %p\n",This,pic); 01181 01182 LIST_FOR_EACH(cursor, &This->ThreadMgrEventSink) 01183 { 01184 ThreadMgrSink* sink = LIST_ENTRY(cursor,ThreadMgrSink,entry); 01185 ITfThreadMgrEventSink_OnPushContext(sink->interfaces.pITfThreadMgrEventSink,pic); 01186 } 01187 01188 return S_OK; 01189 } 01190 01191 static HRESULT WINAPI ThreadMgrEventSink_OnPopContext( 01192 ITfThreadMgrEventSink *iface, ITfContext *pic) 01193 { 01194 struct list *cursor; 01195 ThreadMgr *This = impl_from_ITfThreadMgrEventSink(iface); 01196 01197 TRACE("(%p) %p\n",This,pic); 01198 01199 LIST_FOR_EACH(cursor, &This->ThreadMgrEventSink) 01200 { 01201 ThreadMgrSink* sink = LIST_ENTRY(cursor,ThreadMgrSink,entry); 01202 ITfThreadMgrEventSink_OnPopContext(sink->interfaces.pITfThreadMgrEventSink,pic); 01203 } 01204 01205 return S_OK; 01206 } 01207 01208 static const ITfThreadMgrEventSinkVtbl ThreadMgr_ThreadMgrEventSinkVtbl = 01209 { 01210 ThreadMgrEventSink_QueryInterface, 01211 ThreadMgrEventSink_AddRef, 01212 ThreadMgrEventSink_Release, 01213 01214 ThreadMgrEventSink_OnInitDocumentMgr, 01215 ThreadMgrEventSink_OnUninitDocumentMgr, 01216 ThreadMgrEventSink_OnSetFocus, 01217 ThreadMgrEventSink_OnPushContext, 01218 ThreadMgrEventSink_OnPopContext 01219 }; 01220 01221 /***************************************************** 01222 * ITfSourceSingle functions 01223 *****************************************************/ 01224 static HRESULT WINAPI ThreadMgrSourceSingle_QueryInterface(ITfSourceSingle *iface, REFIID iid, LPVOID *ppvOut) 01225 { 01226 ThreadMgr *This = impl_from_ITfSourceSingleVtbl(iface); 01227 return ThreadMgr_QueryInterface((ITfThreadMgr *)This, iid, *ppvOut); 01228 } 01229 01230 static ULONG WINAPI ThreadMgrSourceSingle_AddRef(ITfSourceSingle *iface) 01231 { 01232 ThreadMgr *This = impl_from_ITfSourceSingleVtbl(iface); 01233 return ThreadMgr_AddRef((ITfThreadMgr *)This); 01234 } 01235 01236 static ULONG WINAPI ThreadMgrSourceSingle_Release(ITfSourceSingle *iface) 01237 { 01238 ThreadMgr *This = impl_from_ITfSourceSingleVtbl(iface); 01239 return ThreadMgr_Release((ITfThreadMgr *)This); 01240 } 01241 01242 static HRESULT WINAPI ThreadMgrSourceSingle_AdviseSingleSink( ITfSourceSingle *iface, 01243 TfClientId tid, REFIID riid, IUnknown *punk) 01244 { 01245 ThreadMgr *This = impl_from_ITfSourceSingleVtbl(iface); 01246 FIXME("STUB:(%p) %i %s %p\n",This, tid, debugstr_guid(riid),punk); 01247 return E_NOTIMPL; 01248 } 01249 01250 static HRESULT WINAPI ThreadMgrSourceSingle_UnadviseSingleSink( ITfSourceSingle *iface, 01251 TfClientId tid, REFIID riid) 01252 { 01253 ThreadMgr *This = impl_from_ITfSourceSingleVtbl(iface); 01254 FIXME("STUB:(%p) %i %s\n",This, tid, debugstr_guid(riid)); 01255 return E_NOTIMPL; 01256 } 01257 01258 static const ITfSourceSingleVtbl ThreadMgr_SourceSingleVtbl = 01259 { 01260 ThreadMgrSourceSingle_QueryInterface, 01261 ThreadMgrSourceSingle_AddRef, 01262 ThreadMgrSourceSingle_Release, 01263 01264 ThreadMgrSourceSingle_AdviseSingleSink, 01265 ThreadMgrSourceSingle_UnadviseSingleSink, 01266 }; 01267 01268 HRESULT ThreadMgr_Constructor(IUnknown *pUnkOuter, IUnknown **ppOut) 01269 { 01270 ThreadMgr *This; 01271 if (pUnkOuter) 01272 return CLASS_E_NOAGGREGATION; 01273 01274 /* Only 1 ThreadMgr is created per thread */ 01275 This = TlsGetValue(tlsIndex); 01276 if (This) 01277 { 01278 ThreadMgr_AddRef((ITfThreadMgr*)This); 01279 *ppOut = (IUnknown*)This; 01280 return S_OK; 01281 } 01282 01283 This = HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,sizeof(ThreadMgr)); 01284 if (This == NULL) 01285 return E_OUTOFMEMORY; 01286 01287 This->ThreadMgrVtbl= &ThreadMgr_ThreadMgrVtbl; 01288 This->SourceVtbl = &ThreadMgr_SourceVtbl; 01289 This->KeystrokeMgrVtbl= &ThreadMgr_KeystrokeMgrVtbl; 01290 This->MessagePumpVtbl= &ThreadMgr_MessagePumpVtbl; 01291 This->ClientIdVtbl = &ThreadMgr_ClientIdVtbl; 01292 This->ThreadMgrEventSinkVtbl = &ThreadMgr_ThreadMgrEventSinkVtbl; 01293 This->SourceSingleVtbl = &ThreadMgr_SourceSingleVtbl; 01294 This->refCount = 1; 01295 TlsSetValue(tlsIndex,This); 01296 01297 CompartmentMgr_Constructor((IUnknown*)This, &IID_IUnknown, (IUnknown**)&This->CompartmentMgr); 01298 01299 list_init(&This->CurrentPreservedKeys); 01300 list_init(&This->CreatedDocumentMgrs); 01301 list_init(&This->AssociatedFocusWindows); 01302 01303 list_init(&This->ActiveLanguageProfileNotifySink); 01304 list_init(&This->DisplayAttributeNotifySink); 01305 list_init(&This->KeyTraceEventSink); 01306 list_init(&This->PreservedKeyNotifySink); 01307 list_init(&This->ThreadFocusSink); 01308 list_init(&This->ThreadMgrEventSink); 01309 01310 TRACE("returning %p\n", This); 01311 *ppOut = (IUnknown *)This; 01312 return S_OK; 01313 } 01314 01315 /************************************************** 01316 * IEnumTfDocumentMgrs implementation 01317 **************************************************/ 01318 static void EnumTfDocumentMgr_Destructor(EnumTfDocumentMgr *This) 01319 { 01320 TRACE("destroying %p\n", This); 01321 HeapFree(GetProcessHeap(),0,This); 01322 } 01323 01324 static HRESULT WINAPI EnumTfDocumentMgr_QueryInterface(IEnumTfDocumentMgrs *iface, REFIID iid, LPVOID *ppvOut) 01325 { 01326 EnumTfDocumentMgr *This = (EnumTfDocumentMgr *)iface; 01327 *ppvOut = NULL; 01328 01329 if (IsEqualIID(iid, &IID_IUnknown) || IsEqualIID(iid, &IID_IEnumTfDocumentMgrs)) 01330 { 01331 *ppvOut = This; 01332 } 01333 01334 if (*ppvOut) 01335 { 01336 IUnknown_AddRef(iface); 01337 return S_OK; 01338 } 01339 01340 WARN("unsupported interface: %s\n", debugstr_guid(iid)); 01341 return E_NOINTERFACE; 01342 } 01343 01344 static ULONG WINAPI EnumTfDocumentMgr_AddRef(IEnumTfDocumentMgrs *iface) 01345 { 01346 EnumTfDocumentMgr *This = (EnumTfDocumentMgr*)iface; 01347 return InterlockedIncrement(&This->refCount); 01348 } 01349 01350 static ULONG WINAPI EnumTfDocumentMgr_Release(IEnumTfDocumentMgrs *iface) 01351 { 01352 EnumTfDocumentMgr *This = (EnumTfDocumentMgr *)iface; 01353 ULONG ret; 01354 01355 ret = InterlockedDecrement(&This->refCount); 01356 if (ret == 0) 01357 EnumTfDocumentMgr_Destructor(This); 01358 return ret; 01359 } 01360 01361 static HRESULT WINAPI EnumTfDocumentMgr_Next(IEnumTfDocumentMgrs *iface, 01362 ULONG ulCount, ITfDocumentMgr **rgDocumentMgr, ULONG *pcFetched) 01363 { 01364 EnumTfDocumentMgr *This = (EnumTfDocumentMgr *)iface; 01365 ULONG fetched = 0; 01366 01367 TRACE("(%p)\n",This); 01368 01369 if (rgDocumentMgr == NULL) return E_POINTER; 01370 01371 while (fetched < ulCount) 01372 { 01373 DocumentMgrEntry *mgrentry; 01374 if (This->index == NULL) 01375 break; 01376 01377 mgrentry = LIST_ENTRY(This->index,DocumentMgrEntry,entry); 01378 if (mgrentry == NULL) 01379 break; 01380 01381 *rgDocumentMgr = mgrentry->docmgr; 01382 ITfDocumentMgr_AddRef(*rgDocumentMgr); 01383 01384 This->index = list_next(This->head, This->index); 01385 ++fetched; 01386 ++rgDocumentMgr; 01387 } 01388 01389 if (pcFetched) *pcFetched = fetched; 01390 return fetched == ulCount ? S_OK : S_FALSE; 01391 } 01392 01393 static HRESULT WINAPI EnumTfDocumentMgr_Skip( IEnumTfDocumentMgrs* iface, ULONG celt) 01394 { 01395 INT i; 01396 EnumTfDocumentMgr *This = (EnumTfDocumentMgr *)iface; 01397 TRACE("(%p)\n",This); 01398 for(i = 0; i < celt && This->index != NULL; i++) 01399 This->index = list_next(This->head, This->index); 01400 return S_OK; 01401 } 01402 01403 static HRESULT WINAPI EnumTfDocumentMgr_Reset( IEnumTfDocumentMgrs* iface) 01404 { 01405 EnumTfDocumentMgr *This = (EnumTfDocumentMgr *)iface; 01406 TRACE("(%p)\n",This); 01407 This->index = list_head(This->head); 01408 return S_OK; 01409 } 01410 01411 static HRESULT WINAPI EnumTfDocumentMgr_Clone( IEnumTfDocumentMgrs *iface, 01412 IEnumTfDocumentMgrs **ppenum) 01413 { 01414 EnumTfDocumentMgr *This = (EnumTfDocumentMgr *)iface; 01415 HRESULT res; 01416 01417 TRACE("(%p)\n",This); 01418 01419 if (ppenum == NULL) return E_POINTER; 01420 01421 res = EnumTfDocumentMgr_Constructor(This->head, ppenum); 01422 if (SUCCEEDED(res)) 01423 { 01424 EnumTfDocumentMgr *new_This = (EnumTfDocumentMgr *)*ppenum; 01425 new_This->index = This->index; 01426 } 01427 return res; 01428 } 01429 01430 static const IEnumTfDocumentMgrsVtbl IEnumTfDocumentMgrs_Vtbl ={ 01431 EnumTfDocumentMgr_QueryInterface, 01432 EnumTfDocumentMgr_AddRef, 01433 EnumTfDocumentMgr_Release, 01434 01435 EnumTfDocumentMgr_Clone, 01436 EnumTfDocumentMgr_Next, 01437 EnumTfDocumentMgr_Reset, 01438 EnumTfDocumentMgr_Skip 01439 }; 01440 01441 static HRESULT EnumTfDocumentMgr_Constructor(struct list* head, IEnumTfDocumentMgrs **ppOut) 01442 { 01443 EnumTfDocumentMgr *This; 01444 01445 This = HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,sizeof(EnumTfDocumentMgr)); 01446 if (This == NULL) 01447 return E_OUTOFMEMORY; 01448 01449 This->Vtbl= &IEnumTfDocumentMgrs_Vtbl; 01450 This->refCount = 1; 01451 This->head = head; 01452 This->index = list_head(This->head); 01453 01454 TRACE("returning %p\n", This); 01455 *ppOut = (IEnumTfDocumentMgrs*)This; 01456 return S_OK; 01457 } 01458 01459 void ThreadMgr_OnDocumentMgrDestruction(ITfThreadMgr *tm, ITfDocumentMgr *mgr) 01460 { 01461 ThreadMgr *This = (ThreadMgr *)tm; 01462 struct list *cursor; 01463 LIST_FOR_EACH(cursor, &This->CreatedDocumentMgrs) 01464 { 01465 DocumentMgrEntry *mgrentry = LIST_ENTRY(cursor,DocumentMgrEntry,entry); 01466 if (mgrentry->docmgr == mgr) 01467 { 01468 list_remove(cursor); 01469 HeapFree(GetProcessHeap(),0,mgrentry); 01470 return; 01471 } 01472 } 01473 FIXME("ITfDocumentMgr %p not found in this thread\n",mgr); 01474 } Generated on Sat May 26 2012 04:23:23 for ReactOS by
1.7.6.1
|