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;
64 IUnknown *punk; /* possible ITextStoreACP or ITfContextOwnerCompositionSink */
66 /* kept as seperate lists to reduce unnesseccary iterations */
67 struct list pContextKeyEventSink;
68 struct list pEditTransactionSink;
69 struct list pStatusSink;
70 struct list pTextEditSink;
71 struct list pTextLayoutSink;
76 typedef struct tagTextStoreACPSink {
77 const ITextStoreACPSinkVtbl *TextStoreACPSinkVtbl;
84 static HRESULT TextStoreACPSink_Constructor(ITextStoreACPSink **ppOut, Context *pContext);
86 static inline Context *impl_from_ITfSourceVtbl(ITfSource *iface)
88 return (Context *)((char *)iface - FIELD_OFFSET(Context,SourceVtbl));
91 static void free_sink(ContextSink *sink)
93 IUnknown_Release(sink->interfaces.pIUnknown);
94 HeapFree(GetProcessHeap(),0,sink);
97 static void Context_Destructor(Context *This)
99 struct list *cursor, *cursor2;
100 TRACE("destroying %p\n", This);
102 LIST_FOR_EACH_SAFE(cursor, cursor2, &This->pContextKeyEventSink)
104 ContextSink* sink = LIST_ENTRY(cursor,ContextSink,entry);
108 LIST_FOR_EACH_SAFE(cursor, cursor2, &This->pEditTransactionSink)
110 ContextSink* sink = LIST_ENTRY(cursor,ContextSink,entry);
114 LIST_FOR_EACH_SAFE(cursor, cursor2, &This->pStatusSink)
116 ContextSink* sink = LIST_ENTRY(cursor,ContextSink,entry);
120 LIST_FOR_EACH_SAFE(cursor, cursor2, &This->pTextEditSink)
122 ContextSink* sink = LIST_ENTRY(cursor,ContextSink,entry);
126 LIST_FOR_EACH_SAFE(cursor, cursor2, &This->pTextLayoutSink)
128 ContextSink* sink = LIST_ENTRY(cursor,ContextSink,entry);
133 HeapFree(GetProcessHeap(),0,This);
136 static HRESULT WINAPI Context_QueryInterface(ITfContext *iface, REFIID iid, LPVOID *ppvOut)
138 Context *This = (Context *)iface;
141 if (IsEqualIID(iid, &IID_IUnknown) || IsEqualIID(iid, &IID_ITfContext))
145 else if (IsEqualIID(iid, &IID_ITfSource))
147 *ppvOut = &This->SourceVtbl;
152 IUnknown_AddRef(iface);
156 WARN("unsupported interface: %s\n", debugstr_guid(iid));
157 return E_NOINTERFACE;
160 static ULONG WINAPI Context_AddRef(ITfContext *iface)
162 Context *This = (Context *)iface;
163 return InterlockedIncrement(&This->refCount);
166 static ULONG WINAPI Context_Release(ITfContext *iface)
168 Context *This = (Context *)iface;
171 ret = InterlockedDecrement(&This->refCount);
173 Context_Destructor(This);
177 /*****************************************************
178 * ITfContext functions
179 *****************************************************/
180 static HRESULT WINAPI Context_RequestEditSession (ITfContext *iface,
181 TfClientId tid, ITfEditSession *pes, DWORD dwFlags,
184 Context *This = (Context *)iface;
185 FIXME("STUB:(%p)\n",This);
189 static HRESULT WINAPI Context_InWriteSession (ITfContext *iface,
191 BOOL *pfWriteSession)
193 Context *This = (Context *)iface;
194 FIXME("STUB:(%p)\n",This);
198 static HRESULT WINAPI Context_GetSelection (ITfContext *iface,
199 TfEditCookie ec, ULONG ulIndex, ULONG ulCount,
200 TF_SELECTION *pSelection, ULONG *pcFetched)
202 Context *This = (Context *)iface;
203 FIXME("STUB:(%p)\n",This);
207 static HRESULT WINAPI Context_SetSelection (ITfContext *iface,
208 TfEditCookie ec, ULONG ulCount, const TF_SELECTION *pSelection)
210 Context *This = (Context *)iface;
211 FIXME("STUB:(%p)\n",This);
215 static HRESULT WINAPI Context_GetStart (ITfContext *iface,
216 TfEditCookie ec, ITfRange **ppStart)
218 Context *This = (Context *)iface;
219 FIXME("STUB:(%p)\n",This);
223 static HRESULT WINAPI Context_GetEnd (ITfContext *iface,
224 TfEditCookie ec, ITfRange **ppEnd)
226 Context *This = (Context *)iface;
227 FIXME("STUB:(%p)\n",This);
231 static HRESULT WINAPI Context_GetActiveView (ITfContext *iface,
232 ITfContextView **ppView)
234 Context *This = (Context *)iface;
235 FIXME("STUB:(%p)\n",This);
239 static HRESULT WINAPI Context_EnumViews (ITfContext *iface,
240 IEnumTfContextViews **ppEnum)
242 Context *This = (Context *)iface;
243 FIXME("STUB:(%p)\n",This);
247 static HRESULT WINAPI Context_GetStatus (ITfContext *iface,
250 Context *This = (Context *)iface;
251 FIXME("STUB:(%p)\n",This);
255 static HRESULT WINAPI Context_GetProperty (ITfContext *iface,
256 REFGUID guidProp, ITfProperty **ppProp)
258 Context *This = (Context *)iface;
259 FIXME("STUB:(%p)\n",This);
263 static HRESULT WINAPI Context_GetAppProperty (ITfContext *iface,
264 REFGUID guidProp, ITfReadOnlyProperty **ppProp)
266 Context *This = (Context *)iface;
267 FIXME("STUB:(%p)\n",This);
271 static HRESULT WINAPI Context_TrackProperties (ITfContext *iface,
272 const GUID **prgProp, ULONG cProp, const GUID **prgAppProp,
273 ULONG cAppProp, ITfReadOnlyProperty **ppProperty)
275 Context *This = (Context *)iface;
276 FIXME("STUB:(%p)\n",This);
280 static HRESULT WINAPI Context_EnumProperties (ITfContext *iface,
281 IEnumTfProperties **ppEnum)
283 Context *This = (Context *)iface;
284 FIXME("STUB:(%p)\n",This);
288 static HRESULT WINAPI Context_GetDocumentMgr (ITfContext *iface,
289 ITfDocumentMgr **ppDm)
291 Context *This = (Context *)iface;
292 FIXME("STUB:(%p)\n",This);
296 static HRESULT WINAPI Context_CreateRangeBackup (ITfContext *iface,
297 TfEditCookie ec, ITfRange *pRange, ITfRangeBackup **ppBackup)
299 Context *This = (Context *)iface;
300 FIXME("STUB:(%p)\n",This);
304 static const ITfContextVtbl Context_ContextVtbl =
306 Context_QueryInterface,
310 Context_RequestEditSession,
311 Context_InWriteSession,
312 Context_GetSelection,
313 Context_SetSelection,
316 Context_GetActiveView,
320 Context_GetAppProperty,
321 Context_TrackProperties,
322 Context_EnumProperties,
323 Context_GetDocumentMgr,
324 Context_CreateRangeBackup
327 static HRESULT WINAPI Source_QueryInterface(ITfSource *iface, REFIID iid, LPVOID *ppvOut)
329 Context *This = impl_from_ITfSourceVtbl(iface);
330 return Context_QueryInterface((ITfContext *)This, iid, *ppvOut);
333 static ULONG WINAPI Source_AddRef(ITfSource *iface)
335 Context *This = impl_from_ITfSourceVtbl(iface);
336 return Context_AddRef((ITfContext *)This);
339 static ULONG WINAPI Source_Release(ITfSource *iface)
341 Context *This = impl_from_ITfSourceVtbl(iface);
342 return Context_Release((ITfContext *)This);
345 /*****************************************************
346 * ITfSource functions
347 *****************************************************/
348 static WINAPI HRESULT ContextSource_AdviseSink(ITfSource *iface,
349 REFIID riid, IUnknown *punk, DWORD *pdwCookie)
352 Context *This = impl_from_ITfSourceVtbl(iface);
353 TRACE("(%p) %s %p %p\n",This,debugstr_guid(riid),punk,pdwCookie);
355 if (!riid || !punk || !pdwCookie)
358 if (IsEqualIID(riid, &IID_ITfTextEditSink))
360 es = HeapAlloc(GetProcessHeap(),0,sizeof(ContextSink));
362 return E_OUTOFMEMORY;
363 if (!SUCCEEDED(IUnknown_QueryInterface(punk, riid, (LPVOID*)&es->interfaces.pITfTextEditSink)))
365 HeapFree(GetProcessHeap(),0,es);
366 return CONNECT_E_CANNOTCONNECT;
368 list_add_head(&This->pTextEditSink ,&es->entry);
369 *pdwCookie = (DWORD)es;
373 FIXME("(%p) Unhandled Sink: %s\n",This,debugstr_guid(riid));
377 TRACE("cookie %x\n",*pdwCookie);
381 static WINAPI HRESULT ContextSource_UnadviseSink(ITfSource *iface, DWORD pdwCookie)
383 ContextSink *sink = (ContextSink*)pdwCookie;
384 Context *This = impl_from_ITfSourceVtbl(iface);
385 TRACE("(%p) %x\n",This,pdwCookie);
387 list_remove(&sink->entry);
393 static const ITfSourceVtbl Context_SourceVtbl =
395 Source_QueryInterface,
399 ContextSource_AdviseSink,
400 ContextSource_UnadviseSink,
403 HRESULT Context_Constructor(TfClientId tidOwner, IUnknown *punk, ITfContext **ppOut, TfEditCookie *pecTextStore)
407 This = HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,sizeof(Context));
409 return E_OUTOFMEMORY;
411 This->ContextVtbl= &Context_ContextVtbl;
412 This->SourceVtbl = &Context_SourceVtbl;
414 This->tidOwner = tidOwner;
417 TRACE("returning %p\n", This);
418 *ppOut = (ITfContext*)This;
420 *pecTextStore = 0xdeaddead;
422 list_init(&This->pContextKeyEventSink);
423 list_init(&This->pEditTransactionSink);
424 list_init(&This->pStatusSink);
425 list_init(&This->pTextEditSink);
426 list_init(&This->pTextLayoutSink);
431 /**************************************************************************
433 **************************************************************************/
435 static void TextStoreACPSink_Destructor(TextStoreACPSink *This)
437 TRACE("destroying %p\n", This);
438 HeapFree(GetProcessHeap(),0,This);
441 static HRESULT WINAPI TextStoreACPSink_QueryInterface(ITextStoreACPSink *iface, REFIID iid, LPVOID *ppvOut)
443 TextStoreACPSink *This = (TextStoreACPSink *)iface;
446 if (IsEqualIID(iid, &IID_IUnknown) || IsEqualIID(iid, &IID_ITextStoreACPSink))
453 IUnknown_AddRef(iface);
457 WARN("unsupported interface: %s\n", debugstr_guid(iid));
458 return E_NOINTERFACE;
461 static ULONG WINAPI TextStoreACPSink_AddRef(ITextStoreACPSink *iface)
463 TextStoreACPSink *This = (TextStoreACPSink *)iface;
464 return InterlockedIncrement(&This->refCount);
467 static ULONG WINAPI TextStoreACPSink_Release(ITextStoreACPSink *iface)
469 TextStoreACPSink *This = (TextStoreACPSink *)iface;
472 ret = InterlockedDecrement(&This->refCount);
474 TextStoreACPSink_Destructor(This);
478 /*****************************************************
479 * ITextStoreACPSink functions
480 *****************************************************/
482 static HRESULT WINAPI TextStoreACPSink_OnTextChange(ITextStoreACPSink *iface,
483 DWORD dwFlags, const TS_TEXTCHANGE *pChange)
485 TextStoreACPSink *This = (TextStoreACPSink *)iface;
486 FIXME("STUB:(%p)\n",This);
490 static HRESULT WINAPI TextStoreACPSink_OnSelectionChange(ITextStoreACPSink *iface)
492 TextStoreACPSink *This = (TextStoreACPSink *)iface;
493 FIXME("STUB:(%p)\n",This);
497 static HRESULT WINAPI TextStoreACPSink_OnLayoutChange(ITextStoreACPSink *iface,
498 TsLayoutCode lcode, TsViewCookie vcView)
500 TextStoreACPSink *This = (TextStoreACPSink *)iface;
501 FIXME("STUB:(%p)\n",This);
505 static HRESULT WINAPI TextStoreACPSink_OnStatusChange(ITextStoreACPSink *iface,
508 TextStoreACPSink *This = (TextStoreACPSink *)iface;
509 FIXME("STUB:(%p)\n",This);
513 static HRESULT WINAPI TextStoreACPSink_OnAttrsChange(ITextStoreACPSink *iface,
514 LONG acpStart, LONG acpEnd, ULONG cAttrs, const TS_ATTRID *paAttrs)
516 TextStoreACPSink *This = (TextStoreACPSink *)iface;
517 FIXME("STUB:(%p)\n",This);
521 static HRESULT WINAPI TextStoreACPSink_OnLockGranted(ITextStoreACPSink *iface,
524 TextStoreACPSink *This = (TextStoreACPSink *)iface;
525 FIXME("STUB:(%p)\n",This);
529 static HRESULT WINAPI TextStoreACPSink_OnStartEditTransaction(ITextStoreACPSink *iface)
531 TextStoreACPSink *This = (TextStoreACPSink *)iface;
532 FIXME("STUB:(%p)\n",This);
536 static HRESULT WINAPI TextStoreACPSink_OnEndEditTransaction(ITextStoreACPSink *iface)
538 TextStoreACPSink *This = (TextStoreACPSink *)iface;
539 FIXME("STUB:(%p)\n",This);
543 static const ITextStoreACPSinkVtbl TextStoreACPSink_TextStoreACPSinkVtbl =
545 TextStoreACPSink_QueryInterface,
546 TextStoreACPSink_AddRef,
547 TextStoreACPSink_Release,
549 TextStoreACPSink_OnTextChange,
550 TextStoreACPSink_OnSelectionChange,
551 TextStoreACPSink_OnLayoutChange,
552 TextStoreACPSink_OnStatusChange,
553 TextStoreACPSink_OnAttrsChange,
554 TextStoreACPSink_OnLockGranted,
555 TextStoreACPSink_OnStartEditTransaction,
556 TextStoreACPSink_OnEndEditTransaction
559 static HRESULT TextStoreACPSink_Constructor(ITextStoreACPSink **ppOut, Context *pContext)
561 TextStoreACPSink *This;
563 This = HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,sizeof(TextStoreACPSink));
565 return E_OUTOFMEMORY;
567 This->TextStoreACPSinkVtbl= &TextStoreACPSink_TextStoreACPSinkVtbl;
570 This->pContext = pContext;
572 TRACE("returning %p\n", This);
573 *ppOut = (ITextStoreACPSink*)This;