2 * ITfContext implementation
4 * Copyright 2009 Aric Stewart, CodeWeavers
6 * This library is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Lesser General Public
8 * License as published by the Free Software Foundation; either
9 * version 2.1 of the License, or (at your option) any later version.
11 * This library is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Lesser General Public License for more details.
16 * You should have received a copy of the GNU Lesser General Public
17 * License along with this library; if not, write to the Free Software
18 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
27 #include "wine/debug.h"
37 #include "wine/unicode.h"
40 #include "msctf_internal.h"
42 WINE_DEFAULT_DEBUG_CHANNEL(msctf
);
44 typedef struct tagContext
{
45 ITfContext ITfContext_iface
;
46 ITfSource ITfSource_iface
;
47 /* const ITfContextCompositionVtbl *ContextCompositionVtbl; */
48 /* const ITfContextOwnerCompositionServicesVtbl *ContextOwnerCompositionServicesVtbl; */
49 /* const ITfContextOwnerServicesVtbl *ContextOwnerServicesVtbl; */
50 ITfInsertAtSelection ITfInsertAtSelection_iface
;
51 /* const ITfMouseTrackerVtbl *MouseTrackerVtbl; */
52 /* const ITfQueryEmbeddedVtbl *QueryEmbeddedVtbl; */
53 ITfSourceSingle ITfSourceSingle_iface
;
54 ITextStoreACPSink ITextStoreACPSink_iface
;
55 ITextStoreACPServices ITextStoreACPServices_iface
;
60 ITfCompartmentMgr
*CompartmentMgr
;
63 TfEditCookie defaultCookie
;
64 TS_STATUS documentStatus
;
65 ITfDocumentMgr
*manager
;
67 ITextStoreACP
*pITextStoreACP
;
68 ITfContextOwnerCompositionSink
*pITfContextOwnerCompositionSink
;
70 ITfEditSession
* currentEditSession
;
72 /* kept as separate lists to reduce unnecessary iterations */
73 struct list pContextKeyEventSink
;
74 struct list pEditTransactionSink
;
75 struct list pStatusSink
;
76 struct list pTextEditSink
;
77 struct list pTextLayoutSink
;
81 typedef struct tagEditCookie
{
83 Context
*pOwningContext
;
86 static inline Context
*impl_from_ITfContext(ITfContext
*iface
)
88 return CONTAINING_RECORD(iface
, Context
, ITfContext_iface
);
91 static inline Context
*impl_from_ITfSource(ITfSource
*iface
)
93 return CONTAINING_RECORD(iface
, Context
, ITfSource_iface
);
96 static inline Context
*impl_from_ITfInsertAtSelection(ITfInsertAtSelection
*iface
)
98 return CONTAINING_RECORD(iface
, Context
, ITfInsertAtSelection_iface
);
101 static inline Context
*impl_from_ITfSourceSingle(ITfSourceSingle
* iface
)
103 return CONTAINING_RECORD(iface
, Context
, ITfSourceSingle_iface
);
106 static inline Context
*impl_from_ITextStoreACPSink(ITextStoreACPSink
*iface
)
108 return CONTAINING_RECORD(iface
, Context
, ITextStoreACPSink_iface
);
111 static inline Context
*impl_from_ITextStoreACPServices(ITextStoreACPServices
*iface
)
113 return CONTAINING_RECORD(iface
, Context
, ITextStoreACPServices_iface
);
116 static void Context_Destructor(Context
*This
)
119 TRACE("destroying %p\n", This
);
121 if (This
->pITextStoreACP
)
122 ITextStoreACP_Release(This
->pITextStoreACP
);
124 if (This
->pITfContextOwnerCompositionSink
)
125 ITfContextOwnerCompositionSink_Release(This
->pITfContextOwnerCompositionSink
);
127 if (This
->defaultCookie
)
129 cookie
= remove_Cookie(This
->defaultCookie
);
130 HeapFree(GetProcessHeap(),0,cookie
);
131 This
->defaultCookie
= 0;
134 free_sinks(&This
->pContextKeyEventSink
);
135 free_sinks(&This
->pEditTransactionSink
);
136 free_sinks(&This
->pStatusSink
);
137 free_sinks(&This
->pTextEditSink
);
138 free_sinks(&This
->pTextLayoutSink
);
140 CompartmentMgr_Destructor(This
->CompartmentMgr
);
141 HeapFree(GetProcessHeap(),0,This
);
144 static HRESULT WINAPI
Context_QueryInterface(ITfContext
*iface
, REFIID iid
, LPVOID
*ppvOut
)
146 Context
*This
= impl_from_ITfContext(iface
);
149 if (IsEqualIID(iid
, &IID_IUnknown
) || IsEqualIID(iid
, &IID_ITfContext
))
151 *ppvOut
= &This
->ITfContext_iface
;
153 else if (IsEqualIID(iid
, &IID_ITfSource
))
155 *ppvOut
= &This
->ITfSource_iface
;
157 else if (IsEqualIID(iid
, &IID_ITfInsertAtSelection
))
159 *ppvOut
= &This
->ITfInsertAtSelection_iface
;
161 else if (IsEqualIID(iid
, &IID_ITfCompartmentMgr
))
163 *ppvOut
= This
->CompartmentMgr
;
165 else if (IsEqualIID(iid
, &IID_ITfSourceSingle
))
167 *ppvOut
= &This
->ITfSourceSingle_iface
;
172 ITfContext_AddRef(iface
);
176 WARN("unsupported interface: %s\n", debugstr_guid(iid
));
177 return E_NOINTERFACE
;
180 static ULONG WINAPI
Context_AddRef(ITfContext
*iface
)
182 Context
*This
= impl_from_ITfContext(iface
);
183 return InterlockedIncrement(&This
->refCount
);
186 static ULONG WINAPI
Context_Release(ITfContext
*iface
)
188 Context
*This
= impl_from_ITfContext(iface
);
191 ret
= InterlockedDecrement(&This
->refCount
);
193 Context_Destructor(This
);
197 /*****************************************************
198 * ITfContext functions
199 *****************************************************/
200 static HRESULT WINAPI
Context_RequestEditSession (ITfContext
*iface
,
201 TfClientId tid
, ITfEditSession
*pes
, DWORD dwFlags
,
204 Context
*This
= impl_from_ITfContext(iface
);
206 DWORD dwLockFlags
= 0x0;
208 TRACE("(%p) %i %p %x %p\n",This
, tid
, pes
, dwFlags
, phrSession
);
210 if (!(dwFlags
& TF_ES_READ
) && !(dwFlags
& TF_ES_READWRITE
))
212 *phrSession
= E_FAIL
;
216 if (!This
->pITextStoreACP
)
218 FIXME("No ITextStoreACP available\n");
219 *phrSession
= E_FAIL
;
223 if (!(dwFlags
& TF_ES_ASYNC
))
224 dwLockFlags
|= TS_LF_SYNC
;
226 if ((dwFlags
& TF_ES_READWRITE
) == TF_ES_READWRITE
)
227 dwLockFlags
|= TS_LF_READWRITE
;
228 else if (dwFlags
& TF_ES_READ
)
229 dwLockFlags
|= TS_LF_READ
;
231 if (!This
->documentStatus
.dwDynamicFlags
)
232 ITextStoreACP_GetStatus(This
->pITextStoreACP
, &This
->documentStatus
);
234 if (((dwFlags
& TF_ES_READWRITE
) == TF_ES_READWRITE
) && (This
->documentStatus
.dwDynamicFlags
& TS_SD_READONLY
))
236 *phrSession
= TS_E_READONLY
;
240 if (FAILED (ITfEditSession_QueryInterface(pes
, &IID_ITfEditSession
, (LPVOID
*)&This
->currentEditSession
)))
242 *phrSession
= E_FAIL
;
246 hr
= ITextStoreACP_RequestLock(This
->pITextStoreACP
, dwLockFlags
, phrSession
);
251 static HRESULT WINAPI
Context_InWriteSession (ITfContext
*iface
,
253 BOOL
*pfWriteSession
)
255 Context
*This
= impl_from_ITfContext(iface
);
256 FIXME("STUB:(%p)\n",This
);
260 static HRESULT WINAPI
Context_GetSelection (ITfContext
*iface
,
261 TfEditCookie ec
, ULONG ulIndex
, ULONG ulCount
,
262 TF_SELECTION
*pSelection
, ULONG
*pcFetched
)
264 Context
*This
= impl_from_ITfContext(iface
);
267 ULONG totalFetched
= 0;
270 if (!pSelection
|| !pcFetched
)
275 if (!This
->connected
)
276 return TF_E_DISCONNECTED
;
278 if (get_Cookie_magic(ec
)!=COOKIE_MAGIC_EDITCOOKIE
)
281 if (!This
->pITextStoreACP
)
283 FIXME("Context does not have a ITextStoreACP\n");
287 cookie
= get_Cookie_data(ec
);
289 if (ulIndex
== TF_DEFAULT_SELECTION
)
294 for (i
= 0; i
< count
; i
++)
297 TS_SELECTION_ACP acps
;
299 hr
= ITextStoreACP_GetSelection(This
->pITextStoreACP
, ulIndex
+ i
,
302 if (hr
== TS_E_NOLOCK
)
304 else if (SUCCEEDED(hr
))
306 pSelection
[totalFetched
].style
.ase
= acps
.style
.ase
;
307 pSelection
[totalFetched
].style
.fInterimChar
= acps
.style
.fInterimChar
;
308 Range_Constructor(iface
, This
->pITextStoreACP
, cookie
->lockType
, acps
.acpStart
, acps
.acpEnd
, &pSelection
[totalFetched
].range
);
315 *pcFetched
= totalFetched
;
320 static HRESULT WINAPI
Context_SetSelection (ITfContext
*iface
,
321 TfEditCookie ec
, ULONG ulCount
, const TF_SELECTION
*pSelection
)
323 Context
*This
= impl_from_ITfContext(iface
);
324 TS_SELECTION_ACP
*acp
;
328 TRACE("(%p) %i %i %p\n",This
,ec
,ulCount
,pSelection
);
330 if (!This
->pITextStoreACP
)
332 FIXME("Context does not have a ITextStoreACP\n");
336 if (get_Cookie_magic(ec
)!=COOKIE_MAGIC_EDITCOOKIE
)
339 acp
= HeapAlloc(GetProcessHeap(), 0, sizeof(TS_SELECTION_ACP
) * ulCount
);
341 return E_OUTOFMEMORY
;
343 for (i
= 0; i
< ulCount
; i
++)
344 if (FAILED(TF_SELECTION_to_TS_SELECTION_ACP(&pSelection
[i
], &acp
[i
])))
346 TRACE("Selection Conversion Failed\n");
347 HeapFree(GetProcessHeap(), 0 , acp
);
351 hr
= ITextStoreACP_SetSelection(This
->pITextStoreACP
, ulCount
, acp
);
353 HeapFree(GetProcessHeap(), 0, acp
);
358 static HRESULT WINAPI
Context_GetStart (ITfContext
*iface
,
359 TfEditCookie ec
, ITfRange
**ppStart
)
361 Context
*This
= impl_from_ITfContext(iface
);
363 TRACE("(%p) %i %p\n",This
,ec
,ppStart
);
370 if (!This
->connected
)
371 return TF_E_DISCONNECTED
;
373 if (get_Cookie_magic(ec
)!=COOKIE_MAGIC_EDITCOOKIE
)
376 cookie
= get_Cookie_data(ec
);
377 return Range_Constructor(iface
, This
->pITextStoreACP
, cookie
->lockType
, 0, 0, ppStart
);
380 static HRESULT WINAPI
Context_GetEnd (ITfContext
*iface
,
381 TfEditCookie ec
, ITfRange
**ppEnd
)
383 Context
*This
= impl_from_ITfContext(iface
);
386 TRACE("(%p) %i %p\n",This
,ec
,ppEnd
);
393 if (!This
->connected
)
394 return TF_E_DISCONNECTED
;
396 if (get_Cookie_magic(ec
)!=COOKIE_MAGIC_EDITCOOKIE
)
399 if (!This
->pITextStoreACP
)
401 FIXME("Context does not have a ITextStoreACP\n");
405 cookie
= get_Cookie_data(ec
);
406 ITextStoreACP_GetEndACP(This
->pITextStoreACP
,&end
);
408 return Range_Constructor(iface
, This
->pITextStoreACP
, cookie
->lockType
, end
, end
, ppEnd
);
411 static HRESULT WINAPI
Context_GetActiveView (ITfContext
*iface
,
412 ITfContextView
**ppView
)
414 Context
*This
= impl_from_ITfContext(iface
);
415 FIXME("STUB:(%p)\n",This
);
419 static HRESULT WINAPI
Context_EnumViews (ITfContext
*iface
,
420 IEnumTfContextViews
**ppEnum
)
422 Context
*This
= impl_from_ITfContext(iface
);
423 FIXME("STUB:(%p)\n",This
);
427 static HRESULT WINAPI
Context_GetStatus (ITfContext
*iface
,
430 Context
*This
= impl_from_ITfContext(iface
);
431 TRACE("(%p) %p\n",This
,pdcs
);
433 if (!This
->connected
)
434 return TF_E_DISCONNECTED
;
439 if (!This
->pITextStoreACP
)
441 FIXME("Context does not have a ITextStoreACP\n");
445 ITextStoreACP_GetStatus(This
->pITextStoreACP
, &This
->documentStatus
);
447 *pdcs
= This
->documentStatus
;
452 static HRESULT WINAPI
Context_GetProperty (ITfContext
*iface
,
453 REFGUID guidProp
, ITfProperty
**ppProp
)
455 Context
*This
= impl_from_ITfContext(iface
);
456 FIXME("STUB:(%p)\n",This
);
460 static HRESULT WINAPI
Context_GetAppProperty (ITfContext
*iface
,
461 REFGUID guidProp
, ITfReadOnlyProperty
**ppProp
)
463 Context
*This
= impl_from_ITfContext(iface
);
464 FIXME("STUB:(%p)\n",This
);
468 static HRESULT WINAPI
Context_TrackProperties (ITfContext
*iface
,
469 const GUID
**prgProp
, ULONG cProp
, const GUID
**prgAppProp
,
470 ULONG cAppProp
, ITfReadOnlyProperty
**ppProperty
)
472 Context
*This
= impl_from_ITfContext(iface
);
473 FIXME("STUB:(%p)\n",This
);
477 static HRESULT WINAPI
Context_EnumProperties (ITfContext
*iface
,
478 IEnumTfProperties
**ppEnum
)
480 Context
*This
= impl_from_ITfContext(iface
);
481 FIXME("STUB:(%p)\n",This
);
485 static HRESULT WINAPI
Context_GetDocumentMgr (ITfContext
*iface
,
486 ITfDocumentMgr
**ppDm
)
488 Context
*This
= impl_from_ITfContext(iface
);
489 TRACE("(%p) %p\n",This
,ppDm
);
494 *ppDm
= This
->manager
;
498 ITfDocumentMgr_AddRef(This
->manager
);
503 static HRESULT WINAPI
Context_CreateRangeBackup (ITfContext
*iface
,
504 TfEditCookie ec
, ITfRange
*pRange
, ITfRangeBackup
**ppBackup
)
506 Context
*This
= impl_from_ITfContext(iface
);
507 FIXME("STUB:(%p)\n",This
);
511 static const ITfContextVtbl ContextVtbl
=
513 Context_QueryInterface
,
516 Context_RequestEditSession
,
517 Context_InWriteSession
,
518 Context_GetSelection
,
519 Context_SetSelection
,
522 Context_GetActiveView
,
526 Context_GetAppProperty
,
527 Context_TrackProperties
,
528 Context_EnumProperties
,
529 Context_GetDocumentMgr
,
530 Context_CreateRangeBackup
533 static HRESULT WINAPI
ContextSource_QueryInterface(ITfSource
*iface
, REFIID iid
, LPVOID
*ppvOut
)
535 Context
*This
= impl_from_ITfSource(iface
);
536 return ITfContext_QueryInterface(&This
->ITfContext_iface
, iid
, ppvOut
);
539 static ULONG WINAPI
ContextSource_AddRef(ITfSource
*iface
)
541 Context
*This
= impl_from_ITfSource(iface
);
542 return ITfContext_AddRef(&This
->ITfContext_iface
);
545 static ULONG WINAPI
ContextSource_Release(ITfSource
*iface
)
547 Context
*This
= impl_from_ITfSource(iface
);
548 return ITfContext_Release(&This
->ITfContext_iface
);
551 /*****************************************************
552 * ITfSource functions
553 *****************************************************/
554 static HRESULT WINAPI
ContextSource_AdviseSink(ITfSource
*iface
,
555 REFIID riid
, IUnknown
*punk
, DWORD
*pdwCookie
)
557 Context
*This
= impl_from_ITfSource(iface
);
559 TRACE("(%p) %s %p %p\n",This
,debugstr_guid(riid
),punk
,pdwCookie
);
561 if (!riid
|| !punk
|| !pdwCookie
)
564 if (IsEqualIID(riid
, &IID_ITfTextEditSink
))
565 return advise_sink(&This
->pTextEditSink
, &IID_ITfTextEditSink
, COOKIE_MAGIC_CONTEXTSINK
, punk
, pdwCookie
);
567 FIXME("(%p) Unhandled Sink: %s\n",This
,debugstr_guid(riid
));
571 static HRESULT WINAPI
ContextSource_UnadviseSink(ITfSource
*iface
, DWORD pdwCookie
)
573 Context
*This
= impl_from_ITfSource(iface
);
575 TRACE("(%p) %x\n",This
,pdwCookie
);
577 if (get_Cookie_magic(pdwCookie
)!=COOKIE_MAGIC_CONTEXTSINK
)
580 return unadvise_sink(pdwCookie
);
583 static const ITfSourceVtbl ContextSourceVtbl
=
585 ContextSource_QueryInterface
,
586 ContextSource_AddRef
,
587 ContextSource_Release
,
588 ContextSource_AdviseSink
,
589 ContextSource_UnadviseSink
592 /*****************************************************
593 * ITfInsertAtSelection functions
594 *****************************************************/
595 static HRESULT WINAPI
InsertAtSelection_QueryInterface(ITfInsertAtSelection
*iface
, REFIID iid
, LPVOID
*ppvOut
)
597 Context
*This
= impl_from_ITfInsertAtSelection(iface
);
598 return ITfContext_QueryInterface(&This
->ITfContext_iface
, iid
, ppvOut
);
601 static ULONG WINAPI
InsertAtSelection_AddRef(ITfInsertAtSelection
*iface
)
603 Context
*This
= impl_from_ITfInsertAtSelection(iface
);
604 return ITfContext_AddRef(&This
->ITfContext_iface
);
607 static ULONG WINAPI
InsertAtSelection_Release(ITfInsertAtSelection
*iface
)
609 Context
*This
= impl_from_ITfInsertAtSelection(iface
);
610 return ITfContext_Release(&This
->ITfContext_iface
);
613 static HRESULT WINAPI
InsertAtSelection_InsertTextAtSelection(
614 ITfInsertAtSelection
*iface
, TfEditCookie ec
, DWORD dwFlags
,
615 const WCHAR
*pchText
, LONG cch
, ITfRange
**ppRange
)
617 Context
*This
= impl_from_ITfInsertAtSelection(iface
);
619 LONG acpStart
, acpEnd
;
620 TS_TEXTCHANGE change
;
623 TRACE("(%p) %i %x %s %p\n",This
, ec
, dwFlags
, debugstr_wn(pchText
,cch
), ppRange
);
625 if (!This
->connected
)
626 return TF_E_DISCONNECTED
;
628 if (get_Cookie_magic(ec
)!=COOKIE_MAGIC_EDITCOOKIE
)
631 cookie
= get_Cookie_data(ec
);
633 if ((cookie
->lockType
& TS_LF_READWRITE
) != TS_LF_READWRITE
)
634 return TS_E_READONLY
;
636 if (!This
->pITextStoreACP
)
638 FIXME("Context does not have a ITextStoreACP\n");
642 hr
= ITextStoreACP_InsertTextAtSelection(This
->pITextStoreACP
, dwFlags
, pchText
, cch
, &acpStart
, &acpEnd
, &change
);
644 Range_Constructor(&This
->ITfContext_iface
, This
->pITextStoreACP
, cookie
->lockType
, change
.acpStart
, change
.acpNewEnd
, ppRange
);
649 static HRESULT WINAPI
InsertAtSelection_InsertEmbeddedAtSelection(
650 ITfInsertAtSelection
*iface
, TfEditCookie ec
, DWORD dwFlags
,
651 IDataObject
*pDataObject
, ITfRange
**ppRange
)
653 Context
*This
= impl_from_ITfInsertAtSelection(iface
);
654 FIXME("STUB:(%p)\n",This
);
658 static const ITfInsertAtSelectionVtbl InsertAtSelectionVtbl
=
660 InsertAtSelection_QueryInterface
,
661 InsertAtSelection_AddRef
,
662 InsertAtSelection_Release
,
663 InsertAtSelection_InsertTextAtSelection
,
664 InsertAtSelection_InsertEmbeddedAtSelection
,
667 /*****************************************************
668 * ITfSourceSingle functions
669 *****************************************************/
670 static HRESULT WINAPI
SourceSingle_QueryInterface(ITfSourceSingle
*iface
, REFIID iid
, LPVOID
*ppvOut
)
672 Context
*This
= impl_from_ITfSourceSingle(iface
);
673 return ITfContext_QueryInterface(&This
->ITfContext_iface
, iid
, ppvOut
);
676 static ULONG WINAPI
SourceSingle_AddRef(ITfSourceSingle
*iface
)
678 Context
*This
= impl_from_ITfSourceSingle(iface
);
679 return ITfContext_AddRef(&This
->ITfContext_iface
);
682 static ULONG WINAPI
SourceSingle_Release(ITfSourceSingle
*iface
)
684 Context
*This
= impl_from_ITfSourceSingle(iface
);
685 return ITfContext_Release(&This
->ITfContext_iface
);
688 static HRESULT WINAPI
SourceSingle_AdviseSingleSink( ITfSourceSingle
*iface
,
689 TfClientId tid
, REFIID riid
, IUnknown
*punk
)
691 Context
*This
= impl_from_ITfSourceSingle(iface
);
692 FIXME("STUB:(%p) %i %s %p\n",This
, tid
, debugstr_guid(riid
),punk
);
696 static HRESULT WINAPI
SourceSingle_UnadviseSingleSink( ITfSourceSingle
*iface
,
697 TfClientId tid
, REFIID riid
)
699 Context
*This
= impl_from_ITfSourceSingle(iface
);
700 FIXME("STUB:(%p) %i %s\n",This
, tid
, debugstr_guid(riid
));
704 static const ITfSourceSingleVtbl ContextSourceSingleVtbl
=
706 SourceSingle_QueryInterface
,
708 SourceSingle_Release
,
709 SourceSingle_AdviseSingleSink
,
710 SourceSingle_UnadviseSingleSink
,
713 /**************************************************************************
715 **************************************************************************/
717 static HRESULT WINAPI
TextStoreACPSink_QueryInterface(ITextStoreACPSink
*iface
, REFIID iid
, LPVOID
*ppvOut
)
719 Context
*This
= impl_from_ITextStoreACPSink(iface
);
723 if (IsEqualIID(iid
, &IID_IUnknown
) || IsEqualIID(iid
, &IID_ITextStoreACPSink
))
725 *ppvOut
= &This
->ITextStoreACPSink_iface
;
727 else if (IsEqualIID(iid
, &IID_ITextStoreACPServices
))
728 *ppvOut
= &This
->ITextStoreACPServices_iface
;
732 ITextStoreACPSink_AddRef(iface
);
736 WARN("unsupported interface: %s\n", debugstr_guid(iid
));
737 return E_NOINTERFACE
;
740 static ULONG WINAPI
TextStoreACPSink_AddRef(ITextStoreACPSink
*iface
)
742 Context
*This
= impl_from_ITextStoreACPSink(iface
);
743 return ITfContext_AddRef(&This
->ITfContext_iface
);
746 static ULONG WINAPI
TextStoreACPSink_Release(ITextStoreACPSink
*iface
)
748 Context
*This
= impl_from_ITextStoreACPSink(iface
);
749 return ITfContext_Release(&This
->ITfContext_iface
);
752 /*****************************************************
753 * ITextStoreACPSink functions
754 *****************************************************/
756 static HRESULT WINAPI
TextStoreACPSink_OnTextChange(ITextStoreACPSink
*iface
,
757 DWORD dwFlags
, const TS_TEXTCHANGE
*pChange
)
759 Context
*This
= impl_from_ITextStoreACPSink(iface
);
760 FIXME("STUB:(%p)\n",This
);
764 static HRESULT WINAPI
TextStoreACPSink_OnSelectionChange(ITextStoreACPSink
*iface
)
766 Context
*This
= impl_from_ITextStoreACPSink(iface
);
767 FIXME("STUB:(%p)\n",This
);
771 static HRESULT WINAPI
TextStoreACPSink_OnLayoutChange(ITextStoreACPSink
*iface
,
772 TsLayoutCode lcode
, TsViewCookie vcView
)
774 Context
*This
= impl_from_ITextStoreACPSink(iface
);
775 FIXME("STUB:(%p)\n",This
);
779 static HRESULT WINAPI
TextStoreACPSink_OnStatusChange(ITextStoreACPSink
*iface
,
782 Context
*This
= impl_from_ITextStoreACPSink(iface
);
783 HRESULT hr
, hrSession
;
785 TRACE("(%p) %x\n",This
, dwFlags
);
787 if (!This
->pITextStoreACP
)
789 FIXME("Context does not have a ITextStoreACP\n");
793 hr
= ITextStoreACP_RequestLock(This
->pITextStoreACP
, TS_LF_READ
, &hrSession
);
795 if(SUCCEEDED(hr
) && SUCCEEDED(hrSession
))
796 This
->documentStatus
.dwDynamicFlags
= dwFlags
;
801 static HRESULT WINAPI
TextStoreACPSink_OnAttrsChange(ITextStoreACPSink
*iface
,
802 LONG acpStart
, LONG acpEnd
, ULONG cAttrs
, const TS_ATTRID
*paAttrs
)
804 Context
*This
= impl_from_ITextStoreACPSink(iface
);
805 FIXME("STUB:(%p)\n",This
);
809 static HRESULT WINAPI
TextStoreACPSink_OnLockGranted(ITextStoreACPSink
*iface
,
812 Context
*This
= impl_from_ITextStoreACPSink(iface
);
814 EditCookie
*cookie
,*sinkcookie
;
818 TRACE("(%p) %x\n",This
, dwLockFlags
);
820 if (!This
->currentEditSession
)
822 FIXME("OnLockGranted called for something other than an EditSession\n");
826 cookie
= HeapAlloc(GetProcessHeap(),0,sizeof(EditCookie
));
828 return E_OUTOFMEMORY
;
830 sinkcookie
= HeapAlloc(GetProcessHeap(),0,sizeof(EditCookie
));
833 HeapFree(GetProcessHeap(), 0, cookie
);
834 return E_OUTOFMEMORY
;
837 cookie
->lockType
= dwLockFlags
;
838 cookie
->pOwningContext
= This
;
839 ec
= generate_Cookie(COOKIE_MAGIC_EDITCOOKIE
, cookie
);
841 hr
= ITfEditSession_DoEditSession(This
->currentEditSession
, ec
);
843 if ((dwLockFlags
&TS_LF_READWRITE
) == TS_LF_READWRITE
)
845 ITfTextEditSink
*sink
;
848 sinkcookie
->lockType
= TS_LF_READ
;
849 sinkcookie
->pOwningContext
= This
;
850 sc
= generate_Cookie(COOKIE_MAGIC_EDITCOOKIE
, sinkcookie
);
852 /*TODO: implement ITfEditRecord */
853 SINK_FOR_EACH(cursor
, &This
->pTextEditSink
, ITfTextEditSink
, sink
)
855 ITfTextEditSink_OnEndEdit(sink
, (ITfContext
*) &This
->ITfContext_iface
, sc
, NULL
);
857 sinkcookie
= remove_Cookie(sc
);
859 HeapFree(GetProcessHeap(),0,sinkcookie
);
861 ITfEditSession_Release(This
->currentEditSession
);
862 This
->currentEditSession
= NULL
;
864 /* Edit Cookie is only valid during the edit session */
865 cookie
= remove_Cookie(ec
);
866 HeapFree(GetProcessHeap(),0,cookie
);
871 static HRESULT WINAPI
TextStoreACPSink_OnStartEditTransaction(ITextStoreACPSink
*iface
)
873 Context
*This
= impl_from_ITextStoreACPSink(iface
);
874 FIXME("STUB:(%p)\n",This
);
878 static HRESULT WINAPI
TextStoreACPSink_OnEndEditTransaction(ITextStoreACPSink
*iface
)
880 Context
*This
= impl_from_ITextStoreACPSink(iface
);
881 FIXME("STUB:(%p)\n",This
);
885 static const ITextStoreACPSinkVtbl TextStoreACPSinkVtbl
=
887 TextStoreACPSink_QueryInterface
,
888 TextStoreACPSink_AddRef
,
889 TextStoreACPSink_Release
,
890 TextStoreACPSink_OnTextChange
,
891 TextStoreACPSink_OnSelectionChange
,
892 TextStoreACPSink_OnLayoutChange
,
893 TextStoreACPSink_OnStatusChange
,
894 TextStoreACPSink_OnAttrsChange
,
895 TextStoreACPSink_OnLockGranted
,
896 TextStoreACPSink_OnStartEditTransaction
,
897 TextStoreACPSink_OnEndEditTransaction
900 static HRESULT WINAPI
TextStoreACPServices_QueryInterface(ITextStoreACPServices
*iface
, REFIID riid
, void **obj
)
902 Context
*This
= impl_from_ITextStoreACPServices(iface
);
903 return ITextStoreACPSink_QueryInterface(&This
->ITextStoreACPSink_iface
, riid
, obj
);
906 static ULONG WINAPI
TextStoreACPServices_AddRef(ITextStoreACPServices
*iface
)
908 Context
*This
= impl_from_ITextStoreACPServices(iface
);
909 return ITextStoreACPSink_AddRef(&This
->ITextStoreACPSink_iface
);
912 static ULONG WINAPI
TextStoreACPServices_Release(ITextStoreACPServices
*iface
)
914 Context
*This
= impl_from_ITextStoreACPServices(iface
);
915 return ITextStoreACPSink_Release(&This
->ITextStoreACPSink_iface
);
918 static HRESULT WINAPI
TextStoreACPServices_Serialize(ITextStoreACPServices
*iface
, ITfProperty
*prop
, ITfRange
*range
,
919 TF_PERSISTENT_PROPERTY_HEADER_ACP
*header
, IStream
*stream
)
921 Context
*This
= impl_from_ITextStoreACPServices(iface
);
923 FIXME("stub: %p %p %p %p %p\n", This
, prop
, range
, header
, stream
);
928 static HRESULT WINAPI
TextStoreACPServices_Unserialize(ITextStoreACPServices
*iface
, ITfProperty
*prop
,
929 const TF_PERSISTENT_PROPERTY_HEADER_ACP
*header
, IStream
*stream
, ITfPersistentPropertyLoaderACP
*loader
)
931 Context
*This
= impl_from_ITextStoreACPServices(iface
);
933 FIXME("stub: %p %p %p %p %p\n", This
, prop
, header
, stream
, loader
);
938 static HRESULT WINAPI
TextStoreACPServices_ForceLoadProperty(ITextStoreACPServices
*iface
, ITfProperty
*prop
)
940 Context
*This
= impl_from_ITextStoreACPServices(iface
);
942 FIXME("stub: %p %p\n", This
, prop
);
947 static HRESULT WINAPI
TextStoreACPServices_CreateRange(ITextStoreACPServices
*iface
,
948 LONG start
, LONG end
, ITfRangeACP
**range
)
950 Context
*This
= impl_from_ITextStoreACPServices(iface
);
952 FIXME("stub: %p %d %d %p\n", This
, start
, end
, range
);
957 static const ITextStoreACPServicesVtbl TextStoreACPServicesVtbl
=
959 TextStoreACPServices_QueryInterface
,
960 TextStoreACPServices_AddRef
,
961 TextStoreACPServices_Release
,
962 TextStoreACPServices_Serialize
,
963 TextStoreACPServices_Unserialize
,
964 TextStoreACPServices_ForceLoadProperty
,
965 TextStoreACPServices_CreateRange
968 HRESULT
Context_Constructor(TfClientId tidOwner
, IUnknown
*punk
, ITfDocumentMgr
*mgr
, ITfContext
**ppOut
, TfEditCookie
*pecTextStore
)
973 This
= HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY
,sizeof(Context
));
975 return E_OUTOFMEMORY
;
977 cookie
= HeapAlloc(GetProcessHeap(),0,sizeof(EditCookie
));
980 HeapFree(GetProcessHeap(),0,This
);
981 return E_OUTOFMEMORY
;
984 TRACE("(%p) %x %p %p %p\n",This
, tidOwner
, punk
, ppOut
, pecTextStore
);
986 This
->ITfContext_iface
.lpVtbl
= &ContextVtbl
;
987 This
->ITfSource_iface
.lpVtbl
= &ContextSourceVtbl
;
988 This
->ITfInsertAtSelection_iface
.lpVtbl
= &InsertAtSelectionVtbl
;
989 This
->ITfSourceSingle_iface
.lpVtbl
= &ContextSourceSingleVtbl
;
990 This
->ITextStoreACPSink_iface
.lpVtbl
= &TextStoreACPSinkVtbl
;
991 This
->ITextStoreACPServices_iface
.lpVtbl
= &TextStoreACPServicesVtbl
;
993 This
->tidOwner
= tidOwner
;
994 This
->connected
= FALSE
;
997 CompartmentMgr_Constructor((IUnknown
*)&This
->ITfContext_iface
, &IID_IUnknown
, (IUnknown
**)&This
->CompartmentMgr
);
999 cookie
->lockType
= TF_ES_READ
;
1000 cookie
->pOwningContext
= This
;
1004 IUnknown_QueryInterface(punk
, &IID_ITextStoreACP
,
1005 (LPVOID
*)&This
->pITextStoreACP
);
1007 IUnknown_QueryInterface(punk
, &IID_ITfContextOwnerCompositionSink
,
1008 (LPVOID
*)&This
->pITfContextOwnerCompositionSink
);
1010 if (!This
->pITextStoreACP
&& !This
->pITfContextOwnerCompositionSink
)
1011 FIXME("Unhandled pUnk\n");
1014 This
->defaultCookie
= generate_Cookie(COOKIE_MAGIC_EDITCOOKIE
,cookie
);
1015 *pecTextStore
= This
->defaultCookie
;
1017 list_init(&This
->pContextKeyEventSink
);
1018 list_init(&This
->pEditTransactionSink
);
1019 list_init(&This
->pStatusSink
);
1020 list_init(&This
->pTextEditSink
);
1021 list_init(&This
->pTextLayoutSink
);
1023 *ppOut
= &This
->ITfContext_iface
;
1024 TRACE("returning %p\n", *ppOut
);
1029 HRESULT
Context_Initialize(ITfContext
*iface
, ITfDocumentMgr
*manager
)
1031 Context
*This
= impl_from_ITfContext(iface
);
1033 if (This
->pITextStoreACP
)
1034 ITextStoreACP_AdviseSink(This
->pITextStoreACP
, &IID_ITextStoreACPSink
,
1035 (IUnknown
*)&This
->ITextStoreACPSink_iface
, TS_AS_ALL_SINKS
);
1036 This
->connected
= TRUE
;
1037 This
->manager
= manager
;
1041 HRESULT
Context_Uninitialize(ITfContext
*iface
)
1043 Context
*This
= impl_from_ITfContext(iface
);
1045 if (This
->pITextStoreACP
)
1046 ITextStoreACP_UnadviseSink(This
->pITextStoreACP
, (IUnknown
*)&This
->ITextStoreACPSink_iface
);
1047 This
->connected
= FALSE
;
1048 This
->manager
= NULL
;