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

Wine Cross Reference
wine/dlls/msctf/documentmgr.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  *  ITfDocumentMgr 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 
 36 #include "wine/unicode.h"
 37 
 38 #include "msctf.h"
 39 #include "msctf_internal.h"
 40 
 41 WINE_DEFAULT_DEBUG_CHANNEL(msctf);
 42 
 43 typedef struct tagDocumentMgr {
 44     ITfDocumentMgr ITfDocumentMgr_iface;
 45     ITfSource ITfSource_iface;
 46     LONG refCount;
 47 
 48     /* Aggregation */
 49     ITfCompartmentMgr  *CompartmentMgr;
 50 
 51     ITfContext*  contextStack[2]; /* limit of 2 contexts */
 52     ITfThreadMgrEventSink* ThreadMgrSink;
 53 } DocumentMgr;
 54 
 55 typedef struct tagEnumTfContext {
 56     IEnumTfContexts IEnumTfContexts_iface;
 57     LONG refCount;
 58 
 59     DWORD   index;
 60     DocumentMgr *docmgr;
 61 } EnumTfContext;
 62 
 63 static HRESULT EnumTfContext_Constructor(DocumentMgr* mgr, IEnumTfContexts **ppOut);
 64 
 65 static inline DocumentMgr *impl_from_ITfDocumentMgr(ITfDocumentMgr *iface)
 66 {
 67     return CONTAINING_RECORD(iface, DocumentMgr, ITfDocumentMgr_iface);
 68 }
 69 
 70 static inline DocumentMgr *impl_from_ITfSource(ITfSource *iface)
 71 {
 72     return CONTAINING_RECORD(iface, DocumentMgr, ITfSource_iface);
 73 }
 74 
 75 static inline EnumTfContext *impl_from_IEnumTfContexts(IEnumTfContexts *iface)\
 76 {
 77     return CONTAINING_RECORD(iface, EnumTfContext, IEnumTfContexts_iface);
 78 }
 79 
 80 static void DocumentMgr_Destructor(DocumentMgr *This)
 81 {
 82     ITfThreadMgr *tm;
 83     TRACE("destroying %p\n", This);
 84 
 85     TF_GetThreadMgr(&tm);
 86     ThreadMgr_OnDocumentMgrDestruction(tm, &This->ITfDocumentMgr_iface);
 87 
 88     if (This->contextStack[0])
 89         ITfContext_Release(This->contextStack[0]);
 90     if (This->contextStack[1])
 91         ITfContext_Release(This->contextStack[1]);
 92     CompartmentMgr_Destructor(This->CompartmentMgr);
 93     HeapFree(GetProcessHeap(),0,This);
 94 }
 95 
 96 static HRESULT WINAPI DocumentMgr_QueryInterface(ITfDocumentMgr *iface, REFIID iid, LPVOID *ppvOut)
 97 {
 98     DocumentMgr *This = impl_from_ITfDocumentMgr(iface);
 99     *ppvOut = NULL;
100 
101     if (IsEqualIID(iid, &IID_IUnknown) || IsEqualIID(iid, &IID_ITfDocumentMgr))
102     {
103         *ppvOut = This;
104     }
105     else if (IsEqualIID(iid, &IID_ITfSource))
106     {
107         *ppvOut = &This->ITfSource_iface;
108     }
109     else if (IsEqualIID(iid, &IID_ITfCompartmentMgr))
110     {
111         *ppvOut = This->CompartmentMgr;
112     }
113 
114     if (*ppvOut)
115     {
116         IUnknown_AddRef(iface);
117         return S_OK;
118     }
119 
120     WARN("unsupported interface: %s\n", debugstr_guid(iid));
121     return E_NOINTERFACE;
122 }
123 
124 static ULONG WINAPI DocumentMgr_AddRef(ITfDocumentMgr *iface)
125 {
126     DocumentMgr *This = impl_from_ITfDocumentMgr(iface);
127     return InterlockedIncrement(&This->refCount);
128 }
129 
130 static ULONG WINAPI DocumentMgr_Release(ITfDocumentMgr *iface)
131 {
132     DocumentMgr *This = impl_from_ITfDocumentMgr(iface);
133     ULONG ret;
134 
135     ret = InterlockedDecrement(&This->refCount);
136     if (ret == 0)
137         DocumentMgr_Destructor(This);
138     return ret;
139 }
140 
141 /*****************************************************
142  * ITfDocumentMgr functions
143  *****************************************************/
144 static HRESULT WINAPI DocumentMgr_CreateContext(ITfDocumentMgr *iface,
145         TfClientId tidOwner,
146         DWORD dwFlags, IUnknown *punk, ITfContext **ppic,
147         TfEditCookie *pecTextStore)
148 {
149     DocumentMgr *This = impl_from_ITfDocumentMgr(iface);
150     TRACE("(%p) 0x%x 0x%x %p %p %p\n",This,tidOwner,dwFlags,punk,ppic,pecTextStore);
151     return Context_Constructor(tidOwner, punk, iface, ppic, pecTextStore);
152 }
153 
154 static HRESULT WINAPI DocumentMgr_Push(ITfDocumentMgr *iface, ITfContext *pic)
155 {
156     DocumentMgr *This = impl_from_ITfDocumentMgr(iface);
157     ITfContext *check;
158 
159     TRACE("(%p) %p\n",This,pic);
160 
161     if (This->contextStack[1])  /* FUll */
162         return TF_E_STACKFULL;
163 
164     if (!pic || FAILED(IUnknown_QueryInterface(pic,&IID_ITfContext,(LPVOID*) &check)))
165         return E_INVALIDARG;
166 
167     if (This->contextStack[0] == NULL)
168         ITfThreadMgrEventSink_OnInitDocumentMgr(This->ThreadMgrSink,iface);
169 
170     This->contextStack[1] = This->contextStack[0];
171     This->contextStack[0] = check;
172 
173     Context_Initialize(check, iface);
174     ITfThreadMgrEventSink_OnPushContext(This->ThreadMgrSink,check);
175 
176     return S_OK;
177 }
178 
179 static HRESULT WINAPI DocumentMgr_Pop(ITfDocumentMgr *iface, DWORD dwFlags)
180 {
181     DocumentMgr *This = impl_from_ITfDocumentMgr(iface);
182     TRACE("(%p) 0x%x\n",This,dwFlags);
183 
184     if (dwFlags == TF_POPF_ALL)
185     {
186         if (This->contextStack[0])
187         {
188             ITfThreadMgrEventSink_OnPopContext(This->ThreadMgrSink,This->contextStack[0]);
189             ITfContext_Release(This->contextStack[0]);
190             Context_Uninitialize(This->contextStack[0]);
191         }
192         if (This->contextStack[1])
193         {
194             ITfThreadMgrEventSink_OnPopContext(This->ThreadMgrSink,This->contextStack[1]);
195             ITfContext_Release(This->contextStack[1]);
196             Context_Uninitialize(This->contextStack[1]);
197         }
198         This->contextStack[0] = This->contextStack[1] = NULL;
199         ITfThreadMgrEventSink_OnUninitDocumentMgr(This->ThreadMgrSink, iface);
200         return S_OK;
201     }
202 
203     if (dwFlags)
204         return E_INVALIDARG;
205 
206     if (This->contextStack[1] == NULL) /* Cannot pop last context */
207         return E_FAIL;
208 
209     ITfThreadMgrEventSink_OnPopContext(This->ThreadMgrSink,This->contextStack[0]);
210     ITfContext_Release(This->contextStack[0]);
211     Context_Uninitialize(This->contextStack[0]);
212     This->contextStack[0] = This->contextStack[1];
213     This->contextStack[1] = NULL;
214 
215     if (This->contextStack[0] == NULL)
216         ITfThreadMgrEventSink_OnUninitDocumentMgr(This->ThreadMgrSink, iface);
217 
218     return S_OK;
219 }
220 
221 static HRESULT WINAPI DocumentMgr_GetTop(ITfDocumentMgr *iface, ITfContext **ppic)
222 {
223     DocumentMgr *This = impl_from_ITfDocumentMgr(iface);
224     TRACE("(%p)\n",This);
225     if (!ppic)
226         return E_INVALIDARG;
227 
228     if (This->contextStack[0])
229         ITfContext_AddRef(This->contextStack[0]);
230 
231     *ppic = This->contextStack[0];
232 
233     return S_OK;
234 }
235 
236 static HRESULT WINAPI DocumentMgr_GetBase(ITfDocumentMgr *iface, ITfContext **ppic)
237 {
238     DocumentMgr *This = impl_from_ITfDocumentMgr(iface);
239     ITfContext *tgt;
240 
241     TRACE("(%p)\n",This);
242     if (!ppic)
243         return E_INVALIDARG;
244 
245     if (This->contextStack[1])
246         tgt = This->contextStack[1];
247     else
248         tgt = This->contextStack[0];
249 
250     if (tgt)
251         ITfContext_AddRef(tgt);
252 
253     *ppic = tgt;
254 
255     return S_OK;
256 }
257 
258 static HRESULT WINAPI DocumentMgr_EnumContexts(ITfDocumentMgr *iface, IEnumTfContexts **ppEnum)
259 {
260     DocumentMgr *This = impl_from_ITfDocumentMgr(iface);
261     TRACE("(%p) %p\n",This,ppEnum);
262     return EnumTfContext_Constructor(This, ppEnum);
263 }
264 
265 static const ITfDocumentMgrVtbl DocumentMgr_DocumentMgrVtbl =
266 {
267     DocumentMgr_QueryInterface,
268     DocumentMgr_AddRef,
269     DocumentMgr_Release,
270 
271     DocumentMgr_CreateContext,
272     DocumentMgr_Push,
273     DocumentMgr_Pop,
274     DocumentMgr_GetTop,
275     DocumentMgr_GetBase,
276     DocumentMgr_EnumContexts
277 };
278 
279 
280 static HRESULT WINAPI Source_QueryInterface(ITfSource *iface, REFIID iid, LPVOID *ppvOut)
281 {
282     DocumentMgr *This = impl_from_ITfSource(iface);
283     return DocumentMgr_QueryInterface(&This->ITfDocumentMgr_iface, iid, *ppvOut);
284 }
285 
286 static ULONG WINAPI Source_AddRef(ITfSource *iface)
287 {
288     DocumentMgr *This = impl_from_ITfSource(iface);
289     return DocumentMgr_AddRef(&This->ITfDocumentMgr_iface);
290 }
291 
292 static ULONG WINAPI Source_Release(ITfSource *iface)
293 {
294     DocumentMgr *This = impl_from_ITfSource(iface);
295     return DocumentMgr_Release(&This->ITfDocumentMgr_iface);
296 }
297 
298 /*****************************************************
299  * ITfSource functions
300  *****************************************************/
301 static HRESULT WINAPI DocumentMgrSource_AdviseSink(ITfSource *iface,
302         REFIID riid, IUnknown *punk, DWORD *pdwCookie)
303 {
304     DocumentMgr *This = impl_from_ITfSource(iface);
305     FIXME("STUB:(%p)\n",This);
306     return E_NOTIMPL;
307 }
308 
309 static HRESULT WINAPI DocumentMgrSource_UnadviseSink(ITfSource *iface, DWORD pdwCookie)
310 {
311     DocumentMgr *This = impl_from_ITfSource(iface);
312     FIXME("STUB:(%p)\n",This);
313     return E_NOTIMPL;
314 }
315 
316 static const ITfSourceVtbl DocumentMgr_SourceVtbl =
317 {
318     Source_QueryInterface,
319     Source_AddRef,
320     Source_Release,
321 
322     DocumentMgrSource_AdviseSink,
323     DocumentMgrSource_UnadviseSink,
324 };
325 
326 HRESULT DocumentMgr_Constructor(ITfThreadMgrEventSink *ThreadMgrSink, ITfDocumentMgr **ppOut)
327 {
328     DocumentMgr *This;
329 
330     This = HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,sizeof(DocumentMgr));
331     if (This == NULL)
332         return E_OUTOFMEMORY;
333 
334     This->ITfDocumentMgr_iface.lpVtbl = &DocumentMgr_DocumentMgrVtbl;
335     This->ITfSource_iface.lpVtbl = &DocumentMgr_SourceVtbl;
336     This->refCount = 1;
337     This->ThreadMgrSink = ThreadMgrSink;
338 
339     CompartmentMgr_Constructor((IUnknown*)This, &IID_IUnknown, (IUnknown**)&This->CompartmentMgr);
340 
341     TRACE("returning %p\n", This);
342     *ppOut = &This->ITfDocumentMgr_iface;
343     return S_OK;
344 }
345 
346 /**************************************************
347  * IEnumTfContexts implementaion
348  **************************************************/
349 static void EnumTfContext_Destructor(EnumTfContext *This)
350 {
351     TRACE("destroying %p\n", This);
352     HeapFree(GetProcessHeap(),0,This);
353 }
354 
355 static HRESULT WINAPI EnumTfContext_QueryInterface(IEnumTfContexts *iface, REFIID iid, LPVOID *ppvOut)
356 {
357     EnumTfContext *This = impl_from_IEnumTfContexts(iface);
358     *ppvOut = NULL;
359 
360     if (IsEqualIID(iid, &IID_IUnknown) || IsEqualIID(iid, &IID_IEnumTfContexts))
361     {
362         *ppvOut = This;
363     }
364 
365     if (*ppvOut)
366     {
367         IUnknown_AddRef(iface);
368         return S_OK;
369     }
370 
371     WARN("unsupported interface: %s\n", debugstr_guid(iid));
372     return E_NOINTERFACE;
373 }
374 
375 static ULONG WINAPI EnumTfContext_AddRef(IEnumTfContexts *iface)
376 {
377     EnumTfContext *This = impl_from_IEnumTfContexts(iface);
378     return InterlockedIncrement(&This->refCount);
379 }
380 
381 static ULONG WINAPI EnumTfContext_Release(IEnumTfContexts *iface)
382 {
383     EnumTfContext *This = impl_from_IEnumTfContexts(iface);
384     ULONG ret;
385 
386     ret = InterlockedDecrement(&This->refCount);
387     if (ret == 0)
388         EnumTfContext_Destructor(This);
389     return ret;
390 }
391 
392 static HRESULT WINAPI EnumTfContext_Next(IEnumTfContexts *iface,
393     ULONG ulCount, ITfContext **rgContext, ULONG *pcFetched)
394 {
395     EnumTfContext *This = impl_from_IEnumTfContexts(iface);
396     ULONG fetched = 0;
397 
398     TRACE("(%p)\n",This);
399 
400     if (rgContext == NULL) return E_POINTER;
401 
402     while (fetched < ulCount)
403     {
404         if (This->index > 1)
405             break;
406 
407         if (!This->docmgr->contextStack[This->index])
408             break;
409 
410         *rgContext = This->docmgr->contextStack[This->index];
411         ITfContext_AddRef(*rgContext);
412 
413         ++This->index;
414         ++fetched;
415         ++rgContext;
416     }
417 
418     if (pcFetched) *pcFetched = fetched;
419     return fetched == ulCount ? S_OK : S_FALSE;
420 }
421 
422 static HRESULT WINAPI EnumTfContext_Skip( IEnumTfContexts* iface, ULONG celt)
423 {
424     EnumTfContext *This = impl_from_IEnumTfContexts(iface);
425     TRACE("(%p)\n",This);
426     This->index += celt;
427     return S_OK;
428 }
429 
430 static HRESULT WINAPI EnumTfContext_Reset( IEnumTfContexts* iface)
431 {
432     EnumTfContext *This = impl_from_IEnumTfContexts(iface);
433     TRACE("(%p)\n",This);
434     This->index = 0;
435     return S_OK;
436 }
437 
438 static HRESULT WINAPI EnumTfContext_Clone( IEnumTfContexts *iface,
439     IEnumTfContexts **ppenum)
440 {
441     EnumTfContext *This = impl_from_IEnumTfContexts(iface);
442     HRESULT res;
443 
444     TRACE("(%p)\n",This);
445 
446     if (ppenum == NULL) return E_POINTER;
447 
448     res = EnumTfContext_Constructor(This->docmgr, ppenum);
449     if (SUCCEEDED(res))
450     {
451         EnumTfContext *new_This = impl_from_IEnumTfContexts(*ppenum);
452         new_This->index = This->index;
453     }
454     return res;
455 }
456 
457 static const IEnumTfContextsVtbl IEnumTfContexts_Vtbl ={
458     EnumTfContext_QueryInterface,
459     EnumTfContext_AddRef,
460     EnumTfContext_Release,
461 
462     EnumTfContext_Clone,
463     EnumTfContext_Next,
464     EnumTfContext_Reset,
465     EnumTfContext_Skip
466 };
467 
468 static HRESULT EnumTfContext_Constructor(DocumentMgr *mgr, IEnumTfContexts **ppOut)
469 {
470     EnumTfContext *This;
471 
472     This = HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,sizeof(EnumTfContext));
473     if (This == NULL)
474         return E_OUTOFMEMORY;
475 
476     This->IEnumTfContexts_iface.lpVtbl = &IEnumTfContexts_Vtbl;
477     This->refCount = 1;
478     This->docmgr = mgr;
479 
480     TRACE("returning %p\n", This);
481     *ppOut = &This->IEnumTfContexts_iface;
482     return S_OK;
483 }
484 

~ [ 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.