[MSCTF] Sync with Wine Staging 1.9.11. CORE-11368
authorAmine Khaldi <amine.khaldi@reactos.org>
Sun, 5 Jun 2016 19:38:23 +0000 (19:38 +0000)
committerAmine Khaldi <amine.khaldi@reactos.org>
Sun, 5 Jun 2016 19:38:23 +0000 (19:38 +0000)
svn path=/trunk/; revision=71568

reactos/dll/win32/msctf/compartmentmgr.c
reactos/dll/win32/msctf/context.c
reactos/dll/win32/msctf/documentmgr.c
reactos/dll/win32/msctf/inputprocessor.c
reactos/dll/win32/msctf/msctf.c
reactos/dll/win32/msctf/msctf_internal.h
reactos/dll/win32/msctf/threadmgr.c
reactos/media/doc/README.WINE

index 17dc2d6..f0017f8 100644 (file)
@@ -46,15 +46,6 @@ typedef struct tagCompartmentEnumGuid {
     struct list *cursor;
 } CompartmentEnumGuid;
 
-
-typedef struct tagCompartmentSink {
-    struct list         entry;
-    union {
-        IUnknown            *pIUnknown;
-        ITfCompartmentEventSink *pITfCompartmentEventSink;
-    } interfaces;
-} CompartmentSink;
-
 typedef struct tagCompartment {
     ITfCompartment ITfCompartment_iface;
     ITfSource ITfSource_iface;
@@ -423,23 +414,11 @@ static HRESULT CompartmentEnumGuid_Constructor(struct list *values, IEnumGUID **
 /**************************************************
  * ITfCompartment
  **************************************************/
-static void free_sink(CompartmentSink *sink)
-{
-        IUnknown_Release(sink->interfaces.pIUnknown);
-        HeapFree(GetProcessHeap(),0,sink);
-}
-
 static void Compartment_Destructor(Compartment *This)
 {
-    struct list *cursor, *cursor2;
     TRACE("destroying %p\n", This);
     VariantClear(&This->variant);
-    LIST_FOR_EACH_SAFE(cursor, cursor2, &This->CompartmentEventSink)
-    {
-        CompartmentSink* sink = LIST_ENTRY(cursor,CompartmentSink,entry);
-        list_remove(cursor);
-        free_sink(sink);
-    }
+    free_sinks(&This->CompartmentEventSink);
     HeapFree(GetProcessHeap(),0,This);
 }
 
@@ -489,6 +468,7 @@ static HRESULT WINAPI Compartment_SetValue(ITfCompartment *iface,
     TfClientId tid, const VARIANT *pvarValue)
 {
     Compartment *This = impl_from_ITfCompartment(iface);
+    ITfCompartmentEventSink *sink;
     struct list *cursor;
 
     TRACE("(%p) %i %p\n",This,tid,pvarValue);
@@ -514,10 +494,9 @@ static HRESULT WINAPI Compartment_SetValue(ITfCompartment *iface,
     else if (V_VT(pvarValue) == VT_UNKNOWN)
         IUnknown_AddRef(V_UNKNOWN(&This->variant));
 
-    LIST_FOR_EACH(cursor, &This->CompartmentEventSink)
+    SINK_FOR_EACH(cursor, &This->CompartmentEventSink, ITfCompartmentEventSink, sink)
     {
-        CompartmentSink* sink = LIST_ENTRY(cursor,CompartmentSink,entry);
-        ITfCompartmentEventSink_OnChange(sink->interfaces.pITfCompartmentEventSink,&This->valueData->guid);
+        ITfCompartmentEventSink_OnChange(sink, &This->valueData->guid);
     }
 
     return S_OK;
@@ -572,7 +551,6 @@ static HRESULT WINAPI CompartmentSource_AdviseSink(ITfSource *iface,
         REFIID riid, IUnknown *punk, DWORD *pdwCookie)
 {
     Compartment *This = impl_from_ITfSource(iface);
-    CompartmentSink *cs;
 
     TRACE("(%p) %s %p %p\n",This,debugstr_guid(riid),punk,pdwCookie);
 
@@ -580,47 +558,23 @@ static HRESULT WINAPI CompartmentSource_AdviseSink(ITfSource *iface,
         return E_INVALIDARG;
 
     if (IsEqualIID(riid, &IID_ITfCompartmentEventSink))
-    {
-        cs = HeapAlloc(GetProcessHeap(),0,sizeof(CompartmentSink));
-        if (!cs)
-            return E_OUTOFMEMORY;
-        if (FAILED(IUnknown_QueryInterface(punk, riid, (LPVOID *)&cs->interfaces.pITfCompartmentEventSink)))
-        {
-            HeapFree(GetProcessHeap(),0,cs);
-            return CONNECT_E_CANNOTCONNECT;
-        }
-        list_add_head(&This->CompartmentEventSink,&cs->entry);
-        *pdwCookie = generate_Cookie(COOKIE_MAGIC_COMPARTMENTSINK , cs);
-    }
-    else
-    {
-        FIXME("(%p) Unhandled Sink: %s\n",This,debugstr_guid(riid));
-        return E_NOTIMPL;
-    }
+        return advise_sink(&This->CompartmentEventSink, &IID_ITfCompartmentEventSink,
+                           COOKIE_MAGIC_COMPARTMENTSINK, punk, pdwCookie);
 
-    TRACE("cookie %x\n",*pdwCookie);
-
-    return S_OK;
+    FIXME("(%p) Unhandled Sink: %s\n",This,debugstr_guid(riid));
+    return E_NOTIMPL;
 }
 
 static HRESULT WINAPI CompartmentSource_UnadviseSink(ITfSource *iface, DWORD pdwCookie)
 {
     Compartment *This = impl_from_ITfSource(iface);
-    CompartmentSink *sink;
 
     TRACE("(%p) %x\n",This,pdwCookie);
 
     if (get_Cookie_magic(pdwCookie)!=COOKIE_MAGIC_COMPARTMENTSINK)
         return E_INVALIDARG;
 
-    sink = remove_Cookie(pdwCookie);
-    if (!sink)
-        return CONNECT_E_NOCONNECTION;
-
-    list_remove(&sink->entry);
-    free_sink(sink);
-
-    return S_OK;
+    return unadvise_sink(pdwCookie);
 }
 
 static const ITfSourceVtbl CompartmentSourceVtbl =
index 8d03749..44f20bc 100644 (file)
 
 #include "msctf_internal.h"
 
-typedef struct tagContextSink {
-    struct list         entry;
-    union {
-        /* Context Sinks */
-        IUnknown            *pIUnknown;
-        /* ITfContextKeyEventSink  *pITfContextKeyEventSink; */
-        /* ITfEditTransactionSink  *pITfEditTransactionSink; */
-        /* ITfStatusSink           *pITfStatusSink; */
-        ITfTextEditSink     *pITfTextEditSink;
-        /* ITfTextLayoutSink       *pITfTextLayoutSink; */
-    } interfaces;
-} ContextSink;
-
 typedef struct tagContext {
     ITfContext ITfContext_iface;
     ITfSource ITfSource_iface;
@@ -43,6 +30,8 @@ typedef struct tagContext {
     /* const ITfMouseTrackerVtbl *MouseTrackerVtbl; */
     /* const ITfQueryEmbeddedVtbl *QueryEmbeddedVtbl; */
     ITfSourceSingle ITfSourceSingle_iface;
+    ITextStoreACPSink ITextStoreACPSink_iface;
+    ITextStoreACPServices ITextStoreACPServices_iface;
     LONG refCount;
     BOOL connected;
 
@@ -57,7 +46,6 @@ typedef struct tagContext {
     ITextStoreACP   *pITextStoreACP;
     ITfContextOwnerCompositionSink *pITfContextOwnerCompositionSink;
 
-    ITextStoreACPSink *pITextStoreACPSink;
     ITfEditSession* currentEditSession;
 
     /* kept as separate lists to reduce unnecessary iterations */
@@ -74,17 +62,6 @@ typedef struct tagEditCookie {
     Context *pOwningContext;
 } EditCookie;
 
-typedef struct tagTextStoreACPSink {
-    ITextStoreACPSink ITextStoreACPSink_iface;
-    /* const ITextStoreACPServicesVtbl *TextStoreACPServicesVtbl; */
-    LONG refCount;
-
-    Context *pContext;
-} TextStoreACPSink;
-
-
-static HRESULT TextStoreACPSink_Constructor(ITextStoreACPSink **ppOut, Context *pContext);
-
 static inline Context *impl_from_ITfContext(ITfContext *iface)
 {
     return CONTAINING_RECORD(iface, Context, ITfContext_iface);
@@ -105,31 +82,26 @@ static inline Context *impl_from_ITfSourceSingle(ITfSourceSingle* iface)
     return CONTAINING_RECORD(iface, Context, ITfSourceSingle_iface);
 }
 
-static inline TextStoreACPSink *impl_from_ITextStoreACPSink(ITextStoreACPSink *iface)
+static inline Context *impl_from_ITextStoreACPSink(ITextStoreACPSink *iface)
 {
-    return CONTAINING_RECORD(iface, TextStoreACPSink, ITextStoreACPSink_iface);
+    return CONTAINING_RECORD(iface, Context, ITextStoreACPSink_iface);
 }
 
-static void free_sink(ContextSink *sink)
+static inline Context *impl_from_ITextStoreACPServices(ITextStoreACPServices *iface)
 {
-        IUnknown_Release(sink->interfaces.pIUnknown);
-        HeapFree(GetProcessHeap(),0,sink);
+    return CONTAINING_RECORD(iface, Context, ITextStoreACPServices_iface);
 }
 
 static void Context_Destructor(Context *This)
 {
-    struct list *cursor, *cursor2;
     EditCookie *cookie;
     TRACE("destroying %p\n", This);
 
-    if (This->pITextStoreACPSink)
-    {
-        ITextStoreACP_UnadviseSink(This->pITextStoreACP, (IUnknown*)This->pITextStoreACPSink);
-        ITextStoreACPSink_Release(This->pITextStoreACPSink);
-    }
-
     if (This->pITextStoreACP)
+    {
+        ITextStoreACP_UnadviseSink(This->pITextStoreACP, (IUnknown*)&This->ITextStoreACPSink_iface);
         ITextStoreACP_Release(This->pITextStoreACP);
+    }
 
     if (This->pITfContextOwnerCompositionSink)
         ITfContextOwnerCompositionSink_Release(This->pITfContextOwnerCompositionSink);
@@ -141,36 +113,11 @@ static void Context_Destructor(Context *This)
         This->defaultCookie = 0;
     }
 
-    LIST_FOR_EACH_SAFE(cursor, cursor2, &This->pContextKeyEventSink)
-    {
-        ContextSink* sink = LIST_ENTRY(cursor,ContextSink,entry);
-        list_remove(cursor);
-        free_sink(sink);
-    }
-    LIST_FOR_EACH_SAFE(cursor, cursor2, &This->pEditTransactionSink)
-    {
-        ContextSink* sink = LIST_ENTRY(cursor,ContextSink,entry);
-        list_remove(cursor);
-        free_sink(sink);
-    }
-    LIST_FOR_EACH_SAFE(cursor, cursor2, &This->pStatusSink)
-    {
-        ContextSink* sink = LIST_ENTRY(cursor,ContextSink,entry);
-        list_remove(cursor);
-        free_sink(sink);
-    }
-    LIST_FOR_EACH_SAFE(cursor, cursor2, &This->pTextEditSink)
-    {
-        ContextSink* sink = LIST_ENTRY(cursor,ContextSink,entry);
-        list_remove(cursor);
-        free_sink(sink);
-    }
-    LIST_FOR_EACH_SAFE(cursor, cursor2, &This->pTextLayoutSink)
-    {
-        ContextSink* sink = LIST_ENTRY(cursor,ContextSink,entry);
-        list_remove(cursor);
-        free_sink(sink);
-    }
+    free_sinks(&This->pContextKeyEventSink);
+    free_sinks(&This->pEditTransactionSink);
+    free_sinks(&This->pStatusSink);
+    free_sinks(&This->pTextEditSink);
+    free_sinks(&This->pTextLayoutSink);
 
     CompartmentMgr_Destructor(This->CompartmentMgr);
     HeapFree(GetProcessHeap(),0,This);
@@ -590,53 +537,29 @@ static HRESULT WINAPI ContextSource_AdviseSink(ITfSource *iface,
         REFIID riid, IUnknown *punk, DWORD *pdwCookie)
 {
     Context *This = impl_from_ITfSource(iface);
-    ContextSink *es;
+
     TRACE("(%p) %s %p %p\n",This,debugstr_guid(riid),punk,pdwCookie);
 
     if (!riid || !punk || !pdwCookie)
         return E_INVALIDARG;
 
     if (IsEqualIID(riid, &IID_ITfTextEditSink))
-    {
-        es = HeapAlloc(GetProcessHeap(),0,sizeof(ContextSink));
-        if (!es)
-            return E_OUTOFMEMORY;
-        if (FAILED(IUnknown_QueryInterface(punk, riid, (LPVOID *)&es->interfaces.pITfTextEditSink)))
-        {
-            HeapFree(GetProcessHeap(),0,es);
-            return CONNECT_E_CANNOTCONNECT;
-        }
-        list_add_head(&This->pTextEditSink ,&es->entry);
-        *pdwCookie = generate_Cookie(COOKIE_MAGIC_CONTEXTSINK, es);
-    }
-    else
-    {
-        FIXME("(%p) Unhandled Sink: %s\n",This,debugstr_guid(riid));
-        return E_NOTIMPL;
-    }
+        return advise_sink(&This->pTextEditSink, &IID_ITfTextEditSink, COOKIE_MAGIC_CONTEXTSINK, punk, pdwCookie);
 
-    TRACE("cookie %x\n",*pdwCookie);
-    return S_OK;
+    FIXME("(%p) Unhandled Sink: %s\n",This,debugstr_guid(riid));
+    return E_NOTIMPL;
 }
 
 static HRESULT WINAPI ContextSource_UnadviseSink(ITfSource *iface, DWORD pdwCookie)
 {
     Context *This = impl_from_ITfSource(iface);
-    ContextSink *sink;
 
     TRACE("(%p) %x\n",This,pdwCookie);
 
     if (get_Cookie_magic(pdwCookie)!=COOKIE_MAGIC_CONTEXTSINK)
         return E_INVALIDARG;
 
-    sink = remove_Cookie(pdwCookie);
-    if (!sink)
-        return CONNECT_E_NOCONNECTION;
-
-    list_remove(&sink->entry);
-    free_sink(sink);
-
-    return S_OK;
+    return unadvise_sink(pdwCookie);
 }
 
 static const ITfSourceVtbl ContextSourceVtbl =
@@ -769,114 +692,22 @@ static const ITfSourceSingleVtbl ContextSourceSingleVtbl =
     SourceSingle_UnadviseSingleSink,
 };
 
-HRESULT Context_Constructor(TfClientId tidOwner, IUnknown *punk, ITfDocumentMgr *mgr, ITfContext **ppOut, TfEditCookie *pecTextStore)
-{
-    Context *This;
-    EditCookie *cookie;
-
-    This = HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,sizeof(Context));
-    if (This == NULL)
-        return E_OUTOFMEMORY;
-
-    cookie = HeapAlloc(GetProcessHeap(),0,sizeof(EditCookie));
-    if (cookie == NULL)
-    {
-        HeapFree(GetProcessHeap(),0,This);
-        return E_OUTOFMEMORY;
-    }
-
-    TRACE("(%p) %x %p %p %p\n",This, tidOwner, punk, ppOut, pecTextStore);
-
-    This->ITfContext_iface.lpVtbl= &ContextVtbl;
-    This->ITfSource_iface.lpVtbl = &ContextSourceVtbl;
-    This->ITfInsertAtSelection_iface.lpVtbl = &InsertAtSelectionVtbl;
-    This->ITfSourceSingle_iface.lpVtbl = &ContextSourceSingleVtbl;
-    This->refCount = 1;
-    This->tidOwner = tidOwner;
-    This->connected = FALSE;
-    This->manager = mgr;
-
-    CompartmentMgr_Constructor((IUnknown*)&This->ITfContext_iface, &IID_IUnknown, (IUnknown**)&This->CompartmentMgr);
-
-    cookie->lockType = TF_ES_READ;
-    cookie->pOwningContext = This;
-
-    if (punk)
-    {
-        IUnknown_QueryInterface(punk, &IID_ITextStoreACP,
-                          (LPVOID*)&This->pITextStoreACP);
-
-        IUnknown_QueryInterface(punk, &IID_ITfContextOwnerCompositionSink,
-                                (LPVOID*)&This->pITfContextOwnerCompositionSink);
-
-        if (!This->pITextStoreACP && !This->pITfContextOwnerCompositionSink)
-            FIXME("Unhandled pUnk\n");
-    }
-
-    This->defaultCookie = generate_Cookie(COOKIE_MAGIC_EDITCOOKIE,cookie);
-    *pecTextStore = This->defaultCookie;
-
-    list_init(&This->pContextKeyEventSink);
-    list_init(&This->pEditTransactionSink);
-    list_init(&This->pStatusSink);
-    list_init(&This->pTextEditSink);
-    list_init(&This->pTextLayoutSink);
-
-    *ppOut = &This->ITfContext_iface;
-    TRACE("returning %p\n", *ppOut);
-
-    return S_OK;
-}
-
-HRESULT Context_Initialize(ITfContext *iface, ITfDocumentMgr *manager)
-{
-    Context *This = impl_from_ITfContext(iface);
-
-    if (This->pITextStoreACP)
-    {
-        if (SUCCEEDED(TextStoreACPSink_Constructor(&This->pITextStoreACPSink, This)))
-            ITextStoreACP_AdviseSink(This->pITextStoreACP, &IID_ITextStoreACPSink,
-                            (IUnknown*)This->pITextStoreACPSink, TS_AS_ALL_SINKS);
-    }
-    This->connected = TRUE;
-    This->manager = manager;
-    return S_OK;
-}
-
-HRESULT Context_Uninitialize(ITfContext *iface)
-{
-    Context *This = impl_from_ITfContext(iface);
-
-    if (This->pITextStoreACPSink)
-    {
-        ITextStoreACP_UnadviseSink(This->pITextStoreACP, (IUnknown*)This->pITextStoreACPSink);
-        if (ITextStoreACPSink_Release(This->pITextStoreACPSink) == 0)
-            This->pITextStoreACPSink = NULL;
-    }
-    This->connected = FALSE;
-    This->manager = NULL;
-    return S_OK;
-}
-
 /**************************************************************************
  *  ITextStoreACPSink
  **************************************************************************/
 
-static void TextStoreACPSink_Destructor(TextStoreACPSink *This)
-{
-    TRACE("destroying %p\n", This);
-    HeapFree(GetProcessHeap(),0,This);
-}
-
 static HRESULT WINAPI TextStoreACPSink_QueryInterface(ITextStoreACPSink *iface, REFIID iid, LPVOID *ppvOut)
 {
-    TextStoreACPSink *This = impl_from_ITextStoreACPSink(iface);
+    Context *This = impl_from_ITextStoreACPSink(iface);
+
     *ppvOut = NULL;
 
     if (IsEqualIID(iid, &IID_IUnknown) || IsEqualIID(iid, &IID_ITextStoreACPSink))
     {
         *ppvOut = &This->ITextStoreACPSink_iface;
     }
+    else if (IsEqualIID(iid, &IID_ITextStoreACPServices))
+        *ppvOut = &This->ITextStoreACPServices_iface;
 
     if (*ppvOut)
     {
@@ -890,19 +721,14 @@ static HRESULT WINAPI TextStoreACPSink_QueryInterface(ITextStoreACPSink *iface,
 
 static ULONG WINAPI TextStoreACPSink_AddRef(ITextStoreACPSink *iface)
 {
-    TextStoreACPSink *This = impl_from_ITextStoreACPSink(iface);
-    return InterlockedIncrement(&This->refCount);
+    Context *This = impl_from_ITextStoreACPSink(iface);
+    return ITfContext_AddRef(&This->ITfContext_iface);
 }
 
 static ULONG WINAPI TextStoreACPSink_Release(ITextStoreACPSink *iface)
 {
-    TextStoreACPSink *This = impl_from_ITextStoreACPSink(iface);
-    ULONG ret;
-
-    ret = InterlockedDecrement(&This->refCount);
-    if (ret == 0)
-        TextStoreACPSink_Destructor(This);
-    return ret;
+    Context *This = impl_from_ITextStoreACPSink(iface);
+    return ITfContext_Release(&This->ITfContext_iface);
 }
 
 /*****************************************************
@@ -912,14 +738,14 @@ static ULONG WINAPI TextStoreACPSink_Release(ITextStoreACPSink *iface)
 static HRESULT WINAPI TextStoreACPSink_OnTextChange(ITextStoreACPSink *iface,
         DWORD dwFlags, const TS_TEXTCHANGE *pChange)
 {
-    TextStoreACPSink *This = impl_from_ITextStoreACPSink(iface);
+    Context *This = impl_from_ITextStoreACPSink(iface);
     FIXME("STUB:(%p)\n",This);
     return E_NOTIMPL;
 }
 
 static HRESULT WINAPI TextStoreACPSink_OnSelectionChange(ITextStoreACPSink *iface)
 {
-    TextStoreACPSink *This = impl_from_ITextStoreACPSink(iface);
+    Context *This = impl_from_ITextStoreACPSink(iface);
     FIXME("STUB:(%p)\n",This);
     return E_NOTIMPL;
 }
@@ -927,7 +753,7 @@ static HRESULT WINAPI TextStoreACPSink_OnSelectionChange(ITextStoreACPSink *ifac
 static HRESULT WINAPI TextStoreACPSink_OnLayoutChange(ITextStoreACPSink *iface,
     TsLayoutCode lcode, TsViewCookie vcView)
 {
-    TextStoreACPSink *This = impl_from_ITextStoreACPSink(iface);
+    Context *This = impl_from_ITextStoreACPSink(iface);
     FIXME("STUB:(%p)\n",This);
     return E_NOTIMPL;
 }
@@ -935,27 +761,21 @@ static HRESULT WINAPI TextStoreACPSink_OnLayoutChange(ITextStoreACPSink *iface,
 static HRESULT WINAPI TextStoreACPSink_OnStatusChange(ITextStoreACPSink *iface,
         DWORD dwFlags)
 {
-    TextStoreACPSink *This = impl_from_ITextStoreACPSink(iface);
+    Context *This = impl_from_ITextStoreACPSink(iface);
     HRESULT hr, hrSession;
 
     TRACE("(%p) %x\n",This, dwFlags);
 
-    if (!This->pContext)
-    {
-        ERR("No context?\n");
-        return E_FAIL;
-    }
-
-    if (!This->pContext->pITextStoreACP)
+    if (!This->pITextStoreACP)
     {
         FIXME("Context does not have a ITextStoreACP\n");
         return E_NOTIMPL;
     }
 
-    hr = ITextStoreACP_RequestLock(This->pContext->pITextStoreACP, TS_LF_READ, &hrSession);
+    hr = ITextStoreACP_RequestLock(This->pITextStoreACP, TS_LF_READ, &hrSession);
 
     if(SUCCEEDED(hr) && SUCCEEDED(hrSession))
-        This->pContext->documentStatus.dwDynamicFlags = dwFlags;
+        This->documentStatus.dwDynamicFlags = dwFlags;
 
     return S_OK;
 }
@@ -963,7 +783,7 @@ static HRESULT WINAPI TextStoreACPSink_OnStatusChange(ITextStoreACPSink *iface,
 static HRESULT WINAPI TextStoreACPSink_OnAttrsChange(ITextStoreACPSink *iface,
         LONG acpStart, LONG acpEnd, ULONG cAttrs, const TS_ATTRID *paAttrs)
 {
-    TextStoreACPSink *This = impl_from_ITextStoreACPSink(iface);
+    Context *This = impl_from_ITextStoreACPSink(iface);
     FIXME("STUB:(%p)\n",This);
     return E_NOTIMPL;
 }
@@ -971,7 +791,7 @@ static HRESULT WINAPI TextStoreACPSink_OnAttrsChange(ITextStoreACPSink *iface,
 static HRESULT WINAPI TextStoreACPSink_OnLockGranted(ITextStoreACPSink *iface,
         DWORD dwLockFlags)
 {
-    TextStoreACPSink *This = impl_from_ITextStoreACPSink(iface);
+    Context *This = impl_from_ITextStoreACPSink(iface);
     HRESULT hr;
     EditCookie *cookie,*sinkcookie;
     TfEditCookie ec;
@@ -979,13 +799,7 @@ static HRESULT WINAPI TextStoreACPSink_OnLockGranted(ITextStoreACPSink *iface,
 
     TRACE("(%p) %x\n",This, dwLockFlags);
 
-    if (!This->pContext)
-    {
-        ERR("OnLockGranted called without a context\n");
-        return E_FAIL;
-    }
-
-    if (!This->pContext->currentEditSession)
+    if (!This->currentEditSession)
     {
         FIXME("OnLockGranted called for something other than an EditSession\n");
         return S_OK;
@@ -1003,32 +817,31 @@ static HRESULT WINAPI TextStoreACPSink_OnLockGranted(ITextStoreACPSink *iface,
     }
 
     cookie->lockType = dwLockFlags;
-    cookie->pOwningContext = This->pContext;
+    cookie->pOwningContext = This;
     ec = generate_Cookie(COOKIE_MAGIC_EDITCOOKIE, cookie);
 
-    hr = ITfEditSession_DoEditSession(This->pContext->currentEditSession, ec);
+    hr = ITfEditSession_DoEditSession(This->currentEditSession, ec);
 
     if ((dwLockFlags&TS_LF_READWRITE) == TS_LF_READWRITE)
     {
+        ITfTextEditSink *sink;
         TfEditCookie sc;
 
         sinkcookie->lockType = TS_LF_READ;
-        sinkcookie->pOwningContext = This->pContext;
+        sinkcookie->pOwningContext = This;
         sc = generate_Cookie(COOKIE_MAGIC_EDITCOOKIE, sinkcookie);
 
         /*TODO: implement ITfEditRecord */
-        LIST_FOR_EACH(cursor, &This->pContext->pTextEditSink)
+        SINK_FOR_EACH(cursor, &This->pTextEditSink, ITfTextEditSink, sink)
         {
-            ContextSink* sink = LIST_ENTRY(cursor,ContextSink,entry);
-            ITfTextEditSink_OnEndEdit(sink->interfaces.pITfTextEditSink,
-                                      (ITfContext*) &This->pContext, sc, NULL);
+            ITfTextEditSink_OnEndEdit(sink, (ITfContext*) &This->ITfContext_iface, sc, NULL);
         }
         sinkcookie = remove_Cookie(sc);
     }
     HeapFree(GetProcessHeap(),0,sinkcookie);
 
-    ITfEditSession_Release(This->pContext->currentEditSession);
-    This->pContext->currentEditSession = NULL;
+    ITfEditSession_Release(This->currentEditSession);
+    This->currentEditSession = NULL;
 
     /* Edit Cookie is only valid during the edit session */
     cookie = remove_Cookie(ec);
@@ -1039,14 +852,14 @@ static HRESULT WINAPI TextStoreACPSink_OnLockGranted(ITextStoreACPSink *iface,
 
 static HRESULT WINAPI TextStoreACPSink_OnStartEditTransaction(ITextStoreACPSink *iface)
 {
-    TextStoreACPSink *This = impl_from_ITextStoreACPSink(iface);
+    Context *This = impl_from_ITextStoreACPSink(iface);
     FIXME("STUB:(%p)\n",This);
     return E_NOTIMPL;
 }
 
 static HRESULT WINAPI TextStoreACPSink_OnEndEditTransaction(ITextStoreACPSink *iface)
 {
-    TextStoreACPSink *This = impl_from_ITextStoreACPSink(iface);
+    Context *This = impl_from_ITextStoreACPSink(iface);
     FIXME("STUB:(%p)\n",This);
     return E_NOTIMPL;
 }
@@ -1066,20 +879,154 @@ static const ITextStoreACPSinkVtbl TextStoreACPSinkVtbl =
     TextStoreACPSink_OnEndEditTransaction
 };
 
-static HRESULT TextStoreACPSink_Constructor(ITextStoreACPSink **ppOut, Context *pContext)
+static HRESULT WINAPI TextStoreACPServices_QueryInterface(ITextStoreACPServices *iface, REFIID riid, void **obj)
+{
+    Context *This = impl_from_ITextStoreACPServices(iface);
+    return ITextStoreACPSink_QueryInterface(&This->ITextStoreACPSink_iface, riid, obj);
+}
+
+static ULONG WINAPI TextStoreACPServices_AddRef(ITextStoreACPServices *iface)
+{
+    Context *This = impl_from_ITextStoreACPServices(iface);
+    return ITextStoreACPSink_AddRef(&This->ITextStoreACPSink_iface);
+}
+
+static ULONG WINAPI TextStoreACPServices_Release(ITextStoreACPServices *iface)
+{
+    Context *This = impl_from_ITextStoreACPServices(iface);
+    return ITextStoreACPSink_Release(&This->ITextStoreACPSink_iface);
+}
+
+static HRESULT WINAPI TextStoreACPServices_Serialize(ITextStoreACPServices *iface, ITfProperty *prop, ITfRange *range,
+    TF_PERSISTENT_PROPERTY_HEADER_ACP *header, IStream *stream)
+{
+    Context *This = impl_from_ITextStoreACPServices(iface);
+
+    FIXME("stub: %p %p %p %p %p\n", This, prop, range, header, stream);
+
+    return E_NOTIMPL;
+}
+
+static HRESULT WINAPI TextStoreACPServices_Unserialize(ITextStoreACPServices *iface, ITfProperty *prop,
+    const TF_PERSISTENT_PROPERTY_HEADER_ACP *header, IStream *stream, ITfPersistentPropertyLoaderACP *loader)
+{
+    Context *This = impl_from_ITextStoreACPServices(iface);
+
+    FIXME("stub: %p %p %p %p %p\n", This, prop, header, stream, loader);
+
+    return E_NOTIMPL;
+}
+
+static HRESULT WINAPI TextStoreACPServices_ForceLoadProperty(ITextStoreACPServices *iface, ITfProperty *prop)
+{
+    Context *This = impl_from_ITextStoreACPServices(iface);
+
+    FIXME("stub: %p %p\n", This, prop);
+
+    return E_NOTIMPL;
+}
+
+static HRESULT WINAPI TextStoreACPServices_CreateRange(ITextStoreACPServices *iface,
+    LONG start, LONG end, ITfRangeACP **range)
+{
+    Context *This = impl_from_ITextStoreACPServices(iface);
+
+    FIXME("stub: %p %d %d %p\n", This, start, end, range);
+
+    return S_OK;
+}
+
+static const ITextStoreACPServicesVtbl TextStoreACPServicesVtbl =
+{
+    TextStoreACPServices_QueryInterface,
+    TextStoreACPServices_AddRef,
+    TextStoreACPServices_Release,
+    TextStoreACPServices_Serialize,
+    TextStoreACPServices_Unserialize,
+    TextStoreACPServices_ForceLoadProperty,
+    TextStoreACPServices_CreateRange
+};
+
+HRESULT Context_Constructor(TfClientId tidOwner, IUnknown *punk, ITfDocumentMgr *mgr, ITfContext **ppOut, TfEditCookie *pecTextStore)
 {
-    TextStoreACPSink *This;
+    Context *This;
+    EditCookie *cookie;
 
-    This = HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,sizeof(TextStoreACPSink));
+    This = HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,sizeof(Context));
     if (This == NULL)
         return E_OUTOFMEMORY;
 
-    This->ITextStoreACPSink_iface.lpVtbl= &TextStoreACPSinkVtbl;
+    cookie = HeapAlloc(GetProcessHeap(),0,sizeof(EditCookie));
+    if (cookie == NULL)
+    {
+        HeapFree(GetProcessHeap(),0,This);
+        return E_OUTOFMEMORY;
+    }
+
+    TRACE("(%p) %x %p %p %p\n",This, tidOwner, punk, ppOut, pecTextStore);
+
+    This->ITfContext_iface.lpVtbl= &ContextVtbl;
+    This->ITfSource_iface.lpVtbl = &ContextSourceVtbl;
+    This->ITfInsertAtSelection_iface.lpVtbl = &InsertAtSelectionVtbl;
+    This->ITfSourceSingle_iface.lpVtbl = &ContextSourceSingleVtbl;
+    This->ITextStoreACPSink_iface.lpVtbl = &TextStoreACPSinkVtbl;
+    This->ITextStoreACPServices_iface.lpVtbl = &TextStoreACPServicesVtbl;
     This->refCount = 1;
+    This->tidOwner = tidOwner;
+    This->connected = FALSE;
+    This->manager = mgr;
 
-    This->pContext = pContext;
+    CompartmentMgr_Constructor((IUnknown*)&This->ITfContext_iface, &IID_IUnknown, (IUnknown**)&This->CompartmentMgr);
 
-    *ppOut = &This->ITextStoreACPSink_iface;
+    cookie->lockType = TF_ES_READ;
+    cookie->pOwningContext = This;
+
+    if (punk)
+    {
+        IUnknown_QueryInterface(punk, &IID_ITextStoreACP,
+                          (LPVOID*)&This->pITextStoreACP);
+
+        IUnknown_QueryInterface(punk, &IID_ITfContextOwnerCompositionSink,
+                                (LPVOID*)&This->pITfContextOwnerCompositionSink);
+
+        if (!This->pITextStoreACP && !This->pITfContextOwnerCompositionSink)
+            FIXME("Unhandled pUnk\n");
+    }
+
+    This->defaultCookie = generate_Cookie(COOKIE_MAGIC_EDITCOOKIE,cookie);
+    *pecTextStore = This->defaultCookie;
+
+    list_init(&This->pContextKeyEventSink);
+    list_init(&This->pEditTransactionSink);
+    list_init(&This->pStatusSink);
+    list_init(&This->pTextEditSink);
+    list_init(&This->pTextLayoutSink);
+
+    *ppOut = &This->ITfContext_iface;
     TRACE("returning %p\n", *ppOut);
+
+    return S_OK;
+}
+
+HRESULT Context_Initialize(ITfContext *iface, ITfDocumentMgr *manager)
+{
+    Context *This = impl_from_ITfContext(iface);
+
+    if (This->pITextStoreACP)
+        ITextStoreACP_AdviseSink(This->pITextStoreACP, &IID_ITextStoreACPSink,
+            (IUnknown*)&This->ITextStoreACPSink_iface, TS_AS_ALL_SINKS);
+    This->connected = TRUE;
+    This->manager = manager;
+    return S_OK;
+}
+
+HRESULT Context_Uninitialize(ITfContext *iface)
+{
+    Context *This = impl_from_ITfContext(iface);
+
+    if (This->pITextStoreACP)
+        ITextStoreACP_UnadviseSink(This->pITextStoreACP, (IUnknown*)&This->ITextStoreACPSink_iface);
+    This->connected = FALSE;
+    This->manager = NULL;
     return S_OK;
 }
index 9ab0675..a764cdd 100644 (file)
@@ -30,6 +30,8 @@ typedef struct tagDocumentMgr {
 
     ITfContext*  contextStack[2]; /* limit of 2 contexts */
     ITfThreadMgrEventSink* ThreadMgrSink;
+
+    struct list TransitoryExtensionSink;
 } DocumentMgr;
 
 typedef struct tagEnumTfContext {
@@ -69,6 +71,7 @@ static void DocumentMgr_Destructor(DocumentMgr *This)
         ITfContext_Release(This->contextStack[0]);
     if (This->contextStack[1])
         ITfContext_Release(This->contextStack[1]);
+    free_sinks(&This->TransitoryExtensionSink);
     CompartmentMgr_Destructor(This->CompartmentMgr);
     HeapFree(GetProcessHeap(),0,This);
 }
@@ -278,15 +281,33 @@ static HRESULT WINAPI DocumentMgrSource_AdviseSink(ITfSource *iface,
         REFIID riid, IUnknown *punk, DWORD *pdwCookie)
 {
     DocumentMgr *This = impl_from_ITfSource(iface);
-    FIXME("STUB:(%p)\n",This);
+
+    TRACE("(%p) %s %p %p\n", This, debugstr_guid(riid), punk, pdwCookie);
+
+    if (!riid || !punk || !pdwCookie)
+        return E_INVALIDARG;
+
+    if (IsEqualIID(riid, &IID_ITfTransitoryExtensionSink))
+    {
+        WARN("semi-stub for ITfTransitoryExtensionSink: callback won't be used.\n");
+        return advise_sink(&This->TransitoryExtensionSink, &IID_ITfTransitoryExtensionSink,
+                           COOKIE_MAGIC_DMSINK, punk, pdwCookie);
+    }
+
+    FIXME("(%p) Unhandled Sink: %s\n",This,debugstr_guid(riid));
     return E_NOTIMPL;
 }
 
 static HRESULT WINAPI DocumentMgrSource_UnadviseSink(ITfSource *iface, DWORD pdwCookie)
 {
     DocumentMgr *This = impl_from_ITfSource(iface);
-    FIXME("STUB:(%p)\n",This);
-    return E_NOTIMPL;
+
+    TRACE("(%p) %x\n",This,pdwCookie);
+
+    if (get_Cookie_magic(pdwCookie)!=COOKIE_MAGIC_DMSINK)
+        return E_INVALIDARG;
+
+    return unadvise_sink(pdwCookie);
 }
 
 static const ITfSourceVtbl DocumentMgrSourceVtbl =
@@ -310,6 +331,7 @@ HRESULT DocumentMgr_Constructor(ITfThreadMgrEventSink *ThreadMgrSink, ITfDocumen
     This->ITfSource_iface.lpVtbl = &DocumentMgrSourceVtbl;
     This->refCount = 1;
     This->ThreadMgrSink = ThreadMgrSink;
+    list_init(&This->TransitoryExtensionSink);
 
     CompartmentMgr_Constructor((IUnknown*)&This->ITfDocumentMgr_iface, &IID_IUnknown, (IUnknown**)&This->CompartmentMgr);
 
index 67445c4..2cd911a 100644 (file)
@@ -30,15 +30,6 @@ static const WCHAR szwDefault[] = {'D','e','f','a','u','l','t',0};
 static const WCHAR szwProfile[] = {'P','r','o','f','i','l','e',0};
 static const WCHAR szwDefaultFmt[] = {'%','s','\\','%','s','\\','0','x','%','0','8','x','\\','%','s',0};
 
-typedef struct tagInputProcessorProfilesSink {
-    struct list         entry;
-    union {
-        /* InputProcessorProfile Sinks */
-        IUnknown            *pIUnknown;
-        ITfLanguageProfileNotifySink *pITfLanguageProfileNotifySink;
-    } interfaces;
-} InputProcessorProfilesSink;
-
 typedef struct tagInputProcessorProfiles {
     ITfInputProcessorProfiles ITfInputProcessorProfiles_iface;
     ITfSource ITfSource_iface;
@@ -196,25 +187,11 @@ static inline EnumTfLanguageProfiles *impl_from_IEnumTfLanguageProfiles(IEnumTfL
     return CONTAINING_RECORD(iface, EnumTfLanguageProfiles, IEnumTfLanguageProfiles_iface);
 }
 
-static void free_sink(InputProcessorProfilesSink *sink)
-{
-        IUnknown_Release(sink->interfaces.pIUnknown);
-        HeapFree(GetProcessHeap(),0,sink);
-}
-
 static void InputProcessorProfiles_Destructor(InputProcessorProfiles *This)
 {
-    struct list *cursor, *cursor2;
     TRACE("destroying %p\n", This);
 
-    /* free sinks */
-    LIST_FOR_EACH_SAFE(cursor, cursor2, &This->LanguageProfileNotifySink)
-    {
-        InputProcessorProfilesSink* sink = LIST_ENTRY(cursor,InputProcessorProfilesSink,entry);
-        list_remove(cursor);
-        free_sink(sink);
-    }
-
+    free_sinks(&This->LanguageProfileNotifySink);
     HeapFree(GetProcessHeap(),0,This);
 }
 
@@ -584,18 +561,18 @@ static HRESULT WINAPI InputProcessorProfiles_ChangeCurrentLanguage(
         ITfInputProcessorProfiles *iface, LANGID langid)
 {
     InputProcessorProfiles *This = impl_from_ITfInputProcessorProfiles(iface);
+    ITfLanguageProfileNotifySink *sink;
     struct list *cursor;
     BOOL accept;
 
     FIXME("STUB:(%p)\n",This);
 
-    LIST_FOR_EACH(cursor, &This->LanguageProfileNotifySink)
+    SINK_FOR_EACH(cursor, &This->LanguageProfileNotifySink, ITfLanguageProfileNotifySink, sink)
     {
-        InputProcessorProfilesSink* sink = LIST_ENTRY(cursor,InputProcessorProfilesSink,entry);
         accept = TRUE;
-        ITfLanguageProfileNotifySink_OnLanguageChange(sink->interfaces.pITfLanguageProfileNotifySink, langid, &accept);
+        ITfLanguageProfileNotifySink_OnLanguageChange(sink, langid, &accept);
         if (!accept)
-            return  E_FAIL;
+            return E_FAIL;
     }
 
     /* TODO:  On successful language change call OnLanguageChanged sink */
@@ -907,7 +884,6 @@ static HRESULT WINAPI IPPSource_AdviseSink(ITfSource *iface,
         REFIID riid, IUnknown *punk, DWORD *pdwCookie)
 {
     InputProcessorProfiles *This = impl_from_ITfSource(iface);
-    InputProcessorProfilesSink *ipps;
 
     TRACE("(%p) %s %p %p\n",This,debugstr_guid(riid),punk,pdwCookie);
 
@@ -915,47 +891,23 @@ static HRESULT WINAPI IPPSource_AdviseSink(ITfSource *iface,
         return E_INVALIDARG;
 
     if (IsEqualIID(riid, &IID_ITfLanguageProfileNotifySink))
-    {
-        ipps = HeapAlloc(GetProcessHeap(),0,sizeof(InputProcessorProfilesSink));
-        if (!ipps)
-            return E_OUTOFMEMORY;
-        if (FAILED(IUnknown_QueryInterface(punk, riid, (LPVOID *)&ipps->interfaces.pITfLanguageProfileNotifySink)))
-        {
-            HeapFree(GetProcessHeap(),0,ipps);
-            return CONNECT_E_CANNOTCONNECT;
-        }
-        list_add_head(&This->LanguageProfileNotifySink,&ipps->entry);
-        *pdwCookie = generate_Cookie(COOKIE_MAGIC_IPPSINK, ipps);
-    }
-    else
-    {
-        FIXME("(%p) Unhandled Sink: %s\n",This,debugstr_guid(riid));
-        return E_NOTIMPL;
-    }
-
-    TRACE("cookie %x\n",*pdwCookie);
+        return advise_sink(&This->LanguageProfileNotifySink, &IID_ITfLanguageProfileNotifySink,
+                           COOKIE_MAGIC_IPPSINK, punk, pdwCookie);
 
-    return S_OK;
+    FIXME("(%p) Unhandled Sink: %s\n",This,debugstr_guid(riid));
+    return E_NOTIMPL;
 }
 
 static HRESULT WINAPI IPPSource_UnadviseSink(ITfSource *iface, DWORD pdwCookie)
 {
     InputProcessorProfiles *This = impl_from_ITfSource(iface);
-    InputProcessorProfilesSink *sink;
 
     TRACE("(%p) %x\n",This,pdwCookie);
 
     if (get_Cookie_magic(pdwCookie)!=COOKIE_MAGIC_IPPSINK)
         return E_INVALIDARG;
 
-    sink = remove_Cookie(pdwCookie);
-    if (!sink)
-        return CONNECT_E_NOCONNECTION;
-
-    list_remove(&sink->entry);
-    free_sink(sink);
-
-    return S_OK;
+    return unadvise_sink(pdwCookie);
 }
 
 static const ITfSourceVtbl InputProcessorProfilesSourceVtbl =
index ba87848..e5e06cd 100644 (file)
@@ -266,6 +266,54 @@ DWORD enumerate_Cookie(DWORD magic, DWORD *index)
     return 0x0;
 }
 
+HRESULT advise_sink(struct list *sink_list, REFIID riid, DWORD cookie_magic, IUnknown *unk, DWORD *cookie)
+{
+    Sink *sink;
+
+    sink = HeapAlloc(GetProcessHeap(), 0, sizeof(*sink));
+    if (!sink)
+        return E_OUTOFMEMORY;
+
+    if (FAILED(IUnknown_QueryInterface(unk, riid, (void**)&sink->interfaces.pIUnknown)))
+    {
+        HeapFree(GetProcessHeap(), 0, sink);
+        return CONNECT_E_CANNOTCONNECT;
+    }
+
+    list_add_head(sink_list, &sink->entry);
+    *cookie = generate_Cookie(cookie_magic, sink);
+    TRACE("cookie %x\n", *cookie);
+    return S_OK;
+}
+
+static void free_sink(Sink *sink)
+{
+    list_remove(&sink->entry);
+    IUnknown_Release(sink->interfaces.pIUnknown);
+    HeapFree(GetProcessHeap(), 0, sink);
+}
+
+HRESULT unadvise_sink(DWORD cookie)
+{
+    Sink *sink;
+
+    sink = remove_Cookie(cookie);
+    if (!sink)
+        return CONNECT_E_NOCONNECTION;
+
+    free_sink(sink);
+    return S_OK;
+}
+
+void free_sinks(struct list *sink_list)
+{
+    while(!list_empty(sink_list))
+    {
+        Sink* sink = LIST_ENTRY(sink_list->next, Sink, entry);
+        free_sink(sink);
+    }
+}
+
 /*****************************************************************************
  * Active Text Service Management
  *****************************************************************************/
index 656acda..cd00b76 100644 (file)
@@ -51,6 +51,7 @@ WINE_DEFAULT_DEBUG_CHANNEL(msctf);
 #define COOKIE_MAGIC_IPPSINK 0x0040
 #define COOKIE_MAGIC_EDITCOOKIE 0x0050
 #define COOKIE_MAGIC_COMPARTMENTSINK 0x0060
+#define COOKIE_MAGIC_DMSINK 0x0070
 
 extern DWORD tlsIndex DECLSPEC_HIDDEN;
 extern TfClientId processId DECLSPEC_HIDDEN;
@@ -89,6 +90,28 @@ extern CLSID get_textservice_clsid(TfClientId tid) DECLSPEC_HIDDEN;
 extern HRESULT get_textservice_sink(TfClientId tid, REFCLSID iid, IUnknown** sink) DECLSPEC_HIDDEN;
 extern HRESULT set_textservice_sink(TfClientId tid, REFCLSID iid, IUnknown* sink) DECLSPEC_HIDDEN;
 
+typedef struct {
+    struct list entry;
+    union {
+        IUnknown *pIUnknown;
+        ITfThreadMgrEventSink *pITfThreadMgrEventSink;
+        ITfCompartmentEventSink *pITfCompartmentEventSink;
+        ITfTextEditSink *pITfTextEditSink;
+        ITfLanguageProfileNotifySink *pITfLanguageProfileNotifySink;
+        ITfTransitoryExtensionSink *pITfTransitoryExtensionSink;
+    } interfaces;
+} Sink;
+
+#define SINK_ENTRY(cursor,type) (LIST_ENTRY(cursor,Sink,entry)->interfaces.p##type)
+#define SINK_FOR_EACH(cursor,list,type,elem) \
+    for ((cursor) = (list)->next, elem = SINK_ENTRY(cursor,type); \
+         (cursor) != (list); \
+         (cursor) = (cursor)->next, elem = SINK_ENTRY(cursor,type))
+
+HRESULT advise_sink(struct list *sink_list, REFIID riid, DWORD cookie_magic, IUnknown *unk, DWORD *cookie) DECLSPEC_HIDDEN;
+HRESULT unadvise_sink(DWORD cookie) DECLSPEC_HIDDEN;
+void free_sinks(struct list *sink_list) DECLSPEC_HIDDEN;
+
 extern const WCHAR szwSystemTIPKey[] DECLSPEC_HIDDEN;
 extern const WCHAR szwSystemCTFKey[] DECLSPEC_HIDDEN;
 
index fe8efb5..89dfa5e 100644 (file)
 
 #include "msctf_internal.h"
 
-typedef struct tagThreadMgrSink {
-    struct list         entry;
-    union {
-        /* ThreadMgr Sinks */
-        IUnknown            *pIUnknown;
-        /* ITfActiveLanguageProfileNotifySink *pITfActiveLanguageProfileNotifySink; */
-        /* ITfDisplayAttributeNotifySink *pITfDisplayAttributeNotifySink; */
-        /* ITfKeyTraceEventSink *pITfKeyTraceEventSink; */
-        /* ITfPreservedKeyNotifySink *pITfPreservedKeyNotifySink; */
-        /* ITfThreadFocusSink *pITfThreadFocusSink; */
-        ITfThreadMgrEventSink *pITfThreadMgrEventSink;
-    } interfaces;
-} ThreadMgrSink;
-
 typedef struct tagPreservedKey
 {
     struct list     entry;
@@ -77,8 +63,8 @@ typedef struct tagACLMulti {
     ITfDocumentMgr *focus;
     LONG activationCount;
 
-    ITfKeyEventSink *forgroundKeyEventSink;
-    CLSID forgroundTextService;
+    ITfKeyEventSink *foregroundKeyEventSink;
+    CLSID foregroundTextService;
 
     struct list CurrentPreservedKeys;
     struct list CreatedDocumentMgrs;
@@ -150,12 +136,6 @@ static inline EnumTfDocumentMgr *impl_from_IEnumTfDocumentMgrs(IEnumTfDocumentMg
     return CONTAINING_RECORD(iface, EnumTfDocumentMgr, IEnumTfDocumentMgrs_iface);
 }
 
-static void free_sink(ThreadMgrSink *sink)
-{
-        IUnknown_Release(sink->interfaces.pIUnknown);
-        HeapFree(GetProcessHeap(),0,sink);
-}
-
 static void ThreadMgr_Destructor(ThreadMgr *This)
 {
     struct list *cursor, *cursor2;
@@ -169,43 +149,12 @@ static void ThreadMgr_Destructor(ThreadMgr *This)
     if (This->focus)
         ITfDocumentMgr_Release(This->focus);
 
-    /* free sinks */
-    LIST_FOR_EACH_SAFE(cursor, cursor2, &This->ActiveLanguageProfileNotifySink)
-    {
-        ThreadMgrSink* sink = LIST_ENTRY(cursor,ThreadMgrSink,entry);
-        list_remove(cursor);
-        free_sink(sink);
-    }
-    LIST_FOR_EACH_SAFE(cursor, cursor2, &This->DisplayAttributeNotifySink)
-    {
-        ThreadMgrSink* sink = LIST_ENTRY(cursor,ThreadMgrSink,entry);
-        list_remove(cursor);
-        free_sink(sink);
-    }
-    LIST_FOR_EACH_SAFE(cursor, cursor2, &This->KeyTraceEventSink)
-    {
-        ThreadMgrSink* sink = LIST_ENTRY(cursor,ThreadMgrSink,entry);
-        list_remove(cursor);
-        free_sink(sink);
-    }
-    LIST_FOR_EACH_SAFE(cursor, cursor2, &This->PreservedKeyNotifySink)
-    {
-        ThreadMgrSink* sink = LIST_ENTRY(cursor,ThreadMgrSink,entry);
-        list_remove(cursor);
-        free_sink(sink);
-    }
-    LIST_FOR_EACH_SAFE(cursor, cursor2, &This->ThreadFocusSink)
-    {
-        ThreadMgrSink* sink = LIST_ENTRY(cursor,ThreadMgrSink,entry);
-        list_remove(cursor);
-        free_sink(sink);
-    }
-    LIST_FOR_EACH_SAFE(cursor, cursor2, &This->ThreadMgrEventSink)
-    {
-        ThreadMgrSink* sink = LIST_ENTRY(cursor,ThreadMgrSink,entry);
-        list_remove(cursor);
-        free_sink(sink);
-    }
+    free_sinks(&This->ActiveLanguageProfileNotifySink);
+    free_sinks(&This->DisplayAttributeNotifySink);
+    free_sinks(&This->KeyTraceEventSink);
+    free_sinks(&This->PreservedKeyNotifySink);
+    free_sinks(&This->ThreadFocusSink);
+    free_sinks(&This->ThreadMgrEventSink);
 
     LIST_FOR_EACH_SAFE(cursor, cursor2, &This->CurrentPreservedKeys)
     {
@@ -636,7 +585,6 @@ static HRESULT WINAPI ThreadMgrSource_AdviseSink(ITfSource *iface,
         REFIID riid, IUnknown *punk, DWORD *pdwCookie)
 {
     ThreadMgr *This = impl_from_ITfSource(iface);
-    ThreadMgrSink *tms;
 
     TRACE("(%p) %s %p %p\n",This,debugstr_guid(riid),punk,pdwCookie);
 
@@ -644,47 +592,22 @@ static HRESULT WINAPI ThreadMgrSource_AdviseSink(ITfSource *iface,
         return E_INVALIDARG;
 
     if (IsEqualIID(riid, &IID_ITfThreadMgrEventSink))
-    {
-        tms = HeapAlloc(GetProcessHeap(),0,sizeof(ThreadMgrSink));
-        if (!tms)
-            return E_OUTOFMEMORY;
-        if (FAILED(IUnknown_QueryInterface(punk, riid, (LPVOID *)&tms->interfaces.pITfThreadMgrEventSink)))
-        {
-            HeapFree(GetProcessHeap(),0,tms);
-            return CONNECT_E_CANNOTCONNECT;
-        }
-        list_add_head(&This->ThreadMgrEventSink,&tms->entry);
-        *pdwCookie = generate_Cookie(COOKIE_MAGIC_TMSINK, tms);
-    }
-    else
-    {
-        FIXME("(%p) Unhandled Sink: %s\n",This,debugstr_guid(riid));
-        return E_NOTIMPL;
-    }
+        return advise_sink(&This->ThreadMgrEventSink, &IID_ITfThreadMgrEventSink, COOKIE_MAGIC_TMSINK, punk, pdwCookie);
 
-    TRACE("cookie %x\n",*pdwCookie);
-
-    return S_OK;
+    FIXME("(%p) Unhandled Sink: %s\n",This,debugstr_guid(riid));
+    return E_NOTIMPL;
 }
 
 static HRESULT WINAPI ThreadMgrSource_UnadviseSink(ITfSource *iface, DWORD pdwCookie)
 {
     ThreadMgr *This = impl_from_ITfSource(iface);
-    ThreadMgrSink *sink;
 
     TRACE("(%p) %x\n",This,pdwCookie);
 
     if (get_Cookie_magic(pdwCookie)!=COOKIE_MAGIC_TMSINK)
         return E_INVALIDARG;
 
-    sink = remove_Cookie(pdwCookie);
-    if (!sink)
-        return CONNECT_E_NOCONNECTION;
-
-    list_remove(&sink->entry);
-    free_sink(sink);
-
-    return S_OK;
+    return unadvise_sink(pdwCookie);
 }
 
 static const ITfSourceVtbl ThreadMgrSourceVtbl =
@@ -745,15 +668,15 @@ static HRESULT WINAPI KeystrokeMgr_AdviseKeyEventSink(ITfKeystrokeMgr *iface,
 
     if (fForeground)
     {
-        if (This->forgroundKeyEventSink)
+        if (This->foregroundKeyEventSink)
         {
-            ITfKeyEventSink_OnSetFocus(This->forgroundKeyEventSink, FALSE);
-            ITfKeyEventSink_Release(This->forgroundKeyEventSink);
+            ITfKeyEventSink_OnSetFocus(This->foregroundKeyEventSink, FALSE);
+            ITfKeyEventSink_Release(This->foregroundKeyEventSink);
         }
         ITfKeyEventSink_AddRef(check);
         ITfKeyEventSink_OnSetFocus(check, TRUE);
-        This->forgroundKeyEventSink = check;
-        This->forgroundTextService = textservice;
+        This->foregroundKeyEventSink = check;
+        This->foregroundTextService = textservice;
     }
     return S_OK;
 }
@@ -781,11 +704,11 @@ static HRESULT WINAPI KeystrokeMgr_UnadviseKeyEventSink(ITfKeystrokeMgr *iface,
     set_textservice_sink(tid, &IID_ITfKeyEventSink, NULL);
     ITfKeyEventSink_Release(check);
 
-    if (This->forgroundKeyEventSink == check)
+    if (This->foregroundKeyEventSink == check)
     {
-        ITfKeyEventSink_Release(This->forgroundKeyEventSink);
-        This->forgroundKeyEventSink = NULL;
-        This->forgroundTextService = GUID_NULL;
+        ITfKeyEventSink_Release(This->foregroundKeyEventSink);
+        This->foregroundKeyEventSink = NULL;
+        This->foregroundTextService = GUID_NULL;
     }
     return S_OK;
 }
@@ -798,10 +721,10 @@ static HRESULT WINAPI KeystrokeMgr_GetForeground(ITfKeystrokeMgr *iface,
     if (!pclsid)
         return E_INVALIDARG;
 
-    if (IsEqualCLSID(&This->forgroundTextService,&GUID_NULL))
+    if (IsEqualCLSID(&This->foregroundTextService,&GUID_NULL))
         return S_FALSE;
 
-    *pclsid = This->forgroundTextService;
+    *pclsid = This->foregroundTextService;
     return S_OK;
 }
 
@@ -810,7 +733,8 @@ static HRESULT WINAPI KeystrokeMgr_TestKeyDown(ITfKeystrokeMgr *iface,
 {
     ThreadMgr *This = impl_from_ITfKeystrokeMgr(iface);
     FIXME("STUB:(%p)\n",This);
-    return E_NOTIMPL;
+    *pfEaten = FALSE;
+    return S_OK;
 }
 
 static HRESULT WINAPI KeystrokeMgr_TestKeyUp(ITfKeystrokeMgr *iface,
@@ -818,7 +742,8 @@ static HRESULT WINAPI KeystrokeMgr_TestKeyUp(ITfKeystrokeMgr *iface,
 {
     ThreadMgr *This = impl_from_ITfKeystrokeMgr(iface);
     FIXME("STUB:(%p)\n",This);
-    return E_NOTIMPL;
+    *pfEaten = FALSE;
+    return S_OK;
 }
 
 static HRESULT WINAPI KeystrokeMgr_KeyDown(ITfKeystrokeMgr *iface,
@@ -1133,15 +1058,15 @@ static ULONG WINAPI ThreadMgrEventSink_Release(ITfThreadMgrEventSink *iface)
 static HRESULT WINAPI ThreadMgrEventSink_OnInitDocumentMgr(
         ITfThreadMgrEventSink *iface,ITfDocumentMgr *pdim)
 {
-    struct list *cursor;
     ThreadMgr *This = impl_from_ITfThreadMgrEventSink(iface);
+    ITfThreadMgrEventSink *sink;
+    struct list *cursor;
 
     TRACE("(%p) %p\n",This,pdim);
 
-    LIST_FOR_EACH(cursor, &This->ThreadMgrEventSink)
+    SINK_FOR_EACH(cursor, &This->ThreadMgrEventSink, ITfThreadMgrEventSink, sink)
     {
-        ThreadMgrSink* sink = LIST_ENTRY(cursor,ThreadMgrSink,entry);
-        ITfThreadMgrEventSink_OnInitDocumentMgr(sink->interfaces.pITfThreadMgrEventSink,pdim);
+        ITfThreadMgrEventSink_OnInitDocumentMgr(sink, pdim);
     }
 
     return S_OK;
@@ -1150,15 +1075,15 @@ static HRESULT WINAPI ThreadMgrEventSink_OnInitDocumentMgr(
 static HRESULT WINAPI ThreadMgrEventSink_OnUninitDocumentMgr(
         ITfThreadMgrEventSink *iface, ITfDocumentMgr *pdim)
 {
-    struct list *cursor;
     ThreadMgr *This = impl_from_ITfThreadMgrEventSink(iface);
+    ITfThreadMgrEventSink *sink;
+    struct list *cursor;
 
     TRACE("(%p) %p\n",This,pdim);
 
-    LIST_FOR_EACH(cursor, &This->ThreadMgrEventSink)
+    SINK_FOR_EACH(cursor, &This->ThreadMgrEventSink, ITfThreadMgrEventSink, sink)
     {
-        ThreadMgrSink* sink = LIST_ENTRY(cursor,ThreadMgrSink,entry);
-        ITfThreadMgrEventSink_OnUninitDocumentMgr(sink->interfaces.pITfThreadMgrEventSink,pdim);
+        ITfThreadMgrEventSink_OnUninitDocumentMgr(sink, pdim);
     }
 
     return S_OK;
@@ -1168,15 +1093,15 @@ static HRESULT WINAPI ThreadMgrEventSink_OnSetFocus(
         ITfThreadMgrEventSink *iface, ITfDocumentMgr *pdimFocus,
         ITfDocumentMgr *pdimPrevFocus)
 {
-    struct list *cursor;
     ThreadMgr *This = impl_from_ITfThreadMgrEventSink(iface);
+    ITfThreadMgrEventSink *sink;
+    struct list *cursor;
 
     TRACE("(%p) %p %p\n",This,pdimFocus, pdimPrevFocus);
 
-    LIST_FOR_EACH(cursor, &This->ThreadMgrEventSink)
+    SINK_FOR_EACH(cursor, &This->ThreadMgrEventSink, ITfThreadMgrEventSink, sink)
     {
-        ThreadMgrSink* sink = LIST_ENTRY(cursor,ThreadMgrSink,entry);
-        ITfThreadMgrEventSink_OnSetFocus(sink->interfaces.pITfThreadMgrEventSink, pdimFocus, pdimPrevFocus);
+        ITfThreadMgrEventSink_OnSetFocus(sink, pdimFocus, pdimPrevFocus);
     }
 
     return S_OK;
@@ -1185,15 +1110,15 @@ static HRESULT WINAPI ThreadMgrEventSink_OnSetFocus(
 static HRESULT WINAPI ThreadMgrEventSink_OnPushContext(
         ITfThreadMgrEventSink *iface, ITfContext *pic)
 {
-    struct list *cursor;
     ThreadMgr *This = impl_from_ITfThreadMgrEventSink(iface);
+    ITfThreadMgrEventSink *sink;
+    struct list *cursor;
 
     TRACE("(%p) %p\n",This,pic);
 
-    LIST_FOR_EACH(cursor, &This->ThreadMgrEventSink)
+    SINK_FOR_EACH(cursor, &This->ThreadMgrEventSink, ITfThreadMgrEventSink, sink)
     {
-        ThreadMgrSink* sink = LIST_ENTRY(cursor,ThreadMgrSink,entry);
-        ITfThreadMgrEventSink_OnPushContext(sink->interfaces.pITfThreadMgrEventSink,pic);
+        ITfThreadMgrEventSink_OnPushContext(sink, pic);
     }
 
     return S_OK;
@@ -1202,15 +1127,15 @@ static HRESULT WINAPI ThreadMgrEventSink_OnPushContext(
 static HRESULT WINAPI ThreadMgrEventSink_OnPopContext(
         ITfThreadMgrEventSink *iface, ITfContext *pic)
 {
-    struct list *cursor;
     ThreadMgr *This = impl_from_ITfThreadMgrEventSink(iface);
+    ITfThreadMgrEventSink *sink;
+    struct list *cursor;
 
     TRACE("(%p) %p\n",This,pic);
 
-    LIST_FOR_EACH(cursor, &This->ThreadMgrEventSink)
+    SINK_FOR_EACH(cursor, &This->ThreadMgrEventSink, ITfThreadMgrEventSink, sink)
     {
-        ThreadMgrSink* sink = LIST_ENTRY(cursor,ThreadMgrSink,entry);
-        ITfThreadMgrEventSink_OnPopContext(sink->interfaces.pITfThreadMgrEventSink,pic);
+        ITfThreadMgrEventSink_OnPopContext(sink, pic);
     }
 
     return S_OK;
index 37e5854..afc05d5 100644 (file)
@@ -108,7 +108,7 @@ reactos/dll/win32/msadp32.acm         # Synced to WineStaging-1.9.4
 reactos/dll/win32/mscat32             # Synced to WineStaging-1.9.4
 reactos/dll/win32/mscms               # Synced to WineStaging-1.9.4
 reactos/dll/win32/mscoree             # Synced to Wine-1.5.4
-reactos/dll/win32/msctf               # Synced to WineStaging-1.9.4
+reactos/dll/win32/msctf               # Synced to WineStaging-1.9.11
 reactos/dll/win32/msftedit            # Synced to WineStaging-1.9.4
 reactos/dll/win32/msg711.acm          # Synced to WineStaging-1.9.4
 reactos/dll/win32/msgsm32.acm         # Synced to WineStaging-1.9.4