msctf: ThreadMgr sink framework.

This commit is contained in:
Aric Stewart 2009-03-24 08:21:28 -05:00 committed by Alexandre Julliard
parent 8d2ce074bb
commit f723e4ca08
1 changed files with 77 additions and 0 deletions

View File

@ -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;