ReactOS 0.4.16-dev-1946-g52006dd
documentmgr.cpp
Go to the documentation of this file.
1/*
2 * PROJECT: ReactOS CTF
3 * LICENSE: LGPL-2.0-or-later (https://spdx.org/licenses/LGPL-2.0-or-later)
4 * PURPOSE: Implementation of ITfDocumentMgr and IEnumTfContexts
5 * COPYRIGHT: Copyright 2009 Aric Stewart, CodeWeavers
6 * Copyright 2025 Katayama Hirofumi MZ <katayama.hirofumi.mz@gmail.com>
7 */
8
9#include "precomp.h"
10#include "documentmgr.h"
11
12#include <wine/debug.h>
14
16
18 : m_cRefs(1)
19 , m_pCompartmentMgr(NULL)
20 , m_initialContext(NULL)
21 , m_pThreadMgrSink(threadMgrSink)
22{
24
26
27 ITfDocumentMgr *pDocMgr = static_cast<ITfDocumentMgr *>(this);
28 ITfCompartmentMgr **ppCompMgr = static_cast<ITfCompartmentMgr **>(&m_pCompartmentMgr);
29 CompartmentMgr_Constructor(pDocMgr, IID_IUnknown, reinterpret_cast<IUnknown **>(ppCompMgr));
30
33}
34
36{
37 TRACE("destroying %p\n", this);
38
41 if (tm)
42 {
44 tm->Release();
45 }
46
49 if (m_contextStack[0])
51 if (m_contextStack[1])
53
55
57 {
60 }
61}
62
65 _In_ ITfThreadMgrEventSink *pThreadMgrSink,
66 _Out_ ITfDocumentMgr **ppOut)
67{
68 if (!ppOut)
69 {
70 ERR("!ppOut\n");
71 return E_POINTER;
72 }
73
74 if (!pThreadMgrSink)
75 {
76 ERR("!pThreadMgrSink\n");
77 return E_INVALIDARG;
78 }
79
80 CDocumentMgr *This = new(cicNoThrow) CDocumentMgr(pThreadMgrSink);
81 if (!This)
82 {
83 ERR("E_OUTOFMEMORY\n");
84 return E_OUTOFMEMORY;
85 }
86
87 *ppOut = static_cast<ITfDocumentMgr *>(This);
88 TRACE("returning %p\n", *ppOut);
89 return S_OK;
90}
91
93{
94 TRACE("%p -> (%s, %p)\n", this, wine_dbgstr_guid(&iid), ppvObject);
95 *ppvObject = NULL;
96
98 if (iid == IID_IUnknown || iid == IID_ITfDocumentMgr)
99 pUnk = static_cast<ITfDocumentMgr *>(this);
100 else if (iid == IID_ITfSource)
101 pUnk = static_cast<ITfSource *>(this);
102 else if (iid == IID_ITfCompartmentMgr)
104
105 if (pUnk)
106 {
107 pUnk->AddRef();
108 *ppvObject = pUnk;
109 return S_OK;
110 }
111
112 WARN("unsupported interface: %s\n", debugstr_guid(&iid));
113 return E_NOINTERFACE;
114}
115
117{
118 TRACE("%p -> ()\n", this);
119 return ::InterlockedIncrement(&m_cRefs);
120}
121
123{
124 TRACE("%p -> ()\n", this);
126 if (!ret)
127 delete this;
128 return ret;
129}
130
133 TfClientId tidOwner,
135 IUnknown *punk,
136 ITfContext **ppic,
137 TfEditCookie *pecTextStore)
138{
139 TRACE("%p -> (%d, 0x%lX, %p, %p, %p)\n", this, tidOwner, dwFlags, punk, ppic, pecTextStore);
140 return Context_Constructor(tidOwner, punk, this, ppic, pecTextStore);
141}
142
144{
145 TRACE("%p -> (%p)\n", this, pic);
146
147 if (m_contextStack[1]) /* Full */
148 {
149 ERR("TF_E_STACKFULL\n");
150 return TF_E_STACKFULL;
151 }
152
153 if (!pic)
154 {
155 ERR("!pic\n");
156 return E_INVALIDARG;
157 }
158
160 HRESULT hr = pic->QueryInterface(IID_ITfContext, reinterpret_cast<LPVOID *>(&check));
161 if (FAILED(hr))
162 {
163 ERR("hr: 0x%lX\n", hr);
164 return E_INVALIDARG;
165 }
166
167 if (!m_contextStack[0])
169
172
175
176 return S_OK;
177}
178
180{
181 TRACE("%p -> (0x%lX)\n", this, dwFlags);
182
183 if (dwFlags == TF_POPF_ALL)
184 {
185 for (SIZE_T i = 0; i < _countof(m_contextStack); i++)
186 {
187 if (!m_contextStack[i])
188 continue;
189
194 }
195
197 return S_OK;
198 }
199
200 if (dwFlags)
201 {
202 ERR("E_INVALIDARG: 0x%lX\n", dwFlags);
203 return E_INVALIDARG;
204 }
205
206 if (!m_contextStack[1]) // Cannot pop last context
207 {
208 ERR("!m_contextStack[1]\n");
209 return E_FAIL;
210 }
211
214
215 if (m_contextStack[0])
217
219 m_contextStack[1] = NULL;
220
221 if (!m_contextStack[0])
223
224 return S_OK;
225}
226
228{
229 TRACE("%p -> (%p)\n", this, ppic);
230
231 if (!ppic)
232 {
233 ERR("!ppic\n");
234 return E_INVALIDARG;
235 }
236
238 if (m_contextStack[0])
240 else
242
243 if (target)
244 target->AddRef();
245
246 *ppic = target;
247 return S_OK;
248}
249
251{
252 TRACE("%p -> (%p)\n", this, ppic);
253
254 if (!ppic)
255 {
256 ERR("!ppic\n");
257 return E_INVALIDARG;
258 }
259
261 if (m_contextStack[1])
263 else if (m_contextStack[0])
265 else
267
268 if (target)
269 target->AddRef();
270
271 *ppic = target;
272 return S_OK;
273}
274
276{
277 TRACE("%p -> (%p)\n", this, ppEnum);
278 return EnumTfContext_Constructor(this, ppEnum);
279}
280
282{
283 TRACE("%p -> (%s, %p, %p)\n", this, wine_dbgstr_guid(&riid), punk, pdwCookie);
284
285 if (cicIsNullPtr(&riid) || !punk || !pdwCookie)
286 return E_INVALIDARG;
287
288 if (riid == IID_ITfTransitoryExtensionSink)
289 {
290 WARN("semi-stub for ITfTransitoryExtensionSink: callback won't be used.\n");
291 return advise_sink(&m_transitoryExtensionSink, IID_ITfTransitoryExtensionSink,
292 COOKIE_MAGIC_DMSINK, punk, pdwCookie);
293 }
294
295 FIXME("(%p) Unhandled Sink: %s\n", this, debugstr_guid(&riid));
296 return E_NOTIMPL;
297}
298
300{
301 TRACE("%p -> (%p)\n", this, pdwCookie);
302
303 if (get_Cookie_magic(pdwCookie) != COOKIE_MAGIC_DMSINK)
304 return E_INVALIDARG;
305
306 return unadvise_sink(pdwCookie);
307}
308
310
312 : m_cRefs(1)
313 , m_index(0)
314 , m_pDocMgr(mgr)
315{
316 if (mgr)
317 mgr->AddRef();
318}
319
321{
322 if (m_pDocMgr)
323 {
325 m_pDocMgr = NULL;
326 }
327}
328
330{
331 if (!ppOut)
332 {
333 ERR("!ppOut\n");
334 return E_POINTER;
335 }
336
338 if (!This)
339 {
340 ERR("E_OUTOFMEMORY\n");
341 return E_OUTOFMEMORY;
342 }
343
344 *ppOut = static_cast<IEnumTfContexts *>(This);
345 TRACE("returning %p\n", *ppOut);
346 return S_OK;
347}
348
350{
351 TRACE("%p -> (%s, %p)\n", this, wine_dbgstr_guid(&iid), ppvObject);
352
353 *ppvObject = NULL;
354
355 if (iid == IID_IUnknown || iid == IID_IEnumTfContexts)
356 *ppvObject = static_cast<IEnumTfContexts *>(this);
357
358 if (*ppvObject)
359 {
360 AddRef();
361 return S_OK;
362 }
363
364 WARN("E_NOINTERFACE: %s\n", wine_dbgstr_guid(&iid));
365 return E_NOINTERFACE;
366}
367
369{
370 TRACE("%p -> ()\n", this);
371 return ::InterlockedIncrement(&m_cRefs);
372}
373
375{
376 TRACE("%p -> ()\n", this);
378 if (!ret)
379 delete this;
380 return ret;
381}
382
383STDMETHODIMP CEnumTfContext::Next(ULONG ulCount, ITfContext **rgContext, ULONG *pcFetched)
384{
385 TRACE("%p -> (%lu, %p, %p)\n",this, ulCount, rgContext, pcFetched);
386
387 if (!rgContext)
388 {
389 ERR("!rgContext\n");
390 return E_POINTER;
391 }
392
393 ULONG fetched;
394 for (fetched = 0; fetched < ulCount; ++fetched, ++m_index, ++rgContext)
395 {
397 break;
398
400 break;
401
402 *rgContext = m_pDocMgr->m_contextStack[m_index];
403 (*rgContext)->AddRef();
404 }
405
406 if (pcFetched)
407 *pcFetched = fetched;
408
409 return (fetched == ulCount) ? S_OK : S_FALSE;
410}
411
413{
414 TRACE("%p -> (%lu)\n", this, celt);
415 m_index += celt;
416 return S_OK;
417}
418
420{
421 TRACE("%p -> ()\n", this);
422 m_index = 0;
423 return S_OK;
424}
425
427{
428 TRACE("%p -> (%p)\n", this, ppenum);
429
430 if (!ppenum)
431 {
432 ERR("!ppenum\n");
433 return E_POINTER;
434 }
435
437 if (!This)
438 {
439 ERR("E_OUTOFMEMORY\n");
440 return E_OUTOFMEMORY;
441 }
442
443 This->m_index = m_index;
444 *ppenum = This;
445 return S_OK;
446}
447
449
452{
453 return CDocumentMgr::CreateInstance(pThreadMgrSink, ppOut);
454}
455
458{
459 return CEnumTfContext::CreateInstance(mgr, ppOut);
460}
#define InterlockedDecrement
Definition: armddk.h:52
#define WINE_DEFAULT_DEBUG_CHANNEL(t)
Definition: precomp.h:23
#define COOKIE_MAGIC_DMSINK
Definition: precomp.h:39
void ThreadMgr_OnDocumentMgrDestruction(ITfThreadMgr *tm, ITfDocumentMgr *mgr)
Definition: threadmgr.cpp:1394
static void list_init(struct list_entry *head)
Definition: list.h:51
#define FIXME(fmt,...)
Definition: precomp.h:53
#define WARN(fmt,...)
Definition: precomp.h:61
#define ERR(fmt,...)
Definition: precomp.h:57
#define EXTERN_C
Definition: basetyps.h:12
#define STDMETHODIMP
Definition: basetyps.h:43
#define STDMETHODIMP_(t)
Definition: basetyps.h:44
const GUID IID_IUnknown
#define cicNoThrow
Definition: cicbase.h:46
static bool cicIsNullPtr(LPCVOID ptr)
Definition: cicbase.h:40
STDMETHODIMP Push(ITfContext *pic) override
struct list m_transitoryExtensionSink
Definition: documentmgr.h:57
STDMETHODIMP CreateContext(TfClientId tidOwner, DWORD dwFlags, IUnknown *punk, ITfContext **ppic, TfEditCookie *pecTextStore) override
STDMETHODIMP Pop(DWORD dwFlags) override
STDMETHODIMP UnadviseSink(DWORD pdwCookie) override
STDMETHODIMP GetTop(ITfContext **ppic) override
static HRESULT CreateInstance(_In_ ITfThreadMgrEventSink *pThreadMgrSink, _Out_ ITfDocumentMgr **ppOut)
Definition: documentmgr.cpp:64
ITfContext * m_initialContext
Definition: documentmgr.h:54
STDMETHODIMP EnumContexts(IEnumTfContexts **ppEnum) override
ITfThreadMgrEventSink * m_pThreadMgrSink
Definition: documentmgr.h:56
STDMETHODIMP GetBase(ITfContext **ppic) override
STDMETHODIMP QueryInterface(REFIID iid, LPVOID *ppvObject) override
Definition: documentmgr.cpp:92
CDocumentMgr(ITfThreadMgrEventSink *threadMgrSink)
Definition: documentmgr.cpp:17
ITfCompartmentMgr * m_pCompartmentMgr
Definition: documentmgr.h:53
STDMETHODIMP AdviseSink(REFIID riid, IUnknown *punk, DWORD *pdwCookie) override
ITfContext * m_contextStack[2]
Definition: documentmgr.h:55
virtual ~CDocumentMgr()
Definition: documentmgr.cpp:35
STDMETHODIMP QueryInterface(REFIID iid, LPVOID *ppvObject) override
CDocumentMgr * m_pDocMgr
Definition: documentmgr.h:89
STDMETHODIMP Reset() override
static HRESULT CreateInstance(_In_opt_ CDocumentMgr *mgr, _Out_ IEnumTfContexts **ppOut)
virtual ~CEnumTfContext()
CEnumTfContext(_In_opt_ CDocumentMgr *mgr)
STDMETHODIMP Next(ULONG ulCount, ITfContext **rgContext, ULONG *pcFetched) override
STDMETHODIMP Skip(ULONG celt) override
STDMETHODIMP Clone(IEnumTfContexts **ppenum) override
EXTERN_C HRESULT CompartmentMgr_Constructor(IUnknown *pUnkOuter, REFIID riid, IUnknown **ppOut)
EXTERN_C HRESULT Context_Initialize(ITfContext *iface, ITfDocumentMgr *manager)
Definition: context.cpp:978
EXTERN_C HRESULT Context_Uninitialize(ITfContext *iface)
Definition: context.cpp:985
EXTERN_C HRESULT Context_Constructor(TfClientId tidOwner, IUnknown *punk, ITfDocumentMgr *mgr, ITfContext **ppOut, TfEditCookie *pecTextStore)
Definition: context.cpp:967
#define E_OUTOFMEMORY
Definition: ddrawi.h:100
#define E_INVALIDARG
Definition: ddrawi.h:101
#define E_NOTIMPL
Definition: ddrawi.h:99
#define E_FAIL
Definition: ddrawi.h:102
#define NULL
Definition: types.h:112
EXTERN_C HRESULT DocumentMgr_Constructor(ITfThreadMgrEventSink *pThreadMgrSink, ITfDocumentMgr **ppOut)
EXTERN_C HRESULT EnumTfContext_Constructor(CDocumentMgr *mgr, IEnumTfContexts **ppOut)
EXTERN_C HRESULT EnumTfContext_Constructor(CDocumentMgr *mgr, IEnumTfContexts **ppOut)
static void *static void *static LPDIRECTPLAY IUnknown * pUnk
Definition: dplayx.c:30
#define check(expected, result)
Definition: dplayx.c:32
return ret
Definition: mutex.c:146
unsigned long DWORD
Definition: ntddk_ex.h:95
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
REFIID riid
Definition: atlbase.h:39
const DWORD TF_POPF_ALL
Definition: msctf.idl:281
HRESULT OnUninitDocumentMgr([in] ITfDocumentMgr *pdim)
HRESULT OnPopContext([in] ITfContext *pic)
HRESULT OnInitDocumentMgr([in] ITfDocumentMgr *pdim)
HRESULT OnPushContext([in] ITfContext *pic)
ULONG AddRef()
HRESULT QueryInterface([in] REFIID riid, [out, iid_is(riid)] void **ppvObject)
ULONG Release()
nsrefcnt AddRef()
#define S_OK
Definition: intsafe.h:52
#define FAILED(hr)
Definition: intsafe.h:51
#define debugstr_guid
Definition: kernel32.h:35
EXTERN_C HRESULT advise_sink(struct list *sink_list, REFIID riid, DWORD cookie_magic, IUnknown *unk, DWORD *cookie)
Definition: msctf.cpp:259
EXTERN_C DWORD get_Cookie_magic(DWORD id)
Definition: msctf.cpp:203
EXTERN_C HRESULT unadvise_sink(DWORD cookie)
Definition: msctf.cpp:286
TfClientId g_processId
Definition: msctf.cpp:44
HRESULT WINAPI TF_GetThreadMgr(ITfThreadMgr **pptim)
Definition: msctf.cpp:611
EXTERN_C void free_sinks(struct list *sink_list)
Definition: msctf.cpp:297
DWORD TfClientId
Definition: msctf.idl:87
DWORD TfEditCookie
Definition: msctf.idl:86
_In_ LPWSTR _In_ DWORD _In_ DWORD _In_ DWORD dwFlags
Definition: netsh.h:141
#define _Out_
Definition: no_sal2.h:160
#define _In_
Definition: no_sal2.h:158
#define _In_opt_
Definition: no_sal2.h:212
#define REFIID
Definition: guiddef.h:118
_In_opt_ IUnknown * punk
Definition: shlwapi.h:158
static __inline const char * wine_dbgstr_guid(const GUID *id)
Definition: debug.h:197
HRESULT hr
Definition: shlfolder.c:183
#define _countof(array)
Definition: sndvol32.h:70
#define TRACE(s)
Definition: solgame.cpp:4
Definition: cookie.c:34
Definition: tools.h:99
Definition: time.h:68
ULONG_PTR SIZE_T
Definition: typedefs.h:80
uint32_t ULONG
Definition: typedefs.h:59
#define S_FALSE
Definition: winerror.h:3451
#define E_NOINTERFACE
Definition: winerror.h:3479
#define E_POINTER
Definition: winerror.h:3480