~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~ [ freetext search ] ~ [ file search ] ~

Wine Cross Reference
wine/dlls/msctf/compartmentmgr.c

Version: ~ [ wine-1.5.30 ] ~ [ wine-1.5.29 ] ~ [ wine-1.5.28 ] ~ [ wine-1.5.27 ] ~ [ wine-1.5.26 ] ~ [ wine-1.5.25 ] ~ [ wine-1.5.24 ] ~ [ wine-1.5.23 ] ~ [ wine-1.5.22 ] ~ [ wine-1.5.21 ] ~ [ wine-1.5.20 ] ~ [ wine-1.5.19 ] ~ [ wine-1.5.18 ] ~ [ wine-1.5.17 ] ~ [ wine-1.5.16 ] ~ [ wine-1.5.15 ] ~ [ wine-1.5.14 ] ~ [ wine-1.5.13 ] ~ [ wine-1.5.12 ] ~ [ wine-1.5.11 ] ~ [ wine-1.5.10 ] ~ [ wine-1.5.9 ] ~ [ wine-1.5.8 ] ~ [ wine-1.5.7 ] ~ [ wine-1.4.1 ] ~ [ wine-1.5.6 ] ~ [ wine-1.5.5 ] ~ [ wine-1.5.4 ] ~ [ wine-1.5.3 ] ~ [ wine-1.5.2 ] ~ [ wine-1.5.1 ] ~ [ wine-1.5.0 ] ~ [ wine-1.4 ] ~ [ wine-1.4-rc6 ] ~ [ wine-1.4-rc5 ] ~ [ wine-1.4-rc4 ] ~ [ wine-1.4-rc3 ] ~ [ wine-1.4-rc2 ] ~ [ wine-1.4-rc1 ] ~ [ wine-1.3.37 ] ~ [ wine-1.3.36 ] ~ [ wine-1.3.35 ] ~ [ wine-1.3.34 ] ~ [ wine-1.3.33 ] ~ [ wine-1.3.32 ] ~ [ wine-1.3.31 ] ~ [ wine-1.3.30 ] ~ [ wine-1.3.29 ] ~ [ wine-1.3.28 ] ~ [ wine-1.3.27 ] ~ [ wine-1.3.26 ] ~ [ wine-1.3.25 ] ~ [ wine-1.3.24 ] ~ [ wine-1.3.23 ] ~ [ wine-1.3.22 ] ~ [ wine-1.3.21 ] ~ [ wine-1.3.20 ] ~ [ wine-1.3.19 ] ~ [ wine-1.3.18 ] ~ [ wine-1.2.3 ] ~ [ wine-1.3.17 ] ~ [ wine-1.3.16 ] ~ [ wine-1.3.15 ] ~ [ wine-1.3.14 ] ~ [ wine-1.3.13 ] ~ [ wine-1.3.12 ] ~ [ wine-1.3.11 ] ~ [ wine-1.3.10 ] ~ [ wine-1.3.9 ] ~ [ wine-1.2.2 ] ~ [ wine-1.3.8 ] ~ [ wine-1.3.7 ] ~ [ wine-1.3.6 ] ~ [ wine-1.3.5 ] ~ [ wine-1.2.1 ] ~ [ wine-1.3.4 ] ~ [ wine-1.3.3 ] ~ [ wine-1.3.2 ] ~ [ wine-1.3.1 ] ~ [ wine-1.3.0 ] ~ [ wine-1.2 ] ~ [ wine-1.2-rc7 ] ~ [ wine-1.2-rc6 ] ~ [ wine-1.2-rc5 ] ~ [ wine-1.2-rc4 ] ~ [ wine-1.2-rc3 ] ~ [ wine-1.2-rc2 ] ~ [ wine-1.2-rc1 ] ~ [ wine-1.1.44 ] ~ [ wine-1.1.43 ] ~ [ wine-1.1.42 ] ~ [ wine-1.1.41 ] ~ [ wine-1.1.40 ] ~ [ wine-1.1.39 ] ~ [ wine-1.1.38 ] ~ [ wine-1.1.37 ] ~ [ wine-1.1.36 ] ~ [ wine-1.1.35 ] ~ [ wine-1.1.34 ] ~ [ wine-1.1.33 ] ~ [ wine-1.1.32 ] ~ [ wine-1.1.31 ] ~ [ wine-1.1.30 ] ~ [ wine-1.1.29 ] ~ [ wine-1.1.28 ] ~ [ wine-1.1.27 ] ~ [ wine-1.1.26 ] ~ [ wine-1.1.25 ] ~ [ wine-1.1.24 ] ~ [ wine-1.1.23 ] ~ [ wine-1.1.22 ] ~ [ wine-1.1.21 ] ~ [ wine-1.1.20 ] ~ [ wine-1.1.19 ] ~ [ wine-1.1.18 ] ~ [ wine-1.1.17 ] ~ [ wine-1.1.16 ] ~ [ wine-1.1.15 ] ~ [ wine-1.1.14 ] ~ [ wine-1.1.13 ] ~ [ wine-1.1.12 ] ~ [ wine-1.1.11 ] ~ [ wine-1.1.10 ] ~ [ wine-1.1.9 ] ~ [ wine-1.1.8 ] ~ [ wine-1.1.7 ] ~ [ wine-1.0.1 ] ~ [ wine-1.1.6 ] ~ [ wine-1.1.5 ] ~ [ wine-1.1.4 ] ~ [ wine-1.1.3 ] ~ [ wine-1.1.2 ] ~ [ wine-1.1.1 ] ~ [ wine-1.1.0 ] ~ [ wine-1.0 ] ~

  1 /*
  2  *  ITfCompartmentMgr implementation
  3  *
  4  *  Copyright 2009 Aric Stewart, CodeWeavers
  5  *
  6  * This library is free software; you can redistribute it and/or
  7  * modify it under the terms of the GNU Lesser General Public
  8  * License as published by the Free Software Foundation; either
  9  * version 2.1 of the License, or (at your option) any later version.
 10  *
 11  * This library is distributed in the hope that it will be useful,
 12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
 13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 14  * Lesser General Public License for more details.
 15  *
 16  * You should have received a copy of the GNU Lesser General Public
 17  * License along with this library; if not, write to the Free Software
 18  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
 19  */
 20 
 21 #include "config.h"
 22 
 23 #include <stdarg.h>
 24 
 25 #define COBJMACROS
 26 
 27 #include "wine/debug.h"
 28 #include "windef.h"
 29 #include "winbase.h"
 30 #include "winreg.h"
 31 #include "winuser.h"
 32 #include "shlwapi.h"
 33 #include "winerror.h"
 34 #include "objbase.h"
 35 #include "oleauto.h"
 36 #include "olectl.h"
 37 
 38 #include "wine/unicode.h"
 39 #include "wine/list.h"
 40 
 41 #include "msctf.h"
 42 #include "msctf_internal.h"
 43 
 44 WINE_DEFAULT_DEBUG_CHANNEL(msctf);
 45 
 46 typedef struct tagCompartmentValue {
 47     struct list entry;
 48     GUID guid;
 49     TfClientId owner;
 50     ITfCompartment *compartment;
 51 } CompartmentValue;
 52 
 53 typedef struct tagCompartmentMgr {
 54     const ITfCompartmentMgrVtbl *CompartmentMgrVtbl;
 55     LONG refCount;
 56 
 57     IUnknown *pUnkOuter;
 58 
 59     struct list values;
 60 } CompartmentMgr;
 61 
 62 typedef struct tagCompartmentEnumGuid {
 63     const IEnumGUIDVtbl *Vtbl;
 64     LONG refCount;
 65 
 66     struct list *values;
 67     struct list *cursor;
 68 } CompartmentEnumGuid;
 69 
 70 
 71 typedef struct tagCompartmentSink {
 72     struct list         entry;
 73     union {
 74         IUnknown            *pIUnknown;
 75         ITfCompartmentEventSink *pITfCompartmentEventSink;
 76     } interfaces;
 77 } CompartmentSink;
 78 
 79 typedef struct tagCompartment {
 80     const ITfCompartmentVtbl *Vtbl;
 81     const ITfSourceVtbl *SourceVtbl;
 82     LONG refCount;
 83 
 84     /* Only VT_I4, VT_UNKNOWN and VT_BSTR data types are allowed */
 85     VARIANT variant;
 86     CompartmentValue *valueData;
 87     struct list CompartmentEventSink;
 88 } Compartment;
 89 
 90 static HRESULT CompartmentEnumGuid_Constructor(struct list* values, IEnumGUID **ppOut);
 91 static HRESULT Compartment_Constructor(CompartmentValue *value, ITfCompartment **ppOut);
 92 
 93 static inline Compartment *impl_from_ITfSourceVtbl(ITfSource *iface)
 94 {
 95     return (Compartment *)((char *)iface - FIELD_OFFSET(Compartment,SourceVtbl));
 96 }
 97 
 98 HRESULT CompartmentMgr_Destructor(ITfCompartmentMgr *iface)
 99 {
100     CompartmentMgr *This = (CompartmentMgr *)iface;
101     struct list *cursor, *cursor2;
102 
103     LIST_FOR_EACH_SAFE(cursor, cursor2, &This->values)
104     {
105         CompartmentValue* value = LIST_ENTRY(cursor,CompartmentValue,entry);
106         list_remove(cursor);
107         ITfCompartment_Release(value->compartment);
108         HeapFree(GetProcessHeap(),0,value);
109     }
110 
111     HeapFree(GetProcessHeap(),0,This);
112     return S_OK;
113 }
114 
115 /*****************************************************
116  * ITfCompartmentMgr functions
117  *****************************************************/
118 static HRESULT WINAPI CompartmentMgr_QueryInterface(ITfCompartmentMgr *iface, REFIID iid, LPVOID *ppvOut)
119 {
120     CompartmentMgr *This = (CompartmentMgr *)iface;
121     if (This->pUnkOuter)
122         return IUnknown_QueryInterface(This->pUnkOuter, iid, *ppvOut);
123     else
124     {
125         *ppvOut = NULL;
126 
127         if (IsEqualIID(iid, &IID_IUnknown) || IsEqualIID(iid, &IID_ITfCompartmentMgr))
128         {
129             *ppvOut = This;
130         }
131 
132         if (*ppvOut)
133         {
134             IUnknown_AddRef(iface);
135             return S_OK;
136         }
137 
138         WARN("unsupported interface: %s\n", debugstr_guid(iid));
139         return E_NOINTERFACE;
140     }
141 }
142 
143 static ULONG WINAPI CompartmentMgr_AddRef(ITfCompartmentMgr *iface)
144 {
145     CompartmentMgr *This = (CompartmentMgr *)iface;
146     if (This->pUnkOuter)
147         return IUnknown_AddRef(This->pUnkOuter);
148     else
149         return InterlockedIncrement(&This->refCount);
150 }
151 
152 static ULONG WINAPI CompartmentMgr_Release(ITfCompartmentMgr *iface)
153 {
154     CompartmentMgr *This = (CompartmentMgr *)iface;
155     if (This->pUnkOuter)
156         return IUnknown_Release(This->pUnkOuter);
157     else
158     {
159         ULONG ret;
160 
161         ret = InterlockedDecrement(&This->refCount);
162         if (ret == 0)
163             CompartmentMgr_Destructor(iface);
164         return ret;
165     }
166 }
167 
168 static HRESULT WINAPI CompartmentMgr_GetCompartment(ITfCompartmentMgr *iface,
169         REFGUID rguid, ITfCompartment **ppcomp)
170 {
171     CompartmentMgr *This = (CompartmentMgr *)iface;
172     CompartmentValue* value;
173     struct list *cursor;
174     HRESULT hr;
175 
176     TRACE("(%p) %s  %p\n",This,debugstr_guid(rguid),ppcomp);
177 
178     LIST_FOR_EACH(cursor, &This->values)
179     {
180         value = LIST_ENTRY(cursor,CompartmentValue,entry);
181         if (IsEqualGUID(rguid,&value->guid))
182         {
183             ITfCompartment_AddRef(value->compartment);
184             *ppcomp = value->compartment;
185             return S_OK;
186         }
187     }
188 
189     value = HeapAlloc(GetProcessHeap(),0,sizeof(CompartmentValue));
190     value->guid = *rguid;
191     value->owner = 0;
192     hr = Compartment_Constructor(value,&value->compartment);
193     if (SUCCEEDED(hr))
194     {
195         list_add_head(&This->values,&value->entry);
196         ITfCompartment_AddRef(value->compartment);
197         *ppcomp = value->compartment;
198     }
199     else
200     {
201         HeapFree(GetProcessHeap(),0,value);
202         *ppcomp = NULL;
203     }
204     return hr;
205 }
206 
207 static HRESULT WINAPI CompartmentMgr_ClearCompartment(ITfCompartmentMgr *iface,
208     TfClientId tid, REFGUID rguid)
209 {
210     struct list *cursor;
211     CompartmentMgr *This = (CompartmentMgr *)iface;
212     TRACE("(%p) %i %s\n",This,tid,debugstr_guid(rguid));
213 
214     LIST_FOR_EACH(cursor, &This->values)
215     {
216         CompartmentValue* value = LIST_ENTRY(cursor,CompartmentValue,entry);
217         if (IsEqualGUID(rguid,&value->guid))
218         {
219             if (value->owner && tid != value->owner)
220                 return E_UNEXPECTED;
221             list_remove(cursor);
222             ITfCompartment_Release(value->compartment);
223             HeapFree(GetProcessHeap(),0,value);
224             return S_OK;
225         }
226     }
227 
228     return CONNECT_E_NOCONNECTION;
229 }
230 
231 static HRESULT WINAPI CompartmentMgr_EnumCompartments(ITfCompartmentMgr *iface,
232  IEnumGUID **ppEnum)
233 {
234     CompartmentMgr *This = (CompartmentMgr *)iface;
235     TRACE("(%p) %p\n",This,ppEnum);
236     if (!ppEnum)
237         return E_INVALIDARG;
238     return CompartmentEnumGuid_Constructor(&This->values, ppEnum);
239 }
240 
241 static const ITfCompartmentMgrVtbl CompartmentMgr_CompartmentMgrVtbl =
242 {
243     CompartmentMgr_QueryInterface,
244     CompartmentMgr_AddRef,
245     CompartmentMgr_Release,
246 
247     CompartmentMgr_GetCompartment,
248     CompartmentMgr_ClearCompartment,
249     CompartmentMgr_EnumCompartments
250 };
251 
252 HRESULT CompartmentMgr_Constructor(IUnknown *pUnkOuter, REFIID riid, IUnknown **ppOut)
253 {
254     CompartmentMgr *This;
255 
256     if (!ppOut)
257         return E_POINTER;
258 
259     if (pUnkOuter && !IsEqualIID (riid, &IID_IUnknown))
260         return CLASS_E_NOAGGREGATION;
261 
262     This = HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,sizeof(CompartmentMgr));
263     if (This == NULL)
264         return E_OUTOFMEMORY;
265 
266     This->CompartmentMgrVtbl = &CompartmentMgr_CompartmentMgrVtbl;
267     This->pUnkOuter = pUnkOuter;
268     list_init(&This->values);
269 
270     if (pUnkOuter)
271     {
272         TRACE("returning %p\n", This);
273         *ppOut = (IUnknown*)This;
274         return S_OK;
275     }
276     else
277     {
278         HRESULT hr;
279         hr = IUnknown_QueryInterface((IUnknown*)This, riid, (LPVOID*)ppOut);
280         if (FAILED(hr))
281             HeapFree(GetProcessHeap(),0,This);
282         return hr;
283     }
284 }
285 
286 /**************************************************
287  * IEnumGUID implementaion for ITfCompartmentMgr::EnumCompartments
288  **************************************************/
289 static void CompartmentEnumGuid_Destructor(CompartmentEnumGuid *This)
290 {
291     TRACE("destroying %p\n", This);
292     HeapFree(GetProcessHeap(),0,This);
293 }
294 
295 static HRESULT WINAPI CompartmentEnumGuid_QueryInterface(IEnumGUID *iface, REFIID iid, LPVOID *ppvOut)
296 {
297     CompartmentEnumGuid *This = (CompartmentEnumGuid *)iface;
298     *ppvOut = NULL;
299 
300     if (IsEqualIID(iid, &IID_IUnknown) || IsEqualIID(iid, &IID_IEnumGUID))
301     {
302         *ppvOut = This;
303     }
304 
305     if (*ppvOut)
306     {
307         IUnknown_AddRef(iface);
308         return S_OK;
309     }
310 
311     WARN("unsupported interface: %s\n", debugstr_guid(iid));
312     return E_NOINTERFACE;
313 }
314 
315 static ULONG WINAPI CompartmentEnumGuid_AddRef(IEnumGUID *iface)
316 {
317     CompartmentEnumGuid *This = (CompartmentEnumGuid*)iface;
318     return InterlockedIncrement(&This->refCount);
319 }
320 
321 static ULONG WINAPI CompartmentEnumGuid_Release(IEnumGUID *iface)
322 {
323     CompartmentEnumGuid *This = (CompartmentEnumGuid *)iface;
324     ULONG ret;
325 
326     ret = InterlockedDecrement(&This->refCount);
327     if (ret == 0)
328         CompartmentEnumGuid_Destructor(This);
329     return ret;
330 }
331 
332 /*****************************************************
333  * IEnumGuid functions
334  *****************************************************/
335 static HRESULT WINAPI CompartmentEnumGuid_Next( LPENUMGUID iface,
336     ULONG celt, GUID *rgelt, ULONG *pceltFetched)
337 {
338     CompartmentEnumGuid *This = (CompartmentEnumGuid *)iface;
339     ULONG fetched = 0;
340 
341     TRACE("(%p)\n",This);
342 
343     if (rgelt == NULL) return E_POINTER;
344 
345     while (fetched < celt && This->cursor)
346     {
347         CompartmentValue* value = LIST_ENTRY(This->cursor,CompartmentValue,entry);
348         if (!value)
349             break;
350 
351         This->cursor = list_next(This->values,This->cursor);
352         *rgelt = value->guid;
353 
354         ++fetched;
355         ++rgelt;
356     }
357 
358     if (pceltFetched) *pceltFetched = fetched;
359     return fetched == celt ? S_OK : S_FALSE;
360 }
361 
362 static HRESULT WINAPI CompartmentEnumGuid_Skip( LPENUMGUID iface, ULONG celt)
363 {
364     CompartmentEnumGuid *This = (CompartmentEnumGuid *)iface;
365     TRACE("(%p)\n",This);
366 
367     This->cursor = list_next(This->values,This->cursor);
368     return S_OK;
369 }
370 
371 static HRESULT WINAPI CompartmentEnumGuid_Reset( LPENUMGUID iface)
372 {
373     CompartmentEnumGuid *This = (CompartmentEnumGuid *)iface;
374     TRACE("(%p)\n",This);
375     This->cursor = list_head(This->values);
376     return S_OK;
377 }
378 
379 static HRESULT WINAPI CompartmentEnumGuid_Clone( LPENUMGUID iface,
380     IEnumGUID **ppenum)
381 {
382     CompartmentEnumGuid *This = (CompartmentEnumGuid *)iface;
383     HRESULT res;
384 
385     TRACE("(%p)\n",This);
386 
387     if (ppenum == NULL) return E_POINTER;
388 
389     res = CompartmentEnumGuid_Constructor(This->values, ppenum);
390     if (SUCCEEDED(res))
391     {
392         CompartmentEnumGuid *new_This = (CompartmentEnumGuid *)*ppenum;
393         new_This->cursor = This->cursor;
394     }
395     return res;
396 }
397 
398 static const IEnumGUIDVtbl IEnumGUID_Vtbl ={
399     CompartmentEnumGuid_QueryInterface,
400     CompartmentEnumGuid_AddRef,
401     CompartmentEnumGuid_Release,
402 
403     CompartmentEnumGuid_Next,
404     CompartmentEnumGuid_Skip,
405     CompartmentEnumGuid_Reset,
406     CompartmentEnumGuid_Clone
407 };
408 
409 static HRESULT CompartmentEnumGuid_Constructor(struct list *values, IEnumGUID **ppOut)
410 {
411     CompartmentEnumGuid *This;
412 
413     This = HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,sizeof(CompartmentEnumGuid));
414     if (This == NULL)
415         return E_OUTOFMEMORY;
416 
417     This->Vtbl= &IEnumGUID_Vtbl;
418     This->refCount = 1;
419 
420     This->values = values;
421     This->cursor = list_head(values);
422 
423     TRACE("returning %p\n", This);
424     *ppOut = (IEnumGUID*)This;
425     return S_OK;
426 }
427 
428 /**************************************************
429  * ITfCompartment
430  **************************************************/
431 static void free_sink(CompartmentSink *sink)
432 {
433         IUnknown_Release(sink->interfaces.pIUnknown);
434         HeapFree(GetProcessHeap(),0,sink);
435 }
436 
437 static void Compartment_Destructor(Compartment *This)
438 {
439     struct list *cursor, *cursor2;
440     TRACE("destroying %p\n", This);
441     VariantClear(&This->variant);
442     LIST_FOR_EACH_SAFE(cursor, cursor2, &This->CompartmentEventSink)
443     {
444         CompartmentSink* sink = LIST_ENTRY(cursor,CompartmentSink,entry);
445         list_remove(cursor);
446         free_sink(sink);
447     }
448     HeapFree(GetProcessHeap(),0,This);
449 }
450 
451 static HRESULT WINAPI Compartment_QueryInterface(ITfCompartment *iface, REFIID iid, LPVOID *ppvOut)
452 {
453     Compartment *This = (Compartment *)iface;
454     *ppvOut = NULL;
455 
456     if (IsEqualIID(iid, &IID_IUnknown) || IsEqualIID(iid, &IID_ITfCompartment))
457     {
458         *ppvOut = This;
459     }
460     else if (IsEqualIID(iid, &IID_ITfSource))
461     {
462         *ppvOut = &This->SourceVtbl;
463     }
464 
465     if (*ppvOut)
466     {
467         IUnknown_AddRef(iface);
468         return S_OK;
469     }
470 
471     WARN("unsupported interface: %s\n", debugstr_guid(iid));
472     return E_NOINTERFACE;
473 }
474 
475 static ULONG WINAPI Compartment_AddRef(ITfCompartment *iface)
476 {
477     Compartment *This = (Compartment*)iface;
478     return InterlockedIncrement(&This->refCount);
479 }
480 
481 static ULONG WINAPI Compartment_Release(ITfCompartment *iface)
482 {
483     Compartment *This = (Compartment *)iface;
484     ULONG ret;
485 
486     ret = InterlockedDecrement(&This->refCount);
487     if (ret == 0)
488         Compartment_Destructor(This);
489     return ret;
490 }
491 
492 static HRESULT WINAPI Compartment_SetValue(ITfCompartment *iface,
493     TfClientId tid, const VARIANT *pvarValue)
494 {
495     Compartment *This = (Compartment *)iface;
496     struct list *cursor;
497 
498     TRACE("(%p) %i %p\n",This,tid,pvarValue);
499 
500     if (!pvarValue)
501         return E_INVALIDARG;
502 
503     if (!(V_VT(pvarValue) == VT_BSTR || V_VT(pvarValue) == VT_I4 ||
504           V_VT(pvarValue) == VT_UNKNOWN))
505         return E_INVALIDARG;
506 
507     if (!This->valueData->owner)
508         This->valueData->owner = tid;
509 
510     VariantClear(&This->variant);
511 
512     /* Shallow copy of value and type */
513     This->variant = *pvarValue;
514 
515     if (V_VT(pvarValue) == VT_BSTR)
516         V_BSTR(&This->variant) = SysAllocStringByteLen((char*)V_BSTR(pvarValue),
517                 SysStringByteLen(V_BSTR(pvarValue)));
518     else if (V_VT(pvarValue) == VT_UNKNOWN)
519         IUnknown_AddRef(V_UNKNOWN(&This->variant));
520 
521     LIST_FOR_EACH(cursor, &This->CompartmentEventSink)
522     {
523         CompartmentSink* sink = LIST_ENTRY(cursor,CompartmentSink,entry);
524         ITfCompartmentEventSink_OnChange(sink->interfaces.pITfCompartmentEventSink,&This->valueData->guid);
525     }
526 
527     return S_OK;
528 }
529 
530 static HRESULT WINAPI Compartment_GetValue(ITfCompartment *iface,
531     VARIANT *pvarValue)
532 {
533     Compartment *This = (Compartment *)iface;
534     TRACE("(%p) %p\n",This, pvarValue);
535 
536     if (!pvarValue)
537         return E_INVALIDARG;
538 
539     VariantInit(pvarValue);
540     if (V_VT(&This->variant) == VT_EMPTY) return S_FALSE;
541     return VariantCopy(pvarValue,&This->variant);
542 }
543 
544 static const ITfCompartmentVtbl ITfCompartment_Vtbl ={
545     Compartment_QueryInterface,
546     Compartment_AddRef,
547     Compartment_Release,
548 
549     Compartment_SetValue,
550     Compartment_GetValue
551 };
552 
553 /*****************************************************
554  * ITfSource functions
555  *****************************************************/
556 
557 static HRESULT WINAPI Source_QueryInterface(ITfSource *iface, REFIID iid, LPVOID *ppvOut)
558 {
559     Compartment *This = impl_from_ITfSourceVtbl(iface);
560     return Compartment_QueryInterface((ITfCompartment *)This, iid, *ppvOut);
561 }
562 
563 static ULONG WINAPI Source_AddRef(ITfSource *iface)
564 {
565     Compartment *This = impl_from_ITfSourceVtbl(iface);
566     return Compartment_AddRef((ITfCompartment*)This);
567 }
568 
569 static ULONG WINAPI Source_Release(ITfSource *iface)
570 {
571     Compartment *This = impl_from_ITfSourceVtbl(iface);
572     return Compartment_Release((ITfCompartment *)This);
573 }
574 
575 static HRESULT WINAPI CompartmentSource_AdviseSink(ITfSource *iface,
576         REFIID riid, IUnknown *punk, DWORD *pdwCookie)
577 {
578     CompartmentSink *cs;
579     Compartment *This = impl_from_ITfSourceVtbl(iface);
580 
581     TRACE("(%p) %s %p %p\n",This,debugstr_guid(riid),punk,pdwCookie);
582 
583     if (!riid || !punk || !pdwCookie)
584         return E_INVALIDARG;
585 
586     if (IsEqualIID(riid, &IID_ITfCompartmentEventSink))
587     {
588         cs = HeapAlloc(GetProcessHeap(),0,sizeof(CompartmentSink));
589         if (!cs)
590             return E_OUTOFMEMORY;
591         if (FAILED(IUnknown_QueryInterface(punk, riid, (LPVOID *)&cs->interfaces.pITfCompartmentEventSink)))
592         {
593             HeapFree(GetProcessHeap(),0,cs);
594             return CONNECT_E_CANNOTCONNECT;
595         }
596         list_add_head(&This->CompartmentEventSink,&cs->entry);
597         *pdwCookie = generate_Cookie(COOKIE_MAGIC_COMPARTMENTSINK , cs);
598     }
599     else
600     {
601         FIXME("(%p) Unhandled Sink: %s\n",This,debugstr_guid(riid));
602         return E_NOTIMPL;
603     }
604 
605     TRACE("cookie %x\n",*pdwCookie);
606 
607     return S_OK;
608 }
609 
610 static HRESULT WINAPI CompartmentSource_UnadviseSink(ITfSource *iface, DWORD pdwCookie)
611 {
612     CompartmentSink *sink;
613     Compartment *This = impl_from_ITfSourceVtbl(iface);
614 
615     TRACE("(%p) %x\n",This,pdwCookie);
616 
617     if (get_Cookie_magic(pdwCookie)!=COOKIE_MAGIC_COMPARTMENTSINK)
618         return E_INVALIDARG;
619 
620     sink = (CompartmentSink*)remove_Cookie(pdwCookie);
621     if (!sink)
622         return CONNECT_E_NOCONNECTION;
623 
624     list_remove(&sink->entry);
625     free_sink(sink);
626 
627     return S_OK;
628 }
629 
630 static const ITfSourceVtbl Compartment_SourceVtbl =
631 {
632     Source_QueryInterface,
633     Source_AddRef,
634     Source_Release,
635 
636     CompartmentSource_AdviseSink,
637     CompartmentSource_UnadviseSink,
638 };
639 
640 static HRESULT Compartment_Constructor(CompartmentValue *valueData, ITfCompartment **ppOut)
641 {
642     Compartment *This;
643 
644     This = HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,sizeof(Compartment));
645     if (This == NULL)
646         return E_OUTOFMEMORY;
647 
648     This->Vtbl= &ITfCompartment_Vtbl;
649     This->SourceVtbl = &Compartment_SourceVtbl;
650     This->refCount = 1;
651 
652     This->valueData = valueData;
653     VariantInit(&This->variant);
654 
655     list_init(&This->CompartmentEventSink);
656 
657     TRACE("returning %p\n", This);
658     *ppOut = (ITfCompartment*)This;
659     return S_OK;
660 }
661 

~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~ [ freetext search ] ~ [ file search ] ~

This page was automatically generated by the LXR engine.
Visit the LXR main site for more information.