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 #define WIN32_NO_STATUS
23 #define COM_NO_WINDOWS_H
31 #include <wine/debug.h>
35 //#include "winuser.h"
36 //#include "shlwapi.h"
37 //#include "winerror.h"
41 //#include "wine/unicode.h"
42 #include <wine/list.h>
45 #include "msctf_internal.h"
47 WINE_DEFAULT_DEBUG_CHANNEL(msctf
);
49 typedef struct tagContextSink
{
54 /* ITfContextKeyEventSink *pITfContextKeyEventSink; */
55 /* ITfEditTransactionSink *pITfEditTransactionSink; */
56 /* ITfStatusSink *pITfStatusSink; */
57 ITfTextEditSink
*pITfTextEditSink
;
58 /* ITfTextLayoutSink *pITfTextLayoutSink; */
62 typedef struct tagContext
{
63 const ITfContextVtbl
*ContextVtbl
;
64 const ITfSourceVtbl
*SourceVtbl
;
65 /* const ITfContextCompositionVtbl *ContextCompositionVtbl; */
66 /* const ITfContextOwnerCompositionServicesVtbl *ContextOwnerCompositionServicesVtbl; */
67 /* const ITfContextOwnerServicesVtbl *ContextOwnerServicesVtbl; */
68 const ITfInsertAtSelectionVtbl
*InsertAtSelectionVtbl
;
69 /* const ITfMouseTrackerVtbl *MouseTrackerVtbl; */
70 /* const ITfQueryEmbeddedVtbl *QueryEmbeddedVtbl; */
71 const ITfSourceSingleVtbl
*SourceSingleVtbl
;
76 ITfCompartmentMgr
*CompartmentMgr
;
79 TfEditCookie defaultCookie
;
80 TS_STATUS documentStatus
;
81 ITfDocumentMgr
*manager
;
83 ITextStoreACP
*pITextStoreACP
;
84 ITfContextOwnerCompositionSink
*pITfContextOwnerCompositionSink
;
86 ITextStoreACPSink
*pITextStoreACPSink
;
87 ITfEditSession
* currentEditSession
;
89 /* kept as separate lists to reduce unnecessary iterations */
90 struct list pContextKeyEventSink
;
91 struct list pEditTransactionSink
;
92 struct list pStatusSink
;
93 struct list pTextEditSink
;
94 struct list pTextLayoutSink
;
98 typedef struct tagEditCookie
{
100 Context
*pOwningContext
;
103 typedef struct tagTextStoreACPSink
{
104 const ITextStoreACPSinkVtbl
*TextStoreACPSinkVtbl
;
105 /* const ITextStoreACPServicesVtbl *TextStoreACPServicesVtbl; */
112 static HRESULT
TextStoreACPSink_Constructor(ITextStoreACPSink
**ppOut
, Context
*pContext
);
114 static inline Context
*impl_from_ITfSourceVtbl(ITfSource
*iface
)
116 return (Context
*)((char *)iface
- FIELD_OFFSET(Context
,SourceVtbl
));
119 static inline Context
*impl_from_ITfInsertAtSelectionVtbl(ITfInsertAtSelection
*iface
)
121 return (Context
*)((char *)iface
- FIELD_OFFSET(Context
,InsertAtSelectionVtbl
));
124 static inline Context
*impl_from_ITfSourceSingleVtbl(ITfSourceSingle
* iface
)
126 return (Context
*)((char *)iface
- FIELD_OFFSET(Context
,SourceSingleVtbl
));
129 static void free_sink(ContextSink
*sink
)
131 IUnknown_Release(sink
->interfaces
.pIUnknown
);
132 HeapFree(GetProcessHeap(),0,sink
);
135 static void Context_Destructor(Context
*This
)
137 struct list
*cursor
, *cursor2
;
139 TRACE("destroying %p\n", This
);
141 if (This
->pITextStoreACPSink
)
143 ITextStoreACP_UnadviseSink(This
->pITextStoreACP
, (IUnknown
*)This
->pITextStoreACPSink
);
144 ITextStoreACPSink_Release(This
->pITextStoreACPSink
);
147 if (This
->pITextStoreACP
)
148 ITextStoreACPSink_Release(This
->pITextStoreACP
);
150 if (This
->pITfContextOwnerCompositionSink
)
151 ITextStoreACPSink_Release(This
->pITfContextOwnerCompositionSink
);
153 if (This
->defaultCookie
)
155 cookie
= remove_Cookie(This
->defaultCookie
);
156 HeapFree(GetProcessHeap(),0,cookie
);
157 This
->defaultCookie
= 0;
160 LIST_FOR_EACH_SAFE(cursor
, cursor2
, &This
->pContextKeyEventSink
)
162 ContextSink
* sink
= LIST_ENTRY(cursor
,ContextSink
,entry
);
166 LIST_FOR_EACH_SAFE(cursor
, cursor2
, &This
->pEditTransactionSink
)
168 ContextSink
* sink
= LIST_ENTRY(cursor
,ContextSink
,entry
);
172 LIST_FOR_EACH_SAFE(cursor
, cursor2
, &This
->pStatusSink
)
174 ContextSink
* sink
= LIST_ENTRY(cursor
,ContextSink
,entry
);
178 LIST_FOR_EACH_SAFE(cursor
, cursor2
, &This
->pTextEditSink
)
180 ContextSink
* sink
= LIST_ENTRY(cursor
,ContextSink
,entry
);
184 LIST_FOR_EACH_SAFE(cursor
, cursor2
, &This
->pTextLayoutSink
)
186 ContextSink
* sink
= LIST_ENTRY(cursor
,ContextSink
,entry
);
191 CompartmentMgr_Destructor(This
->CompartmentMgr
);
192 HeapFree(GetProcessHeap(),0,This
);
195 static HRESULT WINAPI
Context_QueryInterface(ITfContext
*iface
, REFIID iid
, LPVOID
*ppvOut
)
197 Context
*This
= (Context
*)iface
;
200 if (IsEqualIID(iid
, &IID_IUnknown
) || IsEqualIID(iid
, &IID_ITfContext
))
204 else if (IsEqualIID(iid
, &IID_ITfSource
))
206 *ppvOut
= &This
->SourceVtbl
;
208 else if (IsEqualIID(iid
, &IID_ITfInsertAtSelection
))
210 *ppvOut
= &This
->InsertAtSelectionVtbl
;
212 else if (IsEqualIID(iid
, &IID_ITfCompartmentMgr
))
214 *ppvOut
= This
->CompartmentMgr
;
216 else if (IsEqualIID(iid
, &IID_ITfSourceSingle
))
218 *ppvOut
= &This
->SourceSingleVtbl
;
223 IUnknown_AddRef(iface
);
227 WARN("unsupported interface: %s\n", debugstr_guid(iid
));
228 return E_NOINTERFACE
;
231 static ULONG WINAPI
Context_AddRef(ITfContext
*iface
)
233 Context
*This
= (Context
*)iface
;
234 return InterlockedIncrement(&This
->refCount
);
237 static ULONG WINAPI
Context_Release(ITfContext
*iface
)
239 Context
*This
= (Context
*)iface
;
242 ret
= InterlockedDecrement(&This
->refCount
);
244 Context_Destructor(This
);
248 /*****************************************************
249 * ITfContext functions
250 *****************************************************/
251 static HRESULT WINAPI
Context_RequestEditSession (ITfContext
*iface
,
252 TfClientId tid
, ITfEditSession
*pes
, DWORD dwFlags
,
256 Context
*This
= (Context
*)iface
;
257 DWORD dwLockFlags
= 0x0;
259 TRACE("(%p) %i %p %x %p\n",This
, tid
, pes
, dwFlags
, phrSession
);
261 if (!(dwFlags
& TF_ES_READ
) && !(dwFlags
& TF_ES_READWRITE
))
263 *phrSession
= E_FAIL
;
267 if (!This
->pITextStoreACP
)
269 FIXME("No ITextStoreACP available\n");
270 *phrSession
= E_FAIL
;
274 if (!(dwFlags
& TF_ES_ASYNC
))
275 dwLockFlags
|= TS_LF_SYNC
;
277 if ((dwFlags
& TF_ES_READWRITE
) == TF_ES_READWRITE
)
278 dwLockFlags
|= TS_LF_READWRITE
;
279 else if (dwFlags
& TF_ES_READ
)
280 dwLockFlags
|= TS_LF_READ
;
282 if (!This
->documentStatus
.dwDynamicFlags
)
283 ITextStoreACP_GetStatus(This
->pITextStoreACP
, &This
->documentStatus
);
285 if (((dwFlags
& TF_ES_READWRITE
) == TF_ES_READWRITE
) && (This
->documentStatus
.dwDynamicFlags
& TS_SD_READONLY
))
287 *phrSession
= TS_E_READONLY
;
291 if (FAILED (ITfEditSession_QueryInterface(pes
, &IID_ITfEditSession
, (LPVOID
*)&This
->currentEditSession
)))
293 *phrSession
= E_FAIL
;
297 hr
= ITextStoreACP_RequestLock(This
->pITextStoreACP
, dwLockFlags
, phrSession
);
302 static HRESULT WINAPI
Context_InWriteSession (ITfContext
*iface
,
304 BOOL
*pfWriteSession
)
306 Context
*This
= (Context
*)iface
;
307 FIXME("STUB:(%p)\n",This
);
311 static HRESULT WINAPI
Context_GetSelection (ITfContext
*iface
,
312 TfEditCookie ec
, ULONG ulIndex
, ULONG ulCount
,
313 TF_SELECTION
*pSelection
, ULONG
*pcFetched
)
315 Context
*This
= (Context
*)iface
;
318 ULONG totalFetched
= 0;
321 if (!pSelection
|| !pcFetched
)
326 if (!This
->connected
)
327 return TF_E_DISCONNECTED
;
329 if (get_Cookie_magic(ec
)!=COOKIE_MAGIC_EDITCOOKIE
)
332 if (!This
->pITextStoreACP
)
334 FIXME("Context does not have a ITextStoreACP\n");
338 cookie
= get_Cookie_data(ec
);
340 if (ulIndex
== TF_DEFAULT_SELECTION
)
345 for (i
= 0; i
< count
; i
++)
348 TS_SELECTION_ACP acps
;
350 hr
= ITextStoreACP_GetSelection(This
->pITextStoreACP
, ulIndex
+ i
,
353 if (hr
== TS_E_NOLOCK
)
355 else if (SUCCEEDED(hr
))
357 pSelection
[totalFetched
].style
.ase
= acps
.style
.ase
;
358 pSelection
[totalFetched
].style
.fInterimChar
= acps
.style
.fInterimChar
;
359 Range_Constructor(iface
, This
->pITextStoreACP
, cookie
->lockType
, acps
.acpStart
, acps
.acpEnd
, &pSelection
[totalFetched
].range
);
366 *pcFetched
= totalFetched
;
371 static HRESULT WINAPI
Context_SetSelection (ITfContext
*iface
,
372 TfEditCookie ec
, ULONG ulCount
, const TF_SELECTION
*pSelection
)
374 TS_SELECTION_ACP
*acp
;
375 Context
*This
= (Context
*)iface
;
379 TRACE("(%p) %i %i %p\n",This
,ec
,ulCount
,pSelection
);
381 if (!This
->pITextStoreACP
)
383 FIXME("Context does not have a ITextStoreACP\n");
387 if (get_Cookie_magic(ec
)!=COOKIE_MAGIC_EDITCOOKIE
)
390 acp
= HeapAlloc(GetProcessHeap(), 0, sizeof(TS_SELECTION_ACP
) * ulCount
);
392 return E_OUTOFMEMORY
;
394 for (i
= 0; i
< ulCount
; i
++)
395 if (FAILED(TF_SELECTION_to_TS_SELECTION_ACP(&pSelection
[i
], &acp
[i
])))
397 TRACE("Selection Conversion Failed\n");
398 HeapFree(GetProcessHeap(), 0 , acp
);
402 hr
= ITextStoreACP_SetSelection(This
->pITextStoreACP
, ulCount
, acp
);
404 HeapFree(GetProcessHeap(), 0, acp
);
409 static HRESULT WINAPI
Context_GetStart (ITfContext
*iface
,
410 TfEditCookie ec
, ITfRange
**ppStart
)
412 Context
*This
= (Context
*)iface
;
414 TRACE("(%p) %i %p\n",This
,ec
,ppStart
);
421 if (!This
->connected
)
422 return TF_E_DISCONNECTED
;
424 if (get_Cookie_magic(ec
)!=COOKIE_MAGIC_EDITCOOKIE
)
427 cookie
= get_Cookie_data(ec
);
428 return Range_Constructor(iface
, This
->pITextStoreACP
, cookie
->lockType
, 0, 0, ppStart
);
431 static HRESULT WINAPI
Context_GetEnd (ITfContext
*iface
,
432 TfEditCookie ec
, ITfRange
**ppEnd
)
434 Context
*This
= (Context
*)iface
;
437 TRACE("(%p) %i %p\n",This
,ec
,ppEnd
);
444 if (!This
->connected
)
445 return TF_E_DISCONNECTED
;
447 if (get_Cookie_magic(ec
)!=COOKIE_MAGIC_EDITCOOKIE
)
450 if (!This
->pITextStoreACP
)
452 FIXME("Context does not have a ITextStoreACP\n");
456 cookie
= get_Cookie_data(ec
);
457 ITextStoreACP_GetEndACP(This
->pITextStoreACP
,&end
);
459 return Range_Constructor(iface
, This
->pITextStoreACP
, cookie
->lockType
, end
, end
, ppEnd
);
462 static HRESULT WINAPI
Context_GetActiveView (ITfContext
*iface
,
463 ITfContextView
**ppView
)
465 Context
*This
= (Context
*)iface
;
466 FIXME("STUB:(%p)\n",This
);
470 static HRESULT WINAPI
Context_EnumViews (ITfContext
*iface
,
471 IEnumTfContextViews
**ppEnum
)
473 Context
*This
= (Context
*)iface
;
474 FIXME("STUB:(%p)\n",This
);
478 static HRESULT WINAPI
Context_GetStatus (ITfContext
*iface
,
481 Context
*This
= (Context
*)iface
;
482 TRACE("(%p) %p\n",This
,pdcs
);
484 if (!This
->connected
)
485 return TF_E_DISCONNECTED
;
490 if (!This
->pITextStoreACP
)
492 FIXME("Context does not have a ITextStoreACP\n");
496 ITextStoreACP_GetStatus(This
->pITextStoreACP
, &This
->documentStatus
);
498 *pdcs
= This
->documentStatus
;
503 static HRESULT WINAPI
Context_GetProperty (ITfContext
*iface
,
504 REFGUID guidProp
, ITfProperty
**ppProp
)
506 Context
*This
= (Context
*)iface
;
507 FIXME("STUB:(%p)\n",This
);
511 static HRESULT WINAPI
Context_GetAppProperty (ITfContext
*iface
,
512 REFGUID guidProp
, ITfReadOnlyProperty
**ppProp
)
514 Context
*This
= (Context
*)iface
;
515 FIXME("STUB:(%p)\n",This
);
519 static HRESULT WINAPI
Context_TrackProperties (ITfContext
*iface
,
520 const GUID
**prgProp
, ULONG cProp
, const GUID
**prgAppProp
,
521 ULONG cAppProp
, ITfReadOnlyProperty
**ppProperty
)
523 Context
*This
= (Context
*)iface
;
524 FIXME("STUB:(%p)\n",This
);
528 static HRESULT WINAPI
Context_EnumProperties (ITfContext
*iface
,
529 IEnumTfProperties
**ppEnum
)
531 Context
*This
= (Context
*)iface
;
532 FIXME("STUB:(%p)\n",This
);
536 static HRESULT WINAPI
Context_GetDocumentMgr (ITfContext
*iface
,
537 ITfDocumentMgr
**ppDm
)
539 Context
*This
= (Context
*)iface
;
540 TRACE("(%p) %p\n",This
,ppDm
);
545 *ppDm
= This
->manager
;
549 ITfDocumentMgr_AddRef(This
->manager
);
554 static HRESULT WINAPI
Context_CreateRangeBackup (ITfContext
*iface
,
555 TfEditCookie ec
, ITfRange
*pRange
, ITfRangeBackup
**ppBackup
)
557 Context
*This
= (Context
*)iface
;
558 FIXME("STUB:(%p)\n",This
);
562 static const ITfContextVtbl Context_ContextVtbl
=
564 Context_QueryInterface
,
568 Context_RequestEditSession
,
569 Context_InWriteSession
,
570 Context_GetSelection
,
571 Context_SetSelection
,
574 Context_GetActiveView
,
578 Context_GetAppProperty
,
579 Context_TrackProperties
,
580 Context_EnumProperties
,
581 Context_GetDocumentMgr
,
582 Context_CreateRangeBackup
585 static HRESULT WINAPI
Source_QueryInterface(ITfSource
*iface
, REFIID iid
, LPVOID
*ppvOut
)
587 Context
*This
= impl_from_ITfSourceVtbl(iface
);
588 return Context_QueryInterface((ITfContext
*)This
, iid
, *ppvOut
);
591 static ULONG WINAPI
Source_AddRef(ITfSource
*iface
)
593 Context
*This
= impl_from_ITfSourceVtbl(iface
);
594 return Context_AddRef((ITfContext
*)This
);
597 static ULONG WINAPI
Source_Release(ITfSource
*iface
)
599 Context
*This
= impl_from_ITfSourceVtbl(iface
);
600 return Context_Release((ITfContext
*)This
);
603 /*****************************************************
604 * ITfSource functions
605 *****************************************************/
606 static HRESULT WINAPI
ContextSource_AdviseSink(ITfSource
*iface
,
607 REFIID riid
, IUnknown
*punk
, DWORD
*pdwCookie
)
610 Context
*This
= impl_from_ITfSourceVtbl(iface
);
611 TRACE("(%p) %s %p %p\n",This
,debugstr_guid(riid
),punk
,pdwCookie
);
613 if (!riid
|| !punk
|| !pdwCookie
)
616 if (IsEqualIID(riid
, &IID_ITfTextEditSink
))
618 es
= HeapAlloc(GetProcessHeap(),0,sizeof(ContextSink
));
620 return E_OUTOFMEMORY
;
621 if (FAILED(IUnknown_QueryInterface(punk
, riid
, (LPVOID
*)&es
->interfaces
.pITfTextEditSink
)))
623 HeapFree(GetProcessHeap(),0,es
);
624 return CONNECT_E_CANNOTCONNECT
;
626 list_add_head(&This
->pTextEditSink
,&es
->entry
);
627 *pdwCookie
= generate_Cookie(COOKIE_MAGIC_CONTEXTSINK
, es
);
631 FIXME("(%p) Unhandled Sink: %s\n",This
,debugstr_guid(riid
));
635 TRACE("cookie %x\n",*pdwCookie
);
639 static HRESULT WINAPI
ContextSource_UnadviseSink(ITfSource
*iface
, DWORD pdwCookie
)
642 Context
*This
= impl_from_ITfSourceVtbl(iface
);
644 TRACE("(%p) %x\n",This
,pdwCookie
);
646 if (get_Cookie_magic(pdwCookie
)!=COOKIE_MAGIC_CONTEXTSINK
)
649 sink
= (ContextSink
*)remove_Cookie(pdwCookie
);
651 return CONNECT_E_NOCONNECTION
;
653 list_remove(&sink
->entry
);
659 static const ITfSourceVtbl Context_SourceVtbl
=
661 Source_QueryInterface
,
665 ContextSource_AdviseSink
,
666 ContextSource_UnadviseSink
,
669 /*****************************************************
670 * ITfInsertAtSelection functions
671 *****************************************************/
672 static HRESULT WINAPI
InsertAtSelection_QueryInterface(ITfInsertAtSelection
*iface
, REFIID iid
, LPVOID
*ppvOut
)
674 Context
*This
= impl_from_ITfInsertAtSelectionVtbl(iface
);
675 return Context_QueryInterface((ITfContext
*)This
, iid
, *ppvOut
);
678 static ULONG WINAPI
InsertAtSelection_AddRef(ITfInsertAtSelection
*iface
)
680 Context
*This
= impl_from_ITfInsertAtSelectionVtbl(iface
);
681 return Context_AddRef((ITfContext
*)This
);
684 static ULONG WINAPI
InsertAtSelection_Release(ITfInsertAtSelection
*iface
)
686 Context
*This
= impl_from_ITfInsertAtSelectionVtbl(iface
);
687 return Context_Release((ITfContext
*)This
);
690 static HRESULT WINAPI
InsertAtSelection_InsertTextAtSelection(
691 ITfInsertAtSelection
*iface
, TfEditCookie ec
, DWORD dwFlags
,
692 const WCHAR
*pchText
, LONG cch
, ITfRange
**ppRange
)
694 Context
*This
= impl_from_ITfInsertAtSelectionVtbl(iface
);
696 LONG acpStart
, acpEnd
;
697 TS_TEXTCHANGE change
;
700 TRACE("(%p) %i %x %s %p\n",This
, ec
, dwFlags
, debugstr_wn(pchText
,cch
), ppRange
);
702 if (!This
->connected
)
703 return TF_E_DISCONNECTED
;
705 if (get_Cookie_magic(ec
)!=COOKIE_MAGIC_EDITCOOKIE
)
708 cookie
= get_Cookie_data(ec
);
710 if ((cookie
->lockType
& TS_LF_READWRITE
) != TS_LF_READWRITE
)
711 return TS_E_READONLY
;
713 if (!This
->pITextStoreACP
)
715 FIXME("Context does not have a ITextStoreACP\n");
719 hr
= ITextStoreACP_InsertTextAtSelection(This
->pITextStoreACP
, dwFlags
, pchText
, cch
, &acpStart
, &acpEnd
, &change
);
721 Range_Constructor((ITfContext
*)This
, This
->pITextStoreACP
, cookie
->lockType
, change
.acpStart
, change
.acpNewEnd
, ppRange
);
726 static HRESULT WINAPI
InsertAtSelection_InsertEmbeddedAtSelection(
727 ITfInsertAtSelection
*iface
, TfEditCookie ec
, DWORD dwFlags
,
728 IDataObject
*pDataObject
, ITfRange
**ppRange
)
730 Context
*This
= impl_from_ITfInsertAtSelectionVtbl(iface
);
731 FIXME("STUB:(%p)\n",This
);
735 static const ITfInsertAtSelectionVtbl Context_InsertAtSelectionVtbl
=
737 InsertAtSelection_QueryInterface
,
738 InsertAtSelection_AddRef
,
739 InsertAtSelection_Release
,
741 InsertAtSelection_InsertTextAtSelection
,
742 InsertAtSelection_InsertEmbeddedAtSelection
,
745 /*****************************************************
746 * ITfSourceSingle functions
747 *****************************************************/
748 static HRESULT WINAPI
SourceSingle_QueryInterface(ITfSourceSingle
*iface
, REFIID iid
, LPVOID
*ppvOut
)
750 Context
*This
= impl_from_ITfSourceSingleVtbl(iface
);
751 return Context_QueryInterface((ITfContext
*)This
, iid
, *ppvOut
);
754 static ULONG WINAPI
SourceSingle_AddRef(ITfSourceSingle
*iface
)
756 Context
*This
= impl_from_ITfSourceSingleVtbl(iface
);
757 return Context_AddRef((ITfContext
*)This
);
760 static ULONG WINAPI
SourceSingle_Release(ITfSourceSingle
*iface
)
762 Context
*This
= impl_from_ITfSourceSingleVtbl(iface
);
763 return Context_Release((ITfContext
*)This
);
766 static HRESULT WINAPI
SourceSingle_AdviseSingleSink( ITfSourceSingle
*iface
,
767 TfClientId tid
, REFIID riid
, IUnknown
*punk
)
769 Context
*This
= impl_from_ITfSourceSingleVtbl(iface
);
770 FIXME("STUB:(%p) %i %s %p\n",This
, tid
, debugstr_guid(riid
),punk
);
774 static HRESULT WINAPI
SourceSingle_UnadviseSingleSink( ITfSourceSingle
*iface
,
775 TfClientId tid
, REFIID riid
)
777 Context
*This
= impl_from_ITfSourceSingleVtbl(iface
);
778 FIXME("STUB:(%p) %i %s\n",This
, tid
, debugstr_guid(riid
));
782 static const ITfSourceSingleVtbl Context_SourceSingleVtbl
=
784 SourceSingle_QueryInterface
,
786 SourceSingle_Release
,
788 SourceSingle_AdviseSingleSink
,
789 SourceSingle_UnadviseSingleSink
,
792 HRESULT
Context_Constructor(TfClientId tidOwner
, IUnknown
*punk
, ITfDocumentMgr
*mgr
, ITfContext
**ppOut
, TfEditCookie
*pecTextStore
)
797 This
= HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY
,sizeof(Context
));
799 return E_OUTOFMEMORY
;
801 cookie
= HeapAlloc(GetProcessHeap(),0,sizeof(EditCookie
));
804 HeapFree(GetProcessHeap(),0,This
);
805 return E_OUTOFMEMORY
;
808 TRACE("(%p) %x %p %p %p\n",This
, tidOwner
, punk
, ppOut
, pecTextStore
);
810 This
->ContextVtbl
= &Context_ContextVtbl
;
811 This
->SourceVtbl
= &Context_SourceVtbl
;
812 This
->InsertAtSelectionVtbl
= &Context_InsertAtSelectionVtbl
;
813 This
->SourceSingleVtbl
= &Context_SourceSingleVtbl
;
815 This
->tidOwner
= tidOwner
;
816 This
->connected
= FALSE
;
819 CompartmentMgr_Constructor((IUnknown
*)This
, &IID_IUnknown
, (IUnknown
**)&This
->CompartmentMgr
);
821 cookie
->lockType
= TF_ES_READ
;
822 cookie
->pOwningContext
= This
;
826 IUnknown_QueryInterface(punk
, &IID_ITextStoreACP
,
827 (LPVOID
*)&This
->pITextStoreACP
);
829 IUnknown_QueryInterface(punk
, &IID_ITfContextOwnerCompositionSink
,
830 (LPVOID
*)&This
->pITfContextOwnerCompositionSink
);
832 if (!This
->pITextStoreACP
&& !This
->pITfContextOwnerCompositionSink
)
833 FIXME("Unhandled pUnk\n");
836 This
->defaultCookie
= generate_Cookie(COOKIE_MAGIC_EDITCOOKIE
,cookie
);
837 *pecTextStore
= This
->defaultCookie
;
839 list_init(&This
->pContextKeyEventSink
);
840 list_init(&This
->pEditTransactionSink
);
841 list_init(&This
->pStatusSink
);
842 list_init(&This
->pTextEditSink
);
843 list_init(&This
->pTextLayoutSink
);
845 *ppOut
= (ITfContext
*)This
;
846 TRACE("returning %p\n", This
);
851 HRESULT
Context_Initialize(ITfContext
*iface
, ITfDocumentMgr
*manager
)
853 Context
*This
= (Context
*)iface
;
855 if (This
->pITextStoreACP
)
857 if (SUCCEEDED(TextStoreACPSink_Constructor(&This
->pITextStoreACPSink
, This
)))
858 ITextStoreACP_AdviseSink(This
->pITextStoreACP
, &IID_ITextStoreACPSink
,
859 (IUnknown
*)This
->pITextStoreACPSink
, TS_AS_ALL_SINKS
);
861 This
->connected
= TRUE
;
862 This
->manager
= manager
;
866 HRESULT
Context_Uninitialize(ITfContext
*iface
)
868 Context
*This
= (Context
*)iface
;
870 if (This
->pITextStoreACPSink
)
872 ITextStoreACP_UnadviseSink(This
->pITextStoreACP
, (IUnknown
*)This
->pITextStoreACPSink
);
873 if (ITextStoreACPSink_Release(This
->pITextStoreACPSink
) == 0)
874 This
->pITextStoreACPSink
= NULL
;
876 This
->connected
= FALSE
;
877 This
->manager
= NULL
;
881 /**************************************************************************
883 **************************************************************************/
885 static void TextStoreACPSink_Destructor(TextStoreACPSink
*This
)
887 TRACE("destroying %p\n", This
);
888 HeapFree(GetProcessHeap(),0,This
);
891 static HRESULT WINAPI
TextStoreACPSink_QueryInterface(ITextStoreACPSink
*iface
, REFIID iid
, LPVOID
*ppvOut
)
893 TextStoreACPSink
*This
= (TextStoreACPSink
*)iface
;
896 if (IsEqualIID(iid
, &IID_IUnknown
) || IsEqualIID(iid
, &IID_ITextStoreACPSink
))
903 IUnknown_AddRef(iface
);
907 WARN("unsupported interface: %s\n", debugstr_guid(iid
));
908 return E_NOINTERFACE
;
911 static ULONG WINAPI
TextStoreACPSink_AddRef(ITextStoreACPSink
*iface
)
913 TextStoreACPSink
*This
= (TextStoreACPSink
*)iface
;
914 return InterlockedIncrement(&This
->refCount
);
917 static ULONG WINAPI
TextStoreACPSink_Release(ITextStoreACPSink
*iface
)
919 TextStoreACPSink
*This
= (TextStoreACPSink
*)iface
;
922 ret
= InterlockedDecrement(&This
->refCount
);
924 TextStoreACPSink_Destructor(This
);
928 /*****************************************************
929 * ITextStoreACPSink functions
930 *****************************************************/
932 static HRESULT WINAPI
TextStoreACPSink_OnTextChange(ITextStoreACPSink
*iface
,
933 DWORD dwFlags
, const TS_TEXTCHANGE
*pChange
)
935 TextStoreACPSink
*This
= (TextStoreACPSink
*)iface
;
936 FIXME("STUB:(%p)\n",This
);
940 static HRESULT WINAPI
TextStoreACPSink_OnSelectionChange(ITextStoreACPSink
*iface
)
942 TextStoreACPSink
*This
= (TextStoreACPSink
*)iface
;
943 FIXME("STUB:(%p)\n",This
);
947 static HRESULT WINAPI
TextStoreACPSink_OnLayoutChange(ITextStoreACPSink
*iface
,
948 TsLayoutCode lcode
, TsViewCookie vcView
)
950 TextStoreACPSink
*This
= (TextStoreACPSink
*)iface
;
951 FIXME("STUB:(%p)\n",This
);
955 static HRESULT WINAPI
TextStoreACPSink_OnStatusChange(ITextStoreACPSink
*iface
,
958 TextStoreACPSink
*This
= (TextStoreACPSink
*)iface
;
959 HRESULT hr
, hrSession
;
961 TRACE("(%p) %x\n",This
, dwFlags
);
965 ERR("No context?\n");
969 if (!This
->pContext
->pITextStoreACP
)
971 FIXME("Context does not have a ITextStoreACP\n");
975 hr
= ITextStoreACP_RequestLock(This
->pContext
->pITextStoreACP
, TS_LF_READ
, &hrSession
);
977 if(SUCCEEDED(hr
) && SUCCEEDED(hrSession
))
978 This
->pContext
->documentStatus
.dwDynamicFlags
= dwFlags
;
983 static HRESULT WINAPI
TextStoreACPSink_OnAttrsChange(ITextStoreACPSink
*iface
,
984 LONG acpStart
, LONG acpEnd
, ULONG cAttrs
, const TS_ATTRID
*paAttrs
)
986 TextStoreACPSink
*This
= (TextStoreACPSink
*)iface
;
987 FIXME("STUB:(%p)\n",This
);
991 static HRESULT WINAPI
TextStoreACPSink_OnLockGranted(ITextStoreACPSink
*iface
,
994 TextStoreACPSink
*This
= (TextStoreACPSink
*)iface
;
996 EditCookie
*cookie
,*sinkcookie
;
1000 TRACE("(%p) %x\n",This
, dwLockFlags
);
1002 if (!This
->pContext
)
1004 ERR("OnLockGranted called without a context\n");
1008 if (!This
->pContext
->currentEditSession
)
1010 FIXME("OnLockGranted called for something other than an EditSession\n");
1014 cookie
= HeapAlloc(GetProcessHeap(),0,sizeof(EditCookie
));
1016 return E_OUTOFMEMORY
;
1018 sinkcookie
= HeapAlloc(GetProcessHeap(),0,sizeof(EditCookie
));
1021 HeapFree(GetProcessHeap(), 0, cookie
);
1022 return E_OUTOFMEMORY
;
1025 cookie
->lockType
= dwLockFlags
;
1026 cookie
->pOwningContext
= This
->pContext
;
1027 ec
= generate_Cookie(COOKIE_MAGIC_EDITCOOKIE
, cookie
);
1029 hr
= ITfEditSession_DoEditSession(This
->pContext
->currentEditSession
, ec
);
1031 if ((dwLockFlags
&TS_LF_READWRITE
) == TS_LF_READWRITE
)
1035 sinkcookie
->lockType
= TS_LF_READ
;
1036 sinkcookie
->pOwningContext
= This
->pContext
;
1037 sc
= generate_Cookie(COOKIE_MAGIC_EDITCOOKIE
, sinkcookie
);
1039 /*TODO: implement ITfEditRecord */
1040 LIST_FOR_EACH(cursor
, &This
->pContext
->pTextEditSink
)
1042 ContextSink
* sink
= LIST_ENTRY(cursor
,ContextSink
,entry
);
1043 ITfTextEditSink_OnEndEdit(sink
->interfaces
.pITfTextEditSink
,
1044 (ITfContext
*) &This
->pContext
, sc
, NULL
);
1046 sinkcookie
= remove_Cookie(sc
);
1048 HeapFree(GetProcessHeap(),0,sinkcookie
);
1050 ITfEditSession_Release(This
->pContext
->currentEditSession
);
1051 This
->pContext
->currentEditSession
= NULL
;
1053 /* Edit Cookie is only valid during the edit session */
1054 cookie
= remove_Cookie(ec
);
1055 HeapFree(GetProcessHeap(),0,cookie
);
1060 static HRESULT WINAPI
TextStoreACPSink_OnStartEditTransaction(ITextStoreACPSink
*iface
)
1062 TextStoreACPSink
*This
= (TextStoreACPSink
*)iface
;
1063 FIXME("STUB:(%p)\n",This
);
1067 static HRESULT WINAPI
TextStoreACPSink_OnEndEditTransaction(ITextStoreACPSink
*iface
)
1069 TextStoreACPSink
*This
= (TextStoreACPSink
*)iface
;
1070 FIXME("STUB:(%p)\n",This
);
1074 static const ITextStoreACPSinkVtbl TextStoreACPSink_TextStoreACPSinkVtbl
=
1076 TextStoreACPSink_QueryInterface
,
1077 TextStoreACPSink_AddRef
,
1078 TextStoreACPSink_Release
,
1080 TextStoreACPSink_OnTextChange
,
1081 TextStoreACPSink_OnSelectionChange
,
1082 TextStoreACPSink_OnLayoutChange
,
1083 TextStoreACPSink_OnStatusChange
,
1084 TextStoreACPSink_OnAttrsChange
,
1085 TextStoreACPSink_OnLockGranted
,
1086 TextStoreACPSink_OnStartEditTransaction
,
1087 TextStoreACPSink_OnEndEditTransaction
1090 static HRESULT
TextStoreACPSink_Constructor(ITextStoreACPSink
**ppOut
, Context
*pContext
)
1092 TextStoreACPSink
*This
;
1094 This
= HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY
,sizeof(TextStoreACPSink
));
1096 return E_OUTOFMEMORY
;
1098 This
->TextStoreACPSinkVtbl
= &TextStoreACPSink_TextStoreACPSinkVtbl
;
1101 This
->pContext
= pContext
;
1103 TRACE("returning %p\n", This
);
1104 *ppOut
= (ITextStoreACPSink
*)This
;