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

documentmgr.c
Go to the documentation of this file.
00001 /*
00002  *  ITfDocumentMgr implementation
00003  *
00004  *  Copyright 2009 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 
00036 #include "wine/unicode.h"
00037 
00038 #include "msctf.h"
00039 #include "msctf_internal.h"
00040 
00041 WINE_DEFAULT_DEBUG_CHANNEL(msctf);
00042 
00043 typedef struct tagDocumentMgr {
00044     ITfDocumentMgr ITfDocumentMgr_iface;
00045     ITfSource ITfSource_iface;
00046     LONG refCount;
00047 
00048     /* Aggregation */
00049     ITfCompartmentMgr  *CompartmentMgr;
00050 
00051     ITfContext*  contextStack[2]; /* limit of 2 contexts */
00052     ITfThreadMgrEventSink* ThreadMgrSink;
00053 } DocumentMgr;
00054 
00055 typedef struct tagEnumTfContext {
00056     IEnumTfContexts IEnumTfContexts_iface;
00057     LONG refCount;
00058 
00059     DWORD   index;
00060     DocumentMgr *docmgr;
00061 } EnumTfContext;
00062 
00063 static HRESULT EnumTfContext_Constructor(DocumentMgr* mgr, IEnumTfContexts **ppOut);
00064 
00065 static inline DocumentMgr *impl_from_ITfDocumentMgr(ITfDocumentMgr *iface)
00066 {
00067     return CONTAINING_RECORD(iface, DocumentMgr, ITfDocumentMgr_iface);
00068 }
00069 
00070 static inline DocumentMgr *impl_from_ITfSource(ITfSource *iface)
00071 {
00072     return CONTAINING_RECORD(iface, DocumentMgr, ITfSource_iface);
00073 }
00074 
00075 static inline EnumTfContext *impl_from_IEnumTfContexts(IEnumTfContexts *iface)\
00076 {
00077     return CONTAINING_RECORD(iface, EnumTfContext, IEnumTfContexts_iface);
00078 }
00079 
00080 static void DocumentMgr_Destructor(DocumentMgr *This)
00081 {
00082     ITfThreadMgr *tm;
00083     TRACE("destroying %p\n", This);
00084 
00085     TF_GetThreadMgr(&tm);
00086     ThreadMgr_OnDocumentMgrDestruction(tm, &This->ITfDocumentMgr_iface);
00087 
00088     if (This->contextStack[0])
00089         ITfContext_Release(This->contextStack[0]);
00090     if (This->contextStack[1])
00091         ITfContext_Release(This->contextStack[1]);
00092     CompartmentMgr_Destructor(This->CompartmentMgr);
00093     HeapFree(GetProcessHeap(),0,This);
00094 }
00095 
00096 static HRESULT WINAPI DocumentMgr_QueryInterface(ITfDocumentMgr *iface, REFIID iid, LPVOID *ppvOut)
00097 {
00098     DocumentMgr *This = impl_from_ITfDocumentMgr(iface);
00099     *ppvOut = NULL;
00100 
00101     if (IsEqualIID(iid, &IID_IUnknown) || IsEqualIID(iid, &IID_ITfDocumentMgr))
00102     {
00103         *ppvOut = This;
00104     }
00105     else if (IsEqualIID(iid, &IID_ITfSource))
00106     {
00107         *ppvOut = &This->ITfSource_iface;
00108     }
00109     else if (IsEqualIID(iid, &IID_ITfCompartmentMgr))
00110     {
00111         *ppvOut = This->CompartmentMgr;
00112     }
00113 
00114     if (*ppvOut)
00115     {
00116         IUnknown_AddRef(iface);
00117         return S_OK;
00118     }
00119 
00120     WARN("unsupported interface: %s\n", debugstr_guid(iid));
00121     return E_NOINTERFACE;
00122 }
00123 
00124 static ULONG WINAPI DocumentMgr_AddRef(ITfDocumentMgr *iface)
00125 {
00126     DocumentMgr *This = impl_from_ITfDocumentMgr(iface);
00127     return InterlockedIncrement(&This->refCount);
00128 }
00129 
00130 static ULONG WINAPI DocumentMgr_Release(ITfDocumentMgr *iface)
00131 {
00132     DocumentMgr *This = impl_from_ITfDocumentMgr(iface);
00133     ULONG ret;
00134 
00135     ret = InterlockedDecrement(&This->refCount);
00136     if (ret == 0)
00137         DocumentMgr_Destructor(This);
00138     return ret;
00139 }
00140 
00141 /*****************************************************
00142  * ITfDocumentMgr functions
00143  *****************************************************/
00144 static HRESULT WINAPI DocumentMgr_CreateContext(ITfDocumentMgr *iface,
00145         TfClientId tidOwner,
00146         DWORD dwFlags, IUnknown *punk, ITfContext **ppic,
00147         TfEditCookie *pecTextStore)
00148 {
00149     DocumentMgr *This = impl_from_ITfDocumentMgr(iface);
00150     TRACE("(%p) 0x%x 0x%x %p %p %p\n",This,tidOwner,dwFlags,punk,ppic,pecTextStore);
00151     return Context_Constructor(tidOwner, punk, iface, ppic, pecTextStore);
00152 }
00153 
00154 static HRESULT WINAPI DocumentMgr_Push(ITfDocumentMgr *iface, ITfContext *pic)
00155 {
00156     DocumentMgr *This = impl_from_ITfDocumentMgr(iface);
00157     ITfContext *check;
00158 
00159     TRACE("(%p) %p\n",This,pic);
00160 
00161     if (This->contextStack[1])  /* FUll */
00162         return TF_E_STACKFULL;
00163 
00164     if (!pic || FAILED(IUnknown_QueryInterface(pic,&IID_ITfContext,(LPVOID*) &check)))
00165         return E_INVALIDARG;
00166 
00167     if (This->contextStack[0] == NULL)
00168         ITfThreadMgrEventSink_OnInitDocumentMgr(This->ThreadMgrSink,iface);
00169 
00170     This->contextStack[1] = This->contextStack[0];
00171     This->contextStack[0] = check;
00172 
00173     Context_Initialize(check, iface);
00174     ITfThreadMgrEventSink_OnPushContext(This->ThreadMgrSink,check);
00175 
00176     return S_OK;
00177 }
00178 
00179 static HRESULT WINAPI DocumentMgr_Pop(ITfDocumentMgr *iface, DWORD dwFlags)
00180 {
00181     DocumentMgr *This = impl_from_ITfDocumentMgr(iface);
00182     TRACE("(%p) 0x%x\n",This,dwFlags);
00183 
00184     if (dwFlags == TF_POPF_ALL)
00185     {
00186         if (This->contextStack[0])
00187         {
00188             ITfThreadMgrEventSink_OnPopContext(This->ThreadMgrSink,This->contextStack[0]);
00189             ITfContext_Release(This->contextStack[0]);
00190             Context_Uninitialize(This->contextStack[0]);
00191         }
00192         if (This->contextStack[1])
00193         {
00194             ITfThreadMgrEventSink_OnPopContext(This->ThreadMgrSink,This->contextStack[1]);
00195             ITfContext_Release(This->contextStack[1]);
00196             Context_Uninitialize(This->contextStack[1]);
00197         }
00198         This->contextStack[0] = This->contextStack[1] = NULL;
00199         ITfThreadMgrEventSink_OnUninitDocumentMgr(This->ThreadMgrSink, iface);
00200         return S_OK;
00201     }
00202 
00203     if (dwFlags)
00204         return E_INVALIDARG;
00205 
00206     if (This->contextStack[1] == NULL) /* Cannot pop last context */
00207         return E_FAIL;
00208 
00209     ITfThreadMgrEventSink_OnPopContext(This->ThreadMgrSink,This->contextStack[0]);
00210     ITfContext_Release(This->contextStack[0]);
00211     Context_Uninitialize(This->contextStack[0]);
00212     This->contextStack[0] = This->contextStack[1];
00213     This->contextStack[1] = NULL;
00214 
00215     if (This->contextStack[0] == NULL)
00216         ITfThreadMgrEventSink_OnUninitDocumentMgr(This->ThreadMgrSink, iface);
00217 
00218     return S_OK;
00219 }
00220 
00221 static HRESULT WINAPI DocumentMgr_GetTop(ITfDocumentMgr *iface, ITfContext **ppic)
00222 {
00223     DocumentMgr *This = impl_from_ITfDocumentMgr(iface);
00224     TRACE("(%p)\n",This);
00225     if (!ppic)
00226         return E_INVALIDARG;
00227 
00228     if (This->contextStack[0])
00229         ITfContext_AddRef(This->contextStack[0]);
00230 
00231     *ppic = This->contextStack[0];
00232 
00233     return S_OK;
00234 }
00235 
00236 static HRESULT WINAPI DocumentMgr_GetBase(ITfDocumentMgr *iface, ITfContext **ppic)
00237 {
00238     DocumentMgr *This = impl_from_ITfDocumentMgr(iface);
00239     ITfContext *tgt;
00240 
00241     TRACE("(%p)\n",This);
00242     if (!ppic)
00243         return E_INVALIDARG;
00244 
00245     if (This->contextStack[1])
00246         tgt = This->contextStack[1];
00247     else
00248         tgt = This->contextStack[0];
00249 
00250     if (tgt)
00251         ITfContext_AddRef(tgt);
00252 
00253     *ppic = tgt;
00254 
00255     return S_OK;
00256 }
00257 
00258 static HRESULT WINAPI DocumentMgr_EnumContexts(ITfDocumentMgr *iface, IEnumTfContexts **ppEnum)
00259 {
00260     DocumentMgr *This = impl_from_ITfDocumentMgr(iface);
00261     TRACE("(%p) %p\n",This,ppEnum);
00262     return EnumTfContext_Constructor(This, ppEnum);
00263 }
00264 
00265 static const ITfDocumentMgrVtbl DocumentMgr_DocumentMgrVtbl =
00266 {
00267     DocumentMgr_QueryInterface,
00268     DocumentMgr_AddRef,
00269     DocumentMgr_Release,
00270 
00271     DocumentMgr_CreateContext,
00272     DocumentMgr_Push,
00273     DocumentMgr_Pop,
00274     DocumentMgr_GetTop,
00275     DocumentMgr_GetBase,
00276     DocumentMgr_EnumContexts
00277 };
00278 
00279 
00280 static HRESULT WINAPI Source_QueryInterface(ITfSource *iface, REFIID iid, LPVOID *ppvOut)
00281 {
00282     DocumentMgr *This = impl_from_ITfSource(iface);
00283     return DocumentMgr_QueryInterface(&This->ITfDocumentMgr_iface, iid, *ppvOut);
00284 }
00285 
00286 static ULONG WINAPI Source_AddRef(ITfSource *iface)
00287 {
00288     DocumentMgr *This = impl_from_ITfSource(iface);
00289     return DocumentMgr_AddRef(&This->ITfDocumentMgr_iface);
00290 }
00291 
00292 static ULONG WINAPI Source_Release(ITfSource *iface)
00293 {
00294     DocumentMgr *This = impl_from_ITfSource(iface);
00295     return DocumentMgr_Release(&This->ITfDocumentMgr_iface);
00296 }
00297 
00298 /*****************************************************
00299  * ITfSource functions
00300  *****************************************************/
00301 static HRESULT WINAPI DocumentMgrSource_AdviseSink(ITfSource *iface,
00302         REFIID riid, IUnknown *punk, DWORD *pdwCookie)
00303 {
00304     DocumentMgr *This = impl_from_ITfSource(iface);
00305     FIXME("STUB:(%p)\n",This);
00306     return E_NOTIMPL;
00307 }
00308 
00309 static HRESULT WINAPI DocumentMgrSource_UnadviseSink(ITfSource *iface, DWORD pdwCookie)
00310 {
00311     DocumentMgr *This = impl_from_ITfSource(iface);
00312     FIXME("STUB:(%p)\n",This);
00313     return E_NOTIMPL;
00314 }
00315 
00316 static const ITfSourceVtbl DocumentMgr_SourceVtbl =
00317 {
00318     Source_QueryInterface,
00319     Source_AddRef,
00320     Source_Release,
00321 
00322     DocumentMgrSource_AdviseSink,
00323     DocumentMgrSource_UnadviseSink,
00324 };
00325 
00326 HRESULT DocumentMgr_Constructor(ITfThreadMgrEventSink *ThreadMgrSink, ITfDocumentMgr **ppOut)
00327 {
00328     DocumentMgr *This;
00329 
00330     This = HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,sizeof(DocumentMgr));
00331     if (This == NULL)
00332         return E_OUTOFMEMORY;
00333 
00334     This->ITfDocumentMgr_iface.lpVtbl = &DocumentMgr_DocumentMgrVtbl;
00335     This->ITfSource_iface.lpVtbl = &DocumentMgr_SourceVtbl;
00336     This->refCount = 1;
00337     This->ThreadMgrSink = ThreadMgrSink;
00338 
00339     CompartmentMgr_Constructor((IUnknown*)This, &IID_IUnknown, (IUnknown**)&This->CompartmentMgr);
00340 
00341     TRACE("returning %p\n", This);
00342     *ppOut = &This->ITfDocumentMgr_iface;
00343     return S_OK;
00344 }
00345 
00346 /**************************************************
00347  * IEnumTfContexts implementation
00348  **************************************************/
00349 static void EnumTfContext_Destructor(EnumTfContext *This)
00350 {
00351     TRACE("destroying %p\n", This);
00352     HeapFree(GetProcessHeap(),0,This);
00353 }
00354 
00355 static HRESULT WINAPI EnumTfContext_QueryInterface(IEnumTfContexts *iface, REFIID iid, LPVOID *ppvOut)
00356 {
00357     EnumTfContext *This = impl_from_IEnumTfContexts(iface);
00358     *ppvOut = NULL;
00359 
00360     if (IsEqualIID(iid, &IID_IUnknown) || IsEqualIID(iid, &IID_IEnumTfContexts))
00361     {
00362         *ppvOut = This;
00363     }
00364 
00365     if (*ppvOut)
00366     {
00367         IUnknown_AddRef(iface);
00368         return S_OK;
00369     }
00370 
00371     WARN("unsupported interface: %s\n", debugstr_guid(iid));
00372     return E_NOINTERFACE;
00373 }
00374 
00375 static ULONG WINAPI EnumTfContext_AddRef(IEnumTfContexts *iface)
00376 {
00377     EnumTfContext *This = impl_from_IEnumTfContexts(iface);
00378     return InterlockedIncrement(&This->refCount);
00379 }
00380 
00381 static ULONG WINAPI EnumTfContext_Release(IEnumTfContexts *iface)
00382 {
00383     EnumTfContext *This = impl_from_IEnumTfContexts(iface);
00384     ULONG ret;
00385 
00386     ret = InterlockedDecrement(&This->refCount);
00387     if (ret == 0)
00388         EnumTfContext_Destructor(This);
00389     return ret;
00390 }
00391 
00392 static HRESULT WINAPI EnumTfContext_Next(IEnumTfContexts *iface,
00393     ULONG ulCount, ITfContext **rgContext, ULONG *pcFetched)
00394 {
00395     EnumTfContext *This = impl_from_IEnumTfContexts(iface);
00396     ULONG fetched = 0;
00397 
00398     TRACE("(%p)\n",This);
00399 
00400     if (rgContext == NULL) return E_POINTER;
00401 
00402     while (fetched < ulCount)
00403     {
00404         if (This->index > 1)
00405             break;
00406 
00407         if (!This->docmgr->contextStack[This->index])
00408             break;
00409 
00410         *rgContext = This->docmgr->contextStack[This->index];
00411         ITfContext_AddRef(*rgContext);
00412 
00413         ++This->index;
00414         ++fetched;
00415         ++rgContext;
00416     }
00417 
00418     if (pcFetched) *pcFetched = fetched;
00419     return fetched == ulCount ? S_OK : S_FALSE;
00420 }
00421 
00422 static HRESULT WINAPI EnumTfContext_Skip( IEnumTfContexts* iface, ULONG celt)
00423 {
00424     EnumTfContext *This = impl_from_IEnumTfContexts(iface);
00425     TRACE("(%p)\n",This);
00426     This->index += celt;
00427     return S_OK;
00428 }
00429 
00430 static HRESULT WINAPI EnumTfContext_Reset( IEnumTfContexts* iface)
00431 {
00432     EnumTfContext *This = impl_from_IEnumTfContexts(iface);
00433     TRACE("(%p)\n",This);
00434     This->index = 0;
00435     return S_OK;
00436 }
00437 
00438 static HRESULT WINAPI EnumTfContext_Clone( IEnumTfContexts *iface,
00439     IEnumTfContexts **ppenum)
00440 {
00441     EnumTfContext *This = impl_from_IEnumTfContexts(iface);
00442     HRESULT res;
00443 
00444     TRACE("(%p)\n",This);
00445 
00446     if (ppenum == NULL) return E_POINTER;
00447 
00448     res = EnumTfContext_Constructor(This->docmgr, ppenum);
00449     if (SUCCEEDED(res))
00450     {
00451         EnumTfContext *new_This = impl_from_IEnumTfContexts(*ppenum);
00452         new_This->index = This->index;
00453     }
00454     return res;
00455 }
00456 
00457 static const IEnumTfContextsVtbl IEnumTfContexts_Vtbl ={
00458     EnumTfContext_QueryInterface,
00459     EnumTfContext_AddRef,
00460     EnumTfContext_Release,
00461 
00462     EnumTfContext_Clone,
00463     EnumTfContext_Next,
00464     EnumTfContext_Reset,
00465     EnumTfContext_Skip
00466 };
00467 
00468 static HRESULT EnumTfContext_Constructor(DocumentMgr *mgr, IEnumTfContexts **ppOut)
00469 {
00470     EnumTfContext *This;
00471 
00472     This = HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,sizeof(EnumTfContext));
00473     if (This == NULL)
00474         return E_OUTOFMEMORY;
00475 
00476     This->IEnumTfContexts_iface.lpVtbl = &IEnumTfContexts_Vtbl;
00477     This->refCount = 1;
00478     This->docmgr = mgr;
00479 
00480     TRACE("returning %p\n", This);
00481     *ppOut = &This->IEnumTfContexts_iface;
00482     return S_OK;
00483 }

Generated on Fri May 25 2012 04:22:56 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.