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"
38 #include "wine/list.h"
41 #include "msctf_internal.h"
43 WINE_DEFAULT_DEBUG_CHANNEL(msctf
);
45 typedef struct tagContextSink
{
50 /* ITfContextKeyEventSink *pITfContextKeyEventSink; */
51 /* ITfEditTransactionSink *pITfEditTransactionSink; */
52 /* ITfStatusSink *pITfStatusSink; */
53 ITfTextEditSink
*pITfTextEditSink
;
54 /* ITfTextLayoutSink *pITfTextLayoutSink; */
58 typedef struct tagContext
{
59 const ITfContextVtbl
*ContextVtbl
;
60 const ITfSourceVtbl
*SourceVtbl
;
61 /* const ITfContextCompositionVtbl *ContextCompositionVtbl; */
62 /* const ITfContextOwnerCompositionServicesVtbl *ContextOwnerCompositionServicesVtbl; */
63 /* const ITfContextOwnerServicesVtbl *ContextOwnerServicesVtbl; */
64 const ITfInsertAtSelectionVtbl
*InsertAtSelectionVtbl
;
65 /* const ITfMouseTrackerVtbl *MouseTrackerVtbl; */
66 /* const ITfQueryEmbeddedVtbl *QueryEmbeddedVtbl; */
67 /* const ITfSourceSingleVtbl *SourceSingleVtbl; */
72 TfEditCookie defaultCookie
;
73 TS_STATUS documentStatus
;
75 ITextStoreACP
*pITextStoreACP
;
76 ITfContextOwnerCompositionSink
*pITfContextOwnerCompositionSink
;
78 ITextStoreACPSink
*pITextStoreACPSink
;
79 ITfEditSession
* currentEditSession
;
81 /* kept as separate lists to reduce unnecessary iterations */
82 struct list pContextKeyEventSink
;
83 struct list pEditTransactionSink
;
84 struct list pStatusSink
;
85 struct list pTextEditSink
;
86 struct list pTextLayoutSink
;
90 typedef struct tagEditCookie
{
92 Context
*pOwningContext
;
95 typedef struct tagTextStoreACPSink
{
96 const ITextStoreACPSinkVtbl
*TextStoreACPSinkVtbl
;
97 /* const ITextStoreACPServicesVtbl *TextStoreACPServicesVtbl; */
104 static HRESULT
TextStoreACPSink_Constructor(ITextStoreACPSink
**ppOut
, Context
*pContext
);
106 static inline Context
*impl_from_ITfSourceVtbl(ITfSource
*iface
)
108 return (Context
*)((char *)iface
- FIELD_OFFSET(Context
,SourceVtbl
));
111 static inline Context
*impl_from_ITfInsertAtSelectionVtbl(ITfInsertAtSelection
*iface
)
113 return (Context
*)((char *)iface
- FIELD_OFFSET(Context
,InsertAtSelectionVtbl
));
116 static void free_sink(ContextSink
*sink
)
118 IUnknown_Release(sink
->interfaces
.pIUnknown
);
119 HeapFree(GetProcessHeap(),0,sink
);
122 static void Context_Destructor(Context
*This
)
124 struct list
*cursor
, *cursor2
;
126 TRACE("destroying %p\n", This
);
128 if (This
->pITextStoreACPSink
)
130 ITextStoreACP_UnadviseSink(This
->pITextStoreACP
, (IUnknown
*)This
->pITextStoreACPSink
);
131 ITextStoreACPSink_Release(This
->pITextStoreACPSink
);
134 if (This
->pITextStoreACP
)
135 ITextStoreACPSink_Release(This
->pITextStoreACP
);
137 if (This
->pITfContextOwnerCompositionSink
)
138 ITextStoreACPSink_Release(This
->pITfContextOwnerCompositionSink
);
140 if (This
->defaultCookie
)
142 cookie
= remove_Cookie(This
->defaultCookie
);
143 HeapFree(GetProcessHeap(),0,cookie
);
144 This
->defaultCookie
= 0;
147 LIST_FOR_EACH_SAFE(cursor
, cursor2
, &This
->pContextKeyEventSink
)
149 ContextSink
* sink
= LIST_ENTRY(cursor
,ContextSink
,entry
);
153 LIST_FOR_EACH_SAFE(cursor
, cursor2
, &This
->pEditTransactionSink
)
155 ContextSink
* sink
= LIST_ENTRY(cursor
,ContextSink
,entry
);
159 LIST_FOR_EACH_SAFE(cursor
, cursor2
, &This
->pStatusSink
)
161 ContextSink
* sink
= LIST_ENTRY(cursor
,ContextSink
,entry
);
165 LIST_FOR_EACH_SAFE(cursor
, cursor2
, &This
->pTextEditSink
)
167 ContextSink
* sink
= LIST_ENTRY(cursor
,ContextSink
,entry
);
171 LIST_FOR_EACH_SAFE(cursor
, cursor2
, &This
->pTextLayoutSink
)
173 ContextSink
* sink
= LIST_ENTRY(cursor
,ContextSink
,entry
);
178 HeapFree(GetProcessHeap(),0,This
);
181 static HRESULT WINAPI
Context_QueryInterface(ITfContext
*iface
, REFIID iid
, LPVOID
*ppvOut
)
183 Context
*This
= (Context
*)iface
;
186 if (IsEqualIID(iid
, &IID_IUnknown
) || IsEqualIID(iid
, &IID_ITfContext
))
190 else if (IsEqualIID(iid
, &IID_ITfSource
))
192 *ppvOut
= &This
->SourceVtbl
;
194 else if (IsEqualIID(iid
, &IID_ITfInsertAtSelection
))
196 *ppvOut
= &This
->InsertAtSelectionVtbl
;
201 IUnknown_AddRef(iface
);
205 WARN("unsupported interface: %s\n", debugstr_guid(iid
));
206 return E_NOINTERFACE
;
209 static ULONG WINAPI
Context_AddRef(ITfContext
*iface
)
211 Context
*This
= (Context
*)iface
;
212 return InterlockedIncrement(&This
->refCount
);
215 static ULONG WINAPI
Context_Release(ITfContext
*iface
)
217 Context
*This
= (Context
*)iface
;
220 ret
= InterlockedDecrement(&This
->refCount
);
222 Context_Destructor(This
);
226 /*****************************************************
227 * ITfContext functions
228 *****************************************************/
229 static HRESULT WINAPI
Context_RequestEditSession (ITfContext
*iface
,
230 TfClientId tid
, ITfEditSession
*pes
, DWORD dwFlags
,
234 Context
*This
= (Context
*)iface
;
235 DWORD dwLockFlags
= 0x0;
237 TRACE("(%p) %i %p %x %p\n",This
, tid
, pes
, dwFlags
, phrSession
);
239 if (!(dwFlags
& TF_ES_READ
) && !(dwFlags
& TF_ES_READWRITE
))
241 *phrSession
= E_FAIL
;
245 if (!This
->pITextStoreACP
)
247 FIXME("No ITextStoreACP avaliable\n");
248 *phrSession
= E_FAIL
;
252 if (!(dwFlags
& TF_ES_ASYNC
))
253 dwLockFlags
|= TS_LF_SYNC
;
255 if ((dwFlags
& TF_ES_READWRITE
) == TF_ES_READWRITE
)
256 dwLockFlags
|= TS_LF_READWRITE
;
257 else if (dwFlags
& TF_ES_READ
)
258 dwLockFlags
|= TS_LF_READ
;
260 if (!This
->documentStatus
.dwDynamicFlags
)
261 ITextStoreACP_GetStatus(This
->pITextStoreACP
, &This
->documentStatus
);
263 if (((dwFlags
& TF_ES_READWRITE
) == TF_ES_READWRITE
) && (This
->documentStatus
.dwDynamicFlags
& TS_SD_READONLY
))
265 *phrSession
= TS_E_READONLY
;
269 if (FAILED (ITfEditSession_QueryInterface(pes
, &IID_ITfEditSession
, (LPVOID
*)&This
->currentEditSession
)))
271 *phrSession
= E_FAIL
;
275 hr
= ITextStoreACP_RequestLock(This
->pITextStoreACP
, dwLockFlags
, phrSession
);
280 static HRESULT WINAPI
Context_InWriteSession (ITfContext
*iface
,
282 BOOL
*pfWriteSession
)
284 Context
*This
= (Context
*)iface
;
285 FIXME("STUB:(%p)\n",This
);
289 static HRESULT WINAPI
Context_GetSelection (ITfContext
*iface
,
290 TfEditCookie ec
, ULONG ulIndex
, ULONG ulCount
,
291 TF_SELECTION
*pSelection
, ULONG
*pcFetched
)
293 Context
*This
= (Context
*)iface
;
296 ULONG totalFetched
= 0;
299 if (!pSelection
|| !pcFetched
)
304 if (!This
->connected
)
305 return TF_E_DISCONNECTED
;
307 if (get_Cookie_magic(ec
)!=COOKIE_MAGIC_EDITCOOKIE
)
310 if (!This
->pITextStoreACP
)
312 FIXME("Context does not have a ITextStoreACP\n");
316 cookie
= get_Cookie_data(ec
);
318 if (ulIndex
== TF_DEFAULT_SELECTION
)
323 for (i
= 0; i
< count
; i
++)
326 TS_SELECTION_ACP acps
;
328 hr
= ITextStoreACP_GetSelection(This
->pITextStoreACP
, ulIndex
+ i
,
331 if (hr
== TS_E_NOLOCK
)
333 else if (SUCCEEDED(hr
))
335 pSelection
[totalFetched
].style
.ase
= acps
.style
.ase
;
336 pSelection
[totalFetched
].style
.fInterimChar
= acps
.style
.fInterimChar
;
337 Range_Constructor(iface
, This
->pITextStoreACP
, cookie
->lockType
, acps
.acpStart
, acps
.acpEnd
, &pSelection
[totalFetched
].range
);
344 *pcFetched
= totalFetched
;
349 static HRESULT WINAPI
Context_SetSelection (ITfContext
*iface
,
350 TfEditCookie ec
, ULONG ulCount
, const TF_SELECTION
*pSelection
)
352 Context
*This
= (Context
*)iface
;
353 FIXME("STUB:(%p)\n",This
);
357 static HRESULT WINAPI
Context_GetStart (ITfContext
*iface
,
358 TfEditCookie ec
, ITfRange
**ppStart
)
360 Context
*This
= (Context
*)iface
;
362 TRACE("(%p) %i %p\n",This
,ec
,ppStart
);
369 if (!This
->connected
)
370 return TF_E_DISCONNECTED
;
372 if (get_Cookie_magic(ec
)!=COOKIE_MAGIC_EDITCOOKIE
)
375 cookie
= get_Cookie_data(ec
);
376 return Range_Constructor(iface
, This
->pITextStoreACP
, cookie
->lockType
, 0, 0, ppStart
);
379 static HRESULT WINAPI
Context_GetEnd (ITfContext
*iface
,
380 TfEditCookie ec
, ITfRange
**ppEnd
)
382 Context
*This
= (Context
*)iface
;
385 TRACE("(%p) %i %p\n",This
,ec
,ppEnd
);
392 if (!This
->connected
)
393 return TF_E_DISCONNECTED
;
395 if (get_Cookie_magic(ec
)!=COOKIE_MAGIC_EDITCOOKIE
)
398 if (!This
->pITextStoreACP
)
400 FIXME("Context does not have a ITextStoreACP\n");
404 cookie
= get_Cookie_data(ec
);
405 ITextStoreACP_GetEndACP(This
->pITextStoreACP
,&end
);
407 return Range_Constructor(iface
, This
->pITextStoreACP
, cookie
->lockType
, end
, end
, ppEnd
);
410 static HRESULT WINAPI
Context_GetActiveView (ITfContext
*iface
,
411 ITfContextView
**ppView
)
413 Context
*This
= (Context
*)iface
;
414 FIXME("STUB:(%p)\n",This
);
418 static HRESULT WINAPI
Context_EnumViews (ITfContext
*iface
,
419 IEnumTfContextViews
**ppEnum
)
421 Context
*This
= (Context
*)iface
;
422 FIXME("STUB:(%p)\n",This
);
426 static HRESULT WINAPI
Context_GetStatus (ITfContext
*iface
,
429 Context
*This
= (Context
*)iface
;
430 FIXME("STUB:(%p)\n",This
);
434 static HRESULT WINAPI
Context_GetProperty (ITfContext
*iface
,
435 REFGUID guidProp
, ITfProperty
**ppProp
)
437 Context
*This
= (Context
*)iface
;
438 FIXME("STUB:(%p)\n",This
);
442 static HRESULT WINAPI
Context_GetAppProperty (ITfContext
*iface
,
443 REFGUID guidProp
, ITfReadOnlyProperty
**ppProp
)
445 Context
*This
= (Context
*)iface
;
446 FIXME("STUB:(%p)\n",This
);
450 static HRESULT WINAPI
Context_TrackProperties (ITfContext
*iface
,
451 const GUID
**prgProp
, ULONG cProp
, const GUID
**prgAppProp
,
452 ULONG cAppProp
, ITfReadOnlyProperty
**ppProperty
)
454 Context
*This
= (Context
*)iface
;
455 FIXME("STUB:(%p)\n",This
);
459 static HRESULT WINAPI
Context_EnumProperties (ITfContext
*iface
,
460 IEnumTfProperties
**ppEnum
)
462 Context
*This
= (Context
*)iface
;
463 FIXME("STUB:(%p)\n",This
);
467 static HRESULT WINAPI
Context_GetDocumentMgr (ITfContext
*iface
,
468 ITfDocumentMgr
**ppDm
)
470 Context
*This
= (Context
*)iface
;
471 FIXME("STUB:(%p)\n",This
);
475 static HRESULT WINAPI
Context_CreateRangeBackup (ITfContext
*iface
,
476 TfEditCookie ec
, ITfRange
*pRange
, ITfRangeBackup
**ppBackup
)
478 Context
*This
= (Context
*)iface
;
479 FIXME("STUB:(%p)\n",This
);
483 static const ITfContextVtbl Context_ContextVtbl
=
485 Context_QueryInterface
,
489 Context_RequestEditSession
,
490 Context_InWriteSession
,
491 Context_GetSelection
,
492 Context_SetSelection
,
495 Context_GetActiveView
,
499 Context_GetAppProperty
,
500 Context_TrackProperties
,
501 Context_EnumProperties
,
502 Context_GetDocumentMgr
,
503 Context_CreateRangeBackup
506 static HRESULT WINAPI
Source_QueryInterface(ITfSource
*iface
, REFIID iid
, LPVOID
*ppvOut
)
508 Context
*This
= impl_from_ITfSourceVtbl(iface
);
509 return Context_QueryInterface((ITfContext
*)This
, iid
, *ppvOut
);
512 static ULONG WINAPI
Source_AddRef(ITfSource
*iface
)
514 Context
*This
= impl_from_ITfSourceVtbl(iface
);
515 return Context_AddRef((ITfContext
*)This
);
518 static ULONG WINAPI
Source_Release(ITfSource
*iface
)
520 Context
*This
= impl_from_ITfSourceVtbl(iface
);
521 return Context_Release((ITfContext
*)This
);
524 /*****************************************************
525 * ITfSource functions
526 *****************************************************/
527 static WINAPI HRESULT
ContextSource_AdviseSink(ITfSource
*iface
,
528 REFIID riid
, IUnknown
*punk
, DWORD
*pdwCookie
)
531 Context
*This
= impl_from_ITfSourceVtbl(iface
);
532 TRACE("(%p) %s %p %p\n",This
,debugstr_guid(riid
),punk
,pdwCookie
);
534 if (!riid
|| !punk
|| !pdwCookie
)
537 if (IsEqualIID(riid
, &IID_ITfTextEditSink
))
539 es
= HeapAlloc(GetProcessHeap(),0,sizeof(ContextSink
));
541 return E_OUTOFMEMORY
;
542 if (FAILED(IUnknown_QueryInterface(punk
, riid
, (LPVOID
*)&es
->interfaces
.pITfTextEditSink
)))
544 HeapFree(GetProcessHeap(),0,es
);
545 return CONNECT_E_CANNOTCONNECT
;
547 list_add_head(&This
->pTextEditSink
,&es
->entry
);
548 *pdwCookie
= generate_Cookie(COOKIE_MAGIC_CONTEXTSINK
, es
);
552 FIXME("(%p) Unhandled Sink: %s\n",This
,debugstr_guid(riid
));
556 TRACE("cookie %x\n",*pdwCookie
);
560 static WINAPI HRESULT
ContextSource_UnadviseSink(ITfSource
*iface
, DWORD pdwCookie
)
563 Context
*This
= impl_from_ITfSourceVtbl(iface
);
565 TRACE("(%p) %x\n",This
,pdwCookie
);
567 if (get_Cookie_magic(pdwCookie
)!=COOKIE_MAGIC_CONTEXTSINK
)
570 sink
= (ContextSink
*)remove_Cookie(pdwCookie
);
572 return CONNECT_E_NOCONNECTION
;
574 list_remove(&sink
->entry
);
580 static const ITfSourceVtbl Context_SourceVtbl
=
582 Source_QueryInterface
,
586 ContextSource_AdviseSink
,
587 ContextSource_UnadviseSink
,
590 /*****************************************************
591 * ITfInsertAtSelection functions
592 *****************************************************/
593 static HRESULT WINAPI
InsertAtSelection_QueryInterface(ITfInsertAtSelection
*iface
, REFIID iid
, LPVOID
*ppvOut
)
595 Context
*This
= impl_from_ITfInsertAtSelectionVtbl(iface
);
596 return Context_QueryInterface((ITfContext
*)This
, iid
, *ppvOut
);
599 static ULONG WINAPI
InsertAtSelection_AddRef(ITfInsertAtSelection
*iface
)
601 Context
*This
= impl_from_ITfInsertAtSelectionVtbl(iface
);
602 return Context_AddRef((ITfContext
*)This
);
605 static ULONG WINAPI
InsertAtSelection_Release(ITfInsertAtSelection
*iface
)
607 Context
*This
= impl_from_ITfInsertAtSelectionVtbl(iface
);
608 return Context_Release((ITfContext
*)This
);
611 static WINAPI HRESULT
InsertAtSelection_InsertTextAtSelection(
612 ITfInsertAtSelection
*iface
, TfEditCookie ec
, DWORD dwFlags
,
613 const WCHAR
*pchText
, LONG cch
, ITfRange
**ppRange
)
615 Context
*This
= impl_from_ITfInsertAtSelectionVtbl(iface
);
616 FIXME("STUB:(%p)\n",This
);
620 static WINAPI HRESULT
InsertAtSelection_InsertEmbeddedAtSelection(
621 ITfInsertAtSelection
*iface
, TfEditCookie ec
, DWORD dwFlags
,
622 IDataObject
*pDataObject
, ITfRange
**ppRange
)
624 Context
*This
= impl_from_ITfInsertAtSelectionVtbl(iface
);
625 FIXME("STUB:(%p)\n",This
);
629 static const ITfInsertAtSelectionVtbl Context_InsertAtSelectionVtbl
=
631 InsertAtSelection_QueryInterface
,
632 InsertAtSelection_AddRef
,
633 InsertAtSelection_Release
,
635 InsertAtSelection_InsertTextAtSelection
,
636 InsertAtSelection_InsertEmbeddedAtSelection
,
639 HRESULT
Context_Constructor(TfClientId tidOwner
, IUnknown
*punk
, ITfContext
**ppOut
, TfEditCookie
*pecTextStore
)
644 This
= HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY
,sizeof(Context
));
646 return E_OUTOFMEMORY
;
648 cookie
= HeapAlloc(GetProcessHeap(),0,sizeof(EditCookie
));
651 HeapFree(GetProcessHeap(),0,This
);
652 return E_OUTOFMEMORY
;
655 TRACE("(%p) %x %p %p %p\n",This
, tidOwner
, punk
, ppOut
, pecTextStore
);
657 This
->ContextVtbl
= &Context_ContextVtbl
;
658 This
->SourceVtbl
= &Context_SourceVtbl
;
659 This
->InsertAtSelectionVtbl
= &Context_InsertAtSelectionVtbl
;
661 This
->tidOwner
= tidOwner
;
662 This
->connected
= FALSE
;
664 cookie
->lockType
= TF_ES_READ
;
665 cookie
->pOwningContext
= This
;
669 IUnknown_QueryInterface(punk
, &IID_ITextStoreACP
,
670 (LPVOID
*)&This
->pITextStoreACP
);
672 IUnknown_QueryInterface(punk
, &IID_ITfContextOwnerCompositionSink
,
673 (LPVOID
*)&This
->pITfContextOwnerCompositionSink
);
675 if (!This
->pITextStoreACP
&& !This
->pITfContextOwnerCompositionSink
)
676 FIXME("Unhandled pUnk\n");
679 This
->defaultCookie
= generate_Cookie(COOKIE_MAGIC_EDITCOOKIE
,cookie
);
680 *pecTextStore
= This
->defaultCookie
;
682 list_init(&This
->pContextKeyEventSink
);
683 list_init(&This
->pEditTransactionSink
);
684 list_init(&This
->pStatusSink
);
685 list_init(&This
->pTextEditSink
);
686 list_init(&This
->pTextLayoutSink
);
688 *ppOut
= (ITfContext
*)This
;
689 TRACE("returning %p\n", This
);
694 HRESULT
Context_Initialize(ITfContext
*iface
)
696 Context
*This
= (Context
*)iface
;
698 if (This
->pITextStoreACP
)
700 if (SUCCEEDED(TextStoreACPSink_Constructor(&This
->pITextStoreACPSink
, This
)))
701 ITextStoreACP_AdviseSink(This
->pITextStoreACP
, &IID_ITextStoreACPSink
,
702 (IUnknown
*)This
->pITextStoreACPSink
, TS_AS_ALL_SINKS
);
704 This
->connected
= TRUE
;
708 HRESULT
Context_Uninitialize(ITfContext
*iface
)
710 Context
*This
= (Context
*)iface
;
712 if (This
->pITextStoreACPSink
)
714 ITextStoreACP_UnadviseSink(This
->pITextStoreACP
, (IUnknown
*)This
->pITextStoreACPSink
);
715 if (ITextStoreACPSink_Release(This
->pITextStoreACPSink
) == 0)
716 This
->pITextStoreACPSink
= NULL
;
718 This
->connected
= FALSE
;
722 /**************************************************************************
724 **************************************************************************/
726 static void TextStoreACPSink_Destructor(TextStoreACPSink
*This
)
728 TRACE("destroying %p\n", This
);
729 HeapFree(GetProcessHeap(),0,This
);
732 static HRESULT WINAPI
TextStoreACPSink_QueryInterface(ITextStoreACPSink
*iface
, REFIID iid
, LPVOID
*ppvOut
)
734 TextStoreACPSink
*This
= (TextStoreACPSink
*)iface
;
737 if (IsEqualIID(iid
, &IID_IUnknown
) || IsEqualIID(iid
, &IID_ITextStoreACPSink
))
744 IUnknown_AddRef(iface
);
748 WARN("unsupported interface: %s\n", debugstr_guid(iid
));
749 return E_NOINTERFACE
;
752 static ULONG WINAPI
TextStoreACPSink_AddRef(ITextStoreACPSink
*iface
)
754 TextStoreACPSink
*This
= (TextStoreACPSink
*)iface
;
755 return InterlockedIncrement(&This
->refCount
);
758 static ULONG WINAPI
TextStoreACPSink_Release(ITextStoreACPSink
*iface
)
760 TextStoreACPSink
*This
= (TextStoreACPSink
*)iface
;
763 ret
= InterlockedDecrement(&This
->refCount
);
765 TextStoreACPSink_Destructor(This
);
769 /*****************************************************
770 * ITextStoreACPSink functions
771 *****************************************************/
773 static HRESULT WINAPI
TextStoreACPSink_OnTextChange(ITextStoreACPSink
*iface
,
774 DWORD dwFlags
, const TS_TEXTCHANGE
*pChange
)
776 TextStoreACPSink
*This
= (TextStoreACPSink
*)iface
;
777 FIXME("STUB:(%p)\n",This
);
781 static HRESULT WINAPI
TextStoreACPSink_OnSelectionChange(ITextStoreACPSink
*iface
)
783 TextStoreACPSink
*This
= (TextStoreACPSink
*)iface
;
784 FIXME("STUB:(%p)\n",This
);
788 static HRESULT WINAPI
TextStoreACPSink_OnLayoutChange(ITextStoreACPSink
*iface
,
789 TsLayoutCode lcode
, TsViewCookie vcView
)
791 TextStoreACPSink
*This
= (TextStoreACPSink
*)iface
;
792 FIXME("STUB:(%p)\n",This
);
796 static HRESULT WINAPI
TextStoreACPSink_OnStatusChange(ITextStoreACPSink
*iface
,
799 TextStoreACPSink
*This
= (TextStoreACPSink
*)iface
;
800 HRESULT hr
, hrSession
;
802 TRACE("(%p) %x\n",This
, dwFlags
);
806 ERR("No context?\n");
810 if (!This
->pContext
->pITextStoreACP
)
812 FIXME("Context does not have a ITextStoreACP\n");
816 hr
= ITextStoreACP_RequestLock(This
->pContext
->pITextStoreACP
, TS_LF_READ
, &hrSession
);
818 if(SUCCEEDED(hr
) && SUCCEEDED(hrSession
))
819 This
->pContext
->documentStatus
.dwDynamicFlags
= dwFlags
;
824 static HRESULT WINAPI
TextStoreACPSink_OnAttrsChange(ITextStoreACPSink
*iface
,
825 LONG acpStart
, LONG acpEnd
, ULONG cAttrs
, const TS_ATTRID
*paAttrs
)
827 TextStoreACPSink
*This
= (TextStoreACPSink
*)iface
;
828 FIXME("STUB:(%p)\n",This
);
832 static HRESULT WINAPI
TextStoreACPSink_OnLockGranted(ITextStoreACPSink
*iface
,
835 TextStoreACPSink
*This
= (TextStoreACPSink
*)iface
;
840 TRACE("(%p) %x\n",This
, dwLockFlags
);
844 ERR("OnLockGranted called without a context\n");
848 if (!This
->pContext
->currentEditSession
)
850 FIXME("OnLockGranted called for something other than an EditSession\n");
854 cookie
= HeapAlloc(GetProcessHeap(),0,sizeof(EditCookie
));
856 return E_OUTOFMEMORY
;
858 cookie
->lockType
= dwLockFlags
;
859 cookie
->pOwningContext
= This
->pContext
;
860 ec
= generate_Cookie(COOKIE_MAGIC_EDITCOOKIE
, cookie
);
862 hr
= ITfEditSession_DoEditSession(This
->pContext
->currentEditSession
, ec
);
864 ITfEditSession_Release(This
->pContext
->currentEditSession
);
865 This
->pContext
->currentEditSession
= NULL
;
867 /* Edit Cookie is only valid during the edit session */
868 cookie
= remove_Cookie(ec
);
869 HeapFree(GetProcessHeap(),0,cookie
);
874 static HRESULT WINAPI
TextStoreACPSink_OnStartEditTransaction(ITextStoreACPSink
*iface
)
876 TextStoreACPSink
*This
= (TextStoreACPSink
*)iface
;
877 FIXME("STUB:(%p)\n",This
);
881 static HRESULT WINAPI
TextStoreACPSink_OnEndEditTransaction(ITextStoreACPSink
*iface
)
883 TextStoreACPSink
*This
= (TextStoreACPSink
*)iface
;
884 FIXME("STUB:(%p)\n",This
);
888 static const ITextStoreACPSinkVtbl TextStoreACPSink_TextStoreACPSinkVtbl
=
890 TextStoreACPSink_QueryInterface
,
891 TextStoreACPSink_AddRef
,
892 TextStoreACPSink_Release
,
894 TextStoreACPSink_OnTextChange
,
895 TextStoreACPSink_OnSelectionChange
,
896 TextStoreACPSink_OnLayoutChange
,
897 TextStoreACPSink_OnStatusChange
,
898 TextStoreACPSink_OnAttrsChange
,
899 TextStoreACPSink_OnLockGranted
,
900 TextStoreACPSink_OnStartEditTransaction
,
901 TextStoreACPSink_OnEndEditTransaction
904 static HRESULT
TextStoreACPSink_Constructor(ITextStoreACPSink
**ppOut
, Context
*pContext
)
906 TextStoreACPSink
*This
;
908 This
= HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY
,sizeof(TextStoreACPSink
));
910 return E_OUTOFMEMORY
;
912 This
->TextStoreACPSinkVtbl
= &TextStoreACPSink_TextStoreACPSinkVtbl
;
915 This
->pContext
= pContext
;
917 TRACE("returning %p\n", This
);
918 *ppOut
= (ITextStoreACPSink
*)This
;