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

compartmentmgr.c
Go to the documentation of this file.
00001 /*
00002  *  ITfCompartmentMgr 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 #include "oleauto.h"
00036 #include "olectl.h"
00037 
00038 #include "wine/unicode.h"
00039 #include "wine/list.h"
00040 
00041 #include "msctf.h"
00042 #include "msctf_internal.h"
00043 
00044 WINE_DEFAULT_DEBUG_CHANNEL(msctf);
00045 
00046 typedef struct tagCompartmentValue {
00047     struct list entry;
00048     GUID guid;
00049     TfClientId owner;
00050     ITfCompartment *compartment;
00051 } CompartmentValue;
00052 
00053 typedef struct tagCompartmentMgr {
00054     const ITfCompartmentMgrVtbl *CompartmentMgrVtbl;
00055     LONG refCount;
00056 
00057     IUnknown *pUnkOuter;
00058 
00059     struct list values;
00060 } CompartmentMgr;
00061 
00062 typedef struct tagCompartmentEnumGuid {
00063     const IEnumGUIDVtbl *Vtbl;
00064     LONG refCount;
00065 
00066     struct list *values;
00067     struct list *cursor;
00068 } CompartmentEnumGuid;
00069 
00070 
00071 typedef struct tagCompartmentSink {
00072     struct list         entry;
00073     union {
00074         IUnknown            *pIUnknown;
00075         ITfCompartmentEventSink *pITfCompartmentEventSink;
00076     } interfaces;
00077 } CompartmentSink;
00078 
00079 typedef struct tagCompartment {
00080     const ITfCompartmentVtbl *Vtbl;
00081     const ITfSourceVtbl *SourceVtbl;
00082     LONG refCount;
00083 
00084     /* Only VT_I4, VT_UNKNOWN and VT_BSTR data types are allowed */
00085     VARIANT variant;
00086     CompartmentValue *valueData;
00087     struct list CompartmentEventSink;
00088 } Compartment;
00089 
00090 static HRESULT CompartmentEnumGuid_Constructor(struct list* values, IEnumGUID **ppOut);
00091 static HRESULT Compartment_Constructor(CompartmentValue *value, ITfCompartment **ppOut);
00092 
00093 static inline Compartment *impl_from_ITfSourceVtbl(ITfSource *iface)
00094 {
00095     return (Compartment *)((char *)iface - FIELD_OFFSET(Compartment,SourceVtbl));
00096 }
00097 
00098 HRESULT CompartmentMgr_Destructor(ITfCompartmentMgr *iface)
00099 {
00100     CompartmentMgr *This = (CompartmentMgr *)iface;
00101     struct list *cursor, *cursor2;
00102 
00103     LIST_FOR_EACH_SAFE(cursor, cursor2, &This->values)
00104     {
00105         CompartmentValue* value = LIST_ENTRY(cursor,CompartmentValue,entry);
00106         list_remove(cursor);
00107         ITfCompartment_Release(value->compartment);
00108         HeapFree(GetProcessHeap(),0,value);
00109     }
00110 
00111     HeapFree(GetProcessHeap(),0,This);
00112     return S_OK;
00113 }
00114 
00115 /*****************************************************
00116  * ITfCompartmentMgr functions
00117  *****************************************************/
00118 static HRESULT WINAPI CompartmentMgr_QueryInterface(ITfCompartmentMgr *iface, REFIID iid, LPVOID *ppvOut)
00119 {
00120     CompartmentMgr *This = (CompartmentMgr *)iface;
00121     if (This->pUnkOuter)
00122         return IUnknown_QueryInterface(This->pUnkOuter, iid, *ppvOut);
00123     else
00124     {
00125         *ppvOut = NULL;
00126 
00127         if (IsEqualIID(iid, &IID_IUnknown) || IsEqualIID(iid, &IID_ITfCompartmentMgr))
00128         {
00129             *ppvOut = This;
00130         }
00131 
00132         if (*ppvOut)
00133         {
00134             IUnknown_AddRef(iface);
00135             return S_OK;
00136         }
00137 
00138         WARN("unsupported interface: %s\n", debugstr_guid(iid));
00139         return E_NOINTERFACE;
00140     }
00141 }
00142 
00143 static ULONG WINAPI CompartmentMgr_AddRef(ITfCompartmentMgr *iface)
00144 {
00145     CompartmentMgr *This = (CompartmentMgr *)iface;
00146     if (This->pUnkOuter)
00147         return IUnknown_AddRef(This->pUnkOuter);
00148     else
00149         return InterlockedIncrement(&This->refCount);
00150 }
00151 
00152 static ULONG WINAPI CompartmentMgr_Release(ITfCompartmentMgr *iface)
00153 {
00154     CompartmentMgr *This = (CompartmentMgr *)iface;
00155     if (This->pUnkOuter)
00156         return IUnknown_Release(This->pUnkOuter);
00157     else
00158     {
00159         ULONG ret;
00160 
00161         ret = InterlockedDecrement(&This->refCount);
00162         if (ret == 0)
00163             CompartmentMgr_Destructor(iface);
00164         return ret;
00165     }
00166 }
00167 
00168 static HRESULT WINAPI CompartmentMgr_GetCompartment(ITfCompartmentMgr *iface,
00169         REFGUID rguid, ITfCompartment **ppcomp)
00170 {
00171     CompartmentMgr *This = (CompartmentMgr *)iface;
00172     CompartmentValue* value;
00173     struct list *cursor;
00174     HRESULT hr;
00175 
00176     TRACE("(%p) %s  %p\n",This,debugstr_guid(rguid),ppcomp);
00177 
00178     LIST_FOR_EACH(cursor, &This->values)
00179     {
00180         value = LIST_ENTRY(cursor,CompartmentValue,entry);
00181         if (IsEqualGUID(rguid,&value->guid))
00182         {
00183             ITfCompartment_AddRef(value->compartment);
00184             *ppcomp = value->compartment;
00185             return S_OK;
00186         }
00187     }
00188 
00189     value = HeapAlloc(GetProcessHeap(),0,sizeof(CompartmentValue));
00190     value->guid = *rguid;
00191     value->owner = 0;
00192     hr = Compartment_Constructor(value,&value->compartment);
00193     if (SUCCEEDED(hr))
00194     {
00195         list_add_head(&This->values,&value->entry);
00196         ITfCompartment_AddRef(value->compartment);
00197         *ppcomp = value->compartment;
00198     }
00199     else
00200     {
00201         HeapFree(GetProcessHeap(),0,value);
00202         *ppcomp = NULL;
00203     }
00204     return hr;
00205 }
00206 
00207 static HRESULT WINAPI CompartmentMgr_ClearCompartment(ITfCompartmentMgr *iface,
00208     TfClientId tid, REFGUID rguid)
00209 {
00210     struct list *cursor;
00211     CompartmentMgr *This = (CompartmentMgr *)iface;
00212     TRACE("(%p) %i %s\n",This,tid,debugstr_guid(rguid));
00213 
00214     LIST_FOR_EACH(cursor, &This->values)
00215     {
00216         CompartmentValue* value = LIST_ENTRY(cursor,CompartmentValue,entry);
00217         if (IsEqualGUID(rguid,&value->guid))
00218         {
00219             if (value->owner && tid != value->owner)
00220                 return E_UNEXPECTED;
00221             list_remove(cursor);
00222             ITfCompartment_Release(value->compartment);
00223             HeapFree(GetProcessHeap(),0,value);
00224             return S_OK;
00225         }
00226     }
00227 
00228     return CONNECT_E_NOCONNECTION;
00229 }
00230 
00231 static HRESULT WINAPI CompartmentMgr_EnumCompartments(ITfCompartmentMgr *iface,
00232  IEnumGUID **ppEnum)
00233 {
00234     CompartmentMgr *This = (CompartmentMgr *)iface;
00235     TRACE("(%p) %p\n",This,ppEnum);
00236     if (!ppEnum)
00237         return E_INVALIDARG;
00238     return CompartmentEnumGuid_Constructor(&This->values, ppEnum);
00239 }
00240 
00241 static const ITfCompartmentMgrVtbl CompartmentMgr_CompartmentMgrVtbl =
00242 {
00243     CompartmentMgr_QueryInterface,
00244     CompartmentMgr_AddRef,
00245     CompartmentMgr_Release,
00246 
00247     CompartmentMgr_GetCompartment,
00248     CompartmentMgr_ClearCompartment,
00249     CompartmentMgr_EnumCompartments
00250 };
00251 
00252 HRESULT CompartmentMgr_Constructor(IUnknown *pUnkOuter, REFIID riid, IUnknown **ppOut)
00253 {
00254     CompartmentMgr *This;
00255 
00256     if (!ppOut)
00257         return E_POINTER;
00258 
00259     if (pUnkOuter && !IsEqualIID (riid, &IID_IUnknown))
00260         return CLASS_E_NOAGGREGATION;
00261 
00262     This = HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,sizeof(CompartmentMgr));
00263     if (This == NULL)
00264         return E_OUTOFMEMORY;
00265 
00266     This->CompartmentMgrVtbl = &CompartmentMgr_CompartmentMgrVtbl;
00267     This->pUnkOuter = pUnkOuter;
00268     list_init(&This->values);
00269 
00270     if (pUnkOuter)
00271     {
00272         TRACE("returning %p\n", This);
00273         *ppOut = (IUnknown*)This;
00274         return S_OK;
00275     }
00276     else
00277     {
00278         HRESULT hr;
00279         hr = IUnknown_QueryInterface((IUnknown*)This, riid, (LPVOID*)ppOut);
00280         if (FAILED(hr))
00281             HeapFree(GetProcessHeap(),0,This);
00282         return hr;
00283     }
00284 }
00285 
00286 /**************************************************
00287  * IEnumGUID implementation for ITfCompartmentMgr::EnumCompartments
00288  **************************************************/
00289 static void CompartmentEnumGuid_Destructor(CompartmentEnumGuid *This)
00290 {
00291     TRACE("destroying %p\n", This);
00292     HeapFree(GetProcessHeap(),0,This);
00293 }
00294 
00295 static HRESULT WINAPI CompartmentEnumGuid_QueryInterface(IEnumGUID *iface, REFIID iid, LPVOID *ppvOut)
00296 {
00297     CompartmentEnumGuid *This = (CompartmentEnumGuid *)iface;
00298     *ppvOut = NULL;
00299 
00300     if (IsEqualIID(iid, &IID_IUnknown) || IsEqualIID(iid, &IID_IEnumGUID))
00301     {
00302         *ppvOut = This;
00303     }
00304 
00305     if (*ppvOut)
00306     {
00307         IUnknown_AddRef(iface);
00308         return S_OK;
00309     }
00310 
00311     WARN("unsupported interface: %s\n", debugstr_guid(iid));
00312     return E_NOINTERFACE;
00313 }
00314 
00315 static ULONG WINAPI CompartmentEnumGuid_AddRef(IEnumGUID *iface)
00316 {
00317     CompartmentEnumGuid *This = (CompartmentEnumGuid*)iface;
00318     return InterlockedIncrement(&This->refCount);
00319 }
00320 
00321 static ULONG WINAPI CompartmentEnumGuid_Release(IEnumGUID *iface)
00322 {
00323     CompartmentEnumGuid *This = (CompartmentEnumGuid *)iface;
00324     ULONG ret;
00325 
00326     ret = InterlockedDecrement(&This->refCount);
00327     if (ret == 0)
00328         CompartmentEnumGuid_Destructor(This);
00329     return ret;
00330 }
00331 
00332 /*****************************************************
00333  * IEnumGuid functions
00334  *****************************************************/
00335 static HRESULT WINAPI CompartmentEnumGuid_Next( LPENUMGUID iface,
00336     ULONG celt, GUID *rgelt, ULONG *pceltFetched)
00337 {
00338     CompartmentEnumGuid *This = (CompartmentEnumGuid *)iface;
00339     ULONG fetched = 0;
00340 
00341     TRACE("(%p)\n",This);
00342 
00343     if (rgelt == NULL) return E_POINTER;
00344 
00345     while (fetched < celt && This->cursor)
00346     {
00347         CompartmentValue* value = LIST_ENTRY(This->cursor,CompartmentValue,entry);
00348         if (!value)
00349             break;
00350 
00351         This->cursor = list_next(This->values,This->cursor);
00352         *rgelt = value->guid;
00353 
00354         ++fetched;
00355         ++rgelt;
00356     }
00357 
00358     if (pceltFetched) *pceltFetched = fetched;
00359     return fetched == celt ? S_OK : S_FALSE;
00360 }
00361 
00362 static HRESULT WINAPI CompartmentEnumGuid_Skip( LPENUMGUID iface, ULONG celt)
00363 {
00364     CompartmentEnumGuid *This = (CompartmentEnumGuid *)iface;
00365     TRACE("(%p)\n",This);
00366 
00367     This->cursor = list_next(This->values,This->cursor);
00368     return S_OK;
00369 }
00370 
00371 static HRESULT WINAPI CompartmentEnumGuid_Reset( LPENUMGUID iface)
00372 {
00373     CompartmentEnumGuid *This = (CompartmentEnumGuid *)iface;
00374     TRACE("(%p)\n",This);
00375     This->cursor = list_head(This->values);
00376     return S_OK;
00377 }
00378 
00379 static HRESULT WINAPI CompartmentEnumGuid_Clone( LPENUMGUID iface,
00380     IEnumGUID **ppenum)
00381 {
00382     CompartmentEnumGuid *This = (CompartmentEnumGuid *)iface;
00383     HRESULT res;
00384 
00385     TRACE("(%p)\n",This);
00386 
00387     if (ppenum == NULL) return E_POINTER;
00388 
00389     res = CompartmentEnumGuid_Constructor(This->values, ppenum);
00390     if (SUCCEEDED(res))
00391     {
00392         CompartmentEnumGuid *new_This = (CompartmentEnumGuid *)*ppenum;
00393         new_This->cursor = This->cursor;
00394     }
00395     return res;
00396 }
00397 
00398 static const IEnumGUIDVtbl IEnumGUID_Vtbl ={
00399     CompartmentEnumGuid_QueryInterface,
00400     CompartmentEnumGuid_AddRef,
00401     CompartmentEnumGuid_Release,
00402 
00403     CompartmentEnumGuid_Next,
00404     CompartmentEnumGuid_Skip,
00405     CompartmentEnumGuid_Reset,
00406     CompartmentEnumGuid_Clone
00407 };
00408 
00409 static HRESULT CompartmentEnumGuid_Constructor(struct list *values, IEnumGUID **ppOut)
00410 {
00411     CompartmentEnumGuid *This;
00412 
00413     This = HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,sizeof(CompartmentEnumGuid));
00414     if (This == NULL)
00415         return E_OUTOFMEMORY;
00416 
00417     This->Vtbl= &IEnumGUID_Vtbl;
00418     This->refCount = 1;
00419 
00420     This->values = values;
00421     This->cursor = list_head(values);
00422 
00423     TRACE("returning %p\n", This);
00424     *ppOut = (IEnumGUID*)This;
00425     return S_OK;
00426 }
00427 
00428 /**************************************************
00429  * ITfCompartment
00430  **************************************************/
00431 static void free_sink(CompartmentSink *sink)
00432 {
00433         IUnknown_Release(sink->interfaces.pIUnknown);
00434         HeapFree(GetProcessHeap(),0,sink);
00435 }
00436 
00437 static void Compartment_Destructor(Compartment *This)
00438 {
00439     struct list *cursor, *cursor2;
00440     TRACE("destroying %p\n", This);
00441     VariantClear(&This->variant);
00442     LIST_FOR_EACH_SAFE(cursor, cursor2, &This->CompartmentEventSink)
00443     {
00444         CompartmentSink* sink = LIST_ENTRY(cursor,CompartmentSink,entry);
00445         list_remove(cursor);
00446         free_sink(sink);
00447     }
00448     HeapFree(GetProcessHeap(),0,This);
00449 }
00450 
00451 static HRESULT WINAPI Compartment_QueryInterface(ITfCompartment *iface, REFIID iid, LPVOID *ppvOut)
00452 {
00453     Compartment *This = (Compartment *)iface;
00454     *ppvOut = NULL;
00455 
00456     if (IsEqualIID(iid, &IID_IUnknown) || IsEqualIID(iid, &IID_ITfCompartment))
00457     {
00458         *ppvOut = This;
00459     }
00460     else if (IsEqualIID(iid, &IID_ITfSource))
00461     {
00462         *ppvOut = &This->SourceVtbl;
00463     }
00464 
00465     if (*ppvOut)
00466     {
00467         IUnknown_AddRef(iface);
00468         return S_OK;
00469     }
00470 
00471     WARN("unsupported interface: %s\n", debugstr_guid(iid));
00472     return E_NOINTERFACE;
00473 }
00474 
00475 static ULONG WINAPI Compartment_AddRef(ITfCompartment *iface)
00476 {
00477     Compartment *This = (Compartment*)iface;
00478     return InterlockedIncrement(&This->refCount);
00479 }
00480 
00481 static ULONG WINAPI Compartment_Release(ITfCompartment *iface)
00482 {
00483     Compartment *This = (Compartment *)iface;
00484     ULONG ret;
00485 
00486     ret = InterlockedDecrement(&This->refCount);
00487     if (ret == 0)
00488         Compartment_Destructor(This);
00489     return ret;
00490 }
00491 
00492 static HRESULT WINAPI Compartment_SetValue(ITfCompartment *iface,
00493     TfClientId tid, const VARIANT *pvarValue)
00494 {
00495     Compartment *This = (Compartment *)iface;
00496     struct list *cursor;
00497 
00498     TRACE("(%p) %i %p\n",This,tid,pvarValue);
00499 
00500     if (!pvarValue)
00501         return E_INVALIDARG;
00502 
00503     if (!(V_VT(pvarValue) == VT_BSTR || V_VT(pvarValue) == VT_I4 ||
00504           V_VT(pvarValue) == VT_UNKNOWN))
00505         return E_INVALIDARG;
00506 
00507     if (!This->valueData->owner)
00508         This->valueData->owner = tid;
00509 
00510     VariantClear(&This->variant);
00511 
00512     /* Shallow copy of value and type */
00513     This->variant = *pvarValue;
00514 
00515     if (V_VT(pvarValue) == VT_BSTR)
00516         V_BSTR(&This->variant) = SysAllocStringByteLen((char*)V_BSTR(pvarValue),
00517                 SysStringByteLen(V_BSTR(pvarValue)));
00518     else if (V_VT(pvarValue) == VT_UNKNOWN)
00519         IUnknown_AddRef(V_UNKNOWN(&This->variant));
00520 
00521     LIST_FOR_EACH(cursor, &This->CompartmentEventSink)
00522     {
00523         CompartmentSink* sink = LIST_ENTRY(cursor,CompartmentSink,entry);
00524         ITfCompartmentEventSink_OnChange(sink->interfaces.pITfCompartmentEventSink,&This->valueData->guid);
00525     }
00526 
00527     return S_OK;
00528 }
00529 
00530 static HRESULT WINAPI Compartment_GetValue(ITfCompartment *iface,
00531     VARIANT *pvarValue)
00532 {
00533     Compartment *This = (Compartment *)iface;
00534     TRACE("(%p) %p\n",This, pvarValue);
00535 
00536     if (!pvarValue)
00537         return E_INVALIDARG;
00538 
00539     VariantInit(pvarValue);
00540     if (V_VT(&This->variant) == VT_EMPTY) return S_FALSE;
00541     return VariantCopy(pvarValue,&This->variant);
00542 }
00543 
00544 static const ITfCompartmentVtbl ITfCompartment_Vtbl ={
00545     Compartment_QueryInterface,
00546     Compartment_AddRef,
00547     Compartment_Release,
00548 
00549     Compartment_SetValue,
00550     Compartment_GetValue
00551 };
00552 
00553 /*****************************************************
00554  * ITfSource functions
00555  *****************************************************/
00556 
00557 static HRESULT WINAPI Source_QueryInterface(ITfSource *iface, REFIID iid, LPVOID *ppvOut)
00558 {
00559     Compartment *This = impl_from_ITfSourceVtbl(iface);
00560     return Compartment_QueryInterface((ITfCompartment *)This, iid, *ppvOut);
00561 }
00562 
00563 static ULONG WINAPI Source_AddRef(ITfSource *iface)
00564 {
00565     Compartment *This = impl_from_ITfSourceVtbl(iface);
00566     return Compartment_AddRef((ITfCompartment*)This);
00567 }
00568 
00569 static ULONG WINAPI Source_Release(ITfSource *iface)
00570 {
00571     Compartment *This = impl_from_ITfSourceVtbl(iface);
00572     return Compartment_Release((ITfCompartment *)This);
00573 }
00574 
00575 static HRESULT WINAPI CompartmentSource_AdviseSink(ITfSource *iface,
00576         REFIID riid, IUnknown *punk, DWORD *pdwCookie)
00577 {
00578     CompartmentSink *cs;
00579     Compartment *This = impl_from_ITfSourceVtbl(iface);
00580 
00581     TRACE("(%p) %s %p %p\n",This,debugstr_guid(riid),punk,pdwCookie);
00582 
00583     if (!riid || !punk || !pdwCookie)
00584         return E_INVALIDARG;
00585 
00586     if (IsEqualIID(riid, &IID_ITfCompartmentEventSink))
00587     {
00588         cs = HeapAlloc(GetProcessHeap(),0,sizeof(CompartmentSink));
00589         if (!cs)
00590             return E_OUTOFMEMORY;
00591         if (FAILED(IUnknown_QueryInterface(punk, riid, (LPVOID *)&cs->interfaces.pITfCompartmentEventSink)))
00592         {
00593             HeapFree(GetProcessHeap(),0,cs);
00594             return CONNECT_E_CANNOTCONNECT;
00595         }
00596         list_add_head(&This->CompartmentEventSink,&cs->entry);
00597         *pdwCookie = generate_Cookie(COOKIE_MAGIC_COMPARTMENTSINK , cs);
00598     }
00599     else
00600     {
00601         FIXME("(%p) Unhandled Sink: %s\n",This,debugstr_guid(riid));
00602         return E_NOTIMPL;
00603     }
00604 
00605     TRACE("cookie %x\n",*pdwCookie);
00606 
00607     return S_OK;
00608 }
00609 
00610 static HRESULT WINAPI CompartmentSource_UnadviseSink(ITfSource *iface, DWORD pdwCookie)
00611 {
00612     CompartmentSink *sink;
00613     Compartment *This = impl_from_ITfSourceVtbl(iface);
00614 
00615     TRACE("(%p) %x\n",This,pdwCookie);
00616 
00617     if (get_Cookie_magic(pdwCookie)!=COOKIE_MAGIC_COMPARTMENTSINK)
00618         return E_INVALIDARG;
00619 
00620     sink = (CompartmentSink*)remove_Cookie(pdwCookie);
00621     if (!sink)
00622         return CONNECT_E_NOCONNECTION;
00623 
00624     list_remove(&sink->entry);
00625     free_sink(sink);
00626 
00627     return S_OK;
00628 }
00629 
00630 static const ITfSourceVtbl Compartment_SourceVtbl =
00631 {
00632     Source_QueryInterface,
00633     Source_AddRef,
00634     Source_Release,
00635 
00636     CompartmentSource_AdviseSink,
00637     CompartmentSource_UnadviseSink,
00638 };
00639 
00640 static HRESULT Compartment_Constructor(CompartmentValue *valueData, ITfCompartment **ppOut)
00641 {
00642     Compartment *This;
00643 
00644     This = HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,sizeof(Compartment));
00645     if (This == NULL)
00646         return E_OUTOFMEMORY;
00647 
00648     This->Vtbl= &ITfCompartment_Vtbl;
00649     This->SourceVtbl = &Compartment_SourceVtbl;
00650     This->refCount = 1;
00651 
00652     This->valueData = valueData;
00653     VariantInit(&This->variant);
00654 
00655     list_init(&This->CompartmentEventSink);
00656 
00657     TRACE("returning %p\n", This);
00658     *ppOut = (ITfCompartment*)This;
00659     return S_OK;
00660 }

Generated on Sun May 27 2012 04:24:49 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.