Aric Stewart : msctf: ThreadMgr sink framework.
Alexandre Julliard
julliard at winehq.org
Wed Mar 25 10:31:30 CDT 2009
Module: wine
Branch: master
Commit: f723e4ca0862137d6e4ad8adc22d0ee64d38e904
URL: http://source.winehq.org/git/wine.git/?a=commit;h=f723e4ca0862137d6e4ad8adc22d0ee64d38e904
Author: Aric Stewart <aric at 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;
More information about the wine-cvs
mailing list