ReactOS  0.4.14-dev-599-g2d4d3f5
documentmgr.c
Go to the documentation of this file.
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 <stdarg.h>
22 
23 #define COBJMACROS
24 
25 #include "wine/debug.h"
26 #include "windef.h"
27 #include "winbase.h"
28 #include "winreg.h"
29 #include "winuser.h"
30 #include "shlwapi.h"
31 #include "winerror.h"
32 #include "objbase.h"
33 
34 #include "msctf.h"
35 #include "msctf_internal.h"
36 
38 
39 typedef struct tagDocumentMgr {
43 
44  /* Aggregation */
46 
47  ITfContext* contextStack[2]; /* limit of 2 contexts */
49 
51 } DocumentMgr;
52 
53 typedef struct tagEnumTfContext {
56 
60 
62 
64 {
65  return CONTAINING_RECORD(iface, DocumentMgr, ITfDocumentMgr_iface);
66 }
67 
69 {
70  return CONTAINING_RECORD(iface, DocumentMgr, ITfSource_iface);
71 }
72 
74 {
75  return CONTAINING_RECORD(iface, EnumTfContext, IEnumTfContexts_iface);
76 }
77 
79 {
80  ITfThreadMgr *tm = NULL;
81  TRACE("destroying %p\n", This);
82 
84  if (tm)
85  {
86  ThreadMgr_OnDocumentMgrDestruction(tm, &This->ITfDocumentMgr_iface);
87  ITfThreadMgr_Release(tm);
88  }
89 
90  if (This->contextStack[0])
91  ITfContext_Release(This->contextStack[0]);
92  if (This->contextStack[1])
93  ITfContext_Release(This->contextStack[1]);
94  free_sinks(&This->TransitoryExtensionSink);
95  CompartmentMgr_Destructor(This->CompartmentMgr);
97 }
98 
100 {
102  *ppvOut = NULL;
103 
104  if (IsEqualIID(iid, &IID_IUnknown) || IsEqualIID(iid, &IID_ITfDocumentMgr))
105  {
106  *ppvOut = &This->ITfDocumentMgr_iface;
107  }
108  else if (IsEqualIID(iid, &IID_ITfSource))
109  {
110  *ppvOut = &This->ITfSource_iface;
111  }
112  else if (IsEqualIID(iid, &IID_ITfCompartmentMgr))
113  {
114  *ppvOut = This->CompartmentMgr;
115  }
116 
117  if (*ppvOut)
118  {
119  ITfDocumentMgr_AddRef(iface);
120  return S_OK;
121  }
122 
123  WARN("unsupported interface: %s\n", debugstr_guid(iid));
124  return E_NOINTERFACE;
125 }
126 
128 {
130  return InterlockedIncrement(&This->refCount);
131 }
132 
134 {
136  ULONG ret;
137 
138  ret = InterlockedDecrement(&This->refCount);
139  if (ret == 0)
141  return ret;
142 }
143 
144 /*****************************************************
145  * ITfDocumentMgr functions
146  *****************************************************/
148  TfClientId tidOwner,
149  DWORD dwFlags, IUnknown *punk, ITfContext **ppic,
150  TfEditCookie *pecTextStore)
151 {
153  TRACE("(%p) 0x%x 0x%x %p %p %p\n",This,tidOwner,dwFlags,punk,ppic,pecTextStore);
154  return Context_Constructor(tidOwner, punk, iface, ppic, pecTextStore);
155 }
156 
158 {
160  ITfContext *check;
161 
162  TRACE("(%p) %p\n",This,pic);
163 
164  if (This->contextStack[1]) /* FUll */
165  return TF_E_STACKFULL;
166 
167  if (!pic || FAILED(ITfContext_QueryInterface(pic,&IID_ITfContext,(LPVOID*) &check)))
168  return E_INVALIDARG;
169 
170  if (This->contextStack[0] == NULL)
171  ITfThreadMgrEventSink_OnInitDocumentMgr(This->ThreadMgrSink,iface);
172 
173  This->contextStack[1] = This->contextStack[0];
174  This->contextStack[0] = check;
175 
176  Context_Initialize(check, iface);
177  ITfThreadMgrEventSink_OnPushContext(This->ThreadMgrSink,check);
178 
179  return S_OK;
180 }
181 
183 {
185  TRACE("(%p) 0x%x\n",This,dwFlags);
186 
187  if (dwFlags == TF_POPF_ALL)
188  {
189  int i;
190 
191  for (i = 0; i < ARRAY_SIZE(This->contextStack); i++)
192  if (This->contextStack[i])
193  {
194  ITfThreadMgrEventSink_OnPopContext(This->ThreadMgrSink, This->contextStack[i]);
195  Context_Uninitialize(This->contextStack[i]);
196  ITfContext_Release(This->contextStack[i]);
197  This->contextStack[i] = NULL;
198  }
199 
200  ITfThreadMgrEventSink_OnUninitDocumentMgr(This->ThreadMgrSink, iface);
201  return S_OK;
202  }
203 
204  if (dwFlags)
205  return E_INVALIDARG;
206 
207  if (This->contextStack[1] == NULL) /* Cannot pop last context */
208  return E_FAIL;
209 
210  ITfThreadMgrEventSink_OnPopContext(This->ThreadMgrSink,This->contextStack[0]);
211  Context_Uninitialize(This->contextStack[0]);
212  ITfContext_Release(This->contextStack[0]);
213  This->contextStack[0] = This->contextStack[1];
214  This->contextStack[1] = NULL;
215 
216  if (This->contextStack[0] == NULL)
217  ITfThreadMgrEventSink_OnUninitDocumentMgr(This->ThreadMgrSink, iface);
218 
219  return S_OK;
220 }
221 
223 {
225  TRACE("(%p)\n",This);
226  if (!ppic)
227  return E_INVALIDARG;
228 
229  if (This->contextStack[0])
230  ITfContext_AddRef(This->contextStack[0]);
231 
232  *ppic = This->contextStack[0];
233 
234  return S_OK;
235 }
236 
238 {
240  ITfContext *tgt;
241 
242  TRACE("(%p)\n",This);
243  if (!ppic)
244  return E_INVALIDARG;
245 
246  if (This->contextStack[1])
247  tgt = This->contextStack[1];
248  else
249  tgt = This->contextStack[0];
250 
251  if (tgt)
252  ITfContext_AddRef(tgt);
253 
254  *ppic = tgt;
255 
256  return S_OK;
257 }
258 
260 {
262  TRACE("(%p) %p\n",This,ppEnum);
263  return EnumTfContext_Constructor(This, ppEnum);
264 }
265 
266 static const ITfDocumentMgrVtbl DocumentMgrVtbl =
267 {
277 };
278 
280 {
282  return ITfDocumentMgr_QueryInterface(&This->ITfDocumentMgr_iface, iid, ppvOut);
283 }
284 
286 {
288  return ITfDocumentMgr_AddRef(&This->ITfDocumentMgr_iface);
289 }
290 
292 {
294  return ITfDocumentMgr_Release(&This->ITfDocumentMgr_iface);
295 }
296 
297 /*****************************************************
298  * ITfSource functions
299  *****************************************************/
301  REFIID riid, IUnknown *punk, DWORD *pdwCookie)
302 {
304 
305  TRACE("(%p) %s %p %p\n", This, debugstr_guid(riid), punk, pdwCookie);
306 
307  if (!riid || !punk || !pdwCookie)
308  return E_INVALIDARG;
309 
310  if (IsEqualIID(riid, &IID_ITfTransitoryExtensionSink))
311  {
312  WARN("semi-stub for ITfTransitoryExtensionSink: callback won't be used.\n");
313  return advise_sink(&This->TransitoryExtensionSink, &IID_ITfTransitoryExtensionSink,
314  COOKIE_MAGIC_DMSINK, punk, pdwCookie);
315  }
316 
317  FIXME("(%p) Unhandled Sink: %s\n",This,debugstr_guid(riid));
318  return E_NOTIMPL;
319 }
320 
322 {
324 
325  TRACE("(%p) %x\n",This,pdwCookie);
326 
327  if (get_Cookie_magic(pdwCookie)!=COOKIE_MAGIC_DMSINK)
328  return E_INVALIDARG;
329 
330  return unadvise_sink(pdwCookie);
331 }
332 
333 static const ITfSourceVtbl DocumentMgrSourceVtbl =
334 {
340 };
341 
343 {
344  DocumentMgr *This;
345 
347  if (This == NULL)
348  return E_OUTOFMEMORY;
349 
350  This->ITfDocumentMgr_iface.lpVtbl = &DocumentMgrVtbl;
351  This->ITfSource_iface.lpVtbl = &DocumentMgrSourceVtbl;
352  This->refCount = 1;
353  This->ThreadMgrSink = ThreadMgrSink;
354  list_init(&This->TransitoryExtensionSink);
355 
356  CompartmentMgr_Constructor((IUnknown*)&This->ITfDocumentMgr_iface, &IID_IUnknown, (IUnknown**)&This->CompartmentMgr);
357 
358  *ppOut = &This->ITfDocumentMgr_iface;
359  TRACE("returning %p\n", *ppOut);
360  return S_OK;
361 }
362 
363 /**************************************************
364  * IEnumTfContexts implementation
365  **************************************************/
367 {
368  TRACE("destroying %p\n", This);
370 }
371 
373 {
375  *ppvOut = NULL;
376 
377  if (IsEqualIID(iid, &IID_IUnknown) || IsEqualIID(iid, &IID_IEnumTfContexts))
378  {
379  *ppvOut = &This->IEnumTfContexts_iface;
380  }
381 
382  if (*ppvOut)
383  {
384  IEnumTfContexts_AddRef(iface);
385  return S_OK;
386  }
387 
388  WARN("unsupported interface: %s\n", debugstr_guid(iid));
389  return E_NOINTERFACE;
390 }
391 
393 {
395  return InterlockedIncrement(&This->refCount);
396 }
397 
399 {
401  ULONG ret;
402 
403  ret = InterlockedDecrement(&This->refCount);
404  if (ret == 0)
406  return ret;
407 }
408 
410  ULONG ulCount, ITfContext **rgContext, ULONG *pcFetched)
411 {
413  ULONG fetched = 0;
414 
415  TRACE("(%p)\n",This);
416 
417  if (rgContext == NULL) return E_POINTER;
418 
419  while (fetched < ulCount)
420  {
421  if (This->index > 1)
422  break;
423 
424  if (!This->docmgr->contextStack[This->index])
425  break;
426 
427  *rgContext = This->docmgr->contextStack[This->index];
428  ITfContext_AddRef(*rgContext);
429 
430  ++This->index;
431  ++fetched;
432  ++rgContext;
433  }
434 
435  if (pcFetched) *pcFetched = fetched;
436  return fetched == ulCount ? S_OK : S_FALSE;
437 }
438 
440 {
442  TRACE("(%p)\n",This);
443  This->index += celt;
444  return S_OK;
445 }
446 
448 {
450  TRACE("(%p)\n",This);
451  This->index = 0;
452  return S_OK;
453 }
454 
456  IEnumTfContexts **ppenum)
457 {
459  HRESULT res;
460 
461  TRACE("(%p)\n",This);
462 
463  if (ppenum == NULL) return E_POINTER;
464 
465  res = EnumTfContext_Constructor(This->docmgr, ppenum);
466  if (SUCCEEDED(res))
467  {
468  EnumTfContext *new_This = impl_from_IEnumTfContexts(*ppenum);
469  new_This->index = This->index;
470  }
471  return res;
472 }
473 
474 static const IEnumTfContextsVtbl IEnumTfContexts_Vtbl ={
478 
483 };
484 
486 {
488 
490  if (This == NULL)
491  return E_OUTOFMEMORY;
492 
493  This->IEnumTfContexts_iface.lpVtbl = &IEnumTfContexts_Vtbl;
494  This->refCount = 1;
495  This->docmgr = mgr;
496 
497  *ppOut = &This->IEnumTfContexts_iface;
498  TRACE("returning %p\n", *ppOut);
499  return S_OK;
500 }
static HRESULT WINAPI EnumTfContext_Next(IEnumTfContexts *iface, ULONG ulCount, ITfContext **rgContext, ULONG *pcFetched)
Definition: documentmgr.c:409
static HRESULT EnumTfContext_Constructor(DocumentMgr *mgr, IEnumTfContexts **ppOut)
Definition: documentmgr.c:485
static HRESULT WINAPI DocumentMgrSource_QueryInterface(ITfSource *iface, REFIID iid, LPVOID *ppvOut)
Definition: documentmgr.c:279
#define REFIID
Definition: guiddef.h:118
#define COOKIE_MAGIC_DMSINK
#define E_NOINTERFACE
Definition: winerror.h:2364
HRESULT WINAPI TF_GetThreadMgr(ITfThreadMgr **pptim)
Definition: msctf.c:628
static ULONG WINAPI EnumTfContext_Release(IEnumTfContexts *iface)
Definition: documentmgr.c:398
DWORD TfEditCookie
Definition: msctf.idl:67
REFIID riid
Definition: precomp.h:44
struct tagEnumTfContext EnumTfContext
static ULONG WINAPI DocumentMgrSource_AddRef(ITfSource *iface)
Definition: documentmgr.c:285
static HRESULT WINAPI DocumentMgr_Push(ITfDocumentMgr *iface, ITfContext *pic)
Definition: documentmgr.c:157
void free_sinks(struct list *sink_list)
Definition: msctf.c:324
#define WARN(fmt,...)
Definition: debug.h:111
HRESULT advise_sink(struct list *sink_list, REFIID riid, DWORD cookie_magic, IUnknown *unk, DWORD *cookie)
Definition: msctf.c:285
static ULONG WINAPI DocumentMgrSource_Release(ITfSource *iface)
Definition: documentmgr.c:291
DWORD get_Cookie_magic(DWORD id)
Definition: msctf.c:233
static HRESULT WINAPI EnumTfContext_Clone(IEnumTfContexts *iface, IEnumTfContexts **ppenum)
Definition: documentmgr.c:455
#define E_FAIL
Definition: ddrawi.h:102
static ULONG WINAPI EnumTfContext_AddRef(IEnumTfContexts *iface)
Definition: documentmgr.c:392
ITfThreadMgrEventSink * ThreadMgrSink
Definition: documentmgr.c:48
static HRESULT WINAPI DocumentMgr_QueryInterface(ITfDocumentMgr *iface, REFIID iid, LPVOID *ppvOut)
Definition: documentmgr.c:99
GLsizei GLenum const GLvoid GLsizei GLenum GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLint GLint GLint GLshort GLshort GLshort GLubyte GLubyte GLubyte GLuint GLuint GLuint GLushort GLushort GLushort GLbyte GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLfloat GLint GLint GLint GLint GLshort GLshort GLshort GLshort GLubyte GLubyte GLubyte GLubyte GLuint GLuint GLuint GLuint GLushort GLushort GLushort GLushort GLboolean const GLdouble const GLfloat const GLint const GLshort const GLbyte const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLdouble const GLfloat const GLfloat const GLint const GLint const GLshort const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort GLenum GLenum GLenum GLfloat GLenum GLint GLenum GLenum GLenum GLfloat GLenum GLenum GLint GLenum GLfloat GLenum GLint GLint GLushort GLenum GLenum GLfloat GLenum GLenum GLint GLfloat const GLubyte GLenum GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLint GLint GLsizei GLsizei GLint GLenum GLenum const GLvoid GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLenum const GLdouble GLenum GLenum const GLfloat GLenum GLenum const GLint GLsizei GLuint GLfloat GLuint GLbitfield GLfloat GLint GLuint GLboolean GLenum GLfloat GLenum GLbitfield GLenum GLfloat GLfloat GLint GLint const GLfloat GLenum GLfloat GLfloat GLint GLint GLfloat GLfloat GLint GLint const GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat const GLdouble const GLfloat const GLdouble const GLfloat GLint i
Definition: glfuncs.h:248
static HRESULT WINAPI DocumentMgr_CreateContext(ITfDocumentMgr *iface, TfClientId tidOwner, DWORD dwFlags, IUnknown *punk, ITfContext **ppic, TfEditCookie *pecTextStore)
Definition: documentmgr.c:147
#define E_OUTOFMEMORY
Definition: ddrawi.h:100
IEnumTfContexts IEnumTfContexts_iface
Definition: documentmgr.c:54
static DocumentMgr * impl_from_ITfSource(ITfSource *iface)
Definition: documentmgr.c:68
long LONG
Definition: pedump.c:60
static HRESULT WINAPI DocumentMgr_Pop(ITfDocumentMgr *iface, DWORD dwFlags)
Definition: documentmgr.c:182
#define FIXME(fmt,...)
Definition: debug.h:110
static const IEnumTfContextsVtbl IEnumTfContexts_Vtbl
Definition: documentmgr.c:474
#define S_FALSE
Definition: winerror.h:2357
#define E_INVALIDARG
Definition: ddrawi.h:101
smooth NULL
Definition: ftsmooth.c:416
HRESULT Context_Constructor(TfClientId tidOwner, IUnknown *punk, ITfDocumentMgr *mgr, ITfContext **ppOut, TfEditCookie *pecTextStore)
Definition: context.c:1047
#define debugstr_guid
Definition: kernel32.h:35
static HRESULT WINAPI DocumentMgr_GetTop(ITfDocumentMgr *iface, ITfContext **ppic)
Definition: documentmgr.c:222
PFLT_MESSAGE_WAITER_QUEUE CONTAINING_RECORD(Csq, DEVICE_EXTENSION, IrpQueue)) -> WaiterQ.mLock) _IRQL_raises_(DISPATCH_LEVEL) VOID NTAPI FltpAcquireMessageWaiterLock(_In_ PIO_CSQ Csq, _Out_ PKIRQL Irql)
Definition: Messaging.c:560
static HRESULT WINAPI DocumentMgr_EnumContexts(ITfDocumentMgr *iface, IEnumTfContexts **ppEnum)
Definition: documentmgr.c:259
static HRESULT WINAPI EnumTfContext_Reset(IEnumTfContexts *iface)
Definition: documentmgr.c:447
#define TRACE(s)
Definition: solgame.cpp:4
#define GetProcessHeap()
Definition: compat.h:403
PVOID WINAPI HeapAlloc(HANDLE, DWORD, SIZE_T)
static void EnumTfContext_Destructor(EnumTfContext *This)
Definition: documentmgr.c:366
LONG HRESULT
Definition: typedefs.h:77
const GUID IID_IUnknown
#define WINAPI
Definition: msvc.h:6
unsigned long DWORD
Definition: ntddk_ex.h:95
static DocumentMgr * impl_from_ITfDocumentMgr(ITfDocumentMgr *iface)
Definition: documentmgr.c:63
static HRESULT WINAPI EnumTfContext_QueryInterface(IEnumTfContexts *iface, REFIID iid, LPVOID *ppvOut)
Definition: documentmgr.c:372
void check(CONTEXT *pContext)
Definition: NtContinue.c:61
ITfCompartmentMgr * CompartmentMgr
Definition: documentmgr.c:45
int ret
#define InterlockedDecrement
Definition: armddk.h:52
_In_ PCCERT_CONTEXT _In_ DWORD dwFlags
Definition: wincrypt.h:1175
WINE_DEFAULT_DEBUG_CHANNEL(msctf)
Definition: _list.h:228
Definition: time.h:76
static void DocumentMgr_Destructor(DocumentMgr *This)
Definition: documentmgr.c:78
static HRESULT WINAPI EnumTfContext_Skip(IEnumTfContexts *iface, ULONG celt)
Definition: documentmgr.c:439
HRESULT CompartmentMgr_Destructor(ITfCompartmentMgr *iface)
static EnumTfContext * impl_from_IEnumTfContexts(IEnumTfContexts *iface)
Definition: documentmgr.c:73
void ThreadMgr_OnDocumentMgrDestruction(ITfThreadMgr *tm, ITfDocumentMgr *mgr) DECLSPEC_HIDDEN
Definition: threadmgr.c:1537
static HRESULT WINAPI DocumentMgrSource_UnadviseSink(ITfSource *iface, DWORD pdwCookie)
Definition: documentmgr.c:321
#define S_OK
Definition: intsafe.h:59
static ULONG WINAPI DocumentMgr_AddRef(ITfDocumentMgr *iface)
Definition: documentmgr.c:127
#define InterlockedIncrement
Definition: armddk.h:53
static const ITfDocumentMgrVtbl DocumentMgrVtbl
Definition: documentmgr.c:266
struct tagDocumentMgr DocumentMgr
static HRESULT WINAPI DocumentMgrSource_AdviseSink(ITfSource *iface, REFIID riid, IUnknown *punk, DWORD *pdwCookie)
Definition: documentmgr.c:300
ITfDocumentMgr ITfDocumentMgr_iface
Definition: documentmgr.c:40
#define ARRAY_SIZE(a)
Definition: main.h:24
#define E_NOTIMPL
Definition: ddrawi.h:99
ITfSource ITfSource_iface
Definition: documentmgr.c:41
#define HEAP_ZERO_MEMORY
Definition: compat.h:123
HRESULT DocumentMgr_Constructor(ITfThreadMgrEventSink *ThreadMgrSink, ITfDocumentMgr **ppOut)
Definition: documentmgr.c:342
HRESULT unadvise_sink(DWORD cookie)
Definition: msctf.c:312
GLuint res
Definition: glext.h:9613
__WINE_SERVER_LIST_INLINE void list_init(struct list *list)
Definition: list.h:149
unsigned int ULONG
Definition: retypes.h:1
static ULONG WINAPI DocumentMgr_Release(ITfDocumentMgr *iface)
Definition: documentmgr.c:133
DocumentMgr * docmgr
Definition: documentmgr.c:58
HRESULT CompartmentMgr_Constructor(IUnknown *pUnkOuter, REFIID riid, IUnknown **ppOut)
DWORD TfClientId
Definition: msctf.idl:68
#define E_POINTER
Definition: winerror.h:2365
HRESULT Context_Initialize(ITfContext *iface, ITfDocumentMgr *manager)
Definition: context.c:1109
static const ITfSourceVtbl DocumentMgrSourceVtbl
Definition: documentmgr.c:333
static HRESULT WINAPI DocumentMgr_GetBase(ITfDocumentMgr *iface, ITfContext **ppic)
Definition: documentmgr.c:237
ITfContext * contextStack[2]
Definition: documentmgr.c:47
#define HeapFree(x, y, z)
Definition: compat.h:402
#define IsEqualIID(riid1, riid2)
Definition: guiddef.h:95
struct list TransitoryExtensionSink
Definition: documentmgr.c:50
#define SUCCEEDED(hr)
Definition: intsafe.h:57
HRESULT Context_Uninitialize(ITfContext *iface)
Definition: context.c:1121