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
25 #include "wine/debug.h"
36 #include "msctf_internal.h"
38 WINE_DEFAULT_DEBUG_CHANNEL(msctf
);
40 typedef struct tagContext
{
41 ITfContext ITfContext_iface
;
42 ITfSource ITfSource_iface
;
43 /* const ITfContextCompositionVtbl *ContextCompositionVtbl; */
44 ITfContextOwnerCompositionServices ITfContextOwnerCompositionServices_iface
;
45 /* const ITfContextOwnerServicesVtbl *ContextOwnerServicesVtbl; */
46 ITfInsertAtSelection ITfInsertAtSelection_iface
;
47 /* const ITfMouseTrackerVtbl *MouseTrackerVtbl; */
48 /* const ITfQueryEmbeddedVtbl *QueryEmbeddedVtbl; */
49 ITfSourceSingle ITfSourceSingle_iface
;
50 ITextStoreACPSink ITextStoreACPSink_iface
;
51 ITextStoreACPServices ITextStoreACPServices_iface
;
56 ITfCompartmentMgr
*CompartmentMgr
;
59 TfEditCookie defaultCookie
;
60 TS_STATUS documentStatus
;
61 ITfDocumentMgr
*manager
;
63 ITextStoreACP
*pITextStoreACP
;
64 ITfContextOwnerCompositionSink
*pITfContextOwnerCompositionSink
;
66 ITfEditSession
* currentEditSession
;
68 /* kept as separate lists to reduce unnecessary iterations */
69 struct list pContextKeyEventSink
;
70 struct list pEditTransactionSink
;
71 struct list pStatusSink
;
72 struct list pTextEditSink
;
73 struct list pTextLayoutSink
;
77 typedef struct tagEditCookie
{
79 Context
*pOwningContext
;
82 static inline Context
*impl_from_ITfContext(ITfContext
*iface
)
84 return CONTAINING_RECORD(iface
, Context
, ITfContext_iface
);
87 static inline Context
*impl_from_ITfSource(ITfSource
*iface
)
89 return CONTAINING_RECORD(iface
, Context
, ITfSource_iface
);
92 static inline Context
*impl_from_ITfContextOwnerCompositionServices(ITfContextOwnerCompositionServices
*iface
)
94 return CONTAINING_RECORD(iface
, Context
, ITfContextOwnerCompositionServices_iface
);
97 static inline Context
*impl_from_ITfInsertAtSelection(ITfInsertAtSelection
*iface
)
99 return CONTAINING_RECORD(iface
, Context
, ITfInsertAtSelection_iface
);
102 static inline Context
*impl_from_ITfSourceSingle(ITfSourceSingle
* iface
)
104 return CONTAINING_RECORD(iface
, Context
, ITfSourceSingle_iface
);
107 static inline Context
*impl_from_ITextStoreACPSink(ITextStoreACPSink
*iface
)
109 return CONTAINING_RECORD(iface
, Context
, ITextStoreACPSink_iface
);
112 static inline Context
*impl_from_ITextStoreACPServices(ITextStoreACPServices
*iface
)
114 return CONTAINING_RECORD(iface
, Context
, ITextStoreACPServices_iface
);
117 static void Context_Destructor(Context
*This
)
120 TRACE("destroying %p\n", This
);
122 if (This
->pITextStoreACP
)
123 ITextStoreACP_Release(This
->pITextStoreACP
);
125 if (This
->pITfContextOwnerCompositionSink
)
126 ITfContextOwnerCompositionSink_Release(This
->pITfContextOwnerCompositionSink
);
128 if (This
->defaultCookie
)
130 cookie
= remove_Cookie(This
->defaultCookie
);
132 This
->defaultCookie
= 0;
135 free_sinks(&This
->pContextKeyEventSink
);
136 free_sinks(&This
->pEditTransactionSink
);
137 free_sinks(&This
->pStatusSink
);
138 free_sinks(&This
->pTextEditSink
);
139 free_sinks(&This
->pTextLayoutSink
);
141 CompartmentMgr_Destructor(This
->CompartmentMgr
);
145 static HRESULT WINAPI
Context_QueryInterface(ITfContext
*iface
, REFIID iid
, LPVOID
*ppvOut
)
147 Context
*This
= impl_from_ITfContext(iface
);
150 if (IsEqualIID(iid
, &IID_IUnknown
) || IsEqualIID(iid
, &IID_ITfContext
))
152 *ppvOut
= &This
->ITfContext_iface
;
154 else if (IsEqualIID(iid
, &IID_ITfSource
))
156 *ppvOut
= &This
->ITfSource_iface
;
158 else if (IsEqualIID(iid
, &IID_ITfContextOwnerCompositionServices
))
160 *ppvOut
= &This
->ITfContextOwnerCompositionServices_iface
;
162 else if (IsEqualIID(iid
, &IID_ITfInsertAtSelection
))
164 *ppvOut
= &This
->ITfInsertAtSelection_iface
;
166 else if (IsEqualIID(iid
, &IID_ITfCompartmentMgr
))
168 *ppvOut
= This
->CompartmentMgr
;
170 else if (IsEqualIID(iid
, &IID_ITfSourceSingle
))
172 *ppvOut
= &This
->ITfSourceSingle_iface
;
177 ITfContext_AddRef(iface
);
181 WARN("unsupported interface: %s\n", debugstr_guid(iid
));
182 return E_NOINTERFACE
;
185 static ULONG WINAPI
Context_AddRef(ITfContext
*iface
)
187 Context
*This
= impl_from_ITfContext(iface
);
188 return InterlockedIncrement(&This
->refCount
);
191 static ULONG WINAPI
Context_Release(ITfContext
*iface
)
193 Context
*This
= impl_from_ITfContext(iface
);
196 ret
= InterlockedDecrement(&This
->refCount
);
198 Context_Destructor(This
);
202 /*****************************************************
203 * ITfContext functions
204 *****************************************************/
205 static HRESULT WINAPI
Context_RequestEditSession (ITfContext
*iface
,
206 TfClientId tid
, ITfEditSession
*pes
, DWORD dwFlags
,
209 Context
*This
= impl_from_ITfContext(iface
);
211 DWORD dwLockFlags
= 0x0;
213 TRACE("(%p) %li %p %lx %p\n",This
, tid
, pes
, dwFlags
, phrSession
);
215 if (!(dwFlags
& TF_ES_READ
) && !(dwFlags
& TF_ES_READWRITE
))
217 *phrSession
= E_FAIL
;
221 if (!This
->pITextStoreACP
)
223 FIXME("No ITextStoreACP available\n");
224 *phrSession
= E_FAIL
;
228 if (!(dwFlags
& TF_ES_ASYNC
))
229 dwLockFlags
|= TS_LF_SYNC
;
231 if ((dwFlags
& TF_ES_READWRITE
) == TF_ES_READWRITE
)
232 dwLockFlags
|= TS_LF_READWRITE
;
233 else if (dwFlags
& TF_ES_READ
)
234 dwLockFlags
|= TS_LF_READ
;
236 if (!This
->documentStatus
.dwDynamicFlags
)
237 ITextStoreACP_GetStatus(This
->pITextStoreACP
, &This
->documentStatus
);
239 if (((dwFlags
& TF_ES_READWRITE
) == TF_ES_READWRITE
) && (This
->documentStatus
.dwDynamicFlags
& TS_SD_READONLY
))
241 *phrSession
= TS_E_READONLY
;
245 if (FAILED (ITfEditSession_QueryInterface(pes
, &IID_ITfEditSession
, (LPVOID
*)&This
->currentEditSession
)))
247 *phrSession
= E_FAIL
;
251 hr
= ITextStoreACP_RequestLock(This
->pITextStoreACP
, dwLockFlags
, phrSession
);
256 static HRESULT WINAPI
Context_InWriteSession (ITfContext
*iface
,
258 BOOL
*pfWriteSession
)
260 Context
*This
= impl_from_ITfContext(iface
);
261 FIXME("STUB:(%p)\n",This
);
265 static HRESULT WINAPI
Context_GetSelection (ITfContext
*iface
,
266 TfEditCookie ec
, ULONG ulIndex
, ULONG ulCount
,
267 TF_SELECTION
*pSelection
, ULONG
*pcFetched
)
269 Context
*This
= impl_from_ITfContext(iface
);
271 ULONG totalFetched
= 0;
274 if (!pSelection
|| !pcFetched
)
279 if (!This
->connected
)
280 return TF_E_DISCONNECTED
;
282 if (get_Cookie_magic(ec
)!=COOKIE_MAGIC_EDITCOOKIE
)
285 if (!This
->pITextStoreACP
)
287 FIXME("Context does not have a ITextStoreACP\n");
291 if (ulIndex
== TF_DEFAULT_SELECTION
)
296 for (i
= 0; i
< count
; i
++)
299 TS_SELECTION_ACP acps
;
301 hr
= ITextStoreACP_GetSelection(This
->pITextStoreACP
, ulIndex
+ i
,
304 if (hr
== TS_E_NOLOCK
)
306 else if (SUCCEEDED(hr
))
308 pSelection
[totalFetched
].style
.ase
= (TfActiveSelEnd
)acps
.style
.ase
;
309 pSelection
[totalFetched
].style
.fInterimChar
= acps
.style
.fInterimChar
;
310 Range_Constructor(iface
, acps
.acpStart
, acps
.acpEnd
, &pSelection
[totalFetched
].range
);
317 *pcFetched
= totalFetched
;
322 static HRESULT WINAPI
Context_SetSelection (ITfContext
*iface
,
323 TfEditCookie ec
, ULONG ulCount
, const TF_SELECTION
*pSelection
)
325 Context
*This
= impl_from_ITfContext(iface
);
326 TS_SELECTION_ACP
*acp
;
330 TRACE("(%p) %li %li %p\n",This
,ec
,ulCount
,pSelection
);
332 if (!This
->pITextStoreACP
)
334 FIXME("Context does not have a ITextStoreACP\n");
338 if (get_Cookie_magic(ec
)!=COOKIE_MAGIC_EDITCOOKIE
)
341 acp
= malloc(sizeof(TS_SELECTION_ACP
) * ulCount
);
343 return E_OUTOFMEMORY
;
345 for (i
= 0; i
< ulCount
; i
++)
346 if (FAILED(TF_SELECTION_to_TS_SELECTION_ACP(&pSelection
[i
], &acp
[i
])))
348 TRACE("Selection Conversion Failed\n");
353 hr
= ITextStoreACP_SetSelection(This
->pITextStoreACP
, ulCount
, acp
);
360 static HRESULT WINAPI
Context_GetStart (ITfContext
*iface
,
361 TfEditCookie ec
, ITfRange
**ppStart
)
363 Context
*This
= impl_from_ITfContext(iface
);
365 TRACE("(%p) %li %p\n",This
,ec
,ppStart
);
372 if (!This
->connected
)
373 return TF_E_DISCONNECTED
;
375 if (get_Cookie_magic(ec
)!=COOKIE_MAGIC_EDITCOOKIE
)
378 return Range_Constructor(iface
, 0, 0, ppStart
);
381 static HRESULT WINAPI
Context_GetEnd (ITfContext
*iface
,
382 TfEditCookie ec
, ITfRange
**ppEnd
)
384 Context
*This
= impl_from_ITfContext(iface
);
386 TRACE("(%p) %li %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 ITextStoreACP_GetEndACP(This
->pITextStoreACP
,&end
);
407 return Range_Constructor(iface
, end
, end
, ppEnd
);
410 static HRESULT WINAPI
Context_GetActiveView (ITfContext
*iface
,
411 ITfContextView
**ppView
)
413 Context
*This
= impl_from_ITfContext(iface
);
414 FIXME("STUB:(%p)\n",This
);
418 static HRESULT WINAPI
Context_EnumViews (ITfContext
*iface
,
419 IEnumTfContextViews
**ppEnum
)
421 Context
*This
= impl_from_ITfContext(iface
);
422 FIXME("STUB:(%p)\n",This
);
426 static HRESULT WINAPI
Context_GetStatus (ITfContext
*iface
,
429 Context
*This
= impl_from_ITfContext(iface
);
430 TRACE("(%p) %p\n",This
,pdcs
);
432 if (!This
->connected
)
433 return TF_E_DISCONNECTED
;
438 if (!This
->pITextStoreACP
)
440 FIXME("Context does not have a ITextStoreACP\n");
444 ITextStoreACP_GetStatus(This
->pITextStoreACP
, &This
->documentStatus
);
446 *pdcs
= This
->documentStatus
;
451 static HRESULT WINAPI
Context_GetProperty (ITfContext
*iface
,
452 REFGUID guidProp
, ITfProperty
**ppProp
)
454 Context
*This
= impl_from_ITfContext(iface
);
455 FIXME("STUB:(%p)\n",This
);
459 static HRESULT WINAPI
Context_GetAppProperty (ITfContext
*iface
,
460 REFGUID guidProp
, ITfReadOnlyProperty
**ppProp
)
462 Context
*This
= impl_from_ITfContext(iface
);
463 FIXME("STUB:(%p)\n",This
);
467 static HRESULT WINAPI
Context_TrackProperties (ITfContext
*iface
,
468 const GUID
**prgProp
, ULONG cProp
, const GUID
**prgAppProp
,
469 ULONG cAppProp
, ITfReadOnlyProperty
**ppProperty
)
471 Context
*This
= impl_from_ITfContext(iface
);
472 FIXME("STUB:(%p)\n",This
);
476 static HRESULT WINAPI
Context_EnumProperties (ITfContext
*iface
,
477 IEnumTfProperties
**ppEnum
)
479 Context
*This
= impl_from_ITfContext(iface
);
480 FIXME("STUB:(%p)\n",This
);
484 static HRESULT WINAPI
Context_GetDocumentMgr (ITfContext
*iface
,
485 ITfDocumentMgr
**ppDm
)
487 Context
*This
= impl_from_ITfContext(iface
);
488 TRACE("(%p) %p\n",This
,ppDm
);
493 *ppDm
= This
->manager
;
497 ITfDocumentMgr_AddRef(This
->manager
);
502 static HRESULT WINAPI
Context_CreateRangeBackup (ITfContext
*iface
,
503 TfEditCookie ec
, ITfRange
*pRange
, ITfRangeBackup
**ppBackup
)
505 Context
*This
= impl_from_ITfContext(iface
);
506 FIXME("STUB:(%p)\n",This
);
510 static const ITfContextVtbl ContextVtbl
=
512 Context_QueryInterface
,
515 Context_RequestEditSession
,
516 Context_InWriteSession
,
517 Context_GetSelection
,
518 Context_SetSelection
,
521 Context_GetActiveView
,
525 Context_GetAppProperty
,
526 Context_TrackProperties
,
527 Context_EnumProperties
,
528 Context_GetDocumentMgr
,
529 Context_CreateRangeBackup
532 /*****************************************************
533 * ITfSource functions
534 *****************************************************/
535 static HRESULT WINAPI
ContextSource_QueryInterface(ITfSource
*iface
, REFIID iid
, LPVOID
*ppvOut
)
537 Context
*This
= impl_from_ITfSource(iface
);
538 return ITfContext_QueryInterface(&This
->ITfContext_iface
, iid
, ppvOut
);
541 static ULONG WINAPI
ContextSource_AddRef(ITfSource
*iface
)
543 Context
*This
= impl_from_ITfSource(iface
);
544 return ITfContext_AddRef(&This
->ITfContext_iface
);
547 static ULONG WINAPI
ContextSource_Release(ITfSource
*iface
)
549 Context
*This
= impl_from_ITfSource(iface
);
550 return ITfContext_Release(&This
->ITfContext_iface
);
553 static HRESULT WINAPI
ContextSource_AdviseSink(ITfSource
*iface
,
554 REFIID riid
, IUnknown
*punk
, DWORD
*pdwCookie
)
556 Context
*This
= impl_from_ITfSource(iface
);
558 TRACE("(%p) %s %p %p\n",This
,debugstr_guid(riid
),punk
,pdwCookie
);
560 if (!riid
|| !punk
|| !pdwCookie
)
563 if (IsEqualIID(riid
, &IID_ITfTextEditSink
))
564 return advise_sink(&This
->pTextEditSink
, &IID_ITfTextEditSink
, COOKIE_MAGIC_CONTEXTSINK
, punk
, pdwCookie
);
566 FIXME("(%p) Unhandled Sink: %s\n",This
,debugstr_guid(riid
));
570 static HRESULT WINAPI
ContextSource_UnadviseSink(ITfSource
*iface
, DWORD pdwCookie
)
572 Context
*This
= impl_from_ITfSource(iface
);
574 TRACE("(%p) %lx\n",This
,pdwCookie
);
576 if (get_Cookie_magic(pdwCookie
)!=COOKIE_MAGIC_CONTEXTSINK
)
579 return unadvise_sink(pdwCookie
);
582 static const ITfSourceVtbl ContextSourceVtbl
=
584 ContextSource_QueryInterface
,
585 ContextSource_AddRef
,
586 ContextSource_Release
,
587 ContextSource_AdviseSink
,
588 ContextSource_UnadviseSink
591 /*****************************************************
592 * ITfContextOwnerCompositionServices functions
593 *****************************************************/
594 static HRESULT WINAPI
ContextOwnerCompositionServices_QueryInterface(ITfContextOwnerCompositionServices
*iface
,
595 REFIID iid
, LPVOID
*ppvOut
)
597 Context
*This
= impl_from_ITfContextOwnerCompositionServices(iface
);
598 return ITfContext_QueryInterface(&This
->ITfContext_iface
, iid
, ppvOut
);
601 static ULONG WINAPI
ContextOwnerCompositionServices_AddRef(ITfContextOwnerCompositionServices
*iface
)
603 Context
*This
= impl_from_ITfContextOwnerCompositionServices(iface
);
604 return ITfContext_AddRef(&This
->ITfContext_iface
);
607 static ULONG WINAPI
ContextOwnerCompositionServices_Release(ITfContextOwnerCompositionServices
*iface
)
609 Context
*This
= impl_from_ITfContextOwnerCompositionServices(iface
);
610 return ITfContext_Release(&This
->ITfContext_iface
);
613 static HRESULT WINAPI
ContextOwnerCompositionServices_StartComposition(ITfContextOwnerCompositionServices
*iface
,
614 TfEditCookie ecWrite
, ITfRange
*pCompositionRange
, ITfCompositionSink
*pSink
, ITfComposition
**ppComposition
)
616 Context
*This
= impl_from_ITfContextOwnerCompositionServices(iface
);
617 FIXME("STUB:(%p) %#lx %p %p %p\n", This
, ecWrite
, pCompositionRange
, pSink
, ppComposition
);
621 static HRESULT WINAPI
ContextOwnerCompositionServices_EnumCompositions(ITfContextOwnerCompositionServices
*iface
,
622 IEnumITfCompositionView
**ppEnum
)
624 Context
*This
= impl_from_ITfContextOwnerCompositionServices(iface
);
625 FIXME("STUB:(%p) %p\n", This
, ppEnum
);
629 static HRESULT WINAPI
ContextOwnerCompositionServices_FindComposition(ITfContextOwnerCompositionServices
*iface
,
630 TfEditCookie ecRead
, ITfRange
*pTestRange
, IEnumITfCompositionView
**ppEnum
)
632 Context
*This
= impl_from_ITfContextOwnerCompositionServices(iface
);
633 FIXME("STUB:(%p) %#lx %p %p\n", This
, ecRead
, pTestRange
, ppEnum
);
637 static HRESULT WINAPI
ContextOwnerCompositionServices_TakeOwnership(ITfContextOwnerCompositionServices
*iface
,
638 TfEditCookie ecWrite
, ITfCompositionView
*pComposition
, ITfCompositionSink
*pSink
, ITfComposition
**ppComposition
)
640 Context
*This
= impl_from_ITfContextOwnerCompositionServices(iface
);
641 FIXME("STUB:(%p) %#lx %p %p %p\n", This
, ecWrite
, pComposition
, pSink
, ppComposition
);
645 static HRESULT WINAPI
ContextOwnerCompositionServices_TerminateComposition(ITfContextOwnerCompositionServices
*iface
,
646 ITfCompositionView
*pComposition
)
648 Context
*This
= impl_from_ITfContextOwnerCompositionServices(iface
);
649 FIXME("STUB:(%p) %p\n", This
, pComposition
);
653 static const ITfContextOwnerCompositionServicesVtbl ContextOwnerCompositionServicesVtbl
=
655 ContextOwnerCompositionServices_QueryInterface
,
656 ContextOwnerCompositionServices_AddRef
,
657 ContextOwnerCompositionServices_Release
,
658 ContextOwnerCompositionServices_StartComposition
,
659 ContextOwnerCompositionServices_EnumCompositions
,
660 ContextOwnerCompositionServices_FindComposition
,
661 ContextOwnerCompositionServices_TakeOwnership
,
662 ContextOwnerCompositionServices_TerminateComposition
665 /*****************************************************
666 * ITfInsertAtSelection functions
667 *****************************************************/
668 static HRESULT WINAPI
InsertAtSelection_QueryInterface(ITfInsertAtSelection
*iface
, REFIID iid
, LPVOID
*ppvOut
)
670 Context
*This
= impl_from_ITfInsertAtSelection(iface
);
671 return ITfContext_QueryInterface(&This
->ITfContext_iface
, iid
, ppvOut
);
674 static ULONG WINAPI
InsertAtSelection_AddRef(ITfInsertAtSelection
*iface
)
676 Context
*This
= impl_from_ITfInsertAtSelection(iface
);
677 return ITfContext_AddRef(&This
->ITfContext_iface
);
680 static ULONG WINAPI
InsertAtSelection_Release(ITfInsertAtSelection
*iface
)
682 Context
*This
= impl_from_ITfInsertAtSelection(iface
);
683 return ITfContext_Release(&This
->ITfContext_iface
);
686 static HRESULT WINAPI
InsertAtSelection_InsertTextAtSelection(
687 ITfInsertAtSelection
*iface
, TfEditCookie ec
, DWORD dwFlags
,
688 const WCHAR
*pchText
, LONG cch
, ITfRange
**ppRange
)
690 Context
*This
= impl_from_ITfInsertAtSelection(iface
);
692 LONG acpStart
, acpEnd
;
693 TS_TEXTCHANGE change
;
696 TRACE("(%p) %li %lx %s %p\n",This
, ec
, dwFlags
, debugstr_wn(pchText
,cch
), ppRange
);
698 if (!This
->connected
)
699 return TF_E_DISCONNECTED
;
701 if (get_Cookie_magic(ec
)!=COOKIE_MAGIC_EDITCOOKIE
)
704 cookie
= get_Cookie_data(ec
);
706 if ((cookie
->lockType
& TS_LF_READWRITE
) != TS_LF_READWRITE
)
707 return TS_E_READONLY
;
709 if (!This
->pITextStoreACP
)
711 FIXME("Context does not have a ITextStoreACP\n");
715 hr
= ITextStoreACP_InsertTextAtSelection(This
->pITextStoreACP
, dwFlags
, pchText
, cch
, &acpStart
, &acpEnd
, &change
);
717 Range_Constructor(&This
->ITfContext_iface
, change
.acpStart
, change
.acpNewEnd
, ppRange
);
722 static HRESULT WINAPI
InsertAtSelection_InsertEmbeddedAtSelection(
723 ITfInsertAtSelection
*iface
, TfEditCookie ec
, DWORD dwFlags
,
724 IDataObject
*pDataObject
, ITfRange
**ppRange
)
726 Context
*This
= impl_from_ITfInsertAtSelection(iface
);
727 FIXME("STUB:(%p)\n",This
);
731 static const ITfInsertAtSelectionVtbl InsertAtSelectionVtbl
=
733 InsertAtSelection_QueryInterface
,
734 InsertAtSelection_AddRef
,
735 InsertAtSelection_Release
,
736 InsertAtSelection_InsertTextAtSelection
,
737 InsertAtSelection_InsertEmbeddedAtSelection
,
740 /*****************************************************
741 * ITfSourceSingle functions
742 *****************************************************/
743 static HRESULT WINAPI
SourceSingle_QueryInterface(ITfSourceSingle
*iface
, REFIID iid
, LPVOID
*ppvOut
)
745 Context
*This
= impl_from_ITfSourceSingle(iface
);
746 return ITfContext_QueryInterface(&This
->ITfContext_iface
, iid
, ppvOut
);
749 static ULONG WINAPI
SourceSingle_AddRef(ITfSourceSingle
*iface
)
751 Context
*This
= impl_from_ITfSourceSingle(iface
);
752 return ITfContext_AddRef(&This
->ITfContext_iface
);
755 static ULONG WINAPI
SourceSingle_Release(ITfSourceSingle
*iface
)
757 Context
*This
= impl_from_ITfSourceSingle(iface
);
758 return ITfContext_Release(&This
->ITfContext_iface
);
761 static HRESULT WINAPI
SourceSingle_AdviseSingleSink( ITfSourceSingle
*iface
,
762 TfClientId tid
, REFIID riid
, IUnknown
*punk
)
764 Context
*This
= impl_from_ITfSourceSingle(iface
);
765 FIXME("STUB:(%p) %li %s %p\n",This
, tid
, debugstr_guid(riid
),punk
);
769 static HRESULT WINAPI
SourceSingle_UnadviseSingleSink( ITfSourceSingle
*iface
,
770 TfClientId tid
, REFIID riid
)
772 Context
*This
= impl_from_ITfSourceSingle(iface
);
773 FIXME("STUB:(%p) %li %s\n",This
, tid
, debugstr_guid(riid
));
777 static const ITfSourceSingleVtbl ContextSourceSingleVtbl
=
779 SourceSingle_QueryInterface
,
781 SourceSingle_Release
,
782 SourceSingle_AdviseSingleSink
,
783 SourceSingle_UnadviseSingleSink
,
786 /**************************************************************************
788 **************************************************************************/
790 static HRESULT WINAPI
TextStoreACPSink_QueryInterface(ITextStoreACPSink
*iface
, REFIID iid
, LPVOID
*ppvOut
)
792 Context
*This
= impl_from_ITextStoreACPSink(iface
);
796 if (IsEqualIID(iid
, &IID_IUnknown
) || IsEqualIID(iid
, &IID_ITextStoreACPSink
))
798 *ppvOut
= &This
->ITextStoreACPSink_iface
;
800 else if (IsEqualIID(iid
, &IID_ITextStoreACPServices
))
801 *ppvOut
= &This
->ITextStoreACPServices_iface
;
805 ITextStoreACPSink_AddRef(iface
);
809 WARN("unsupported interface: %s\n", debugstr_guid(iid
));
810 return E_NOINTERFACE
;
813 static ULONG WINAPI
TextStoreACPSink_AddRef(ITextStoreACPSink
*iface
)
815 Context
*This
= impl_from_ITextStoreACPSink(iface
);
816 return ITfContext_AddRef(&This
->ITfContext_iface
);
819 static ULONG WINAPI
TextStoreACPSink_Release(ITextStoreACPSink
*iface
)
821 Context
*This
= impl_from_ITextStoreACPSink(iface
);
822 return ITfContext_Release(&This
->ITfContext_iface
);
825 /*****************************************************
826 * ITextStoreACPSink functions
827 *****************************************************/
829 static HRESULT WINAPI
TextStoreACPSink_OnTextChange(ITextStoreACPSink
*iface
,
830 DWORD dwFlags
, const TS_TEXTCHANGE
*pChange
)
832 Context
*This
= impl_from_ITextStoreACPSink(iface
);
833 FIXME("STUB:(%p)\n",This
);
837 static HRESULT WINAPI
TextStoreACPSink_OnSelectionChange(ITextStoreACPSink
*iface
)
839 Context
*This
= impl_from_ITextStoreACPSink(iface
);
840 FIXME("STUB:(%p)\n",This
);
844 static HRESULT WINAPI
TextStoreACPSink_OnLayoutChange(ITextStoreACPSink
*iface
,
845 TsLayoutCode lcode
, TsViewCookie vcView
)
847 Context
*This
= impl_from_ITextStoreACPSink(iface
);
848 FIXME("STUB:(%p)\n",This
);
852 static HRESULT WINAPI
TextStoreACPSink_OnStatusChange(ITextStoreACPSink
*iface
,
855 Context
*This
= impl_from_ITextStoreACPSink(iface
);
856 HRESULT hr
, hrSession
;
858 TRACE("(%p) %lx\n",This
, dwFlags
);
860 if (!This
->pITextStoreACP
)
862 FIXME("Context does not have a ITextStoreACP\n");
866 hr
= ITextStoreACP_RequestLock(This
->pITextStoreACP
, TS_LF_READ
, &hrSession
);
868 if(SUCCEEDED(hr
) && SUCCEEDED(hrSession
))
869 This
->documentStatus
.dwDynamicFlags
= dwFlags
;
874 static HRESULT WINAPI
TextStoreACPSink_OnAttrsChange(ITextStoreACPSink
*iface
,
875 LONG acpStart
, LONG acpEnd
, ULONG cAttrs
, const TS_ATTRID
*paAttrs
)
877 Context
*This
= impl_from_ITextStoreACPSink(iface
);
878 FIXME("STUB:(%p)\n",This
);
882 static HRESULT WINAPI
TextStoreACPSink_OnLockGranted(ITextStoreACPSink
*iface
,
885 Context
*This
= impl_from_ITextStoreACPSink(iface
);
887 EditCookie
*cookie
,*sinkcookie
;
891 TRACE("(%p) %lx\n",This
, dwLockFlags
);
893 if (!This
->currentEditSession
)
895 FIXME("OnLockGranted called for something other than an EditSession\n");
899 cookie
= malloc(sizeof(EditCookie
));
901 return E_OUTOFMEMORY
;
903 sinkcookie
= malloc(sizeof(EditCookie
));
907 return E_OUTOFMEMORY
;
910 cookie
->lockType
= dwLockFlags
;
911 cookie
->pOwningContext
= This
;
912 ec
= generate_Cookie(COOKIE_MAGIC_EDITCOOKIE
, cookie
);
914 hr
= ITfEditSession_DoEditSession(This
->currentEditSession
, ec
);
916 if ((dwLockFlags
&TS_LF_READWRITE
) == TS_LF_READWRITE
)
918 ITfTextEditSink
*sink
;
921 sinkcookie
->lockType
= TS_LF_READ
;
922 sinkcookie
->pOwningContext
= This
;
923 sc
= generate_Cookie(COOKIE_MAGIC_EDITCOOKIE
, sinkcookie
);
925 /*TODO: implement ITfEditRecord */
926 SINK_FOR_EACH(cursor
, &This
->pTextEditSink
, ITfTextEditSink
, sink
)
928 ITfTextEditSink_OnEndEdit(sink
, &This
->ITfContext_iface
, sc
, NULL
);
930 sinkcookie
= remove_Cookie(sc
);
934 ITfEditSession_Release(This
->currentEditSession
);
935 This
->currentEditSession
= NULL
;
937 /* Edit Cookie is only valid during the edit session */
938 cookie
= remove_Cookie(ec
);
944 static HRESULT WINAPI
TextStoreACPSink_OnStartEditTransaction(ITextStoreACPSink
*iface
)
946 Context
*This
= impl_from_ITextStoreACPSink(iface
);
947 FIXME("STUB:(%p)\n",This
);
951 static HRESULT WINAPI
TextStoreACPSink_OnEndEditTransaction(ITextStoreACPSink
*iface
)
953 Context
*This
= impl_from_ITextStoreACPSink(iface
);
954 FIXME("STUB:(%p)\n",This
);
958 static const ITextStoreACPSinkVtbl TextStoreACPSinkVtbl
=
960 TextStoreACPSink_QueryInterface
,
961 TextStoreACPSink_AddRef
,
962 TextStoreACPSink_Release
,
963 TextStoreACPSink_OnTextChange
,
964 TextStoreACPSink_OnSelectionChange
,
965 TextStoreACPSink_OnLayoutChange
,
966 TextStoreACPSink_OnStatusChange
,
967 TextStoreACPSink_OnAttrsChange
,
968 TextStoreACPSink_OnLockGranted
,
969 TextStoreACPSink_OnStartEditTransaction
,
970 TextStoreACPSink_OnEndEditTransaction
973 static HRESULT WINAPI
TextStoreACPServices_QueryInterface(ITextStoreACPServices
*iface
, REFIID riid
, void **obj
)
975 Context
*This
= impl_from_ITextStoreACPServices(iface
);
976 return ITextStoreACPSink_QueryInterface(&This
->ITextStoreACPSink_iface
, riid
, obj
);
979 static ULONG WINAPI
TextStoreACPServices_AddRef(ITextStoreACPServices
*iface
)
981 Context
*This
= impl_from_ITextStoreACPServices(iface
);
982 return ITextStoreACPSink_AddRef(&This
->ITextStoreACPSink_iface
);
985 static ULONG WINAPI
TextStoreACPServices_Release(ITextStoreACPServices
*iface
)
987 Context
*This
= impl_from_ITextStoreACPServices(iface
);
988 return ITextStoreACPSink_Release(&This
->ITextStoreACPSink_iface
);
991 static HRESULT WINAPI
TextStoreACPServices_Serialize(ITextStoreACPServices
*iface
, ITfProperty
*prop
, ITfRange
*range
,
992 TF_PERSISTENT_PROPERTY_HEADER_ACP
*header
, IStream
*stream
)
994 Context
*This
= impl_from_ITextStoreACPServices(iface
);
996 FIXME("stub: %p %p %p %p %p\n", This
, prop
, range
, header
, stream
);
1001 static HRESULT WINAPI
TextStoreACPServices_Unserialize(ITextStoreACPServices
*iface
, ITfProperty
*prop
,
1002 const TF_PERSISTENT_PROPERTY_HEADER_ACP
*header
, IStream
*stream
, ITfPersistentPropertyLoaderACP
*loader
)
1004 Context
*This
= impl_from_ITextStoreACPServices(iface
);
1006 FIXME("stub: %p %p %p %p %p\n", This
, prop
, header
, stream
, loader
);
1011 static HRESULT WINAPI
TextStoreACPServices_ForceLoadProperty(ITextStoreACPServices
*iface
, ITfProperty
*prop
)
1013 Context
*This
= impl_from_ITextStoreACPServices(iface
);
1015 FIXME("stub: %p %p\n", This
, prop
);
1020 static HRESULT WINAPI
TextStoreACPServices_CreateRange(ITextStoreACPServices
*iface
,
1021 LONG start
, LONG end
, ITfRangeACP
**range
)
1023 Context
*This
= impl_from_ITextStoreACPServices(iface
);
1025 TRACE("%p, %ld, %ld, %p.\n", This
, start
, end
, range
);
1027 return Range_Constructor(&This
->ITfContext_iface
, start
, end
, (ITfRange
**)range
);
1030 static const ITextStoreACPServicesVtbl TextStoreACPServicesVtbl
=
1032 TextStoreACPServices_QueryInterface
,
1033 TextStoreACPServices_AddRef
,
1034 TextStoreACPServices_Release
,
1035 TextStoreACPServices_Serialize
,
1036 TextStoreACPServices_Unserialize
,
1037 TextStoreACPServices_ForceLoadProperty
,
1038 TextStoreACPServices_CreateRange
1041 HRESULT
Context_Constructor(TfClientId tidOwner
, IUnknown
*punk
, ITfDocumentMgr
*mgr
, ITfContext
**ppOut
, TfEditCookie
*pecTextStore
)
1046 This
= calloc(1, sizeof(Context
));
1048 return E_OUTOFMEMORY
;
1050 cookie
= malloc(sizeof(EditCookie
));
1054 return E_OUTOFMEMORY
;
1057 TRACE("(%p) %lx %p %p %p\n",This
, tidOwner
, punk
, ppOut
, pecTextStore
);
1059 This
->ITfContext_iface
.lpVtbl
= &ContextVtbl
;
1060 This
->ITfSource_iface
.lpVtbl
= &ContextSourceVtbl
;
1061 This
->ITfContextOwnerCompositionServices_iface
.lpVtbl
= &ContextOwnerCompositionServicesVtbl
;
1062 This
->ITfInsertAtSelection_iface
.lpVtbl
= &InsertAtSelectionVtbl
;
1063 This
->ITfSourceSingle_iface
.lpVtbl
= &ContextSourceSingleVtbl
;
1064 This
->ITextStoreACPSink_iface
.lpVtbl
= &TextStoreACPSinkVtbl
;
1065 This
->ITextStoreACPServices_iface
.lpVtbl
= &TextStoreACPServicesVtbl
;
1067 This
->tidOwner
= tidOwner
;
1068 This
->connected
= FALSE
;
1069 This
->manager
= mgr
;
1071 CompartmentMgr_Constructor((IUnknown
*)&This
->ITfContext_iface
, &IID_IUnknown
, (IUnknown
**)&This
->CompartmentMgr
);
1073 cookie
->lockType
= TF_ES_READ
;
1074 cookie
->pOwningContext
= This
;
1078 IUnknown_QueryInterface(punk
, &IID_ITextStoreACP
,
1079 (LPVOID
*)&This
->pITextStoreACP
);
1081 IUnknown_QueryInterface(punk
, &IID_ITfContextOwnerCompositionSink
,
1082 (LPVOID
*)&This
->pITfContextOwnerCompositionSink
);
1084 if (!This
->pITextStoreACP
&& !This
->pITfContextOwnerCompositionSink
)
1085 FIXME("Unhandled pUnk\n");
1088 This
->defaultCookie
= generate_Cookie(COOKIE_MAGIC_EDITCOOKIE
,cookie
);
1089 *pecTextStore
= This
->defaultCookie
;
1091 list_init(&This
->pContextKeyEventSink
);
1092 list_init(&This
->pEditTransactionSink
);
1093 list_init(&This
->pStatusSink
);
1094 list_init(&This
->pTextEditSink
);
1095 list_init(&This
->pTextLayoutSink
);
1097 *ppOut
= &This
->ITfContext_iface
;
1098 TRACE("returning %p\n", *ppOut
);
1103 HRESULT
Context_Initialize(ITfContext
*iface
, ITfDocumentMgr
*manager
)
1105 Context
*This
= impl_from_ITfContext(iface
);
1107 if (This
->pITextStoreACP
)
1108 ITextStoreACP_AdviseSink(This
->pITextStoreACP
, &IID_ITextStoreACPSink
,
1109 (IUnknown
*)&This
->ITextStoreACPSink_iface
, TS_AS_ALL_SINKS
);
1110 This
->connected
= TRUE
;
1111 This
->manager
= manager
;
1115 HRESULT
Context_Uninitialize(ITfContext
*iface
)
1117 Context
*This
= impl_from_ITfContext(iface
);
1119 if (This
->pITextStoreACP
)
1120 ITextStoreACP_UnadviseSink(This
->pITextStoreACP
, (IUnknown
*)&This
->ITextStoreACPSink_iface
);
1121 This
->connected
= FALSE
;
1122 This
->manager
= NULL
;