ReactOS Fundraising Campaign 2012
 
€ 4,410 / € 30,000

Information | Donate

Home | Info | Community | Development | myReactOS | Contact Us

  1. Home
  2. Community
  3. Development
  4. myReactOS
  5. Fundraiser 2012

  1. Main Page
  2. Alphabetical List
  3. Data Structures
  4. Directories
  5. File List
  6. Data Fields
  7. Globals
  8. Related Pages

ReactOS Development > Doxygen

threadmgr.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 doxygen 1.7.6.1

ReactOS is a registered trademark or a trademark of ReactOS Foundation in the United States and other countries.