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 ITfCompartmentMgr
*CompartmentMgr
;
75 TfEditCookie defaultCookie
;
76 TS_STATUS documentStatus
;
78 ITextStoreACP
*pITextStoreACP
;
79 ITfContextOwnerCompositionSink
*pITfContextOwnerCompositionSink
;
81 ITextStoreACPSink
*pITextStoreACPSink
;
82 ITfEditSession
* currentEditSession
;
84 /* kept as separate lists to reduce unnecessary iterations */
85 struct list pContextKeyEventSink
;
86 struct list pEditTransactionSink
;
87 struct list pStatusSink
;
88 struct list pTextEditSink
;
89 struct list pTextLayoutSink
;
93 typedef struct tagEditCookie
{
95 Context
*pOwningContext
;
98 typedef struct tagTextStoreACPSink
{
99 const ITextStoreACPSinkVtbl
*TextStoreACPSinkVtbl
;
100 /* const ITextStoreACPServicesVtbl *TextStoreACPServicesVtbl; */
107 static HRESULT
TextStoreACPSink_Constructor(ITextStoreACPSink
**ppOut
, Context
*pContext
);
109 static inline Context
*impl_from_ITfSourceVtbl(ITfSource
*iface
)
111 return (Context
*)((char *)iface
- FIELD_OFFSET(Context
,SourceVtbl
));
114 static inline Context
*impl_from_ITfInsertAtSelectionVtbl(ITfInsertAtSelection
*iface
)
116 return (Context
*)((char *)iface
- FIELD_OFFSET(Context
,InsertAtSelectionVtbl
));
119 static void free_sink(ContextSink
*sink
)
121 IUnknown_Release(sink
->interfaces
.pIUnknown
);
122 HeapFree(GetProcessHeap(),0,sink
);
125 static void Context_Destructor(Context
*This
)
127 struct list
*cursor
, *cursor2
;
129 TRACE("destroying %p\n", This
);
131 if (This
->pITextStoreACPSink
)
133 ITextStoreACP_UnadviseSink(This
->pITextStoreACP
, (IUnknown
*)This
->pITextStoreACPSink
);
134 ITextStoreACPSink_Release(This
->pITextStoreACPSink
);
137 if (This
->pITextStoreACP
)
138 ITextStoreACPSink_Release(This
->pITextStoreACP
);
140 if (This
->pITfContextOwnerCompositionSink
)
141 ITextStoreACPSink_Release(This
->pITfContextOwnerCompositionSink
);
143 if (This
->defaultCookie
)
145 cookie
= remove_Cookie(This
->defaultCookie
);
146 HeapFree(GetProcessHeap(),0,cookie
);
147 This
->defaultCookie
= 0;
150 LIST_FOR_EACH_SAFE(cursor
, cursor2
, &This
->pContextKeyEventSink
)
152 ContextSink
* sink
= LIST_ENTRY(cursor
,ContextSink
,entry
);
156 LIST_FOR_EACH_SAFE(cursor
, cursor2
, &This
->pEditTransactionSink
)
158 ContextSink
* sink
= LIST_ENTRY(cursor
,ContextSink
,entry
);
162 LIST_FOR_EACH_SAFE(cursor
, cursor2
, &This
->pStatusSink
)
164 ContextSink
* sink
= LIST_ENTRY(cursor
,ContextSink
,entry
);
168 LIST_FOR_EACH_SAFE(cursor
, cursor2
, &This
->pTextEditSink
)
170 ContextSink
* sink
= LIST_ENTRY(cursor
,ContextSink
,entry
);
174 LIST_FOR_EACH_SAFE(cursor
, cursor2
, &This
->pTextLayoutSink
)
176 ContextSink
* sink
= LIST_ENTRY(cursor
,ContextSink
,entry
);
181 CompartmentMgr_Destructor(This
->CompartmentMgr
);
182 HeapFree(GetProcessHeap(),0,This
);
185 static HRESULT WINAPI
Context_QueryInterface(ITfContext
*iface
, REFIID iid
, LPVOID
*ppvOut
)
187 Context
*This
= (Context
*)iface
;
190 if (IsEqualIID(iid
, &IID_IUnknown
) || IsEqualIID(iid
, &IID_ITfContext
))
194 else if (IsEqualIID(iid
, &IID_ITfSource
))
196 *ppvOut
= &This
->SourceVtbl
;
198 else if (IsEqualIID(iid
, &IID_ITfInsertAtSelection
))
200 *ppvOut
= &This
->InsertAtSelectionVtbl
;
202 else if (IsEqualIID(iid
, &IID_ITfCompartmentMgr
))
204 *ppvOut
= This
->CompartmentMgr
;
209 IUnknown_AddRef(iface
);
213 WARN("unsupported interface: %s\n", debugstr_guid(iid
));
214 return E_NOINTERFACE
;
217 static ULONG WINAPI
Context_AddRef(ITfContext
*iface
)
219 Context
*This
= (Context
*)iface
;
220 return InterlockedIncrement(&This
->refCount
);
223 static ULONG WINAPI
Context_Release(ITfContext
*iface
)
225 Context
*This
= (Context
*)iface
;
228 ret
= InterlockedDecrement(&This
->refCount
);
230 Context_Destructor(This
);
234 /*****************************************************
235 * ITfContext functions
236 *****************************************************/
237 static HRESULT WINAPI
Context_RequestEditSession (ITfContext
*iface
,
238 TfClientId tid
, ITfEditSession
*pes
, DWORD dwFlags
,
242 Context
*This
= (Context
*)iface
;
243 DWORD dwLockFlags
= 0x0;
245 TRACE("(%p) %i %p %x %p\n",This
, tid
, pes
, dwFlags
, phrSession
);
247 if (!(dwFlags
& TF_ES_READ
) && !(dwFlags
& TF_ES_READWRITE
))
249 *phrSession
= E_FAIL
;
253 if (!This
->pITextStoreACP
)
255 FIXME("No ITextStoreACP avaliable\n");
256 *phrSession
= E_FAIL
;
260 if (!(dwFlags
& TF_ES_ASYNC
))
261 dwLockFlags
|= TS_LF_SYNC
;
263 if ((dwFlags
& TF_ES_READWRITE
) == TF_ES_READWRITE
)
264 dwLockFlags
|= TS_LF_READWRITE
;
265 else if (dwFlags
& TF_ES_READ
)
266 dwLockFlags
|= TS_LF_READ
;
268 if (!This
->documentStatus
.dwDynamicFlags
)
269 ITextStoreACP_GetStatus(This
->pITextStoreACP
, &This
->documentStatus
);
271 if (((dwFlags
& TF_ES_READWRITE
) == TF_ES_READWRITE
) && (This
->documentStatus
.dwDynamicFlags
& TS_SD_READONLY
))
273 *phrSession
= TS_E_READONLY
;
277 if (FAILED (ITfEditSession_QueryInterface(pes
, &IID_ITfEditSession
, (LPVOID
*)&This
->currentEditSession
)))
279 *phrSession
= E_FAIL
;
283 hr
= ITextStoreACP_RequestLock(This
->pITextStoreACP
, dwLockFlags
, phrSession
);
288 static HRESULT WINAPI
Context_InWriteSession (ITfContext
*iface
,
290 BOOL
*pfWriteSession
)
292 Context
*This
= (Context
*)iface
;
293 FIXME("STUB:(%p)\n",This
);
297 static HRESULT WINAPI
Context_GetSelection (ITfContext
*iface
,
298 TfEditCookie ec
, ULONG ulIndex
, ULONG ulCount
,
299 TF_SELECTION
*pSelection
, ULONG
*pcFetched
)
301 Context
*This
= (Context
*)iface
;
304 ULONG totalFetched
= 0;
307 if (!pSelection
|| !pcFetched
)
312 if (!This
->connected
)
313 return TF_E_DISCONNECTED
;
315 if (get_Cookie_magic(ec
)!=COOKIE_MAGIC_EDITCOOKIE
)
318 if (!This
->pITextStoreACP
)
320 FIXME("Context does not have a ITextStoreACP\n");
324 cookie
= get_Cookie_data(ec
);
326 if (ulIndex
== TF_DEFAULT_SELECTION
)
331 for (i
= 0; i
< count
; i
++)
334 TS_SELECTION_ACP acps
;
336 hr
= ITextStoreACP_GetSelection(This
->pITextStoreACP
, ulIndex
+ i
,
339 if (hr
== TS_E_NOLOCK
)
341 else if (SUCCEEDED(hr
))
343 pSelection
[totalFetched
].style
.ase
= acps
.style
.ase
;
344 pSelection
[totalFetched
].style
.fInterimChar
= acps
.style
.fInterimChar
;
345 Range_Constructor(iface
, This
->pITextStoreACP
, cookie
->lockType
, acps
.acpStart
, acps
.acpEnd
, &pSelection
[totalFetched
].range
);
352 *pcFetched
= totalFetched
;
357 static HRESULT WINAPI
Context_SetSelection (ITfContext
*iface
,
358 TfEditCookie ec
, ULONG ulCount
, const TF_SELECTION
*pSelection
)
360 TS_SELECTION_ACP
*acp
;
361 Context
*This
= (Context
*)iface
;
365 TRACE("(%p) %i %i %p\n",This
,ec
,ulCount
,pSelection
);
367 if (!This
->pITextStoreACP
)
369 FIXME("Context does not have a ITextStoreACP\n");
373 if (get_Cookie_magic(ec
)!=COOKIE_MAGIC_EDITCOOKIE
)
376 acp
= HeapAlloc(GetProcessHeap(), 0, sizeof(TS_SELECTION_ACP
) * ulCount
);
378 return E_OUTOFMEMORY
;
380 for (i
= 0; i
< ulCount
; i
++)
381 if (FAILED(TF_SELECTION_to_TS_SELECTION_ACP(&pSelection
[i
], &acp
[i
])))
383 TRACE("Selection Conversion Failed\n");
384 HeapFree(GetProcessHeap(), 0 , acp
);
388 hr
= ITextStoreACP_SetSelection(This
->pITextStoreACP
, ulCount
, acp
);
390 HeapFree(GetProcessHeap(), 0, acp
);
395 static HRESULT WINAPI
Context_GetStart (ITfContext
*iface
,
396 TfEditCookie ec
, ITfRange
**ppStart
)
398 Context
*This
= (Context
*)iface
;
400 TRACE("(%p) %i %p\n",This
,ec
,ppStart
);
407 if (!This
->connected
)
408 return TF_E_DISCONNECTED
;
410 if (get_Cookie_magic(ec
)!=COOKIE_MAGIC_EDITCOOKIE
)
413 cookie
= get_Cookie_data(ec
);
414 return Range_Constructor(iface
, This
->pITextStoreACP
, cookie
->lockType
, 0, 0, ppStart
);
417 static HRESULT WINAPI
Context_GetEnd (ITfContext
*iface
,
418 TfEditCookie ec
, ITfRange
**ppEnd
)
420 Context
*This
= (Context
*)iface
;
423 TRACE("(%p) %i %p\n",This
,ec
,ppEnd
);
430 if (!This
->connected
)
431 return TF_E_DISCONNECTED
;
433 if (get_Cookie_magic(ec
)!=COOKIE_MAGIC_EDITCOOKIE
)
436 if (!This
->pITextStoreACP
)
438 FIXME("Context does not have a ITextStoreACP\n");
442 cookie
= get_Cookie_data(ec
);
443 ITextStoreACP_GetEndACP(This
->pITextStoreACP
,&end
);
445 return Range_Constructor(iface
, This
->pITextStoreACP
, cookie
->lockType
, end
, end
, ppEnd
);
448 static HRESULT WINAPI
Context_GetActiveView (ITfContext
*iface
,
449 ITfContextView
**ppView
)
451 Context
*This
= (Context
*)iface
;
452 FIXME("STUB:(%p)\n",This
);
456 static HRESULT WINAPI
Context_EnumViews (ITfContext
*iface
,
457 IEnumTfContextViews
**ppEnum
)
459 Context
*This
= (Context
*)iface
;
460 FIXME("STUB:(%p)\n",This
);
464 static HRESULT WINAPI
Context_GetStatus (ITfContext
*iface
,
467 Context
*This
= (Context
*)iface
;
468 FIXME("STUB:(%p)\n",This
);
472 static HRESULT WINAPI
Context_GetProperty (ITfContext
*iface
,
473 REFGUID guidProp
, ITfProperty
**ppProp
)
475 Context
*This
= (Context
*)iface
;
476 FIXME("STUB:(%p)\n",This
);
480 static HRESULT WINAPI
Context_GetAppProperty (ITfContext
*iface
,
481 REFGUID guidProp
, ITfReadOnlyProperty
**ppProp
)
483 Context
*This
= (Context
*)iface
;
484 FIXME("STUB:(%p)\n",This
);
488 static HRESULT WINAPI
Context_TrackProperties (ITfContext
*iface
,
489 const GUID
**prgProp
, ULONG cProp
, const GUID
**prgAppProp
,
490 ULONG cAppProp
, ITfReadOnlyProperty
**ppProperty
)
492 Context
*This
= (Context
*)iface
;
493 FIXME("STUB:(%p)\n",This
);
497 static HRESULT WINAPI
Context_EnumProperties (ITfContext
*iface
,
498 IEnumTfProperties
**ppEnum
)
500 Context
*This
= (Context
*)iface
;
501 FIXME("STUB:(%p)\n",This
);
505 static HRESULT WINAPI
Context_GetDocumentMgr (ITfContext
*iface
,
506 ITfDocumentMgr
**ppDm
)
508 Context
*This
= (Context
*)iface
;
509 FIXME("STUB:(%p)\n",This
);
513 static HRESULT WINAPI
Context_CreateRangeBackup (ITfContext
*iface
,
514 TfEditCookie ec
, ITfRange
*pRange
, ITfRangeBackup
**ppBackup
)
516 Context
*This
= (Context
*)iface
;
517 FIXME("STUB:(%p)\n",This
);
521 static const ITfContextVtbl Context_ContextVtbl
=
523 Context_QueryInterface
,
527 Context_RequestEditSession
,
528 Context_InWriteSession
,
529 Context_GetSelection
,
530 Context_SetSelection
,
533 Context_GetActiveView
,
537 Context_GetAppProperty
,
538 Context_TrackProperties
,
539 Context_EnumProperties
,
540 Context_GetDocumentMgr
,
541 Context_CreateRangeBackup
544 static HRESULT WINAPI
Source_QueryInterface(ITfSource
*iface
, REFIID iid
, LPVOID
*ppvOut
)
546 Context
*This
= impl_from_ITfSourceVtbl(iface
);
547 return Context_QueryInterface((ITfContext
*)This
, iid
, *ppvOut
);
550 static ULONG WINAPI
Source_AddRef(ITfSource
*iface
)
552 Context
*This
= impl_from_ITfSourceVtbl(iface
);
553 return Context_AddRef((ITfContext
*)This
);
556 static ULONG WINAPI
Source_Release(ITfSource
*iface
)
558 Context
*This
= impl_from_ITfSourceVtbl(iface
);
559 return Context_Release((ITfContext
*)This
);
562 /*****************************************************
563 * ITfSource functions
564 *****************************************************/
565 static WINAPI HRESULT
ContextSource_AdviseSink(ITfSource
*iface
,
566 REFIID riid
, IUnknown
*punk
, DWORD
*pdwCookie
)
569 Context
*This
= impl_from_ITfSourceVtbl(iface
);
570 TRACE("(%p) %s %p %p\n",This
,debugstr_guid(riid
),punk
,pdwCookie
);
572 if (!riid
|| !punk
|| !pdwCookie
)
575 if (IsEqualIID(riid
, &IID_ITfTextEditSink
))
577 es
= HeapAlloc(GetProcessHeap(),0,sizeof(ContextSink
));
579 return E_OUTOFMEMORY
;
580 if (FAILED(IUnknown_QueryInterface(punk
, riid
, (LPVOID
*)&es
->interfaces
.pITfTextEditSink
)))
582 HeapFree(GetProcessHeap(),0,es
);
583 return CONNECT_E_CANNOTCONNECT
;
585 list_add_head(&This
->pTextEditSink
,&es
->entry
);
586 *pdwCookie
= generate_Cookie(COOKIE_MAGIC_CONTEXTSINK
, es
);
590 FIXME("(%p) Unhandled Sink: %s\n",This
,debugstr_guid(riid
));
594 TRACE("cookie %x\n",*pdwCookie
);
598 static WINAPI HRESULT
ContextSource_UnadviseSink(ITfSource
*iface
, DWORD pdwCookie
)
601 Context
*This
= impl_from_ITfSourceVtbl(iface
);
603 TRACE("(%p) %x\n",This
,pdwCookie
);
605 if (get_Cookie_magic(pdwCookie
)!=COOKIE_MAGIC_CONTEXTSINK
)
608 sink
= (ContextSink
*)remove_Cookie(pdwCookie
);
610 return CONNECT_E_NOCONNECTION
;
612 list_remove(&sink
->entry
);
618 static const ITfSourceVtbl Context_SourceVtbl
=
620 Source_QueryInterface
,
624 ContextSource_AdviseSink
,
625 ContextSource_UnadviseSink
,
628 /*****************************************************
629 * ITfInsertAtSelection functions
630 *****************************************************/
631 static HRESULT WINAPI
InsertAtSelection_QueryInterface(ITfInsertAtSelection
*iface
, REFIID iid
, LPVOID
*ppvOut
)
633 Context
*This
= impl_from_ITfInsertAtSelectionVtbl(iface
);
634 return Context_QueryInterface((ITfContext
*)This
, iid
, *ppvOut
);
637 static ULONG WINAPI
InsertAtSelection_AddRef(ITfInsertAtSelection
*iface
)
639 Context
*This
= impl_from_ITfInsertAtSelectionVtbl(iface
);
640 return Context_AddRef((ITfContext
*)This
);
643 static ULONG WINAPI
InsertAtSelection_Release(ITfInsertAtSelection
*iface
)
645 Context
*This
= impl_from_ITfInsertAtSelectionVtbl(iface
);
646 return Context_Release((ITfContext
*)This
);
649 static WINAPI HRESULT
InsertAtSelection_InsertTextAtSelection(
650 ITfInsertAtSelection
*iface
, TfEditCookie ec
, DWORD dwFlags
,
651 const WCHAR
*pchText
, LONG cch
, ITfRange
**ppRange
)
653 Context
*This
= impl_from_ITfInsertAtSelectionVtbl(iface
);
655 LONG acpStart
, acpEnd
;
656 TS_TEXTCHANGE change
;
659 TRACE("(%p) %i %x %s %p\n",This
, ec
, dwFlags
, debugstr_wn(pchText
,cch
), ppRange
);
661 if (!This
->connected
)
662 return TF_E_DISCONNECTED
;
664 if (get_Cookie_magic(ec
)!=COOKIE_MAGIC_EDITCOOKIE
)
667 cookie
= get_Cookie_data(ec
);
669 if ((cookie
->lockType
& TS_LF_READWRITE
) != TS_LF_READWRITE
)
670 return TS_E_READONLY
;
672 if (!This
->pITextStoreACP
)
674 FIXME("Context does not have a ITextStoreACP\n");
678 hr
= ITextStoreACP_InsertTextAtSelection(This
->pITextStoreACP
, dwFlags
, pchText
, cch
, &acpStart
, &acpEnd
, &change
);
680 Range_Constructor((ITfContext
*)This
, This
->pITextStoreACP
, cookie
->lockType
, change
.acpStart
, change
.acpNewEnd
, ppRange
);
685 static WINAPI HRESULT
InsertAtSelection_InsertEmbeddedAtSelection(
686 ITfInsertAtSelection
*iface
, TfEditCookie ec
, DWORD dwFlags
,
687 IDataObject
*pDataObject
, ITfRange
**ppRange
)
689 Context
*This
= impl_from_ITfInsertAtSelectionVtbl(iface
);
690 FIXME("STUB:(%p)\n",This
);
694 static const ITfInsertAtSelectionVtbl Context_InsertAtSelectionVtbl
=
696 InsertAtSelection_QueryInterface
,
697 InsertAtSelection_AddRef
,
698 InsertAtSelection_Release
,
700 InsertAtSelection_InsertTextAtSelection
,
701 InsertAtSelection_InsertEmbeddedAtSelection
,
704 HRESULT
Context_Constructor(TfClientId tidOwner
, IUnknown
*punk
, ITfContext
**ppOut
, TfEditCookie
*pecTextStore
)
709 This
= HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY
,sizeof(Context
));
711 return E_OUTOFMEMORY
;
713 cookie
= HeapAlloc(GetProcessHeap(),0,sizeof(EditCookie
));
716 HeapFree(GetProcessHeap(),0,This
);
717 return E_OUTOFMEMORY
;
720 TRACE("(%p) %x %p %p %p\n",This
, tidOwner
, punk
, ppOut
, pecTextStore
);
722 This
->ContextVtbl
= &Context_ContextVtbl
;
723 This
->SourceVtbl
= &Context_SourceVtbl
;
724 This
->InsertAtSelectionVtbl
= &Context_InsertAtSelectionVtbl
;
726 This
->tidOwner
= tidOwner
;
727 This
->connected
= FALSE
;
729 CompartmentMgr_Constructor((IUnknown
*)This
, &IID_IUnknown
, (IUnknown
**)&This
->CompartmentMgr
);
731 cookie
->lockType
= TF_ES_READ
;
732 cookie
->pOwningContext
= This
;
736 IUnknown_QueryInterface(punk
, &IID_ITextStoreACP
,
737 (LPVOID
*)&This
->pITextStoreACP
);
739 IUnknown_QueryInterface(punk
, &IID_ITfContextOwnerCompositionSink
,
740 (LPVOID
*)&This
->pITfContextOwnerCompositionSink
);
742 if (!This
->pITextStoreACP
&& !This
->pITfContextOwnerCompositionSink
)
743 FIXME("Unhandled pUnk\n");
746 This
->defaultCookie
= generate_Cookie(COOKIE_MAGIC_EDITCOOKIE
,cookie
);
747 *pecTextStore
= This
->defaultCookie
;
749 list_init(&This
->pContextKeyEventSink
);
750 list_init(&This
->pEditTransactionSink
);
751 list_init(&This
->pStatusSink
);
752 list_init(&This
->pTextEditSink
);
753 list_init(&This
->pTextLayoutSink
);
755 *ppOut
= (ITfContext
*)This
;
756 TRACE("returning %p\n", This
);
761 HRESULT
Context_Initialize(ITfContext
*iface
)
763 Context
*This
= (Context
*)iface
;
765 if (This
->pITextStoreACP
)
767 if (SUCCEEDED(TextStoreACPSink_Constructor(&This
->pITextStoreACPSink
, This
)))
768 ITextStoreACP_AdviseSink(This
->pITextStoreACP
, &IID_ITextStoreACPSink
,
769 (IUnknown
*)This
->pITextStoreACPSink
, TS_AS_ALL_SINKS
);
771 This
->connected
= TRUE
;
775 HRESULT
Context_Uninitialize(ITfContext
*iface
)
777 Context
*This
= (Context
*)iface
;
779 if (This
->pITextStoreACPSink
)
781 ITextStoreACP_UnadviseSink(This
->pITextStoreACP
, (IUnknown
*)This
->pITextStoreACPSink
);
782 if (ITextStoreACPSink_Release(This
->pITextStoreACPSink
) == 0)
783 This
->pITextStoreACPSink
= NULL
;
785 This
->connected
= FALSE
;
789 /**************************************************************************
791 **************************************************************************/
793 static void TextStoreACPSink_Destructor(TextStoreACPSink
*This
)
795 TRACE("destroying %p\n", This
);
796 HeapFree(GetProcessHeap(),0,This
);
799 static HRESULT WINAPI
TextStoreACPSink_QueryInterface(ITextStoreACPSink
*iface
, REFIID iid
, LPVOID
*ppvOut
)
801 TextStoreACPSink
*This
= (TextStoreACPSink
*)iface
;
804 if (IsEqualIID(iid
, &IID_IUnknown
) || IsEqualIID(iid
, &IID_ITextStoreACPSink
))
811 IUnknown_AddRef(iface
);
815 WARN("unsupported interface: %s\n", debugstr_guid(iid
));
816 return E_NOINTERFACE
;
819 static ULONG WINAPI
TextStoreACPSink_AddRef(ITextStoreACPSink
*iface
)
821 TextStoreACPSink
*This
= (TextStoreACPSink
*)iface
;
822 return InterlockedIncrement(&This
->refCount
);
825 static ULONG WINAPI
TextStoreACPSink_Release(ITextStoreACPSink
*iface
)
827 TextStoreACPSink
*This
= (TextStoreACPSink
*)iface
;
830 ret
= InterlockedDecrement(&This
->refCount
);
832 TextStoreACPSink_Destructor(This
);
836 /*****************************************************
837 * ITextStoreACPSink functions
838 *****************************************************/
840 static HRESULT WINAPI
TextStoreACPSink_OnTextChange(ITextStoreACPSink
*iface
,
841 DWORD dwFlags
, const TS_TEXTCHANGE
*pChange
)
843 TextStoreACPSink
*This
= (TextStoreACPSink
*)iface
;
844 FIXME("STUB:(%p)\n",This
);
848 static HRESULT WINAPI
TextStoreACPSink_OnSelectionChange(ITextStoreACPSink
*iface
)
850 TextStoreACPSink
*This
= (TextStoreACPSink
*)iface
;
851 FIXME("STUB:(%p)\n",This
);
855 static HRESULT WINAPI
TextStoreACPSink_OnLayoutChange(ITextStoreACPSink
*iface
,
856 TsLayoutCode lcode
, TsViewCookie vcView
)
858 TextStoreACPSink
*This
= (TextStoreACPSink
*)iface
;
859 FIXME("STUB:(%p)\n",This
);
863 static HRESULT WINAPI
TextStoreACPSink_OnStatusChange(ITextStoreACPSink
*iface
,
866 TextStoreACPSink
*This
= (TextStoreACPSink
*)iface
;
867 HRESULT hr
, hrSession
;
869 TRACE("(%p) %x\n",This
, dwFlags
);
873 ERR("No context?\n");
877 if (!This
->pContext
->pITextStoreACP
)
879 FIXME("Context does not have a ITextStoreACP\n");
883 hr
= ITextStoreACP_RequestLock(This
->pContext
->pITextStoreACP
, TS_LF_READ
, &hrSession
);
885 if(SUCCEEDED(hr
) && SUCCEEDED(hrSession
))
886 This
->pContext
->documentStatus
.dwDynamicFlags
= dwFlags
;
891 static HRESULT WINAPI
TextStoreACPSink_OnAttrsChange(ITextStoreACPSink
*iface
,
892 LONG acpStart
, LONG acpEnd
, ULONG cAttrs
, const TS_ATTRID
*paAttrs
)
894 TextStoreACPSink
*This
= (TextStoreACPSink
*)iface
;
895 FIXME("STUB:(%p)\n",This
);
899 static HRESULT WINAPI
TextStoreACPSink_OnLockGranted(ITextStoreACPSink
*iface
,
902 TextStoreACPSink
*This
= (TextStoreACPSink
*)iface
;
907 TRACE("(%p) %x\n",This
, dwLockFlags
);
911 ERR("OnLockGranted called without a context\n");
915 if (!This
->pContext
->currentEditSession
)
917 FIXME("OnLockGranted called for something other than an EditSession\n");
921 cookie
= HeapAlloc(GetProcessHeap(),0,sizeof(EditCookie
));
923 return E_OUTOFMEMORY
;
925 cookie
->lockType
= dwLockFlags
;
926 cookie
->pOwningContext
= This
->pContext
;
927 ec
= generate_Cookie(COOKIE_MAGIC_EDITCOOKIE
, cookie
);
929 hr
= ITfEditSession_DoEditSession(This
->pContext
->currentEditSession
, ec
);
931 ITfEditSession_Release(This
->pContext
->currentEditSession
);
932 This
->pContext
->currentEditSession
= NULL
;
934 /* Edit Cookie is only valid during the edit session */
935 cookie
= remove_Cookie(ec
);
936 HeapFree(GetProcessHeap(),0,cookie
);
941 static HRESULT WINAPI
TextStoreACPSink_OnStartEditTransaction(ITextStoreACPSink
*iface
)
943 TextStoreACPSink
*This
= (TextStoreACPSink
*)iface
;
944 FIXME("STUB:(%p)\n",This
);
948 static HRESULT WINAPI
TextStoreACPSink_OnEndEditTransaction(ITextStoreACPSink
*iface
)
950 TextStoreACPSink
*This
= (TextStoreACPSink
*)iface
;
951 FIXME("STUB:(%p)\n",This
);
955 static const ITextStoreACPSinkVtbl TextStoreACPSink_TextStoreACPSinkVtbl
=
957 TextStoreACPSink_QueryInterface
,
958 TextStoreACPSink_AddRef
,
959 TextStoreACPSink_Release
,
961 TextStoreACPSink_OnTextChange
,
962 TextStoreACPSink_OnSelectionChange
,
963 TextStoreACPSink_OnLayoutChange
,
964 TextStoreACPSink_OnStatusChange
,
965 TextStoreACPSink_OnAttrsChange
,
966 TextStoreACPSink_OnLockGranted
,
967 TextStoreACPSink_OnStartEditTransaction
,
968 TextStoreACPSink_OnEndEditTransaction
971 static HRESULT
TextStoreACPSink_Constructor(ITextStoreACPSink
**ppOut
, Context
*pContext
)
973 TextStoreACPSink
*This
;
975 This
= HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY
,sizeof(TextStoreACPSink
));
977 return E_OUTOFMEMORY
;
979 This
->TextStoreACPSinkVtbl
= &TextStoreACPSink_TextStoreACPSinkVtbl
;
982 This
->pContext
= pContext
;
984 TRACE("returning %p\n", This
);
985 *ppOut
= (ITextStoreACPSink
*)This
;