1 /*
2 * ITfContext 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 #include "olectl.h"
34
35 #include "msctf.h"
36 #include "msctf_internal.h"
37
38 WINE_DEFAULT_DEBUG_CHANNEL(msctf);
39
40 typedef struct tagContext {
41 ITfContext ITfContext_iface;
42 ITfSource ITfSource_iface;
43 /* const ITfContextCompositionVtbl *ContextCompositionVtbl; */
44 ITfContextOwnerCompositionServices ITfContextOwnerCompositionServices_iface;
45 /* const ITfContextOwnerServicesVtbl *ContextOwnerServicesVtbl; */
46 ITfInsertAtSelection ITfInsertAtSelection_iface;
47 /* const ITfMouseTrackerVtbl *MouseTrackerVtbl; */
48 /* const ITfQueryEmbeddedVtbl *QueryEmbeddedVtbl; */
49 ITfSourceSingle ITfSourceSingle_iface;
50 ITextStoreACPSink ITextStoreACPSink_iface;
51 ITextStoreACPServices ITextStoreACPServices_iface;
52 LONG refCount;
53 BOOL connected;
54
55 /* Aggregation */
56 ITfCompartmentMgr *CompartmentMgr;
57
58 TfClientId tidOwner;
59 TfEditCookie defaultCookie;
60 TS_STATUS documentStatus;
61 ITfDocumentMgr *manager;
62
63 ITextStoreACP *pITextStoreACP;
64 ITfContextOwnerCompositionSink *pITfContextOwnerCompositionSink;
65
66 ITfEditSession* currentEditSession;
67
68 /* kept as separate lists to reduce unnecessary iterations */
69 struct list pContextKeyEventSink;
70 struct list pEditTransactionSink;
71 struct list pStatusSink;
72 struct list pTextEditSink;
73 struct list pTextLayoutSink;
74
75 } Context;
76
77 typedef struct tagEditCookie {
78 DWORD lockType;
79 Context *pOwningContext;
80 } EditCookie;
81
impl_from_ITfContext(ITfContext * iface)82 static inline Context *impl_from_ITfContext(ITfContext *iface)
83 {
84 return CONTAINING_RECORD(iface, Context, ITfContext_iface);
85 }
86
impl_from_ITfSource(ITfSource * iface)87 static inline Context *impl_from_ITfSource(ITfSource *iface)
88 {
89 return CONTAINING_RECORD(iface, Context, ITfSource_iface);
90 }
91
impl_from_ITfContextOwnerCompositionServices(ITfContextOwnerCompositionServices * iface)92 static inline Context *impl_from_ITfContextOwnerCompositionServices(ITfContextOwnerCompositionServices *iface)
93 {
94 return CONTAINING_RECORD(iface, Context, ITfContextOwnerCompositionServices_iface);
95 }
96
impl_from_ITfInsertAtSelection(ITfInsertAtSelection * iface)97 static inline Context *impl_from_ITfInsertAtSelection(ITfInsertAtSelection *iface)
98 {
99 return CONTAINING_RECORD(iface, Context, ITfInsertAtSelection_iface);
100 }
101
impl_from_ITfSourceSingle(ITfSourceSingle * iface)102 static inline Context *impl_from_ITfSourceSingle(ITfSourceSingle* iface)
103 {
104 return CONTAINING_RECORD(iface, Context, ITfSourceSingle_iface);
105 }
106
impl_from_ITextStoreACPSink(ITextStoreACPSink * iface)107 static inline Context *impl_from_ITextStoreACPSink(ITextStoreACPSink *iface)
108 {
109 return CONTAINING_RECORD(iface, Context, ITextStoreACPSink_iface);
110 }
111
impl_from_ITextStoreACPServices(ITextStoreACPServices * iface)112 static inline Context *impl_from_ITextStoreACPServices(ITextStoreACPServices *iface)
113 {
114 return CONTAINING_RECORD(iface, Context, ITextStoreACPServices_iface);
115 }
116
Context_Destructor(Context * This)117 static void Context_Destructor(Context *This)
118 {
119 EditCookie *cookie;
120 TRACE("destroying %p\n", This);
121
122 if (This->pITextStoreACP)
123 ITextStoreACP_Release(This->pITextStoreACP);
124
125 if (This->pITfContextOwnerCompositionSink)
126 ITfContextOwnerCompositionSink_Release(This->pITfContextOwnerCompositionSink);
127
128 if (This->defaultCookie)
129 {
130 cookie = remove_Cookie(This->defaultCookie);
131 HeapFree(GetProcessHeap(),0,cookie);
132 This->defaultCookie = 0;
133 }
134
135 free_sinks(&This->pContextKeyEventSink);
136 free_sinks(&This->pEditTransactionSink);
137 free_sinks(&This->pStatusSink);
138 free_sinks(&This->pTextEditSink);
139 free_sinks(&This->pTextLayoutSink);
140
141 CompartmentMgr_Destructor(This->CompartmentMgr);
142 HeapFree(GetProcessHeap(),0,This);
143 }
144
Context_QueryInterface(ITfContext * iface,REFIID iid,LPVOID * ppvOut)145 static HRESULT WINAPI Context_QueryInterface(ITfContext *iface, REFIID iid, LPVOID *ppvOut)
146 {
147 Context *This = impl_from_ITfContext(iface);
148 *ppvOut = NULL;
149
150 if (IsEqualIID(iid, &IID_IUnknown) || IsEqualIID(iid, &IID_ITfContext))
151 {
152 *ppvOut = &This->ITfContext_iface;
153 }
154 else if (IsEqualIID(iid, &IID_ITfSource))
155 {
156 *ppvOut = &This->ITfSource_iface;
157 }
158 else if (IsEqualIID(iid, &IID_ITfContextOwnerCompositionServices))
159 {
160 *ppvOut = &This->ITfContextOwnerCompositionServices_iface;
161 }
162 else if (IsEqualIID(iid, &IID_ITfInsertAtSelection))
163 {
164 *ppvOut = &This->ITfInsertAtSelection_iface;
165 }
166 else if (IsEqualIID(iid, &IID_ITfCompartmentMgr))
167 {
168 *ppvOut = This->CompartmentMgr;
169 }
170 else if (IsEqualIID(iid, &IID_ITfSourceSingle))
171 {
172 *ppvOut = &This->ITfSourceSingle_iface;
173 }
174
175 if (*ppvOut)
176 {
177 ITfContext_AddRef(iface);
178 return S_OK;
179 }
180
181 WARN("unsupported interface: %s\n", debugstr_guid(iid));
182 return E_NOINTERFACE;
183 }
184
Context_AddRef(ITfContext * iface)185 static ULONG WINAPI Context_AddRef(ITfContext *iface)
186 {
187 Context *This = impl_from_ITfContext(iface);
188 return InterlockedIncrement(&This->refCount);
189 }
190
Context_Release(ITfContext * iface)191 static ULONG WINAPI Context_Release(ITfContext *iface)
192 {
193 Context *This = impl_from_ITfContext(iface);
194 ULONG ret;
195
196 ret = InterlockedDecrement(&This->refCount);
197 if (ret == 0)
198 Context_Destructor(This);
199 return ret;
200 }
201
202 /*****************************************************
203 * ITfContext functions
204 *****************************************************/
Context_RequestEditSession(ITfContext * iface,TfClientId tid,ITfEditSession * pes,DWORD dwFlags,HRESULT * phrSession)205 static HRESULT WINAPI Context_RequestEditSession (ITfContext *iface,
206 TfClientId tid, ITfEditSession *pes, DWORD dwFlags,
207 HRESULT *phrSession)
208 {
209 Context *This = impl_from_ITfContext(iface);
210 HRESULT hr;
211 DWORD dwLockFlags = 0x0;
212
213 TRACE("(%p) %i %p %x %p\n",This, tid, pes, dwFlags, phrSession);
214
215 if (!(dwFlags & TF_ES_READ) && !(dwFlags & TF_ES_READWRITE))
216 {
217 *phrSession = E_FAIL;
218 return E_INVALIDARG;
219 }
220
221 if (!This->pITextStoreACP)
222 {
223 FIXME("No ITextStoreACP available\n");
224 *phrSession = E_FAIL;
225 return E_FAIL;
226 }
227
228 if (!(dwFlags & TF_ES_ASYNC))
229 dwLockFlags |= TS_LF_SYNC;
230
231 if ((dwFlags & TF_ES_READWRITE) == TF_ES_READWRITE)
232 dwLockFlags |= TS_LF_READWRITE;
233 else if (dwFlags & TF_ES_READ)
234 dwLockFlags |= TS_LF_READ;
235
236 if (!This->documentStatus.dwDynamicFlags)
237 ITextStoreACP_GetStatus(This->pITextStoreACP, &This->documentStatus);
238
239 if (((dwFlags & TF_ES_READWRITE) == TF_ES_READWRITE) && (This->documentStatus.dwDynamicFlags & TS_SD_READONLY))
240 {
241 *phrSession = TS_E_READONLY;
242 return S_OK;
243 }
244
245 if (FAILED (ITfEditSession_QueryInterface(pes, &IID_ITfEditSession, (LPVOID*)&This->currentEditSession)))
246 {
247 *phrSession = E_FAIL;
248 return E_INVALIDARG;
249 }
250
251 hr = ITextStoreACP_RequestLock(This->pITextStoreACP, dwLockFlags, phrSession);
252
253 return hr;
254 }
255
Context_InWriteSession(ITfContext * iface,TfClientId tid,BOOL * pfWriteSession)256 static HRESULT WINAPI Context_InWriteSession (ITfContext *iface,
257 TfClientId tid,
258 BOOL *pfWriteSession)
259 {
260 Context *This = impl_from_ITfContext(iface);
261 FIXME("STUB:(%p)\n",This);
262 return E_NOTIMPL;
263 }
264
Context_GetSelection(ITfContext * iface,TfEditCookie ec,ULONG ulIndex,ULONG ulCount,TF_SELECTION * pSelection,ULONG * pcFetched)265 static HRESULT WINAPI Context_GetSelection (ITfContext *iface,
266 TfEditCookie ec, ULONG ulIndex, ULONG ulCount,
267 TF_SELECTION *pSelection, ULONG *pcFetched)
268 {
269 Context *This = impl_from_ITfContext(iface);
270 EditCookie *cookie;
271 ULONG count, i;
272 ULONG totalFetched = 0;
273 HRESULT hr = S_OK;
274
275 if (!pSelection || !pcFetched)
276 return E_INVALIDARG;
277
278 *pcFetched = 0;
279
280 if (!This->connected)
281 return TF_E_DISCONNECTED;
282
283 if (get_Cookie_magic(ec)!=COOKIE_MAGIC_EDITCOOKIE)
284 return TF_E_NOLOCK;
285
286 if (!This->pITextStoreACP)
287 {
288 FIXME("Context does not have a ITextStoreACP\n");
289 return E_NOTIMPL;
290 }
291
292 cookie = get_Cookie_data(ec);
293
294 if (ulIndex == TF_DEFAULT_SELECTION)
295 count = 1;
296 else
297 count = ulCount;
298
299 for (i = 0; i < count; i++)
300 {
301 DWORD fetched;
302 TS_SELECTION_ACP acps;
303
304 hr = ITextStoreACP_GetSelection(This->pITextStoreACP, ulIndex + i,
305 1, &acps, &fetched);
306
307 if (hr == TS_E_NOLOCK)
308 return TF_E_NOLOCK;
309 else if (SUCCEEDED(hr))
310 {
311 pSelection[totalFetched].style.ase = acps.style.ase;
312 pSelection[totalFetched].style.fInterimChar = acps.style.fInterimChar;
313 Range_Constructor(iface, This->pITextStoreACP, cookie->lockType, acps.acpStart, acps.acpEnd, &pSelection[totalFetched].range);
314 totalFetched ++;
315 }
316 else
317 break;
318 }
319
320 *pcFetched = totalFetched;
321
322 return hr;
323 }
324
Context_SetSelection(ITfContext * iface,TfEditCookie ec,ULONG ulCount,const TF_SELECTION * pSelection)325 static HRESULT WINAPI Context_SetSelection (ITfContext *iface,
326 TfEditCookie ec, ULONG ulCount, const TF_SELECTION *pSelection)
327 {
328 Context *This = impl_from_ITfContext(iface);
329 TS_SELECTION_ACP *acp;
330 ULONG i;
331 HRESULT hr;
332
333 TRACE("(%p) %i %i %p\n",This,ec,ulCount,pSelection);
334
335 if (!This->pITextStoreACP)
336 {
337 FIXME("Context does not have a ITextStoreACP\n");
338 return E_NOTIMPL;
339 }
340
341 if (get_Cookie_magic(ec)!=COOKIE_MAGIC_EDITCOOKIE)
342 return TF_E_NOLOCK;
343
344 acp = HeapAlloc(GetProcessHeap(), 0, sizeof(TS_SELECTION_ACP) * ulCount);
345 if (!acp)
346 return E_OUTOFMEMORY;
347
348 for (i = 0; i < ulCount; i++)
349 if (FAILED(TF_SELECTION_to_TS_SELECTION_ACP(&pSelection[i], &acp[i])))
350 {
351 TRACE("Selection Conversion Failed\n");
352 HeapFree(GetProcessHeap(), 0 , acp);
353 return E_FAIL;
354 }
355
356 hr = ITextStoreACP_SetSelection(This->pITextStoreACP, ulCount, acp);
357
358 HeapFree(GetProcessHeap(), 0, acp);
359
360 return hr;
361 }
362
Context_GetStart(ITfContext * iface,TfEditCookie ec,ITfRange ** ppStart)363 static HRESULT WINAPI Context_GetStart (ITfContext *iface,
364 TfEditCookie ec, ITfRange **ppStart)
365 {
366 Context *This = impl_from_ITfContext(iface);
367 EditCookie *cookie;
368 TRACE("(%p) %i %p\n",This,ec,ppStart);
369
370 if (!ppStart)
371 return E_INVALIDARG;
372
373 *ppStart = NULL;
374
375 if (!This->connected)
376 return TF_E_DISCONNECTED;
377
378 if (get_Cookie_magic(ec)!=COOKIE_MAGIC_EDITCOOKIE)
379 return TF_E_NOLOCK;
380
381 cookie = get_Cookie_data(ec);
382 return Range_Constructor(iface, This->pITextStoreACP, cookie->lockType, 0, 0, ppStart);
383 }
384
Context_GetEnd(ITfContext * iface,TfEditCookie ec,ITfRange ** ppEnd)385 static HRESULT WINAPI Context_GetEnd (ITfContext *iface,
386 TfEditCookie ec, ITfRange **ppEnd)
387 {
388 Context *This = impl_from_ITfContext(iface);
389 EditCookie *cookie;
390 LONG end;
391 TRACE("(%p) %i %p\n",This,ec,ppEnd);
392
393 if (!ppEnd)
394 return E_INVALIDARG;
395
396 *ppEnd = NULL;
397
398 if (!This->connected)
399 return TF_E_DISCONNECTED;
400
401 if (get_Cookie_magic(ec)!=COOKIE_MAGIC_EDITCOOKIE)
402 return TF_E_NOLOCK;
403
404 if (!This->pITextStoreACP)
405 {
406 FIXME("Context does not have a ITextStoreACP\n");
407 return E_NOTIMPL;
408 }
409
410 cookie = get_Cookie_data(ec);
411 ITextStoreACP_GetEndACP(This->pITextStoreACP,&end);
412
413 return Range_Constructor(iface, This->pITextStoreACP, cookie->lockType, end, end, ppEnd);
414 }
415
Context_GetActiveView(ITfContext * iface,ITfContextView ** ppView)416 static HRESULT WINAPI Context_GetActiveView (ITfContext *iface,
417 ITfContextView **ppView)
418 {
419 Context *This = impl_from_ITfContext(iface);
420 FIXME("STUB:(%p)\n",This);
421 return E_NOTIMPL;
422 }
423
Context_EnumViews(ITfContext * iface,IEnumTfContextViews ** ppEnum)424 static HRESULT WINAPI Context_EnumViews (ITfContext *iface,
425 IEnumTfContextViews **ppEnum)
426 {
427 Context *This = impl_from_ITfContext(iface);
428 FIXME("STUB:(%p)\n",This);
429 return E_NOTIMPL;
430 }
431
Context_GetStatus(ITfContext * iface,TF_STATUS * pdcs)432 static HRESULT WINAPI Context_GetStatus (ITfContext *iface,
433 TF_STATUS *pdcs)
434 {
435 Context *This = impl_from_ITfContext(iface);
436 TRACE("(%p) %p\n",This,pdcs);
437
438 if (!This->connected)
439 return TF_E_DISCONNECTED;
440
441 if (!pdcs)
442 return E_INVALIDARG;
443
444 if (!This->pITextStoreACP)
445 {
446 FIXME("Context does not have a ITextStoreACP\n");
447 return E_NOTIMPL;
448 }
449
450 ITextStoreACP_GetStatus(This->pITextStoreACP, &This->documentStatus);
451
452 *pdcs = This->documentStatus;
453
454 return S_OK;
455 }
456
Context_GetProperty(ITfContext * iface,REFGUID guidProp,ITfProperty ** ppProp)457 static HRESULT WINAPI Context_GetProperty (ITfContext *iface,
458 REFGUID guidProp, ITfProperty **ppProp)
459 {
460 Context *This = impl_from_ITfContext(iface);
461 FIXME("STUB:(%p)\n",This);
462 return E_NOTIMPL;
463 }
464
Context_GetAppProperty(ITfContext * iface,REFGUID guidProp,ITfReadOnlyProperty ** ppProp)465 static HRESULT WINAPI Context_GetAppProperty (ITfContext *iface,
466 REFGUID guidProp, ITfReadOnlyProperty **ppProp)
467 {
468 Context *This = impl_from_ITfContext(iface);
469 FIXME("STUB:(%p)\n",This);
470 return E_NOTIMPL;
471 }
472
Context_TrackProperties(ITfContext * iface,const GUID ** prgProp,ULONG cProp,const GUID ** prgAppProp,ULONG cAppProp,ITfReadOnlyProperty ** ppProperty)473 static HRESULT WINAPI Context_TrackProperties (ITfContext *iface,
474 const GUID **prgProp, ULONG cProp, const GUID **prgAppProp,
475 ULONG cAppProp, ITfReadOnlyProperty **ppProperty)
476 {
477 Context *This = impl_from_ITfContext(iface);
478 FIXME("STUB:(%p)\n",This);
479 return E_NOTIMPL;
480 }
481
Context_EnumProperties(ITfContext * iface,IEnumTfProperties ** ppEnum)482 static HRESULT WINAPI Context_EnumProperties (ITfContext *iface,
483 IEnumTfProperties **ppEnum)
484 {
485 Context *This = impl_from_ITfContext(iface);
486 FIXME("STUB:(%p)\n",This);
487 return E_NOTIMPL;
488 }
489
Context_GetDocumentMgr(ITfContext * iface,ITfDocumentMgr ** ppDm)490 static HRESULT WINAPI Context_GetDocumentMgr (ITfContext *iface,
491 ITfDocumentMgr **ppDm)
492 {
493 Context *This = impl_from_ITfContext(iface);
494 TRACE("(%p) %p\n",This,ppDm);
495
496 if (!ppDm)
497 return E_INVALIDARG;
498
499 *ppDm = This->manager;
500 if (!This->manager)
501 return S_FALSE;
502
503 ITfDocumentMgr_AddRef(This->manager);
504
505 return S_OK;
506 }
507
Context_CreateRangeBackup(ITfContext * iface,TfEditCookie ec,ITfRange * pRange,ITfRangeBackup ** ppBackup)508 static HRESULT WINAPI Context_CreateRangeBackup (ITfContext *iface,
509 TfEditCookie ec, ITfRange *pRange, ITfRangeBackup **ppBackup)
510 {
511 Context *This = impl_from_ITfContext(iface);
512 FIXME("STUB:(%p)\n",This);
513 return E_NOTIMPL;
514 }
515
516 static const ITfContextVtbl ContextVtbl =
517 {
518 Context_QueryInterface,
519 Context_AddRef,
520 Context_Release,
521 Context_RequestEditSession,
522 Context_InWriteSession,
523 Context_GetSelection,
524 Context_SetSelection,
525 Context_GetStart,
526 Context_GetEnd,
527 Context_GetActiveView,
528 Context_EnumViews,
529 Context_GetStatus,
530 Context_GetProperty,
531 Context_GetAppProperty,
532 Context_TrackProperties,
533 Context_EnumProperties,
534 Context_GetDocumentMgr,
535 Context_CreateRangeBackup
536 };
537
538 /*****************************************************
539 * ITfSource functions
540 *****************************************************/
ContextSource_QueryInterface(ITfSource * iface,REFIID iid,LPVOID * ppvOut)541 static HRESULT WINAPI ContextSource_QueryInterface(ITfSource *iface, REFIID iid, LPVOID *ppvOut)
542 {
543 Context *This = impl_from_ITfSource(iface);
544 return ITfContext_QueryInterface(&This->ITfContext_iface, iid, ppvOut);
545 }
546
ContextSource_AddRef(ITfSource * iface)547 static ULONG WINAPI ContextSource_AddRef(ITfSource *iface)
548 {
549 Context *This = impl_from_ITfSource(iface);
550 return ITfContext_AddRef(&This->ITfContext_iface);
551 }
552
ContextSource_Release(ITfSource * iface)553 static ULONG WINAPI ContextSource_Release(ITfSource *iface)
554 {
555 Context *This = impl_from_ITfSource(iface);
556 return ITfContext_Release(&This->ITfContext_iface);
557 }
558
ContextSource_AdviseSink(ITfSource * iface,REFIID riid,IUnknown * punk,DWORD * pdwCookie)559 static HRESULT WINAPI ContextSource_AdviseSink(ITfSource *iface,
560 REFIID riid, IUnknown *punk, DWORD *pdwCookie)
561 {
562 Context *This = impl_from_ITfSource(iface);
563
564 TRACE("(%p) %s %p %p\n",This,debugstr_guid(riid),punk,pdwCookie);
565
566 if (!riid || !punk || !pdwCookie)
567 return E_INVALIDARG;
568
569 if (IsEqualIID(riid, &IID_ITfTextEditSink))
570 return advise_sink(&This->pTextEditSink, &IID_ITfTextEditSink, COOKIE_MAGIC_CONTEXTSINK, punk, pdwCookie);
571
572 FIXME("(%p) Unhandled Sink: %s\n",This,debugstr_guid(riid));
573 return E_NOTIMPL;
574 }
575
ContextSource_UnadviseSink(ITfSource * iface,DWORD pdwCookie)576 static HRESULT WINAPI ContextSource_UnadviseSink(ITfSource *iface, DWORD pdwCookie)
577 {
578 Context *This = impl_from_ITfSource(iface);
579
580 TRACE("(%p) %x\n",This,pdwCookie);
581
582 if (get_Cookie_magic(pdwCookie)!=COOKIE_MAGIC_CONTEXTSINK)
583 return E_INVALIDARG;
584
585 return unadvise_sink(pdwCookie);
586 }
587
588 static const ITfSourceVtbl ContextSourceVtbl =
589 {
590 ContextSource_QueryInterface,
591 ContextSource_AddRef,
592 ContextSource_Release,
593 ContextSource_AdviseSink,
594 ContextSource_UnadviseSink
595 };
596
597 /*****************************************************
598 * ITfContextOwnerCompositionServices functions
599 *****************************************************/
ContextOwnerCompositionServices_QueryInterface(ITfContextOwnerCompositionServices * iface,REFIID iid,LPVOID * ppvOut)600 static HRESULT WINAPI ContextOwnerCompositionServices_QueryInterface(ITfContextOwnerCompositionServices *iface,
601 REFIID iid, LPVOID *ppvOut)
602 {
603 Context *This = impl_from_ITfContextOwnerCompositionServices(iface);
604 return ITfContext_QueryInterface(&This->ITfContext_iface, iid, ppvOut);
605 }
606
ContextOwnerCompositionServices_AddRef(ITfContextOwnerCompositionServices * iface)607 static ULONG WINAPI ContextOwnerCompositionServices_AddRef(ITfContextOwnerCompositionServices *iface)
608 {
609 Context *This = impl_from_ITfContextOwnerCompositionServices(iface);
610 return ITfContext_AddRef(&This->ITfContext_iface);
611 }
612
ContextOwnerCompositionServices_Release(ITfContextOwnerCompositionServices * iface)613 static ULONG WINAPI ContextOwnerCompositionServices_Release(ITfContextOwnerCompositionServices *iface)
614 {
615 Context *This = impl_from_ITfContextOwnerCompositionServices(iface);
616 return ITfContext_Release(&This->ITfContext_iface);
617 }
618
ContextOwnerCompositionServices_StartComposition(ITfContextOwnerCompositionServices * iface,TfEditCookie ecWrite,ITfRange * pCompositionRange,ITfCompositionSink * pSink,ITfComposition ** ppComposition)619 static HRESULT WINAPI ContextOwnerCompositionServices_StartComposition(ITfContextOwnerCompositionServices *iface,
620 TfEditCookie ecWrite, ITfRange *pCompositionRange, ITfCompositionSink *pSink, ITfComposition **ppComposition)
621 {
622 Context *This = impl_from_ITfContextOwnerCompositionServices(iface);
623 FIXME("STUB:(%p) %#x %p %p %p\n", This, ecWrite, pCompositionRange, pSink, ppComposition);
624 return E_NOTIMPL;
625 }
626
ContextOwnerCompositionServices_EnumCompositions(ITfContextOwnerCompositionServices * iface,IEnumITfCompositionView ** ppEnum)627 static HRESULT WINAPI ContextOwnerCompositionServices_EnumCompositions(ITfContextOwnerCompositionServices *iface,
628 IEnumITfCompositionView **ppEnum)
629 {
630 Context *This = impl_from_ITfContextOwnerCompositionServices(iface);
631 FIXME("STUB:(%p) %p\n", This, ppEnum);
632 return E_NOTIMPL;
633 }
634
ContextOwnerCompositionServices_FindComposition(ITfContextOwnerCompositionServices * iface,TfEditCookie ecRead,ITfRange * pTestRange,IEnumITfCompositionView ** ppEnum)635 static HRESULT WINAPI ContextOwnerCompositionServices_FindComposition(ITfContextOwnerCompositionServices *iface,
636 TfEditCookie ecRead, ITfRange *pTestRange, IEnumITfCompositionView **ppEnum)
637 {
638 Context *This = impl_from_ITfContextOwnerCompositionServices(iface);
639 FIXME("STUB:(%p) %#x %p %p\n", This, ecRead, pTestRange, ppEnum);
640 return E_NOTIMPL;
641 }
642
ContextOwnerCompositionServices_TakeOwnership(ITfContextOwnerCompositionServices * iface,TfEditCookie ecWrite,ITfCompositionView * pComposition,ITfCompositionSink * pSink,ITfComposition ** ppComposition)643 static HRESULT WINAPI ContextOwnerCompositionServices_TakeOwnership(ITfContextOwnerCompositionServices *iface,
644 TfEditCookie ecWrite, ITfCompositionView *pComposition, ITfCompositionSink *pSink, ITfComposition **ppComposition)
645 {
646 Context *This = impl_from_ITfContextOwnerCompositionServices(iface);
647 FIXME("STUB:(%p) %#x %p %p %p\n", This, ecWrite, pComposition, pSink, ppComposition);
648 return E_NOTIMPL;
649 }
650
ContextOwnerCompositionServices_TerminateComposition(ITfContextOwnerCompositionServices * iface,ITfCompositionView * pComposition)651 static HRESULT WINAPI ContextOwnerCompositionServices_TerminateComposition(ITfContextOwnerCompositionServices *iface,
652 ITfCompositionView *pComposition)
653 {
654 Context *This = impl_from_ITfContextOwnerCompositionServices(iface);
655 FIXME("STUB:(%p) %p\n", This, pComposition);
656 return E_NOTIMPL;
657 }
658
659 static const ITfContextOwnerCompositionServicesVtbl ContextOwnerCompositionServicesVtbl =
660 {
661 ContextOwnerCompositionServices_QueryInterface,
662 ContextOwnerCompositionServices_AddRef,
663 ContextOwnerCompositionServices_Release,
664 ContextOwnerCompositionServices_StartComposition,
665 ContextOwnerCompositionServices_EnumCompositions,
666 ContextOwnerCompositionServices_FindComposition,
667 ContextOwnerCompositionServices_TakeOwnership,
668 ContextOwnerCompositionServices_TerminateComposition
669 };
670
671 /*****************************************************
672 * ITfInsertAtSelection functions
673 *****************************************************/
InsertAtSelection_QueryInterface(ITfInsertAtSelection * iface,REFIID iid,LPVOID * ppvOut)674 static HRESULT WINAPI InsertAtSelection_QueryInterface(ITfInsertAtSelection *iface, REFIID iid, LPVOID *ppvOut)
675 {
676 Context *This = impl_from_ITfInsertAtSelection(iface);
677 return ITfContext_QueryInterface(&This->ITfContext_iface, iid, ppvOut);
678 }
679
InsertAtSelection_AddRef(ITfInsertAtSelection * iface)680 static ULONG WINAPI InsertAtSelection_AddRef(ITfInsertAtSelection *iface)
681 {
682 Context *This = impl_from_ITfInsertAtSelection(iface);
683 return ITfContext_AddRef(&This->ITfContext_iface);
684 }
685
InsertAtSelection_Release(ITfInsertAtSelection * iface)686 static ULONG WINAPI InsertAtSelection_Release(ITfInsertAtSelection *iface)
687 {
688 Context *This = impl_from_ITfInsertAtSelection(iface);
689 return ITfContext_Release(&This->ITfContext_iface);
690 }
691
InsertAtSelection_InsertTextAtSelection(ITfInsertAtSelection * iface,TfEditCookie ec,DWORD dwFlags,const WCHAR * pchText,LONG cch,ITfRange ** ppRange)692 static HRESULT WINAPI InsertAtSelection_InsertTextAtSelection(
693 ITfInsertAtSelection *iface, TfEditCookie ec, DWORD dwFlags,
694 const WCHAR *pchText, LONG cch, ITfRange **ppRange)
695 {
696 Context *This = impl_from_ITfInsertAtSelection(iface);
697 EditCookie *cookie;
698 LONG acpStart, acpEnd;
699 TS_TEXTCHANGE change;
700 HRESULT hr;
701
702 TRACE("(%p) %i %x %s %p\n",This, ec, dwFlags, debugstr_wn(pchText,cch), ppRange);
703
704 if (!This->connected)
705 return TF_E_DISCONNECTED;
706
707 if (get_Cookie_magic(ec)!=COOKIE_MAGIC_EDITCOOKIE)
708 return TF_E_NOLOCK;
709
710 cookie = get_Cookie_data(ec);
711
712 if ((cookie->lockType & TS_LF_READWRITE) != TS_LF_READWRITE )
713 return TS_E_READONLY;
714
715 if (!This->pITextStoreACP)
716 {
717 FIXME("Context does not have a ITextStoreACP\n");
718 return E_NOTIMPL;
719 }
720
721 hr = ITextStoreACP_InsertTextAtSelection(This->pITextStoreACP, dwFlags, pchText, cch, &acpStart, &acpEnd, &change);
722 if (SUCCEEDED(hr))
723 Range_Constructor(&This->ITfContext_iface, This->pITextStoreACP, cookie->lockType, change.acpStart, change.acpNewEnd, ppRange);
724
725 return hr;
726 }
727
InsertAtSelection_InsertEmbeddedAtSelection(ITfInsertAtSelection * iface,TfEditCookie ec,DWORD dwFlags,IDataObject * pDataObject,ITfRange ** ppRange)728 static HRESULT WINAPI InsertAtSelection_InsertEmbeddedAtSelection(
729 ITfInsertAtSelection *iface, TfEditCookie ec, DWORD dwFlags,
730 IDataObject *pDataObject, ITfRange **ppRange)
731 {
732 Context *This = impl_from_ITfInsertAtSelection(iface);
733 FIXME("STUB:(%p)\n",This);
734 return E_NOTIMPL;
735 }
736
737 static const ITfInsertAtSelectionVtbl InsertAtSelectionVtbl =
738 {
739 InsertAtSelection_QueryInterface,
740 InsertAtSelection_AddRef,
741 InsertAtSelection_Release,
742 InsertAtSelection_InsertTextAtSelection,
743 InsertAtSelection_InsertEmbeddedAtSelection,
744 };
745
746 /*****************************************************
747 * ITfSourceSingle functions
748 *****************************************************/
SourceSingle_QueryInterface(ITfSourceSingle * iface,REFIID iid,LPVOID * ppvOut)749 static HRESULT WINAPI SourceSingle_QueryInterface(ITfSourceSingle *iface, REFIID iid, LPVOID *ppvOut)
750 {
751 Context *This = impl_from_ITfSourceSingle(iface);
752 return ITfContext_QueryInterface(&This->ITfContext_iface, iid, ppvOut);
753 }
754
SourceSingle_AddRef(ITfSourceSingle * iface)755 static ULONG WINAPI SourceSingle_AddRef(ITfSourceSingle *iface)
756 {
757 Context *This = impl_from_ITfSourceSingle(iface);
758 return ITfContext_AddRef(&This->ITfContext_iface);
759 }
760
SourceSingle_Release(ITfSourceSingle * iface)761 static ULONG WINAPI SourceSingle_Release(ITfSourceSingle *iface)
762 {
763 Context *This = impl_from_ITfSourceSingle(iface);
764 return ITfContext_Release(&This->ITfContext_iface);
765 }
766
SourceSingle_AdviseSingleSink(ITfSourceSingle * iface,TfClientId tid,REFIID riid,IUnknown * punk)767 static HRESULT WINAPI SourceSingle_AdviseSingleSink( ITfSourceSingle *iface,
768 TfClientId tid, REFIID riid, IUnknown *punk)
769 {
770 Context *This = impl_from_ITfSourceSingle(iface);
771 FIXME("STUB:(%p) %i %s %p\n",This, tid, debugstr_guid(riid),punk);
772 return E_NOTIMPL;
773 }
774
SourceSingle_UnadviseSingleSink(ITfSourceSingle * iface,TfClientId tid,REFIID riid)775 static HRESULT WINAPI SourceSingle_UnadviseSingleSink( ITfSourceSingle *iface,
776 TfClientId tid, REFIID riid)
777 {
778 Context *This = impl_from_ITfSourceSingle(iface);
779 FIXME("STUB:(%p) %i %s\n",This, tid, debugstr_guid(riid));
780 return E_NOTIMPL;
781 }
782
783 static const ITfSourceSingleVtbl ContextSourceSingleVtbl =
784 {
785 SourceSingle_QueryInterface,
786 SourceSingle_AddRef,
787 SourceSingle_Release,
788 SourceSingle_AdviseSingleSink,
789 SourceSingle_UnadviseSingleSink,
790 };
791
792 /**************************************************************************
793 * ITextStoreACPSink
794 **************************************************************************/
795
TextStoreACPSink_QueryInterface(ITextStoreACPSink * iface,REFIID iid,LPVOID * ppvOut)796 static HRESULT WINAPI TextStoreACPSink_QueryInterface(ITextStoreACPSink *iface, REFIID iid, LPVOID *ppvOut)
797 {
798 Context *This = impl_from_ITextStoreACPSink(iface);
799
800 *ppvOut = NULL;
801
802 if (IsEqualIID(iid, &IID_IUnknown) || IsEqualIID(iid, &IID_ITextStoreACPSink))
803 {
804 *ppvOut = &This->ITextStoreACPSink_iface;
805 }
806 else if (IsEqualIID(iid, &IID_ITextStoreACPServices))
807 *ppvOut = &This->ITextStoreACPServices_iface;
808
809 if (*ppvOut)
810 {
811 ITextStoreACPSink_AddRef(iface);
812 return S_OK;
813 }
814
815 WARN("unsupported interface: %s\n", debugstr_guid(iid));
816 return E_NOINTERFACE;
817 }
818
TextStoreACPSink_AddRef(ITextStoreACPSink * iface)819 static ULONG WINAPI TextStoreACPSink_AddRef(ITextStoreACPSink *iface)
820 {
821 Context *This = impl_from_ITextStoreACPSink(iface);
822 return ITfContext_AddRef(&This->ITfContext_iface);
823 }
824
TextStoreACPSink_Release(ITextStoreACPSink * iface)825 static ULONG WINAPI TextStoreACPSink_Release(ITextStoreACPSink *iface)
826 {
827 Context *This = impl_from_ITextStoreACPSink(iface);
828 return ITfContext_Release(&This->ITfContext_iface);
829 }
830
831 /*****************************************************
832 * ITextStoreACPSink functions
833 *****************************************************/
834
TextStoreACPSink_OnTextChange(ITextStoreACPSink * iface,DWORD dwFlags,const TS_TEXTCHANGE * pChange)835 static HRESULT WINAPI TextStoreACPSink_OnTextChange(ITextStoreACPSink *iface,
836 DWORD dwFlags, const TS_TEXTCHANGE *pChange)
837 {
838 Context *This = impl_from_ITextStoreACPSink(iface);
839 FIXME("STUB:(%p)\n",This);
840 return S_OK;
841 }
842
TextStoreACPSink_OnSelectionChange(ITextStoreACPSink * iface)843 static HRESULT WINAPI TextStoreACPSink_OnSelectionChange(ITextStoreACPSink *iface)
844 {
845 Context *This = impl_from_ITextStoreACPSink(iface);
846 FIXME("STUB:(%p)\n",This);
847 return S_OK;
848 }
849
TextStoreACPSink_OnLayoutChange(ITextStoreACPSink * iface,TsLayoutCode lcode,TsViewCookie vcView)850 static HRESULT WINAPI TextStoreACPSink_OnLayoutChange(ITextStoreACPSink *iface,
851 TsLayoutCode lcode, TsViewCookie vcView)
852 {
853 Context *This = impl_from_ITextStoreACPSink(iface);
854 FIXME("STUB:(%p)\n",This);
855 return S_OK;
856 }
857
TextStoreACPSink_OnStatusChange(ITextStoreACPSink * iface,DWORD dwFlags)858 static HRESULT WINAPI TextStoreACPSink_OnStatusChange(ITextStoreACPSink *iface,
859 DWORD dwFlags)
860 {
861 Context *This = impl_from_ITextStoreACPSink(iface);
862 HRESULT hr, hrSession;
863
864 TRACE("(%p) %x\n",This, dwFlags);
865
866 if (!This->pITextStoreACP)
867 {
868 FIXME("Context does not have a ITextStoreACP\n");
869 return E_NOTIMPL;
870 }
871
872 hr = ITextStoreACP_RequestLock(This->pITextStoreACP, TS_LF_READ, &hrSession);
873
874 if(SUCCEEDED(hr) && SUCCEEDED(hrSession))
875 This->documentStatus.dwDynamicFlags = dwFlags;
876
877 return S_OK;
878 }
879
TextStoreACPSink_OnAttrsChange(ITextStoreACPSink * iface,LONG acpStart,LONG acpEnd,ULONG cAttrs,const TS_ATTRID * paAttrs)880 static HRESULT WINAPI TextStoreACPSink_OnAttrsChange(ITextStoreACPSink *iface,
881 LONG acpStart, LONG acpEnd, ULONG cAttrs, const TS_ATTRID *paAttrs)
882 {
883 Context *This = impl_from_ITextStoreACPSink(iface);
884 FIXME("STUB:(%p)\n",This);
885 return E_NOTIMPL;
886 }
887
TextStoreACPSink_OnLockGranted(ITextStoreACPSink * iface,DWORD dwLockFlags)888 static HRESULT WINAPI TextStoreACPSink_OnLockGranted(ITextStoreACPSink *iface,
889 DWORD dwLockFlags)
890 {
891 Context *This = impl_from_ITextStoreACPSink(iface);
892 HRESULT hr;
893 EditCookie *cookie,*sinkcookie;
894 TfEditCookie ec;
895 struct list *cursor;
896
897 TRACE("(%p) %x\n",This, dwLockFlags);
898
899 if (!This->currentEditSession)
900 {
901 FIXME("OnLockGranted called for something other than an EditSession\n");
902 return S_OK;
903 }
904
905 cookie = HeapAlloc(GetProcessHeap(),0,sizeof(EditCookie));
906 if (!cookie)
907 return E_OUTOFMEMORY;
908
909 sinkcookie = HeapAlloc(GetProcessHeap(),0,sizeof(EditCookie));
910 if (!sinkcookie)
911 {
912 HeapFree(GetProcessHeap(), 0, cookie);
913 return E_OUTOFMEMORY;
914 }
915
916 cookie->lockType = dwLockFlags;
917 cookie->pOwningContext = This;
918 ec = generate_Cookie(COOKIE_MAGIC_EDITCOOKIE, cookie);
919
920 hr = ITfEditSession_DoEditSession(This->currentEditSession, ec);
921
922 if ((dwLockFlags&TS_LF_READWRITE) == TS_LF_READWRITE)
923 {
924 ITfTextEditSink *sink;
925 TfEditCookie sc;
926
927 sinkcookie->lockType = TS_LF_READ;
928 sinkcookie->pOwningContext = This;
929 sc = generate_Cookie(COOKIE_MAGIC_EDITCOOKIE, sinkcookie);
930
931 /*TODO: implement ITfEditRecord */
932 SINK_FOR_EACH(cursor, &This->pTextEditSink, ITfTextEditSink, sink)
933 {
934 ITfTextEditSink_OnEndEdit(sink, &This->ITfContext_iface, sc, NULL);
935 }
936 sinkcookie = remove_Cookie(sc);
937 }
938 HeapFree(GetProcessHeap(),0,sinkcookie);
939
940 ITfEditSession_Release(This->currentEditSession);
941 This->currentEditSession = NULL;
942
943 /* Edit Cookie is only valid during the edit session */
944 cookie = remove_Cookie(ec);
945 HeapFree(GetProcessHeap(),0,cookie);
946
947 return hr;
948 }
949
TextStoreACPSink_OnStartEditTransaction(ITextStoreACPSink * iface)950 static HRESULT WINAPI TextStoreACPSink_OnStartEditTransaction(ITextStoreACPSink *iface)
951 {
952 Context *This = impl_from_ITextStoreACPSink(iface);
953 FIXME("STUB:(%p)\n",This);
954 return E_NOTIMPL;
955 }
956
TextStoreACPSink_OnEndEditTransaction(ITextStoreACPSink * iface)957 static HRESULT WINAPI TextStoreACPSink_OnEndEditTransaction(ITextStoreACPSink *iface)
958 {
959 Context *This = impl_from_ITextStoreACPSink(iface);
960 FIXME("STUB:(%p)\n",This);
961 return E_NOTIMPL;
962 }
963
964 static const ITextStoreACPSinkVtbl TextStoreACPSinkVtbl =
965 {
966 TextStoreACPSink_QueryInterface,
967 TextStoreACPSink_AddRef,
968 TextStoreACPSink_Release,
969 TextStoreACPSink_OnTextChange,
970 TextStoreACPSink_OnSelectionChange,
971 TextStoreACPSink_OnLayoutChange,
972 TextStoreACPSink_OnStatusChange,
973 TextStoreACPSink_OnAttrsChange,
974 TextStoreACPSink_OnLockGranted,
975 TextStoreACPSink_OnStartEditTransaction,
976 TextStoreACPSink_OnEndEditTransaction
977 };
978
TextStoreACPServices_QueryInterface(ITextStoreACPServices * iface,REFIID riid,void ** obj)979 static HRESULT WINAPI TextStoreACPServices_QueryInterface(ITextStoreACPServices *iface, REFIID riid, void **obj)
980 {
981 Context *This = impl_from_ITextStoreACPServices(iface);
982 return ITextStoreACPSink_QueryInterface(&This->ITextStoreACPSink_iface, riid, obj);
983 }
984
TextStoreACPServices_AddRef(ITextStoreACPServices * iface)985 static ULONG WINAPI TextStoreACPServices_AddRef(ITextStoreACPServices *iface)
986 {
987 Context *This = impl_from_ITextStoreACPServices(iface);
988 return ITextStoreACPSink_AddRef(&This->ITextStoreACPSink_iface);
989 }
990
TextStoreACPServices_Release(ITextStoreACPServices * iface)991 static ULONG WINAPI TextStoreACPServices_Release(ITextStoreACPServices *iface)
992 {
993 Context *This = impl_from_ITextStoreACPServices(iface);
994 return ITextStoreACPSink_Release(&This->ITextStoreACPSink_iface);
995 }
996
TextStoreACPServices_Serialize(ITextStoreACPServices * iface,ITfProperty * prop,ITfRange * range,TF_PERSISTENT_PROPERTY_HEADER_ACP * header,IStream * stream)997 static HRESULT WINAPI TextStoreACPServices_Serialize(ITextStoreACPServices *iface, ITfProperty *prop, ITfRange *range,
998 TF_PERSISTENT_PROPERTY_HEADER_ACP *header, IStream *stream)
999 {
1000 Context *This = impl_from_ITextStoreACPServices(iface);
1001
1002 FIXME("stub: %p %p %p %p %p\n", This, prop, range, header, stream);
1003
1004 return E_NOTIMPL;
1005 }
1006
TextStoreACPServices_Unserialize(ITextStoreACPServices * iface,ITfProperty * prop,const TF_PERSISTENT_PROPERTY_HEADER_ACP * header,IStream * stream,ITfPersistentPropertyLoaderACP * loader)1007 static HRESULT WINAPI TextStoreACPServices_Unserialize(ITextStoreACPServices *iface, ITfProperty *prop,
1008 const TF_PERSISTENT_PROPERTY_HEADER_ACP *header, IStream *stream, ITfPersistentPropertyLoaderACP *loader)
1009 {
1010 Context *This = impl_from_ITextStoreACPServices(iface);
1011
1012 FIXME("stub: %p %p %p %p %p\n", This, prop, header, stream, loader);
1013
1014 return E_NOTIMPL;
1015 }
1016
TextStoreACPServices_ForceLoadProperty(ITextStoreACPServices * iface,ITfProperty * prop)1017 static HRESULT WINAPI TextStoreACPServices_ForceLoadProperty(ITextStoreACPServices *iface, ITfProperty *prop)
1018 {
1019 Context *This = impl_from_ITextStoreACPServices(iface);
1020
1021 FIXME("stub: %p %p\n", This, prop);
1022
1023 return E_NOTIMPL;
1024 }
1025
TextStoreACPServices_CreateRange(ITextStoreACPServices * iface,LONG start,LONG end,ITfRangeACP ** range)1026 static HRESULT WINAPI TextStoreACPServices_CreateRange(ITextStoreACPServices *iface,
1027 LONG start, LONG end, ITfRangeACP **range)
1028 {
1029 Context *This = impl_from_ITextStoreACPServices(iface);
1030
1031 FIXME("stub: %p %d %d %p\n", This, start, end, range);
1032
1033 return S_OK;
1034 }
1035
1036 static const ITextStoreACPServicesVtbl TextStoreACPServicesVtbl =
1037 {
1038 TextStoreACPServices_QueryInterface,
1039 TextStoreACPServices_AddRef,
1040 TextStoreACPServices_Release,
1041 TextStoreACPServices_Serialize,
1042 TextStoreACPServices_Unserialize,
1043 TextStoreACPServices_ForceLoadProperty,
1044 TextStoreACPServices_CreateRange
1045 };
1046
Context_Constructor(TfClientId tidOwner,IUnknown * punk,ITfDocumentMgr * mgr,ITfContext ** ppOut,TfEditCookie * pecTextStore)1047 HRESULT Context_Constructor(TfClientId tidOwner, IUnknown *punk, ITfDocumentMgr *mgr, ITfContext **ppOut, TfEditCookie *pecTextStore)
1048 {
1049 Context *This;
1050 EditCookie *cookie;
1051
1052 This = HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,sizeof(Context));
1053 if (This == NULL)
1054 return E_OUTOFMEMORY;
1055
1056 cookie = HeapAlloc(GetProcessHeap(),0,sizeof(EditCookie));
1057 if (cookie == NULL)
1058 {
1059 HeapFree(GetProcessHeap(),0,This);
1060 return E_OUTOFMEMORY;
1061 }
1062
1063 TRACE("(%p) %x %p %p %p\n",This, tidOwner, punk, ppOut, pecTextStore);
1064
1065 This->ITfContext_iface.lpVtbl= &ContextVtbl;
1066 This->ITfSource_iface.lpVtbl = &ContextSourceVtbl;
1067 This->ITfContextOwnerCompositionServices_iface.lpVtbl = &ContextOwnerCompositionServicesVtbl;
1068 This->ITfInsertAtSelection_iface.lpVtbl = &InsertAtSelectionVtbl;
1069 This->ITfSourceSingle_iface.lpVtbl = &ContextSourceSingleVtbl;
1070 This->ITextStoreACPSink_iface.lpVtbl = &TextStoreACPSinkVtbl;
1071 This->ITextStoreACPServices_iface.lpVtbl = &TextStoreACPServicesVtbl;
1072 This->refCount = 1;
1073 This->tidOwner = tidOwner;
1074 This->connected = FALSE;
1075 This->manager = mgr;
1076
1077 CompartmentMgr_Constructor((IUnknown*)&This->ITfContext_iface, &IID_IUnknown, (IUnknown**)&This->CompartmentMgr);
1078
1079 cookie->lockType = TF_ES_READ;
1080 cookie->pOwningContext = This;
1081
1082 if (punk)
1083 {
1084 IUnknown_QueryInterface(punk, &IID_ITextStoreACP,
1085 (LPVOID*)&This->pITextStoreACP);
1086
1087 IUnknown_QueryInterface(punk, &IID_ITfContextOwnerCompositionSink,
1088 (LPVOID*)&This->pITfContextOwnerCompositionSink);
1089
1090 if (!This->pITextStoreACP && !This->pITfContextOwnerCompositionSink)
1091 FIXME("Unhandled pUnk\n");
1092 }
1093
1094 This->defaultCookie = generate_Cookie(COOKIE_MAGIC_EDITCOOKIE,cookie);
1095 *pecTextStore = This->defaultCookie;
1096
1097 list_init(&This->pContextKeyEventSink);
1098 list_init(&This->pEditTransactionSink);
1099 list_init(&This->pStatusSink);
1100 list_init(&This->pTextEditSink);
1101 list_init(&This->pTextLayoutSink);
1102
1103 *ppOut = &This->ITfContext_iface;
1104 TRACE("returning %p\n", *ppOut);
1105
1106 return S_OK;
1107 }
1108
Context_Initialize(ITfContext * iface,ITfDocumentMgr * manager)1109 HRESULT Context_Initialize(ITfContext *iface, ITfDocumentMgr *manager)
1110 {
1111 Context *This = impl_from_ITfContext(iface);
1112
1113 if (This->pITextStoreACP)
1114 ITextStoreACP_AdviseSink(This->pITextStoreACP, &IID_ITextStoreACPSink,
1115 (IUnknown*)&This->ITextStoreACPSink_iface, TS_AS_ALL_SINKS);
1116 This->connected = TRUE;
1117 This->manager = manager;
1118 return S_OK;
1119 }
1120
Context_Uninitialize(ITfContext * iface)1121 HRESULT Context_Uninitialize(ITfContext *iface)
1122 {
1123 Context *This = impl_from_ITfContext(iface);
1124
1125 if (This->pITextStoreACP)
1126 ITextStoreACP_UnadviseSink(This->pITextStoreACP, (IUnknown*)&This->ITextStoreACPSink_iface);
1127 This->connected = FALSE;
1128 This->manager = NULL;
1129 return S_OK;
1130 }
1131