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
21 #include "msctf_internal.h"
23 typedef struct tagContextSink
{
28 /* ITfContextKeyEventSink *pITfContextKeyEventSink; */
29 /* ITfEditTransactionSink *pITfEditTransactionSink; */
30 /* ITfStatusSink *pITfStatusSink; */
31 ITfTextEditSink
*pITfTextEditSink
;
32 /* ITfTextLayoutSink *pITfTextLayoutSink; */
36 typedef struct tagContext
{
37 ITfContext ITfContext_iface
;
38 ITfSource ITfSource_iface
;
39 /* const ITfContextCompositionVtbl *ContextCompositionVtbl; */
40 /* const ITfContextOwnerCompositionServicesVtbl *ContextOwnerCompositionServicesVtbl; */
41 /* const ITfContextOwnerServicesVtbl *ContextOwnerServicesVtbl; */
42 ITfInsertAtSelection ITfInsertAtSelection_iface
;
43 /* const ITfMouseTrackerVtbl *MouseTrackerVtbl; */
44 /* const ITfQueryEmbeddedVtbl *QueryEmbeddedVtbl; */
45 ITfSourceSingle ITfSourceSingle_iface
;
50 ITfCompartmentMgr
*CompartmentMgr
;
53 TfEditCookie defaultCookie
;
54 TS_STATUS documentStatus
;
55 ITfDocumentMgr
*manager
;
57 ITextStoreACP
*pITextStoreACP
;
58 ITfContextOwnerCompositionSink
*pITfContextOwnerCompositionSink
;
60 ITextStoreACPSink
*pITextStoreACPSink
;
61 ITfEditSession
* currentEditSession
;
63 /* kept as separate lists to reduce unnecessary iterations */
64 struct list pContextKeyEventSink
;
65 struct list pEditTransactionSink
;
66 struct list pStatusSink
;
67 struct list pTextEditSink
;
68 struct list pTextLayoutSink
;
72 typedef struct tagEditCookie
{
74 Context
*pOwningContext
;
77 typedef struct tagTextStoreACPSink
{
78 ITextStoreACPSink ITextStoreACPSink_iface
;
79 /* const ITextStoreACPServicesVtbl *TextStoreACPServicesVtbl; */
86 static HRESULT
TextStoreACPSink_Constructor(ITextStoreACPSink
**ppOut
, Context
*pContext
);
88 static inline Context
*impl_from_ITfContext(ITfContext
*iface
)
90 return CONTAINING_RECORD(iface
, Context
, ITfContext_iface
);
93 static inline Context
*impl_from_ITfSource(ITfSource
*iface
)
95 return CONTAINING_RECORD(iface
, Context
, ITfSource_iface
);
98 static inline Context
*impl_from_ITfInsertAtSelection(ITfInsertAtSelection
*iface
)
100 return CONTAINING_RECORD(iface
, Context
, ITfInsertAtSelection_iface
);
103 static inline Context
*impl_from_ITfSourceSingle(ITfSourceSingle
* iface
)
105 return CONTAINING_RECORD(iface
, Context
, ITfSourceSingle_iface
);
108 static inline TextStoreACPSink
*impl_from_ITextStoreACPSink(ITextStoreACPSink
*iface
)
110 return CONTAINING_RECORD(iface
, TextStoreACPSink
, ITextStoreACPSink_iface
);
113 static void free_sink(ContextSink
*sink
)
115 IUnknown_Release(sink
->interfaces
.pIUnknown
);
116 HeapFree(GetProcessHeap(),0,sink
);
119 static void Context_Destructor(Context
*This
)
121 struct list
*cursor
, *cursor2
;
123 TRACE("destroying %p\n", This
);
125 if (This
->pITextStoreACPSink
)
127 ITextStoreACP_UnadviseSink(This
->pITextStoreACP
, (IUnknown
*)This
->pITextStoreACPSink
);
128 ITextStoreACPSink_Release(This
->pITextStoreACPSink
);
131 if (This
->pITextStoreACP
)
132 ITextStoreACP_Release(This
->pITextStoreACP
);
134 if (This
->pITfContextOwnerCompositionSink
)
135 ITfContextOwnerCompositionSink_Release(This
->pITfContextOwnerCompositionSink
);
137 if (This
->defaultCookie
)
139 cookie
= remove_Cookie(This
->defaultCookie
);
140 HeapFree(GetProcessHeap(),0,cookie
);
141 This
->defaultCookie
= 0;
144 LIST_FOR_EACH_SAFE(cursor
, cursor2
, &This
->pContextKeyEventSink
)
146 ContextSink
* sink
= LIST_ENTRY(cursor
,ContextSink
,entry
);
150 LIST_FOR_EACH_SAFE(cursor
, cursor2
, &This
->pEditTransactionSink
)
152 ContextSink
* sink
= LIST_ENTRY(cursor
,ContextSink
,entry
);
156 LIST_FOR_EACH_SAFE(cursor
, cursor2
, &This
->pStatusSink
)
158 ContextSink
* sink
= LIST_ENTRY(cursor
,ContextSink
,entry
);
162 LIST_FOR_EACH_SAFE(cursor
, cursor2
, &This
->pTextEditSink
)
164 ContextSink
* sink
= LIST_ENTRY(cursor
,ContextSink
,entry
);
168 LIST_FOR_EACH_SAFE(cursor
, cursor2
, &This
->pTextLayoutSink
)
170 ContextSink
* sink
= LIST_ENTRY(cursor
,ContextSink
,entry
);
175 CompartmentMgr_Destructor(This
->CompartmentMgr
);
176 HeapFree(GetProcessHeap(),0,This
);
179 static HRESULT WINAPI
Context_QueryInterface(ITfContext
*iface
, REFIID iid
, LPVOID
*ppvOut
)
181 Context
*This
= impl_from_ITfContext(iface
);
184 if (IsEqualIID(iid
, &IID_IUnknown
) || IsEqualIID(iid
, &IID_ITfContext
))
186 *ppvOut
= &This
->ITfContext_iface
;
188 else if (IsEqualIID(iid
, &IID_ITfSource
))
190 *ppvOut
= &This
->ITfSource_iface
;
192 else if (IsEqualIID(iid
, &IID_ITfInsertAtSelection
))
194 *ppvOut
= &This
->ITfInsertAtSelection_iface
;
196 else if (IsEqualIID(iid
, &IID_ITfCompartmentMgr
))
198 *ppvOut
= This
->CompartmentMgr
;
200 else if (IsEqualIID(iid
, &IID_ITfSourceSingle
))
202 *ppvOut
= &This
->ITfSourceSingle_iface
;
207 ITfContext_AddRef(iface
);
211 WARN("unsupported interface: %s\n", debugstr_guid(iid
));
212 return E_NOINTERFACE
;
215 static ULONG WINAPI
Context_AddRef(ITfContext
*iface
)
217 Context
*This
= impl_from_ITfContext(iface
);
218 return InterlockedIncrement(&This
->refCount
);
221 static ULONG WINAPI
Context_Release(ITfContext
*iface
)
223 Context
*This
= impl_from_ITfContext(iface
);
226 ret
= InterlockedDecrement(&This
->refCount
);
228 Context_Destructor(This
);
232 /*****************************************************
233 * ITfContext functions
234 *****************************************************/
235 static HRESULT WINAPI
Context_RequestEditSession (ITfContext
*iface
,
236 TfClientId tid
, ITfEditSession
*pes
, DWORD dwFlags
,
239 Context
*This
= impl_from_ITfContext(iface
);
241 DWORD dwLockFlags
= 0x0;
243 TRACE("(%p) %i %p %x %p\n",This
, tid
, pes
, dwFlags
, phrSession
);
245 if (!(dwFlags
& TF_ES_READ
) && !(dwFlags
& TF_ES_READWRITE
))
247 *phrSession
= E_FAIL
;
251 if (!This
->pITextStoreACP
)
253 FIXME("No ITextStoreACP available\n");
254 *phrSession
= E_FAIL
;
258 if (!(dwFlags
& TF_ES_ASYNC
))
259 dwLockFlags
|= TS_LF_SYNC
;
261 if ((dwFlags
& TF_ES_READWRITE
) == TF_ES_READWRITE
)
262 dwLockFlags
|= TS_LF_READWRITE
;
263 else if (dwFlags
& TF_ES_READ
)
264 dwLockFlags
|= TS_LF_READ
;
266 if (!This
->documentStatus
.dwDynamicFlags
)
267 ITextStoreACP_GetStatus(This
->pITextStoreACP
, &This
->documentStatus
);
269 if (((dwFlags
& TF_ES_READWRITE
) == TF_ES_READWRITE
) && (This
->documentStatus
.dwDynamicFlags
& TS_SD_READONLY
))
271 *phrSession
= TS_E_READONLY
;
275 if (FAILED (ITfEditSession_QueryInterface(pes
, &IID_ITfEditSession
, (LPVOID
*)&This
->currentEditSession
)))
277 *phrSession
= E_FAIL
;
281 hr
= ITextStoreACP_RequestLock(This
->pITextStoreACP
, dwLockFlags
, phrSession
);
286 static HRESULT WINAPI
Context_InWriteSession (ITfContext
*iface
,
288 BOOL
*pfWriteSession
)
290 Context
*This
= impl_from_ITfContext(iface
);
291 FIXME("STUB:(%p)\n",This
);
295 static HRESULT WINAPI
Context_GetSelection (ITfContext
*iface
,
296 TfEditCookie ec
, ULONG ulIndex
, ULONG ulCount
,
297 TF_SELECTION
*pSelection
, ULONG
*pcFetched
)
299 Context
*This
= impl_from_ITfContext(iface
);
302 ULONG totalFetched
= 0;
305 if (!pSelection
|| !pcFetched
)
310 if (!This
->connected
)
311 return TF_E_DISCONNECTED
;
313 if (get_Cookie_magic(ec
)!=COOKIE_MAGIC_EDITCOOKIE
)
316 if (!This
->pITextStoreACP
)
318 FIXME("Context does not have a ITextStoreACP\n");
322 cookie
= get_Cookie_data(ec
);
324 if (ulIndex
== TF_DEFAULT_SELECTION
)
329 for (i
= 0; i
< count
; i
++)
332 TS_SELECTION_ACP acps
;
334 hr
= ITextStoreACP_GetSelection(This
->pITextStoreACP
, ulIndex
+ i
,
337 if (hr
== TS_E_NOLOCK
)
339 else if (SUCCEEDED(hr
))
341 pSelection
[totalFetched
].style
.ase
= acps
.style
.ase
;
342 pSelection
[totalFetched
].style
.fInterimChar
= acps
.style
.fInterimChar
;
343 Range_Constructor(iface
, This
->pITextStoreACP
, cookie
->lockType
, acps
.acpStart
, acps
.acpEnd
, &pSelection
[totalFetched
].range
);
350 *pcFetched
= totalFetched
;
355 static HRESULT WINAPI
Context_SetSelection (ITfContext
*iface
,
356 TfEditCookie ec
, ULONG ulCount
, const TF_SELECTION
*pSelection
)
358 Context
*This
= impl_from_ITfContext(iface
);
359 TS_SELECTION_ACP
*acp
;
363 TRACE("(%p) %i %i %p\n",This
,ec
,ulCount
,pSelection
);
365 if (!This
->pITextStoreACP
)
367 FIXME("Context does not have a ITextStoreACP\n");
371 if (get_Cookie_magic(ec
)!=COOKIE_MAGIC_EDITCOOKIE
)
374 acp
= HeapAlloc(GetProcessHeap(), 0, sizeof(TS_SELECTION_ACP
) * ulCount
);
376 return E_OUTOFMEMORY
;
378 for (i
= 0; i
< ulCount
; i
++)
379 if (FAILED(TF_SELECTION_to_TS_SELECTION_ACP(&pSelection
[i
], &acp
[i
])))
381 TRACE("Selection Conversion Failed\n");
382 HeapFree(GetProcessHeap(), 0 , acp
);
386 hr
= ITextStoreACP_SetSelection(This
->pITextStoreACP
, ulCount
, acp
);
388 HeapFree(GetProcessHeap(), 0, acp
);
393 static HRESULT WINAPI
Context_GetStart (ITfContext
*iface
,
394 TfEditCookie ec
, ITfRange
**ppStart
)
396 Context
*This
= impl_from_ITfContext(iface
);
398 TRACE("(%p) %i %p\n",This
,ec
,ppStart
);
405 if (!This
->connected
)
406 return TF_E_DISCONNECTED
;
408 if (get_Cookie_magic(ec
)!=COOKIE_MAGIC_EDITCOOKIE
)
411 cookie
= get_Cookie_data(ec
);
412 return Range_Constructor(iface
, This
->pITextStoreACP
, cookie
->lockType
, 0, 0, ppStart
);
415 static HRESULT WINAPI
Context_GetEnd (ITfContext
*iface
,
416 TfEditCookie ec
, ITfRange
**ppEnd
)
418 Context
*This
= impl_from_ITfContext(iface
);
421 TRACE("(%p) %i %p\n",This
,ec
,ppEnd
);
428 if (!This
->connected
)
429 return TF_E_DISCONNECTED
;
431 if (get_Cookie_magic(ec
)!=COOKIE_MAGIC_EDITCOOKIE
)
434 if (!This
->pITextStoreACP
)
436 FIXME("Context does not have a ITextStoreACP\n");
440 cookie
= get_Cookie_data(ec
);
441 ITextStoreACP_GetEndACP(This
->pITextStoreACP
,&end
);
443 return Range_Constructor(iface
, This
->pITextStoreACP
, cookie
->lockType
, end
, end
, ppEnd
);
446 static HRESULT WINAPI
Context_GetActiveView (ITfContext
*iface
,
447 ITfContextView
**ppView
)
449 Context
*This
= impl_from_ITfContext(iface
);
450 FIXME("STUB:(%p)\n",This
);
454 static HRESULT WINAPI
Context_EnumViews (ITfContext
*iface
,
455 IEnumTfContextViews
**ppEnum
)
457 Context
*This
= impl_from_ITfContext(iface
);
458 FIXME("STUB:(%p)\n",This
);
462 static HRESULT WINAPI
Context_GetStatus (ITfContext
*iface
,
465 Context
*This
= impl_from_ITfContext(iface
);
466 TRACE("(%p) %p\n",This
,pdcs
);
468 if (!This
->connected
)
469 return TF_E_DISCONNECTED
;
474 if (!This
->pITextStoreACP
)
476 FIXME("Context does not have a ITextStoreACP\n");
480 ITextStoreACP_GetStatus(This
->pITextStoreACP
, &This
->documentStatus
);
482 *pdcs
= This
->documentStatus
;
487 static HRESULT WINAPI
Context_GetProperty (ITfContext
*iface
,
488 REFGUID guidProp
, ITfProperty
**ppProp
)
490 Context
*This
= impl_from_ITfContext(iface
);
491 FIXME("STUB:(%p)\n",This
);
495 static HRESULT WINAPI
Context_GetAppProperty (ITfContext
*iface
,
496 REFGUID guidProp
, ITfReadOnlyProperty
**ppProp
)
498 Context
*This
= impl_from_ITfContext(iface
);
499 FIXME("STUB:(%p)\n",This
);
503 static HRESULT WINAPI
Context_TrackProperties (ITfContext
*iface
,
504 const GUID
**prgProp
, ULONG cProp
, const GUID
**prgAppProp
,
505 ULONG cAppProp
, ITfReadOnlyProperty
**ppProperty
)
507 Context
*This
= impl_from_ITfContext(iface
);
508 FIXME("STUB:(%p)\n",This
);
512 static HRESULT WINAPI
Context_EnumProperties (ITfContext
*iface
,
513 IEnumTfProperties
**ppEnum
)
515 Context
*This
= impl_from_ITfContext(iface
);
516 FIXME("STUB:(%p)\n",This
);
520 static HRESULT WINAPI
Context_GetDocumentMgr (ITfContext
*iface
,
521 ITfDocumentMgr
**ppDm
)
523 Context
*This
= impl_from_ITfContext(iface
);
524 TRACE("(%p) %p\n",This
,ppDm
);
529 *ppDm
= This
->manager
;
533 ITfDocumentMgr_AddRef(This
->manager
);
538 static HRESULT WINAPI
Context_CreateRangeBackup (ITfContext
*iface
,
539 TfEditCookie ec
, ITfRange
*pRange
, ITfRangeBackup
**ppBackup
)
541 Context
*This
= impl_from_ITfContext(iface
);
542 FIXME("STUB:(%p)\n",This
);
546 static const ITfContextVtbl ContextVtbl
=
548 Context_QueryInterface
,
551 Context_RequestEditSession
,
552 Context_InWriteSession
,
553 Context_GetSelection
,
554 Context_SetSelection
,
557 Context_GetActiveView
,
561 Context_GetAppProperty
,
562 Context_TrackProperties
,
563 Context_EnumProperties
,
564 Context_GetDocumentMgr
,
565 Context_CreateRangeBackup
568 static HRESULT WINAPI
ContextSource_QueryInterface(ITfSource
*iface
, REFIID iid
, LPVOID
*ppvOut
)
570 Context
*This
= impl_from_ITfSource(iface
);
571 return ITfContext_QueryInterface(&This
->ITfContext_iface
, iid
, ppvOut
);
574 static ULONG WINAPI
ContextSource_AddRef(ITfSource
*iface
)
576 Context
*This
= impl_from_ITfSource(iface
);
577 return ITfContext_AddRef(&This
->ITfContext_iface
);
580 static ULONG WINAPI
ContextSource_Release(ITfSource
*iface
)
582 Context
*This
= impl_from_ITfSource(iface
);
583 return ITfContext_Release(&This
->ITfContext_iface
);
586 /*****************************************************
587 * ITfSource functions
588 *****************************************************/
589 static HRESULT WINAPI
ContextSource_AdviseSink(ITfSource
*iface
,
590 REFIID riid
, IUnknown
*punk
, DWORD
*pdwCookie
)
592 Context
*This
= impl_from_ITfSource(iface
);
594 TRACE("(%p) %s %p %p\n",This
,debugstr_guid(riid
),punk
,pdwCookie
);
596 if (!riid
|| !punk
|| !pdwCookie
)
599 if (IsEqualIID(riid
, &IID_ITfTextEditSink
))
601 es
= HeapAlloc(GetProcessHeap(),0,sizeof(ContextSink
));
603 return E_OUTOFMEMORY
;
604 if (FAILED(IUnknown_QueryInterface(punk
, riid
, (LPVOID
*)&es
->interfaces
.pITfTextEditSink
)))
606 HeapFree(GetProcessHeap(),0,es
);
607 return CONNECT_E_CANNOTCONNECT
;
609 list_add_head(&This
->pTextEditSink
,&es
->entry
);
610 *pdwCookie
= generate_Cookie(COOKIE_MAGIC_CONTEXTSINK
, es
);
614 FIXME("(%p) Unhandled Sink: %s\n",This
,debugstr_guid(riid
));
618 TRACE("cookie %x\n",*pdwCookie
);
622 static HRESULT WINAPI
ContextSource_UnadviseSink(ITfSource
*iface
, DWORD pdwCookie
)
624 Context
*This
= impl_from_ITfSource(iface
);
627 TRACE("(%p) %x\n",This
,pdwCookie
);
629 if (get_Cookie_magic(pdwCookie
)!=COOKIE_MAGIC_CONTEXTSINK
)
632 sink
= remove_Cookie(pdwCookie
);
634 return CONNECT_E_NOCONNECTION
;
636 list_remove(&sink
->entry
);
642 static const ITfSourceVtbl ContextSourceVtbl
=
644 ContextSource_QueryInterface
,
645 ContextSource_AddRef
,
646 ContextSource_Release
,
647 ContextSource_AdviseSink
,
648 ContextSource_UnadviseSink
651 /*****************************************************
652 * ITfInsertAtSelection functions
653 *****************************************************/
654 static HRESULT WINAPI
InsertAtSelection_QueryInterface(ITfInsertAtSelection
*iface
, REFIID iid
, LPVOID
*ppvOut
)
656 Context
*This
= impl_from_ITfInsertAtSelection(iface
);
657 return ITfContext_QueryInterface(&This
->ITfContext_iface
, iid
, ppvOut
);
660 static ULONG WINAPI
InsertAtSelection_AddRef(ITfInsertAtSelection
*iface
)
662 Context
*This
= impl_from_ITfInsertAtSelection(iface
);
663 return ITfContext_AddRef(&This
->ITfContext_iface
);
666 static ULONG WINAPI
InsertAtSelection_Release(ITfInsertAtSelection
*iface
)
668 Context
*This
= impl_from_ITfInsertAtSelection(iface
);
669 return ITfContext_Release(&This
->ITfContext_iface
);
672 static HRESULT WINAPI
InsertAtSelection_InsertTextAtSelection(
673 ITfInsertAtSelection
*iface
, TfEditCookie ec
, DWORD dwFlags
,
674 const WCHAR
*pchText
, LONG cch
, ITfRange
**ppRange
)
676 Context
*This
= impl_from_ITfInsertAtSelection(iface
);
678 LONG acpStart
, acpEnd
;
679 TS_TEXTCHANGE change
;
682 TRACE("(%p) %i %x %s %p\n",This
, ec
, dwFlags
, debugstr_wn(pchText
,cch
), ppRange
);
684 if (!This
->connected
)
685 return TF_E_DISCONNECTED
;
687 if (get_Cookie_magic(ec
)!=COOKIE_MAGIC_EDITCOOKIE
)
690 cookie
= get_Cookie_data(ec
);
692 if ((cookie
->lockType
& TS_LF_READWRITE
) != TS_LF_READWRITE
)
693 return TS_E_READONLY
;
695 if (!This
->pITextStoreACP
)
697 FIXME("Context does not have a ITextStoreACP\n");
701 hr
= ITextStoreACP_InsertTextAtSelection(This
->pITextStoreACP
, dwFlags
, pchText
, cch
, &acpStart
, &acpEnd
, &change
);
703 Range_Constructor(&This
->ITfContext_iface
, This
->pITextStoreACP
, cookie
->lockType
, change
.acpStart
, change
.acpNewEnd
, ppRange
);
708 static HRESULT WINAPI
InsertAtSelection_InsertEmbeddedAtSelection(
709 ITfInsertAtSelection
*iface
, TfEditCookie ec
, DWORD dwFlags
,
710 IDataObject
*pDataObject
, ITfRange
**ppRange
)
712 Context
*This
= impl_from_ITfInsertAtSelection(iface
);
713 FIXME("STUB:(%p)\n",This
);
717 static const ITfInsertAtSelectionVtbl InsertAtSelectionVtbl
=
719 InsertAtSelection_QueryInterface
,
720 InsertAtSelection_AddRef
,
721 InsertAtSelection_Release
,
722 InsertAtSelection_InsertTextAtSelection
,
723 InsertAtSelection_InsertEmbeddedAtSelection
,
726 /*****************************************************
727 * ITfSourceSingle functions
728 *****************************************************/
729 static HRESULT WINAPI
SourceSingle_QueryInterface(ITfSourceSingle
*iface
, REFIID iid
, LPVOID
*ppvOut
)
731 Context
*This
= impl_from_ITfSourceSingle(iface
);
732 return ITfContext_QueryInterface(&This
->ITfContext_iface
, iid
, ppvOut
);
735 static ULONG WINAPI
SourceSingle_AddRef(ITfSourceSingle
*iface
)
737 Context
*This
= impl_from_ITfSourceSingle(iface
);
738 return ITfContext_AddRef(&This
->ITfContext_iface
);
741 static ULONG WINAPI
SourceSingle_Release(ITfSourceSingle
*iface
)
743 Context
*This
= impl_from_ITfSourceSingle(iface
);
744 return ITfContext_Release(&This
->ITfContext_iface
);
747 static HRESULT WINAPI
SourceSingle_AdviseSingleSink( ITfSourceSingle
*iface
,
748 TfClientId tid
, REFIID riid
, IUnknown
*punk
)
750 Context
*This
= impl_from_ITfSourceSingle(iface
);
751 FIXME("STUB:(%p) %i %s %p\n",This
, tid
, debugstr_guid(riid
),punk
);
755 static HRESULT WINAPI
SourceSingle_UnadviseSingleSink( ITfSourceSingle
*iface
,
756 TfClientId tid
, REFIID riid
)
758 Context
*This
= impl_from_ITfSourceSingle(iface
);
759 FIXME("STUB:(%p) %i %s\n",This
, tid
, debugstr_guid(riid
));
763 static const ITfSourceSingleVtbl ContextSourceSingleVtbl
=
765 SourceSingle_QueryInterface
,
767 SourceSingle_Release
,
768 SourceSingle_AdviseSingleSink
,
769 SourceSingle_UnadviseSingleSink
,
772 HRESULT
Context_Constructor(TfClientId tidOwner
, IUnknown
*punk
, ITfDocumentMgr
*mgr
, ITfContext
**ppOut
, TfEditCookie
*pecTextStore
)
777 This
= HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY
,sizeof(Context
));
779 return E_OUTOFMEMORY
;
781 cookie
= HeapAlloc(GetProcessHeap(),0,sizeof(EditCookie
));
784 HeapFree(GetProcessHeap(),0,This
);
785 return E_OUTOFMEMORY
;
788 TRACE("(%p) %x %p %p %p\n",This
, tidOwner
, punk
, ppOut
, pecTextStore
);
790 This
->ITfContext_iface
.lpVtbl
= &ContextVtbl
;
791 This
->ITfSource_iface
.lpVtbl
= &ContextSourceVtbl
;
792 This
->ITfInsertAtSelection_iface
.lpVtbl
= &InsertAtSelectionVtbl
;
793 This
->ITfSourceSingle_iface
.lpVtbl
= &ContextSourceSingleVtbl
;
795 This
->tidOwner
= tidOwner
;
796 This
->connected
= FALSE
;
799 CompartmentMgr_Constructor((IUnknown
*)&This
->ITfContext_iface
, &IID_IUnknown
, (IUnknown
**)&This
->CompartmentMgr
);
801 cookie
->lockType
= TF_ES_READ
;
802 cookie
->pOwningContext
= This
;
806 IUnknown_QueryInterface(punk
, &IID_ITextStoreACP
,
807 (LPVOID
*)&This
->pITextStoreACP
);
809 IUnknown_QueryInterface(punk
, &IID_ITfContextOwnerCompositionSink
,
810 (LPVOID
*)&This
->pITfContextOwnerCompositionSink
);
812 if (!This
->pITextStoreACP
&& !This
->pITfContextOwnerCompositionSink
)
813 FIXME("Unhandled pUnk\n");
816 This
->defaultCookie
= generate_Cookie(COOKIE_MAGIC_EDITCOOKIE
,cookie
);
817 *pecTextStore
= This
->defaultCookie
;
819 list_init(&This
->pContextKeyEventSink
);
820 list_init(&This
->pEditTransactionSink
);
821 list_init(&This
->pStatusSink
);
822 list_init(&This
->pTextEditSink
);
823 list_init(&This
->pTextLayoutSink
);
825 *ppOut
= &This
->ITfContext_iface
;
826 TRACE("returning %p\n", *ppOut
);
831 HRESULT
Context_Initialize(ITfContext
*iface
, ITfDocumentMgr
*manager
)
833 Context
*This
= impl_from_ITfContext(iface
);
835 if (This
->pITextStoreACP
)
837 if (SUCCEEDED(TextStoreACPSink_Constructor(&This
->pITextStoreACPSink
, This
)))
838 ITextStoreACP_AdviseSink(This
->pITextStoreACP
, &IID_ITextStoreACPSink
,
839 (IUnknown
*)This
->pITextStoreACPSink
, TS_AS_ALL_SINKS
);
841 This
->connected
= TRUE
;
842 This
->manager
= manager
;
846 HRESULT
Context_Uninitialize(ITfContext
*iface
)
848 Context
*This
= impl_from_ITfContext(iface
);
850 if (This
->pITextStoreACPSink
)
852 ITextStoreACP_UnadviseSink(This
->pITextStoreACP
, (IUnknown
*)This
->pITextStoreACPSink
);
853 if (ITextStoreACPSink_Release(This
->pITextStoreACPSink
) == 0)
854 This
->pITextStoreACPSink
= NULL
;
856 This
->connected
= FALSE
;
857 This
->manager
= NULL
;
861 /**************************************************************************
863 **************************************************************************/
865 static void TextStoreACPSink_Destructor(TextStoreACPSink
*This
)
867 TRACE("destroying %p\n", This
);
868 HeapFree(GetProcessHeap(),0,This
);
871 static HRESULT WINAPI
TextStoreACPSink_QueryInterface(ITextStoreACPSink
*iface
, REFIID iid
, LPVOID
*ppvOut
)
873 TextStoreACPSink
*This
= impl_from_ITextStoreACPSink(iface
);
876 if (IsEqualIID(iid
, &IID_IUnknown
) || IsEqualIID(iid
, &IID_ITextStoreACPSink
))
878 *ppvOut
= &This
->ITextStoreACPSink_iface
;
883 ITextStoreACPSink_AddRef(iface
);
887 WARN("unsupported interface: %s\n", debugstr_guid(iid
));
888 return E_NOINTERFACE
;
891 static ULONG WINAPI
TextStoreACPSink_AddRef(ITextStoreACPSink
*iface
)
893 TextStoreACPSink
*This
= impl_from_ITextStoreACPSink(iface
);
894 return InterlockedIncrement(&This
->refCount
);
897 static ULONG WINAPI
TextStoreACPSink_Release(ITextStoreACPSink
*iface
)
899 TextStoreACPSink
*This
= impl_from_ITextStoreACPSink(iface
);
902 ret
= InterlockedDecrement(&This
->refCount
);
904 TextStoreACPSink_Destructor(This
);
908 /*****************************************************
909 * ITextStoreACPSink functions
910 *****************************************************/
912 static HRESULT WINAPI
TextStoreACPSink_OnTextChange(ITextStoreACPSink
*iface
,
913 DWORD dwFlags
, const TS_TEXTCHANGE
*pChange
)
915 TextStoreACPSink
*This
= impl_from_ITextStoreACPSink(iface
);
916 FIXME("STUB:(%p)\n",This
);
920 static HRESULT WINAPI
TextStoreACPSink_OnSelectionChange(ITextStoreACPSink
*iface
)
922 TextStoreACPSink
*This
= impl_from_ITextStoreACPSink(iface
);
923 FIXME("STUB:(%p)\n",This
);
927 static HRESULT WINAPI
TextStoreACPSink_OnLayoutChange(ITextStoreACPSink
*iface
,
928 TsLayoutCode lcode
, TsViewCookie vcView
)
930 TextStoreACPSink
*This
= impl_from_ITextStoreACPSink(iface
);
931 FIXME("STUB:(%p)\n",This
);
935 static HRESULT WINAPI
TextStoreACPSink_OnStatusChange(ITextStoreACPSink
*iface
,
938 TextStoreACPSink
*This
= impl_from_ITextStoreACPSink(iface
);
939 HRESULT hr
, hrSession
;
941 TRACE("(%p) %x\n",This
, dwFlags
);
945 ERR("No context?\n");
949 if (!This
->pContext
->pITextStoreACP
)
951 FIXME("Context does not have a ITextStoreACP\n");
955 hr
= ITextStoreACP_RequestLock(This
->pContext
->pITextStoreACP
, TS_LF_READ
, &hrSession
);
957 if(SUCCEEDED(hr
) && SUCCEEDED(hrSession
))
958 This
->pContext
->documentStatus
.dwDynamicFlags
= dwFlags
;
963 static HRESULT WINAPI
TextStoreACPSink_OnAttrsChange(ITextStoreACPSink
*iface
,
964 LONG acpStart
, LONG acpEnd
, ULONG cAttrs
, const TS_ATTRID
*paAttrs
)
966 TextStoreACPSink
*This
= impl_from_ITextStoreACPSink(iface
);
967 FIXME("STUB:(%p)\n",This
);
971 static HRESULT WINAPI
TextStoreACPSink_OnLockGranted(ITextStoreACPSink
*iface
,
974 TextStoreACPSink
*This
= impl_from_ITextStoreACPSink(iface
);
976 EditCookie
*cookie
,*sinkcookie
;
980 TRACE("(%p) %x\n",This
, dwLockFlags
);
984 ERR("OnLockGranted called without a context\n");
988 if (!This
->pContext
->currentEditSession
)
990 FIXME("OnLockGranted called for something other than an EditSession\n");
994 cookie
= HeapAlloc(GetProcessHeap(),0,sizeof(EditCookie
));
996 return E_OUTOFMEMORY
;
998 sinkcookie
= HeapAlloc(GetProcessHeap(),0,sizeof(EditCookie
));
1001 HeapFree(GetProcessHeap(), 0, cookie
);
1002 return E_OUTOFMEMORY
;
1005 cookie
->lockType
= dwLockFlags
;
1006 cookie
->pOwningContext
= This
->pContext
;
1007 ec
= generate_Cookie(COOKIE_MAGIC_EDITCOOKIE
, cookie
);
1009 hr
= ITfEditSession_DoEditSession(This
->pContext
->currentEditSession
, ec
);
1011 if ((dwLockFlags
&TS_LF_READWRITE
) == TS_LF_READWRITE
)
1015 sinkcookie
->lockType
= TS_LF_READ
;
1016 sinkcookie
->pOwningContext
= This
->pContext
;
1017 sc
= generate_Cookie(COOKIE_MAGIC_EDITCOOKIE
, sinkcookie
);
1019 /*TODO: implement ITfEditRecord */
1020 LIST_FOR_EACH(cursor
, &This
->pContext
->pTextEditSink
)
1022 ContextSink
* sink
= LIST_ENTRY(cursor
,ContextSink
,entry
);
1023 ITfTextEditSink_OnEndEdit(sink
->interfaces
.pITfTextEditSink
,
1024 (ITfContext
*) &This
->pContext
, sc
, NULL
);
1026 sinkcookie
= remove_Cookie(sc
);
1028 HeapFree(GetProcessHeap(),0,sinkcookie
);
1030 ITfEditSession_Release(This
->pContext
->currentEditSession
);
1031 This
->pContext
->currentEditSession
= NULL
;
1033 /* Edit Cookie is only valid during the edit session */
1034 cookie
= remove_Cookie(ec
);
1035 HeapFree(GetProcessHeap(),0,cookie
);
1040 static HRESULT WINAPI
TextStoreACPSink_OnStartEditTransaction(ITextStoreACPSink
*iface
)
1042 TextStoreACPSink
*This
= impl_from_ITextStoreACPSink(iface
);
1043 FIXME("STUB:(%p)\n",This
);
1047 static HRESULT WINAPI
TextStoreACPSink_OnEndEditTransaction(ITextStoreACPSink
*iface
)
1049 TextStoreACPSink
*This
= impl_from_ITextStoreACPSink(iface
);
1050 FIXME("STUB:(%p)\n",This
);
1054 static const ITextStoreACPSinkVtbl TextStoreACPSinkVtbl
=
1056 TextStoreACPSink_QueryInterface
,
1057 TextStoreACPSink_AddRef
,
1058 TextStoreACPSink_Release
,
1059 TextStoreACPSink_OnTextChange
,
1060 TextStoreACPSink_OnSelectionChange
,
1061 TextStoreACPSink_OnLayoutChange
,
1062 TextStoreACPSink_OnStatusChange
,
1063 TextStoreACPSink_OnAttrsChange
,
1064 TextStoreACPSink_OnLockGranted
,
1065 TextStoreACPSink_OnStartEditTransaction
,
1066 TextStoreACPSink_OnEndEditTransaction
1069 static HRESULT
TextStoreACPSink_Constructor(ITextStoreACPSink
**ppOut
, Context
*pContext
)
1071 TextStoreACPSink
*This
;
1073 This
= HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY
,sizeof(TextStoreACPSink
));
1075 return E_OUTOFMEMORY
;
1077 This
->ITextStoreACPSink_iface
.lpVtbl
= &TextStoreACPSinkVtbl
;
1080 This
->pContext
= pContext
;
1082 *ppOut
= &This
->ITextStoreACPSink_iface
;
1083 TRACE("returning %p\n", *ppOut
);