Module: wine Branch: master Commit: f723e4ca0862137d6e4ad8adc22d0ee64d38e904 URL: http://source.winehq.org/git/wine.git/?a=commit;h=f723e4ca0862137d6e4ad8adc2...
Author: Aric Stewart aric@codeweavers.com Date: Tue Mar 24 08:21:28 2009 -0500
msctf: ThreadMgr sink framework.
---
dlls/msctf/threadmgr.c | 77 ++++++++++++++++++++++++++++++++++++++++++++++++ 1 files changed, 77 insertions(+), 0 deletions(-)
diff --git a/dlls/msctf/threadmgr.c b/dlls/msctf/threadmgr.c index 76c1fd6..eb5918e 100644 --- a/dlls/msctf/threadmgr.c +++ b/dlls/msctf/threadmgr.c @@ -34,18 +34,41 @@ #include "objbase.h"
#include "wine/unicode.h" +#include "wine/list.h"
#include "msctf.h" #include "msctf_internal.h"
WINE_DEFAULT_DEBUG_CHANNEL(msctf);
+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 tagACLMulti { const ITfThreadMgrVtbl *ThreadMgrVtbl; const ITfSourceVtbl *SourceVtbl; LONG refCount;
ITfDocumentMgr *focus; + + /* kept as separate lists to reduce unnecessary iterations */ + struct list ActiveLanguageProfileNotifySink; + struct list DisplayAttributeNotifySink; + struct list KeyTraceEventSink; + struct list PreservedKeyNotifySink; + struct list ThreadFocusSink; + struct list ThreadMgrEventSink; } ThreadMgr;
static inline ThreadMgr *impl_from_ITfSourceVtbl(ITfSource *iface) @@ -53,12 +76,59 @@ static inline ThreadMgr *impl_from_ITfSourceVtbl(ITfSource *iface) return (ThreadMgr *)((char *)iface - FIELD_OFFSET(ThreadMgr,SourceVtbl)); }
+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; + TlsSetValue(tlsIndex,NULL); TRACE("destroying %p\n", 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); + } + HeapFree(GetProcessHeap(),0,This); }
@@ -303,6 +373,13 @@ HRESULT ThreadMgr_Constructor(IUnknown *pUnkOuter, IUnknown **ppOut) This->refCount = 1; TlsSetValue(tlsIndex,This);
+ list_init(&This->ActiveLanguageProfileNotifySink); + list_init(&This->DisplayAttributeNotifySink); + list_init(&This->KeyTraceEventSink); + list_init(&This->PreservedKeyNotifySink); + list_init(&This->ThreadFocusSink); + list_init(&This->ThreadMgrEventSink); + TRACE("returning %p\n", This); *ppOut = (IUnknown *)This; return S_OK;