[MSCTF] Sync with Wine Staging 3.3. CORE-14434
[reactos.git] / dll / win32 / msctf / documentmgr.c
index fec3de3..cf4c601 100644 (file)
@@ -41,8 +41,8 @@
 WINE_DEFAULT_DEBUG_CHANNEL(msctf);
 
 typedef struct tagDocumentMgr {
-    const ITfDocumentMgrVtbl *DocumentMgrVtbl;
-    const ITfSourceVtbl *SourceVtbl;
+    ITfDocumentMgr ITfDocumentMgr_iface;
+    ITfSource ITfSource_iface;
     LONG refCount;
 
     /* Aggregation */
@@ -50,10 +50,12 @@ typedef struct tagDocumentMgr {
 
     ITfContext*  contextStack[2]; /* limit of 2 contexts */
     ITfThreadMgrEventSink* ThreadMgrSink;
+
+    struct list TransitoryExtensionSink;
 } DocumentMgr;
 
 typedef struct tagEnumTfContext {
-    const IEnumTfContextsVtbl *Vtbl;
+    IEnumTfContexts IEnumTfContexts_iface;
     LONG refCount;
 
     DWORD   index;
@@ -62,9 +64,19 @@ typedef struct tagEnumTfContext {
 
 static HRESULT EnumTfContext_Constructor(DocumentMgr* mgr, IEnumTfContexts **ppOut);
 
-static inline DocumentMgr *impl_from_ITfSourceVtbl(ITfSource *iface)
+static inline DocumentMgr *impl_from_ITfDocumentMgr(ITfDocumentMgr *iface)
+{
+    return CONTAINING_RECORD(iface, DocumentMgr, ITfDocumentMgr_iface);
+}
+
+static inline DocumentMgr *impl_from_ITfSource(ITfSource *iface)
+{
+    return CONTAINING_RECORD(iface, DocumentMgr, ITfSource_iface);
+}
+
+static inline EnumTfContext *impl_from_IEnumTfContexts(IEnumTfContexts *iface)
 {
-    return (DocumentMgr *)((char *)iface - FIELD_OFFSET(DocumentMgr,SourceVtbl));
+    return CONTAINING_RECORD(iface, EnumTfContext, IEnumTfContexts_iface);
 }
 
 static void DocumentMgr_Destructor(DocumentMgr *This)
@@ -73,28 +85,29 @@ static void DocumentMgr_Destructor(DocumentMgr *This)
     TRACE("destroying %p\n", This);
 
     TF_GetThreadMgr(&tm);
-    ThreadMgr_OnDocumentMgrDestruction(tm, (ITfDocumentMgr*)This);
+    ThreadMgr_OnDocumentMgrDestruction(tm, &This->ITfDocumentMgr_iface);
 
     if (This->contextStack[0])
         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);
 }
 
 static HRESULT WINAPI DocumentMgr_QueryInterface(ITfDocumentMgr *iface, REFIID iid, LPVOID *ppvOut)
 {
-    DocumentMgr *This = (DocumentMgr *)iface;
+    DocumentMgr *This = impl_from_ITfDocumentMgr(iface);
     *ppvOut = NULL;
 
     if (IsEqualIID(iid, &IID_IUnknown) || IsEqualIID(iid, &IID_ITfDocumentMgr))
     {
-        *ppvOut = This;
+        *ppvOut = &This->ITfDocumentMgr_iface;
     }
     else if (IsEqualIID(iid, &IID_ITfSource))
     {
-        *ppvOut = &This->SourceVtbl;
+        *ppvOut = &This->ITfSource_iface;
     }
     else if (IsEqualIID(iid, &IID_ITfCompartmentMgr))
     {
@@ -103,7 +116,7 @@ static HRESULT WINAPI DocumentMgr_QueryInterface(ITfDocumentMgr *iface, REFIID i
 
     if (*ppvOut)
     {
-        IUnknown_AddRef(iface);
+        ITfDocumentMgr_AddRef(iface);
         return S_OK;
     }
 
@@ -113,13 +126,13 @@ static HRESULT WINAPI DocumentMgr_QueryInterface(ITfDocumentMgr *iface, REFIID i
 
 static ULONG WINAPI DocumentMgr_AddRef(ITfDocumentMgr *iface)
 {
-    DocumentMgr *This = (DocumentMgr *)iface;
+    DocumentMgr *This = impl_from_ITfDocumentMgr(iface);
     return InterlockedIncrement(&This->refCount);
 }
 
 static ULONG WINAPI DocumentMgr_Release(ITfDocumentMgr *iface)
 {
-    DocumentMgr *This = (DocumentMgr *)iface;
+    DocumentMgr *This = impl_from_ITfDocumentMgr(iface);
     ULONG ret;
 
     ret = InterlockedDecrement(&This->refCount);
@@ -136,14 +149,14 @@ static HRESULT WINAPI DocumentMgr_CreateContext(ITfDocumentMgr *iface,
         DWORD dwFlags, IUnknown *punk, ITfContext **ppic,
         TfEditCookie *pecTextStore)
 {
-    DocumentMgr *This = (DocumentMgr *)iface;
+    DocumentMgr *This = impl_from_ITfDocumentMgr(iface);
     TRACE("(%p) 0x%x 0x%x %p %p %p\n",This,tidOwner,dwFlags,punk,ppic,pecTextStore);
     return Context_Constructor(tidOwner, punk, iface, ppic, pecTextStore);
 }
 
 static HRESULT WINAPI DocumentMgr_Push(ITfDocumentMgr *iface, ITfContext *pic)
 {
-    DocumentMgr *This = (DocumentMgr *)iface;
+    DocumentMgr *This = impl_from_ITfDocumentMgr(iface);
     ITfContext *check;
 
     TRACE("(%p) %p\n",This,pic);
@@ -151,7 +164,7 @@ static HRESULT WINAPI DocumentMgr_Push(ITfDocumentMgr *iface, ITfContext *pic)
     if (This->contextStack[1])  /* FUll */
         return TF_E_STACKFULL;
 
-    if (!pic || FAILED(IUnknown_QueryInterface(pic,&IID_ITfContext,(LPVOID*) &check)))
+    if (!pic || FAILED(ITfContext_QueryInterface(pic,&IID_ITfContext,(LPVOID*) &check)))
         return E_INVALIDARG;
 
     if (This->contextStack[0] == NULL)
@@ -168,24 +181,22 @@ static HRESULT WINAPI DocumentMgr_Push(ITfDocumentMgr *iface, ITfContext *pic)
 
 static HRESULT WINAPI DocumentMgr_Pop(ITfDocumentMgr *iface, DWORD dwFlags)
 {
-    DocumentMgr *This = (DocumentMgr *)iface;
+    DocumentMgr *This = impl_from_ITfDocumentMgr(iface);
     TRACE("(%p) 0x%x\n",This,dwFlags);
 
     if (dwFlags == TF_POPF_ALL)
     {
-        if (This->contextStack[0])
-        {
-            ITfThreadMgrEventSink_OnPopContext(This->ThreadMgrSink,This->contextStack[0]);
-            ITfContext_Release(This->contextStack[0]);
-            Context_Uninitialize(This->contextStack[0]);
-        }
-        if (This->contextStack[1])
-        {
-            ITfThreadMgrEventSink_OnPopContext(This->ThreadMgrSink,This->contextStack[1]);
-            ITfContext_Release(This->contextStack[1]);
-            Context_Uninitialize(This->contextStack[1]);
-        }
-        This->contextStack[0] = This->contextStack[1] = NULL;
+        int i;
+
+        for (i = 0; i < sizeof(This->contextStack)/sizeof(This->contextStack[0]); i++)
+            if (This->contextStack[i])
+            {
+                ITfThreadMgrEventSink_OnPopContext(This->ThreadMgrSink, This->contextStack[i]);
+                Context_Uninitialize(This->contextStack[i]);
+                ITfContext_Release(This->contextStack[i]);
+                This->contextStack[i] = NULL;
+            }
+
         ITfThreadMgrEventSink_OnUninitDocumentMgr(This->ThreadMgrSink, iface);
         return S_OK;
     }
@@ -197,8 +208,8 @@ static HRESULT WINAPI DocumentMgr_Pop(ITfDocumentMgr *iface, DWORD dwFlags)
         return E_FAIL;
 
     ITfThreadMgrEventSink_OnPopContext(This->ThreadMgrSink,This->contextStack[0]);
-    ITfContext_Release(This->contextStack[0]);
     Context_Uninitialize(This->contextStack[0]);
+    ITfContext_Release(This->contextStack[0]);
     This->contextStack[0] = This->contextStack[1];
     This->contextStack[1] = NULL;
 
@@ -210,7 +221,7 @@ static HRESULT WINAPI DocumentMgr_Pop(ITfDocumentMgr *iface, DWORD dwFlags)
 
 static HRESULT WINAPI DocumentMgr_GetTop(ITfDocumentMgr *iface, ITfContext **ppic)
 {
-    DocumentMgr *This = (DocumentMgr *)iface;
+    DocumentMgr *This = impl_from_ITfDocumentMgr(iface);
     TRACE("(%p)\n",This);
     if (!ppic)
         return E_INVALIDARG;
@@ -225,7 +236,7 @@ static HRESULT WINAPI DocumentMgr_GetTop(ITfDocumentMgr *iface, ITfContext **ppi
 
 static HRESULT WINAPI DocumentMgr_GetBase(ITfDocumentMgr *iface, ITfContext **ppic)
 {
-    DocumentMgr *This = (DocumentMgr *)iface;
+    DocumentMgr *This = impl_from_ITfDocumentMgr(iface);
     ITfContext *tgt;
 
     TRACE("(%p)\n",This);
@@ -247,17 +258,16 @@ static HRESULT WINAPI DocumentMgr_GetBase(ITfDocumentMgr *iface, ITfContext **pp
 
 static HRESULT WINAPI DocumentMgr_EnumContexts(ITfDocumentMgr *iface, IEnumTfContexts **ppEnum)
 {
-    DocumentMgr *This = (DocumentMgr *)iface;
+    DocumentMgr *This = impl_from_ITfDocumentMgr(iface);
     TRACE("(%p) %p\n",This,ppEnum);
     return EnumTfContext_Constructor(This, ppEnum);
 }
 
-static const ITfDocumentMgrVtbl DocumentMgr_DocumentMgrVtbl =
+static const ITfDocumentMgrVtbl DocumentMgrVtbl =
 {
     DocumentMgr_QueryInterface,
     DocumentMgr_AddRef,
     DocumentMgr_Release,
-
     DocumentMgr_CreateContext,
     DocumentMgr_Push,
     DocumentMgr_Pop,
@@ -266,23 +276,22 @@ static const ITfDocumentMgrVtbl DocumentMgr_DocumentMgrVtbl =
     DocumentMgr_EnumContexts
 };
 
-
-static HRESULT WINAPI Source_QueryInterface(ITfSource *iface, REFIID iid, LPVOID *ppvOut)
+static HRESULT WINAPI DocumentMgrSource_QueryInterface(ITfSource *iface, REFIID iid, LPVOID *ppvOut)
 {
-    DocumentMgr *This = impl_from_ITfSourceVtbl(iface);
-    return DocumentMgr_QueryInterface((ITfDocumentMgr*)This, iid, *ppvOut);
+    DocumentMgr *This = impl_from_ITfSource(iface);
+    return ITfDocumentMgr_QueryInterface(&This->ITfDocumentMgr_iface, iid, ppvOut);
 }
 
-static ULONG WINAPI Source_AddRef(ITfSource *iface)
+static ULONG WINAPI DocumentMgrSource_AddRef(ITfSource *iface)
 {
-    DocumentMgr *This = impl_from_ITfSourceVtbl(iface);
-    return DocumentMgr_AddRef((ITfDocumentMgr*)This);
+    DocumentMgr *This = impl_from_ITfSource(iface);
+    return ITfDocumentMgr_AddRef(&This->ITfDocumentMgr_iface);
 }
 
-static ULONG WINAPI Source_Release(ITfSource *iface)
+static ULONG WINAPI DocumentMgrSource_Release(ITfSource *iface)
 {
-    DocumentMgr *This = impl_from_ITfSourceVtbl(iface);
-    return DocumentMgr_Release((ITfDocumentMgr*)This);
+    DocumentMgr *This = impl_from_ITfSource(iface);
+    return ITfDocumentMgr_Release(&This->ITfDocumentMgr_iface);
 }
 
 /*****************************************************
@@ -291,24 +300,41 @@ static ULONG WINAPI Source_Release(ITfSource *iface)
 static HRESULT WINAPI DocumentMgrSource_AdviseSink(ITfSource *iface,
         REFIID riid, IUnknown *punk, DWORD *pdwCookie)
 {
-    DocumentMgr *This = impl_from_ITfSourceVtbl(iface);
-    FIXME("STUB:(%p)\n",This);
+    DocumentMgr *This = impl_from_ITfSource(iface);
+
+    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_ITfSourceVtbl(iface);
-    FIXME("STUB:(%p)\n",This);
-    return E_NOTIMPL;
+    DocumentMgr *This = impl_from_ITfSource(iface);
+
+    TRACE("(%p) %x\n",This,pdwCookie);
+
+    if (get_Cookie_magic(pdwCookie)!=COOKIE_MAGIC_DMSINK)
+        return E_INVALIDARG;
+
+    return unadvise_sink(pdwCookie);
 }
 
-static const ITfSourceVtbl DocumentMgr_SourceVtbl =
+static const ITfSourceVtbl DocumentMgrSourceVtbl =
 {
-    Source_QueryInterface,
-    Source_AddRef,
-    Source_Release,
-
+    DocumentMgrSource_QueryInterface,
+    DocumentMgrSource_AddRef,
+    DocumentMgrSource_Release,
     DocumentMgrSource_AdviseSink,
     DocumentMgrSource_UnadviseSink,
 };
@@ -321,20 +347,21 @@ HRESULT DocumentMgr_Constructor(ITfThreadMgrEventSink *ThreadMgrSink, ITfDocumen
     if (This == NULL)
         return E_OUTOFMEMORY;
 
-    This->DocumentMgrVtbl= &DocumentMgr_DocumentMgrVtbl;
-    This->SourceVtbl = &DocumentMgr_SourceVtbl;
+    This->ITfDocumentMgr_iface.lpVtbl = &DocumentMgrVtbl;
+    This->ITfSource_iface.lpVtbl = &DocumentMgrSourceVtbl;
     This->refCount = 1;
     This->ThreadMgrSink = ThreadMgrSink;
+    list_init(&This->TransitoryExtensionSink);
 
-    CompartmentMgr_Constructor((IUnknown*)This, &IID_IUnknown, (IUnknown**)&This->CompartmentMgr);
+    CompartmentMgr_Constructor((IUnknown*)&This->ITfDocumentMgr_iface, &IID_IUnknown, (IUnknown**)&This->CompartmentMgr);
 
-    TRACE("returning %p\n", This);
-    *ppOut = (ITfDocumentMgr*)This;
+    *ppOut = &This->ITfDocumentMgr_iface;
+    TRACE("returning %p\n", *ppOut);
     return S_OK;
 }
 
 /**************************************************
- * IEnumTfContexts implementaion
+ * IEnumTfContexts implementation
  **************************************************/
 static void EnumTfContext_Destructor(EnumTfContext *This)
 {
@@ -344,17 +371,17 @@ static void EnumTfContext_Destructor(EnumTfContext *This)
 
 static HRESULT WINAPI EnumTfContext_QueryInterface(IEnumTfContexts *iface, REFIID iid, LPVOID *ppvOut)
 {
-    EnumTfContext *This = (EnumTfContext *)iface;
+    EnumTfContext *This = impl_from_IEnumTfContexts(iface);
     *ppvOut = NULL;
 
     if (IsEqualIID(iid, &IID_IUnknown) || IsEqualIID(iid, &IID_IEnumTfContexts))
     {
-        *ppvOut = This;
+        *ppvOut = &This->IEnumTfContexts_iface;
     }
 
     if (*ppvOut)
     {
-        IUnknown_AddRef(iface);
+        IEnumTfContexts_AddRef(iface);
         return S_OK;
     }
 
@@ -364,13 +391,13 @@ static HRESULT WINAPI EnumTfContext_QueryInterface(IEnumTfContexts *iface, REFII
 
 static ULONG WINAPI EnumTfContext_AddRef(IEnumTfContexts *iface)
 {
-    EnumTfContext *This = (EnumTfContext*)iface;
+    EnumTfContext *This = impl_from_IEnumTfContexts(iface);
     return InterlockedIncrement(&This->refCount);
 }
 
 static ULONG WINAPI EnumTfContext_Release(IEnumTfContexts *iface)
 {
-    EnumTfContext *This = (EnumTfContext *)iface;
+    EnumTfContext *This = impl_from_IEnumTfContexts(iface);
     ULONG ret;
 
     ret = InterlockedDecrement(&This->refCount);
@@ -382,7 +409,7 @@ static ULONG WINAPI EnumTfContext_Release(IEnumTfContexts *iface)
 static HRESULT WINAPI EnumTfContext_Next(IEnumTfContexts *iface,
     ULONG ulCount, ITfContext **rgContext, ULONG *pcFetched)
 {
-    EnumTfContext *This = (EnumTfContext *)iface;
+    EnumTfContext *This = impl_from_IEnumTfContexts(iface);
     ULONG fetched = 0;
 
     TRACE("(%p)\n",This);
@@ -411,7 +438,7 @@ static HRESULT WINAPI EnumTfContext_Next(IEnumTfContexts *iface,
 
 static HRESULT WINAPI EnumTfContext_Skip( IEnumTfContexts* iface, ULONG celt)
 {
-    EnumTfContext *This = (EnumTfContext *)iface;
+    EnumTfContext *This = impl_from_IEnumTfContexts(iface);
     TRACE("(%p)\n",This);
     This->index += celt;
     return S_OK;
@@ -419,7 +446,7 @@ static HRESULT WINAPI EnumTfContext_Skip( IEnumTfContexts* iface, ULONG celt)
 
 static HRESULT WINAPI EnumTfContext_Reset( IEnumTfContexts* iface)
 {
-    EnumTfContext *This = (EnumTfContext *)iface;
+    EnumTfContext *This = impl_from_IEnumTfContexts(iface);
     TRACE("(%p)\n",This);
     This->index = 0;
     return S_OK;
@@ -428,7 +455,7 @@ static HRESULT WINAPI EnumTfContext_Reset( IEnumTfContexts* iface)
 static HRESULT WINAPI EnumTfContext_Clone( IEnumTfContexts *iface,
     IEnumTfContexts **ppenum)
 {
-    EnumTfContext *This = (EnumTfContext *)iface;
+    EnumTfContext *This = impl_from_IEnumTfContexts(iface);
     HRESULT res;
 
     TRACE("(%p)\n",This);
@@ -438,7 +465,7 @@ static HRESULT WINAPI EnumTfContext_Clone( IEnumTfContexts *iface,
     res = EnumTfContext_Constructor(This->docmgr, ppenum);
     if (SUCCEEDED(res))
     {
-        EnumTfContext *new_This = (EnumTfContext *)*ppenum;
+        EnumTfContext *new_This = impl_from_IEnumTfContexts(*ppenum);
         new_This->index = This->index;
     }
     return res;
@@ -463,11 +490,11 @@ static HRESULT EnumTfContext_Constructor(DocumentMgr *mgr, IEnumTfContexts **ppO
     if (This == NULL)
         return E_OUTOFMEMORY;
 
-    This->Vtbl= &IEnumTfContexts_Vtbl;
+    This->IEnumTfContexts_iface.lpVtbl = &IEnumTfContexts_Vtbl;
     This->refCount = 1;
     This->docmgr = mgr;
 
-    TRACE("returning %p\n", This);
-    *ppOut = (IEnumTfContexts*)This;
+    *ppOut = &This->IEnumTfContexts_iface;
+    TRACE("returning %p\n", *ppOut);
     return S_OK;
 }