Module: wine Branch: master Commit: db37679b4e8e3e25729ec2364027d78cd8de60f0 URL: http://source.winehq.org/git/wine.git/?a=commit;h=db37679b4e8e3e25729ec23640...
Author: Aric Stewart aric@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);