Aric Stewart : msctf: Hook up the DocumentMgr to be able to forward ITfThreadMgrEventSink events to sinks advised to the ThreadMgr .
Alexandre Julliard
julliard at winehq.org
Wed Mar 25 10:31:31 CDT 2009
Module: wine
Branch: master
Commit: db37679b4e8e3e25729ec2364027d78cd8de60f0
URL: http://source.winehq.org/git/wine.git/?a=commit;h=db37679b4e8e3e25729ec2364027d78cd8de60f0
Author: Aric Stewart <aric at codeweavers.com>
Date: Tue Mar 24 08:21:47 2009 -0500
msctf: Hook up the DocumentMgr to be able to forward ITfThreadMgrEventSink events to sinks advised to the ThreadMgr.
---
dlls/msctf/documentmgr.c | 20 ++++++-
dlls/msctf/msctf_internal.h | 2 +-
dlls/msctf/threadmgr.c | 134 ++++++++++++++++++++++++++++++++++++++++++-
3 files changed, 153 insertions(+), 3 deletions(-)
diff --git a/dlls/msctf/documentmgr.c b/dlls/msctf/documentmgr.c
index c875145..ab250cb 100644
--- a/dlls/msctf/documentmgr.c
+++ b/dlls/msctf/documentmgr.c
@@ -46,6 +46,7 @@ typedef struct tagDocumentMgr {
LONG refCount;
ITfContext* contextStack[2]; /* limit of 2 contexts */
+ ITfThreadMgrEventSink* ThreadMgrSink;
} DocumentMgr;
static inline DocumentMgr *impl_from_ITfSourceVtbl(ITfSource *iface)
@@ -130,9 +131,14 @@ static HRESULT WINAPI DocumentMgr_Push(ITfDocumentMgr *iface, ITfContext *pic)
if (!pic || FAILED(IUnknown_QueryInterface(pic,&IID_ITfContext,(LPVOID*) &check)))
return E_INVALIDARG;
+ if (This->contextStack[0] == NULL)
+ ITfThreadMgrEventSink_OnInitDocumentMgr(This->ThreadMgrSink,iface);
+
This->contextStack[1] = This->contextStack[0];
This->contextStack[0] = check;
+ ITfThreadMgrEventSink_OnPushContext(This->ThreadMgrSink,check);
+
return S_OK;
}
@@ -144,10 +150,17 @@ static HRESULT WINAPI DocumentMgr_Pop(ITfDocumentMgr *iface, DWORD dwFlags)
if (dwFlags == TF_POPF_ALL)
{
if (This->contextStack[0])
+ {
+ ITfThreadMgrEventSink_OnPopContext(This->ThreadMgrSink,This->contextStack[0]);
ITfContext_Release(This->contextStack[0]);
+ }
if (This->contextStack[1])
+ {
+ ITfThreadMgrEventSink_OnPopContext(This->ThreadMgrSink,This->contextStack[1]);
ITfContext_Release(This->contextStack[1]);
+ }
This->contextStack[0] = This->contextStack[1] = NULL;
+ ITfThreadMgrEventSink_OnUninitDocumentMgr(This->ThreadMgrSink, iface);
return S_OK;
}
@@ -157,10 +170,14 @@ static HRESULT WINAPI DocumentMgr_Pop(ITfDocumentMgr *iface, DWORD dwFlags)
if (This->contextStack[0] == NULL) /* Cannot pop last context */
return E_FAIL;
+ ITfThreadMgrEventSink_OnPopContext(This->ThreadMgrSink,This->contextStack[0]);
ITfContext_Release(This->contextStack[0]);
This->contextStack[0] = This->contextStack[1];
This->contextStack[1] = NULL;
+ if (This->contextStack[0] == NULL)
+ ITfThreadMgrEventSink_OnUninitDocumentMgr(This->ThreadMgrSink, iface);
+
return S_OK;
}
@@ -262,7 +279,7 @@ static const ITfSourceVtbl DocumentMgr_SourceVtbl =
DocumentMgrSource_UnadviseSink,
};
-HRESULT DocumentMgr_Constructor(ITfDocumentMgr **ppOut)
+HRESULT DocumentMgr_Constructor(ITfThreadMgrEventSink *ThreadMgrSink, ITfDocumentMgr **ppOut)
{
DocumentMgr *This;
@@ -273,6 +290,7 @@ HRESULT DocumentMgr_Constructor(ITfDocumentMgr **ppOut)
This->DocumentMgrVtbl= &DocumentMgr_DocumentMgrVtbl;
This->SourceVtbl = &DocumentMgr_SourceVtbl;
This->refCount = 1;
+ This->ThreadMgrSink = ThreadMgrSink;
TRACE("returning %p\n", This);
*ppOut = (ITfDocumentMgr*)This;
diff --git a/dlls/msctf/msctf_internal.h b/dlls/msctf/msctf_internal.h
index 4d83aa3..7a05b7b 100644
--- a/dlls/msctf/msctf_internal.h
+++ b/dlls/msctf/msctf_internal.h
@@ -23,7 +23,7 @@
extern DWORD tlsIndex;
extern HRESULT ThreadMgr_Constructor(IUnknown *pUnkOuter, IUnknown **ppOut);
-extern HRESULT DocumentMgr_Constructor(ITfDocumentMgr **ppOut);
+extern HRESULT DocumentMgr_Constructor(ITfThreadMgrEventSink*, ITfDocumentMgr **ppOut);
extern HRESULT Context_Constructor(TfClientId tidOwner, IUnknown *punk, ITfContext **ppOut, TfEditCookie *pecTextStore);
extern HRESULT InputProcessorProfiles_Constructor(IUnknown *pUnkOuter, IUnknown **ppOut);
extern HRESULT CategoryMgr_Constructor(IUnknown *pUnkOuter, IUnknown **ppOut);
diff --git a/dlls/msctf/threadmgr.c b/dlls/msctf/threadmgr.c
index 080c023..b2ec069 100644
--- a/dlls/msctf/threadmgr.c
+++ b/dlls/msctf/threadmgr.c
@@ -61,6 +61,8 @@ typedef struct tagACLMulti {
const ITfSourceVtbl *SourceVtbl;
LONG refCount;
+ const ITfThreadMgrEventSinkVtbl *ThreadMgrEventSinkVtbl; /* internal */
+
ITfDocumentMgr *focus;
/* kept as separate lists to reduce unnecessary iterations */
@@ -77,6 +79,11 @@ static inline ThreadMgr *impl_from_ITfSourceVtbl(ITfSource *iface)
return (ThreadMgr *)((char *)iface - FIELD_OFFSET(ThreadMgr,SourceVtbl));
}
+static inline ThreadMgr *impl_from_ITfThreadMgrEventSink(ITfThreadMgrEventSink *iface)
+{
+ return (ThreadMgr *)((char *)iface - FIELD_OFFSET(ThreadMgr,ThreadMgrEventSinkVtbl));
+}
+
static void free_sink(ThreadMgrSink *sink)
{
IUnknown_Release(sink->interfaces.pIUnknown);
@@ -195,8 +202,9 @@ static HRESULT WINAPI ThreadMgr_fnDeactivate( ITfThreadMgr* iface)
static HRESULT WINAPI ThreadMgr_CreateDocumentMgr( ITfThreadMgr* iface, ITfDocumentMgr
**ppdim)
{
+ ThreadMgr *This = (ThreadMgr *)iface;
TRACE("(%p)\n",iface);
- return DocumentMgr_Constructor(ppdim);
+ return DocumentMgr_Constructor((ITfThreadMgrEventSink*)&This->ThreadMgrEventSinkVtbl, ppdim);
}
static HRESULT WINAPI ThreadMgr_EnumDocumentMgrs( ITfThreadMgr* iface, IEnumTfDocumentMgrs
@@ -238,6 +246,8 @@ static HRESULT WINAPI ThreadMgr_SetFocus( ITfThreadMgr* iface, ITfDocumentMgr *p
if (!pdimFocus || FAILED(IUnknown_QueryInterface(pdimFocus,&IID_ITfDocumentMgr,(LPVOID*) &check)))
return E_INVALIDARG;
+ ITfThreadMgrEventSink_OnSetFocus((ITfThreadMgrEventSink*)&This->ThreadMgrEventSinkVtbl, This->focus, check);
+
if (This->focus)
ITfDocumentMgr_Release(This->focus);
@@ -377,6 +387,127 @@ static const ITfSourceVtbl ThreadMgr_SourceVtbl =
ThreadMgrSource_UnadviseSink,
};
+/*****************************************************
+ * ITfThreadMgrEventSink functions (internal)
+ *****************************************************/
+static HRESULT WINAPI ThreadMgrEventSink_QueryInterface(ITfThreadMgrEventSink *iface, REFIID iid, LPVOID *ppvOut)
+{
+ ThreadMgr *This = impl_from_ITfThreadMgrEventSink(iface);
+ return ThreadMgr_QueryInterface((ITfThreadMgr *)This, iid, *ppvOut);
+}
+
+static ULONG WINAPI ThreadMgrEventSink_AddRef(ITfThreadMgrEventSink *iface)
+{
+ ThreadMgr *This = impl_from_ITfThreadMgrEventSink(iface);
+ return ThreadMgr_AddRef((ITfThreadMgr*)This);
+}
+
+static ULONG WINAPI ThreadMgrEventSink_Release(ITfThreadMgrEventSink *iface)
+{
+ ThreadMgr *This = impl_from_ITfThreadMgrEventSink(iface);
+ return ThreadMgr_Release((ITfThreadMgr *)This);
+}
+
+
+static WINAPI HRESULT ThreadMgrEventSink_OnInitDocumentMgr(
+ ITfThreadMgrEventSink *iface,ITfDocumentMgr *pdim)
+{
+ struct list *cursor;
+ ThreadMgr *This = impl_from_ITfThreadMgrEventSink(iface);
+
+ TRACE("(%p) %p\n",This,pdim);
+
+ LIST_FOR_EACH(cursor, &This->ThreadMgrEventSink)
+ {
+ ThreadMgrSink* sink = LIST_ENTRY(cursor,ThreadMgrSink,entry);
+ ITfThreadMgrEventSink_OnInitDocumentMgr(sink->interfaces.pITfThreadMgrEventSink,pdim);
+ }
+
+ return S_OK;
+}
+
+static WINAPI HRESULT ThreadMgrEventSink_OnUninitDocumentMgr(
+ ITfThreadMgrEventSink *iface, ITfDocumentMgr *pdim)
+{
+ struct list *cursor;
+ ThreadMgr *This = impl_from_ITfThreadMgrEventSink(iface);
+
+ TRACE("(%p) %p\n",This,pdim);
+
+ LIST_FOR_EACH(cursor, &This->ThreadMgrEventSink)
+ {
+ ThreadMgrSink* sink = LIST_ENTRY(cursor,ThreadMgrSink,entry);
+ ITfThreadMgrEventSink_OnUninitDocumentMgr(sink->interfaces.pITfThreadMgrEventSink,pdim);
+ }
+
+ return S_OK;
+}
+
+static WINAPI HRESULT ThreadMgrEventSink_OnSetFocus(
+ ITfThreadMgrEventSink *iface, ITfDocumentMgr *pdimFocus,
+ ITfDocumentMgr *pdimPrevFocus)
+{
+ struct list *cursor;
+ ThreadMgr *This = impl_from_ITfThreadMgrEventSink(iface);
+
+ TRACE("(%p) %p %p\n",This,pdimFocus, pdimPrevFocus);
+
+ LIST_FOR_EACH(cursor, &This->ThreadMgrEventSink)
+ {
+ ThreadMgrSink* sink = LIST_ENTRY(cursor,ThreadMgrSink,entry);
+ ITfThreadMgrEventSink_OnSetFocus(sink->interfaces.pITfThreadMgrEventSink, pdimFocus, pdimPrevFocus);
+ }
+
+ return S_OK;
+}
+
+static WINAPI HRESULT ThreadMgrEventSink_OnPushContext(
+ ITfThreadMgrEventSink *iface, ITfContext *pic)
+{
+ struct list *cursor;
+ ThreadMgr *This = impl_from_ITfThreadMgrEventSink(iface);
+
+ TRACE("(%p) %p\n",This,pic);
+
+ LIST_FOR_EACH(cursor, &This->ThreadMgrEventSink)
+ {
+ ThreadMgrSink* sink = LIST_ENTRY(cursor,ThreadMgrSink,entry);
+ ITfThreadMgrEventSink_OnPushContext(sink->interfaces.pITfThreadMgrEventSink,pic);
+ }
+
+ return S_OK;
+}
+
+static WINAPI HRESULT ThreadMgrEventSink_OnPopContext(
+ ITfThreadMgrEventSink *iface, ITfContext *pic)
+{
+ struct list *cursor;
+ ThreadMgr *This = impl_from_ITfThreadMgrEventSink(iface);
+
+ TRACE("(%p) %p\n",This,pic);
+
+ LIST_FOR_EACH(cursor, &This->ThreadMgrEventSink)
+ {
+ ThreadMgrSink* sink = LIST_ENTRY(cursor,ThreadMgrSink,entry);
+ ITfThreadMgrEventSink_OnPopContext(sink->interfaces.pITfThreadMgrEventSink,pic);
+ }
+
+ return S_OK;
+}
+
+static const ITfThreadMgrEventSinkVtbl ThreadMgr_ThreadMgrEventSinkVtbl =
+{
+ ThreadMgrEventSink_QueryInterface,
+ ThreadMgrEventSink_AddRef,
+ ThreadMgrEventSink_Release,
+
+ ThreadMgrEventSink_OnInitDocumentMgr,
+ ThreadMgrEventSink_OnUninitDocumentMgr,
+ ThreadMgrEventSink_OnSetFocus,
+ ThreadMgrEventSink_OnPushContext,
+ ThreadMgrEventSink_OnPopContext
+};
+
HRESULT ThreadMgr_Constructor(IUnknown *pUnkOuter, IUnknown **ppOut)
{
ThreadMgr *This;
@@ -398,6 +529,7 @@ HRESULT ThreadMgr_Constructor(IUnknown *pUnkOuter, IUnknown **ppOut)
This->ThreadMgrVtbl= &ThreadMgr_ThreadMgrVtbl;
This->SourceVtbl = &ThreadMgr_SourceVtbl;
+ This->ThreadMgrEventSinkVtbl = &ThreadMgr_ThreadMgrEventSinkVtbl;
This->refCount = 1;
TlsSetValue(tlsIndex,This);
More information about the wine-cvs
mailing list