2 * ITfCompartmentMgr implementation
4 * Copyright 2009 Aric Stewart, CodeWeavers
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.
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.
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
27 #include "wine/debug.h"
38 #include "wine/unicode.h"
39 #include "wine/list.h"
42 #include "msctf_internal.h"
44 WINE_DEFAULT_DEBUG_CHANNEL(msctf
);
46 typedef struct tagCompartmentValue
{
50 ITfCompartment
*compartment
;
53 typedef struct tagCompartmentMgr
{
54 const ITfCompartmentMgrVtbl
*CompartmentMgrVtbl
;
62 typedef struct tagCompartmentEnumGuid
{
63 const IEnumGUIDVtbl
*Vtbl
;
68 } CompartmentEnumGuid
;
70 static HRESULT
CompartmentEnumGuid_Constructor(struct list
* values
, IEnumGUID
**ppOut
);
72 HRESULT
CompartmentMgr_Destructor(ITfCompartmentMgr
*iface
)
74 CompartmentMgr
*This
= (CompartmentMgr
*)iface
;
75 struct list
*cursor
, *cursor2
;
77 LIST_FOR_EACH_SAFE(cursor
, cursor2
, &This
->values
)
79 CompartmentValue
* value
= LIST_ENTRY(cursor
,CompartmentValue
,entry
);
81 ITfCompartment_Release(value
->compartment
);
82 HeapFree(GetProcessHeap(),0,value
);
85 HeapFree(GetProcessHeap(),0,This
);
89 /*****************************************************
90 * ITfCompartmentMgr functions
91 *****************************************************/
92 static HRESULT WINAPI
CompartmentMgr_QueryInterface(ITfCompartmentMgr
*iface
, REFIID iid
, LPVOID
*ppvOut
)
94 CompartmentMgr
*This
= (CompartmentMgr
*)iface
;
96 return IUnknown_QueryInterface(This
->pUnkOuter
, iid
, *ppvOut
);
101 if (IsEqualIID(iid
, &IID_IUnknown
) || IsEqualIID(iid
, &IID_ITfCompartmentMgr
))
108 IUnknown_AddRef(iface
);
112 WARN("unsupported interface: %s\n", debugstr_guid(iid
));
113 return E_NOINTERFACE
;
117 static ULONG WINAPI
CompartmentMgr_AddRef(ITfCompartmentMgr
*iface
)
119 CompartmentMgr
*This
= (CompartmentMgr
*)iface
;
121 return IUnknown_AddRef(This
->pUnkOuter
);
123 return InterlockedIncrement(&This
->refCount
);
126 static ULONG WINAPI
CompartmentMgr_Release(ITfCompartmentMgr
*iface
)
128 CompartmentMgr
*This
= (CompartmentMgr
*)iface
;
130 return IUnknown_Release(This
->pUnkOuter
);
135 ret
= InterlockedDecrement(&This
->refCount
);
137 CompartmentMgr_Destructor(iface
);
142 static HRESULT WINAPI
CompartmentMgr_GetCompartment(ITfCompartmentMgr
*iface
,
143 REFGUID rguid
, ITfCompartment
**ppcomp
)
145 CompartmentMgr
*This
= (CompartmentMgr
*)iface
;
146 FIXME("STUB:(%p)\n",This
);
150 static HRESULT WINAPI
CompartmentMgr_ClearCompartment(ITfCompartmentMgr
*iface
,
151 TfClientId tid
, REFGUID rguid
)
154 CompartmentMgr
*This
= (CompartmentMgr
*)iface
;
155 TRACE("(%p) %i %s\n",This
,tid
,debugstr_guid(rguid
));
157 LIST_FOR_EACH(cursor
, &This
->values
)
159 CompartmentValue
* value
= LIST_ENTRY(cursor
,CompartmentValue
,entry
);
160 if (IsEqualGUID(rguid
,&value
->guid
))
162 if (value
->owner
&& tid
!= value
->owner
)
165 ITfCompartment_Release(value
->compartment
);
166 HeapFree(GetProcessHeap(),0,value
);
171 return CONNECT_E_NOCONNECTION
;
174 static HRESULT WINAPI
CompartmentMgr_EnumCompartments(ITfCompartmentMgr
*iface
,
177 CompartmentMgr
*This
= (CompartmentMgr
*)iface
;
178 TRACE("(%p) %p\n",This
,ppEnum
);
181 return CompartmentEnumGuid_Constructor(&This
->values
, ppEnum
);
184 static const ITfCompartmentMgrVtbl CompartmentMgr_CompartmentMgrVtbl
=
186 CompartmentMgr_QueryInterface
,
187 CompartmentMgr_AddRef
,
188 CompartmentMgr_Release
,
190 CompartmentMgr_GetCompartment
,
191 CompartmentMgr_ClearCompartment
,
192 CompartmentMgr_EnumCompartments
195 HRESULT
CompartmentMgr_Constructor(IUnknown
*pUnkOuter
, REFIID riid
, IUnknown
**ppOut
)
197 CompartmentMgr
*This
;
202 if (pUnkOuter
&& !IsEqualIID (riid
, &IID_IUnknown
))
203 return CLASS_E_NOAGGREGATION
;
205 This
= HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY
,sizeof(CompartmentMgr
));
207 return E_OUTOFMEMORY
;
209 This
->CompartmentMgrVtbl
= &CompartmentMgr_CompartmentMgrVtbl
;
210 This
->pUnkOuter
= pUnkOuter
;
211 list_init(&This
->values
);
215 TRACE("returning %p\n", This
);
216 *ppOut
= (IUnknown
*)This
;
222 hr
= IUnknown_QueryInterface((IUnknown
*)This
, riid
, (LPVOID
*)ppOut
);
224 HeapFree(GetProcessHeap(),0,This
);
229 /**************************************************
230 * IEnumGUID implementaion for ITfCompartmentMgr::EnumCompartments
231 **************************************************/
232 static void CompartmentEnumGuid_Destructor(CompartmentEnumGuid
*This
)
234 TRACE("destroying %p\n", This
);
235 HeapFree(GetProcessHeap(),0,This
);
238 static HRESULT WINAPI
CompartmentEnumGuid_QueryInterface(IEnumGUID
*iface
, REFIID iid
, LPVOID
*ppvOut
)
240 CompartmentEnumGuid
*This
= (CompartmentEnumGuid
*)iface
;
243 if (IsEqualIID(iid
, &IID_IUnknown
) || IsEqualIID(iid
, &IID_IEnumGUID
))
250 IUnknown_AddRef(iface
);
254 WARN("unsupported interface: %s\n", debugstr_guid(iid
));
255 return E_NOINTERFACE
;
258 static ULONG WINAPI
CompartmentEnumGuid_AddRef(IEnumGUID
*iface
)
260 CompartmentEnumGuid
*This
= (CompartmentEnumGuid
*)iface
;
261 return InterlockedIncrement(&This
->refCount
);
264 static ULONG WINAPI
CompartmentEnumGuid_Release(IEnumGUID
*iface
)
266 CompartmentEnumGuid
*This
= (CompartmentEnumGuid
*)iface
;
269 ret
= InterlockedDecrement(&This
->refCount
);
271 CompartmentEnumGuid_Destructor(This
);
275 /*****************************************************
276 * IEnumGuid functions
277 *****************************************************/
278 static HRESULT WINAPI
CompartmentEnumGuid_Next( LPENUMGUID iface
,
279 ULONG celt
, GUID
*rgelt
, ULONG
*pceltFetched
)
281 CompartmentEnumGuid
*This
= (CompartmentEnumGuid
*)iface
;
284 TRACE("(%p)\n",This
);
286 if (rgelt
== NULL
) return E_POINTER
;
288 while (fetched
< celt
&& This
->cursor
)
290 CompartmentValue
* value
= LIST_ENTRY(This
->cursor
,CompartmentValue
,entry
);
294 This
->cursor
= list_next(This
->values
,This
->cursor
);
295 *rgelt
= value
->guid
;
301 if (pceltFetched
) *pceltFetched
= fetched
;
302 return fetched
== celt
? S_OK
: S_FALSE
;
305 static HRESULT WINAPI
CompartmentEnumGuid_Skip( LPENUMGUID iface
, ULONG celt
)
307 CompartmentEnumGuid
*This
= (CompartmentEnumGuid
*)iface
;
308 TRACE("(%p)\n",This
);
310 This
->cursor
= list_next(This
->values
,This
->cursor
);
314 static HRESULT WINAPI
CompartmentEnumGuid_Reset( LPENUMGUID iface
)
316 CompartmentEnumGuid
*This
= (CompartmentEnumGuid
*)iface
;
317 TRACE("(%p)\n",This
);
318 This
->cursor
= list_head(This
->values
);
322 static HRESULT WINAPI
CompartmentEnumGuid_Clone( LPENUMGUID iface
,
325 CompartmentEnumGuid
*This
= (CompartmentEnumGuid
*)iface
;
328 TRACE("(%p)\n",This
);
330 if (ppenum
== NULL
) return E_POINTER
;
332 res
= CompartmentEnumGuid_Constructor(This
->values
, ppenum
);
335 CompartmentEnumGuid
*new_This
= (CompartmentEnumGuid
*)*ppenum
;
336 new_This
->cursor
= This
->cursor
;
341 static const IEnumGUIDVtbl IEnumGUID_Vtbl
={
342 CompartmentEnumGuid_QueryInterface
,
343 CompartmentEnumGuid_AddRef
,
344 CompartmentEnumGuid_Release
,
346 CompartmentEnumGuid_Next
,
347 CompartmentEnumGuid_Skip
,
348 CompartmentEnumGuid_Reset
,
349 CompartmentEnumGuid_Clone
352 static HRESULT
CompartmentEnumGuid_Constructor(struct list
*values
, IEnumGUID
**ppOut
)
354 CompartmentEnumGuid
*This
;
356 This
= HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY
,sizeof(CompartmentEnumGuid
));
358 return E_OUTOFMEMORY
;
360 This
->Vtbl
= &IEnumGUID_Vtbl
;
363 This
->values
= values
;
364 This
->cursor
= list_head(values
);
366 TRACE("returning %p\n", This
);
367 *ppOut
= (IEnumGUID
*)This
;