/*
 *  ITfThreadMgr implementation
 *
 *  Copyright 2008 Aric Stewart, CodeWeavers
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2.1 of the License, or (at your option) any later version.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this library; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
 */

#include "config.h"

#include <stdarg.h>

#define COBJMACROS

#include "wine/debug.h"
#include "windef.h"
#include "winbase.h"
#include "winreg.h"
#include "winuser.h"
#include "shlwapi.h"
#include "winerror.h"
#include "objbase.h"
#include "olectl.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 tagPreservedKey
{
    struct list     entry;
    GUID            guid;
    TF_PRESERVEDKEY prekey;
    LPWSTR          description;
    TfClientId      tid;
} PreservedKey;

typedef struct tagDocumentMgrs
{
    struct list     entry;
    ITfDocumentMgr  *docmgr;
} DocumentMgrEntry;

typedef struct tagAssociatedWindow
{
    struct list     entry;
    HWND            hwnd;
    ITfDocumentMgr  *docmgr;
} AssociatedWindow;

typedef struct tagACLMulti {
    const ITfThreadMgrVtbl *ThreadMgrVtbl;
    const ITfSourceVtbl *SourceVtbl;
    const ITfKeystrokeMgrVtbl *KeystrokeMgrVtbl;
    const ITfMessagePumpVtbl *MessagePumpVtbl;
    const ITfClientIdVtbl *ClientIdVtbl;
    /* const ITfThreadMgrExVtbl *ThreadMgrExVtbl; */
    /* const ITfConfigureSystemKeystrokeFeedVtbl *ConfigureSystemKeystrokeFeedVtbl; */
    /* const ITfLangBarItemMgrVtbl *LangBarItemMgrVtbl; */
    /* const ITfUIElementMgrVtbl *UIElementMgrVtbl; */
    const ITfSourceSingleVtbl *SourceSingleVtbl;
    LONG refCount;

    /* Aggregation */
    ITfCompartmentMgr  *CompartmentMgr;

    const ITfThreadMgrEventSinkVtbl *ThreadMgrEventSinkVtbl; /* internal */

    ITfDocumentMgr *focus;
    LONG activationCount;

    ITfKeyEventSink *forgroundKeyEventSink;
    CLSID forgroundTextService;

    struct list CurrentPreservedKeys;
    struct list CreatedDocumentMgrs;

    struct list AssociatedFocusWindows;
    HHOOK  focusHook;

    /* 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;

typedef struct tagEnumTfDocumentMgr {
    const IEnumTfDocumentMgrsVtbl *Vtbl;
    LONG refCount;

    struct list *index;
    struct list *head;
} EnumTfDocumentMgr;

static HRESULT EnumTfDocumentMgr_Constructor(struct list* head, IEnumTfDocumentMgrs **ppOut);

static inline ThreadMgr *impl_from_ITfSourceVtbl(ITfSource *iface)
{
    return (ThreadMgr *)((char *)iface - FIELD_OFFSET(ThreadMgr,SourceVtbl));
}

static inline ThreadMgr *impl_from_ITfKeystrokeMgrVtbl(ITfKeystrokeMgr *iface)
{
    return (ThreadMgr *)((char *)iface - FIELD_OFFSET(ThreadMgr,KeystrokeMgrVtbl));
}

static inline ThreadMgr *impl_from_ITfMessagePumpVtbl(ITfMessagePump *iface)
{
    return (ThreadMgr *)((char *)iface - FIELD_OFFSET(ThreadMgr,MessagePumpVtbl));
}

static inline ThreadMgr *impl_from_ITfClientIdVtbl(ITfClientId *iface)
{
    return (ThreadMgr *)((char *)iface - FIELD_OFFSET(ThreadMgr,ClientIdVtbl));
}

static inline ThreadMgr *impl_from_ITfThreadMgrEventSink(ITfThreadMgrEventSink *iface)
{
    return (ThreadMgr *)((char *)iface - FIELD_OFFSET(ThreadMgr,ThreadMgrEventSinkVtbl));
}

static inline ThreadMgr *impl_from_ITfSourceSingleVtbl(ITfSourceSingle* iface)

{
    return (ThreadMgr *)((char *)iface - FIELD_OFFSET(ThreadMgr,SourceSingleVtbl));
}

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;

    /* unhook right away */
    if (This->focusHook)
        UnhookWindowsHookEx(This->focusHook);

    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);
    }

    LIST_FOR_EACH_SAFE(cursor, cursor2, &This->CurrentPreservedKeys)
    {
        PreservedKey* key = LIST_ENTRY(cursor,PreservedKey,entry);
        list_remove(cursor);
        HeapFree(GetProcessHeap(),0,key->description);
        HeapFree(GetProcessHeap(),0,key);
    }

    LIST_FOR_EACH_SAFE(cursor, cursor2, &This->CreatedDocumentMgrs)
    {
        DocumentMgrEntry *mgr = LIST_ENTRY(cursor,DocumentMgrEntry,entry);
        list_remove(cursor);
        FIXME("Left Over ITfDocumentMgr.  Should we do something with it?\n");
        HeapFree(GetProcessHeap(),0,mgr);
    }

    LIST_FOR_EACH_SAFE(cursor, cursor2, &This->AssociatedFocusWindows)
    {
        AssociatedWindow *wnd = LIST_ENTRY(cursor,AssociatedWindow,entry);
        list_remove(cursor);
        HeapFree(GetProcessHeap(),0,wnd);
    }

    CompartmentMgr_Destructor(This->CompartmentMgr);

    HeapFree(GetProcessHeap(),0,This);
}

static HRESULT WINAPI ThreadMgr_QueryInterface(ITfThreadMgr *iface, REFIID iid, LPVOID *ppvOut)
{
    ThreadMgr *This = (ThreadMgr *)iface;
    *ppvOut = NULL;

    if (IsEqualIID(iid, &IID_IUnknown) || IsEqualIID(iid, &IID_ITfThreadMgr))
    {
        *ppvOut = This;
    }
    else if (IsEqualIID(iid, &IID_ITfSource))
    {
        *ppvOut = &This->SourceVtbl;
    }
    else if (IsEqualIID(iid, &IID_ITfKeystrokeMgr))
    {
        *ppvOut = &This->KeystrokeMgrVtbl;
    }
    else if (IsEqualIID(iid, &IID_ITfMessagePump))
    {
        *ppvOut = &This->MessagePumpVtbl;
    }
    else if (IsEqualIID(iid, &IID_ITfClientId))
    {
        *ppvOut = &This->ClientIdVtbl;
    }
    else if (IsEqualIID(iid, &IID_ITfCompartmentMgr))
    {
        *ppvOut = This->CompartmentMgr;
    }
    else if (IsEqualIID(iid, &IID_ITfSourceSingle))
    {
        *ppvOut = &This->SourceSingleVtbl;
    }

    if (*ppvOut)
    {
        ITfThreadMgr_AddRef(iface);
        return S_OK;
    }

    WARN("unsupported interface: %s\n", debugstr_guid(iid));
    return E_NOINTERFACE;
}

static ULONG WINAPI ThreadMgr_AddRef(ITfThreadMgr *iface)
{
    ThreadMgr *This = (ThreadMgr *)iface;
    return InterlockedIncrement(&This->refCount);
}

static ULONG WINAPI ThreadMgr_Release(ITfThreadMgr *iface)
{
    ThreadMgr *This = (ThreadMgr *)iface;
    ULONG ret;

    ret = InterlockedDecrement(&This->refCount);
    if (ret == 0)
        ThreadMgr_Destructor(This);
    return ret;
}

/*****************************************************
 * ITfThreadMgr functions
 *****************************************************/

static HRESULT WINAPI ThreadMgr_fnActivate( ITfThreadMgr* iface, TfClientId *ptid)
{
    ThreadMgr *This = (ThreadMgr *)iface;

    TRACE("(%p) %p\n",This, ptid);

    if (!ptid)
        return E_INVALIDARG;

    if (!processId)
    {
        GUID guid;
        CoCreateGuid(&guid);
        ITfClientId_GetClientId((ITfClientId*)&This->ClientIdVtbl,&guid,&processId);
    }

    activate_textservices(iface);
    This->activationCount++;
    *ptid = processId;
    return S_OK;
}

static HRESULT WINAPI ThreadMgr_fnDeactivate( ITfThreadMgr* iface)
{
    ThreadMgr *This = (ThreadMgr *)iface;
    TRACE("(%p)\n",This);

    if (This->activationCount == 0)
        return E_UNEXPECTED;

    This->activationCount --;

    if (This->activationCount == 0)
    {
        if (This->focus)
        {
            ITfThreadMgrEventSink_OnSetFocus((ITfThreadMgrEventSink*)&This->ThreadMgrEventSinkVtbl, 0, This->focus);
            ITfDocumentMgr_Release(This->focus);
            This->focus = 0;
        }
    }

    deactivate_textservices();

    return S_OK;
}

static HRESULT WINAPI ThreadMgr_CreateDocumentMgr( ITfThreadMgr* iface, ITfDocumentMgr
**ppdim)
{
    ThreadMgr *This = (ThreadMgr *)iface;
    DocumentMgrEntry *mgrentry;
    HRESULT hr;

    TRACE("(%p)\n",iface);
    mgrentry = HeapAlloc(GetProcessHeap(),0,sizeof(DocumentMgrEntry));
    if (mgrentry == NULL)
        return E_OUTOFMEMORY;

    hr = DocumentMgr_Constructor((ITfThreadMgrEventSink*)&This->ThreadMgrEventSinkVtbl, ppdim);

    if (SUCCEEDED(hr))
    {
        mgrentry->docmgr = *ppdim;
        list_add_head(&This->CreatedDocumentMgrs,&mgrentry->entry);
    }
    else
        HeapFree(GetProcessHeap(),0,mgrentry);

    return hr;
}

static HRESULT WINAPI ThreadMgr_EnumDocumentMgrs( ITfThreadMgr* iface, IEnumTfDocumentMgrs
**ppEnum)
{
    ThreadMgr *This = (ThreadMgr *)iface;
    TRACE("(%p) %p\n",This,ppEnum);

    if (!ppEnum)
        return E_INVALIDARG;

    return EnumTfDocumentMgr_Constructor(&This->CreatedDocumentMgrs, ppEnum);
}

static HRESULT WINAPI ThreadMgr_GetFocus( ITfThreadMgr* iface, ITfDocumentMgr
**ppdimFocus)
{
    ThreadMgr *This = (ThreadMgr *)iface;
    TRACE("(%p)\n",This);

    if (!ppdimFocus)
        return E_INVALIDARG;

    *ppdimFocus = This->focus;

    TRACE("->%p\n",This->focus);

    if (This->focus == NULL)
        return S_FALSE;

    ITfDocumentMgr_AddRef(This->focus);

    return S_OK;
}

static HRESULT WINAPI ThreadMgr_SetFocus( ITfThreadMgr* iface, ITfDocumentMgr *pdimFocus)
{
    ITfDocumentMgr *check;
    ThreadMgr *This = (ThreadMgr *)iface;

    TRACE("(%p) %p\n",This,pdimFocus);

    if (!pdimFocus)
        check = NULL;
    else if (FAILED(ITfDocumentMgr_QueryInterface(pdimFocus,&IID_ITfDocumentMgr,(LPVOID*) &check)))
        return E_INVALIDARG;

    ITfThreadMgrEventSink_OnSetFocus((ITfThreadMgrEventSink*)&This->ThreadMgrEventSinkVtbl, check, This->focus);

    if (This->focus)
        ITfDocumentMgr_Release(This->focus);

    This->focus = check;
    return S_OK;
}

static LRESULT CALLBACK ThreadFocusHookProc(int nCode, WPARAM wParam, LPARAM lParam)
{
    ThreadMgr *This;

    This = TlsGetValue(tlsIndex);
    if (!This)
    {
        ERR("Hook proc but no ThreadMgr for this thread. Serious Error\n");
        return 0;
    }
    if (!This->focusHook)
    {
        ERR("Hook proc but no ThreadMgr focus Hook. Serious Error\n");
        return 0;
    }

    if (nCode == HCBT_SETFOCUS) /* focus change within our thread */
    {
        struct list *cursor;

        LIST_FOR_EACH(cursor, &This->AssociatedFocusWindows)
        {
            AssociatedWindow *wnd = LIST_ENTRY(cursor,AssociatedWindow,entry);
            if (wnd->hwnd == (HWND)wParam)
            {
                TRACE("Triggering Associated window focus\n");
                if (This->focus != wnd->docmgr)
                    ThreadMgr_SetFocus((ITfThreadMgr*)This, wnd->docmgr);
                break;
            }
        }
    }

    return CallNextHookEx(This->focusHook, nCode, wParam, lParam);
}

static HRESULT SetupWindowsHook(ThreadMgr *This)
{
    if (!This->focusHook)
    {
        This->focusHook = SetWindowsHookExW(WH_CBT, ThreadFocusHookProc, 0,
                             GetCurrentThreadId());
        if (!This->focusHook)
        {
            ERR("Unable to set focus hook\n");
            return E_FAIL;
        }
        return S_OK;
    }
    return S_FALSE;
}

static HRESULT WINAPI ThreadMgr_AssociateFocus( ITfThreadMgr* iface, HWND hwnd,
ITfDocumentMgr *pdimNew, ITfDocumentMgr **ppdimPrev)
{
    struct list *cursor, *cursor2;
    ThreadMgr *This = (ThreadMgr *)iface;
    AssociatedWindow *wnd;

    TRACE("(%p) %p %p %p\n",This,hwnd,pdimNew,ppdimPrev);

    if (!ppdimPrev)
        return E_INVALIDARG;

    *ppdimPrev = NULL;

    LIST_FOR_EACH_SAFE(cursor, cursor2, &This->AssociatedFocusWindows)
    {
        wnd = LIST_ENTRY(cursor,AssociatedWindow,entry);
        if (wnd->hwnd == hwnd)
        {
            if (wnd->docmgr)
                ITfDocumentMgr_AddRef(wnd->docmgr);
            *ppdimPrev = wnd->docmgr;
            wnd->docmgr = pdimNew;
            if (GetFocus() == hwnd)
                ThreadMgr_SetFocus(iface,pdimNew);
            return S_OK;
        }
    }

    wnd = HeapAlloc(GetProcessHeap(),0,sizeof(AssociatedWindow));
    wnd->hwnd = hwnd;
    wnd->docmgr = pdimNew;
    list_add_head(&This->AssociatedFocusWindows,&wnd->entry);

    if (GetFocus() == hwnd)
        ThreadMgr_SetFocus(iface,pdimNew);

    SetupWindowsHook(This);

    return S_OK;
}

static HRESULT WINAPI ThreadMgr_IsThreadFocus( ITfThreadMgr* iface, BOOL *pfThreadFocus)
{
    HWND focus;
    ThreadMgr *This = (ThreadMgr *)iface;
    TRACE("(%p) %p\n",This,pfThreadFocus);
    focus = GetFocus();
    *pfThreadFocus = (focus == NULL);
    return S_OK;
}

static HRESULT WINAPI ThreadMgr_GetFunctionProvider( ITfThreadMgr* iface, REFCLSID clsid,
ITfFunctionProvider **ppFuncProv)
{
    ThreadMgr *This = (ThreadMgr *)iface;
    FIXME("STUB:(%p)\n",This);
    return E_NOTIMPL;
}

static HRESULT WINAPI ThreadMgr_EnumFunctionProviders( ITfThreadMgr* iface,
IEnumTfFunctionProviders **ppEnum)
{
    ThreadMgr *This = (ThreadMgr *)iface;
    FIXME("STUB:(%p)\n",This);
    return E_NOTIMPL;
}

static HRESULT WINAPI ThreadMgr_GetGlobalCompartment( ITfThreadMgr* iface,
ITfCompartmentMgr **ppCompMgr)
{
    ThreadMgr *This = (ThreadMgr *)iface;
    HRESULT hr;
    TRACE("(%p) %p\n",This, ppCompMgr);

    if (!ppCompMgr)
        return E_INVALIDARG;

    if (!globalCompartmentMgr)
    {
        hr = CompartmentMgr_Constructor(NULL,&IID_ITfCompartmentMgr,(IUnknown**)&globalCompartmentMgr);
        if (FAILED(hr))
            return hr;
    }

    ITfCompartmentMgr_AddRef(globalCompartmentMgr);
    *ppCompMgr = globalCompartmentMgr;
    return S_OK;
}

static const ITfThreadMgrVtbl ThreadMgr_ThreadMgrVtbl =
{
    ThreadMgr_QueryInterface,
    ThreadMgr_AddRef,
    ThreadMgr_Release,

    ThreadMgr_fnActivate,
    ThreadMgr_fnDeactivate,
    ThreadMgr_CreateDocumentMgr,
    ThreadMgr_EnumDocumentMgrs,
    ThreadMgr_GetFocus,
    ThreadMgr_SetFocus,
    ThreadMgr_AssociateFocus,
    ThreadMgr_IsThreadFocus,
    ThreadMgr_GetFunctionProvider,
    ThreadMgr_EnumFunctionProviders,
    ThreadMgr_GetGlobalCompartment
};


static HRESULT WINAPI Source_QueryInterface(ITfSource *iface, REFIID iid, LPVOID *ppvOut)
{
    ThreadMgr *This = impl_from_ITfSourceVtbl(iface);
    return ThreadMgr_QueryInterface((ITfThreadMgr *)This, iid, *ppvOut);
}

static ULONG WINAPI Source_AddRef(ITfSource *iface)
{
    ThreadMgr *This = impl_from_ITfSourceVtbl(iface);
    return ThreadMgr_AddRef((ITfThreadMgr*)This);
}

static ULONG WINAPI Source_Release(ITfSource *iface)
{
    ThreadMgr *This = impl_from_ITfSourceVtbl(iface);
    return ThreadMgr_Release((ITfThreadMgr *)This);
}

/*****************************************************
 * ITfSource functions
 *****************************************************/
static HRESULT WINAPI ThreadMgrSource_AdviseSink(ITfSource *iface,
        REFIID riid, IUnknown *punk, DWORD *pdwCookie)
{
    ThreadMgrSink *tms;
    ThreadMgr *This = impl_from_ITfSourceVtbl(iface);

    TRACE("(%p) %s %p %p\n",This,debugstr_guid(riid),punk,pdwCookie);

    if (!riid || !punk || !pdwCookie)
        return E_INVALIDARG;

    if (IsEqualIID(riid, &IID_ITfThreadMgrEventSink))
    {
        tms = HeapAlloc(GetProcessHeap(),0,sizeof(ThreadMgrSink));
        if (!tms)
            return E_OUTOFMEMORY;
        if (FAILED(IUnknown_QueryInterface(punk, riid, (LPVOID *)&tms->interfaces.pITfThreadMgrEventSink)))
        {
            HeapFree(GetProcessHeap(),0,tms);
            return CONNECT_E_CANNOTCONNECT;
        }
        list_add_head(&This->ThreadMgrEventSink,&tms->entry);
        *pdwCookie = generate_Cookie(COOKIE_MAGIC_TMSINK, tms);
    }
    else
    {
        FIXME("(%p) Unhandled Sink: %s\n",This,debugstr_guid(riid));
        return E_NOTIMPL;
    }

    TRACE("cookie %x\n",*pdwCookie);

    return S_OK;
}

static HRESULT WINAPI ThreadMgrSource_UnadviseSink(ITfSource *iface, DWORD pdwCookie)
{
    ThreadMgrSink *sink;
    ThreadMgr *This = impl_from_ITfSourceVtbl(iface);

    TRACE("(%p) %x\n",This,pdwCookie);

    if (get_Cookie_magic(pdwCookie)!=COOKIE_MAGIC_TMSINK)
        return E_INVALIDARG;

    sink = (ThreadMgrSink*)remove_Cookie(pdwCookie);
    if (!sink)
        return CONNECT_E_NOCONNECTION;

    list_remove(&sink->entry);
    free_sink(sink);

    return S_OK;
}

static const ITfSourceVtbl ThreadMgr_SourceVtbl =
{
    Source_QueryInterface,
    Source_AddRef,
    Source_Release,

    ThreadMgrSource_AdviseSink,
    ThreadMgrSource_UnadviseSink,
};

/*****************************************************
 * ITfKeystrokeMgr functions
 *****************************************************/

static HRESULT WINAPI KeystrokeMgr_QueryInterface(ITfKeystrokeMgr *iface, REFIID iid, LPVOID *ppvOut)
{
    ThreadMgr *This = impl_from_ITfKeystrokeMgrVtbl(iface);
    return ThreadMgr_QueryInterface((ITfThreadMgr *)This, iid, *ppvOut);
}

static ULONG WINAPI KeystrokeMgr_AddRef(ITfKeystrokeMgr *iface)
{
    ThreadMgr *This = impl_from_ITfKeystrokeMgrVtbl(iface);
    return ThreadMgr_AddRef((ITfThreadMgr*)This);
}

static ULONG WINAPI KeystrokeMgr_Release(ITfKeystrokeMgr *iface)
{
    ThreadMgr *This = impl_from_ITfKeystrokeMgrVtbl(iface);
    return ThreadMgr_Release((ITfThreadMgr *)This);
}

static HRESULT WINAPI KeystrokeMgr_AdviseKeyEventSink(ITfKeystrokeMgr *iface,
        TfClientId tid, ITfKeyEventSink *pSink, BOOL fForeground)
{
    ThreadMgr *This = impl_from_ITfKeystrokeMgrVtbl(iface);
    CLSID textservice;
    ITfKeyEventSink *check = NULL;

    TRACE("(%p) %x %p %i\n",This,tid,pSink,fForeground);

    if (!tid || !pSink)
        return E_INVALIDARG;

    textservice = get_textservice_clsid(tid);
    if (IsEqualCLSID(&GUID_NULL,&textservice))
        return E_INVALIDARG;

    get_textservice_sink(tid, &IID_ITfKeyEventSink, (IUnknown**)&check);
    if (check != NULL)
        return CONNECT_E_ADVISELIMIT;

    if (FAILED(ITfKeyEventSink_QueryInterface(pSink,&IID_ITfKeyEventSink,(LPVOID*) &check)))
        return E_INVALIDARG;

    set_textservice_sink(tid, &IID_ITfKeyEventSink, (IUnknown*)check);

    if (fForeground)
    {
        if (This->forgroundKeyEventSink)
        {
            ITfKeyEventSink_OnSetFocus(This->forgroundKeyEventSink, FALSE);
            ITfKeyEventSink_Release(This->forgroundKeyEventSink);
        }
        ITfKeyEventSink_AddRef(check);
        ITfKeyEventSink_OnSetFocus(check, TRUE);
        This->forgroundKeyEventSink = check;
        This->forgroundTextService = textservice;
    }
    return S_OK;
}

static HRESULT WINAPI KeystrokeMgr_UnadviseKeyEventSink(ITfKeystrokeMgr *iface,
        TfClientId tid)
{
    ThreadMgr *This = impl_from_ITfKeystrokeMgrVtbl(iface);
    CLSID textservice;
    ITfKeyEventSink *check = NULL;
    TRACE("(%p) %x\n",This,tid);

    if (!tid)
        return E_INVALIDARG;

    textservice = get_textservice_clsid(tid);
    if (IsEqualCLSID(&GUID_NULL,&textservice))
        return E_INVALIDARG;

    get_textservice_sink(tid, &IID_ITfKeyEventSink, (IUnknown**)&check);

    if (!check)
        return CONNECT_E_NOCONNECTION;

    set_textservice_sink(tid, &IID_ITfKeyEventSink, NULL);
    ITfKeyEventSink_Release(check);

    if (This->forgroundKeyEventSink == check)
    {
        ITfKeyEventSink_Release(This->forgroundKeyEventSink);
        This->forgroundKeyEventSink = NULL;
        This->forgroundTextService = GUID_NULL;
    }
    return S_OK;
}

static HRESULT WINAPI KeystrokeMgr_GetForeground(ITfKeystrokeMgr *iface,
        CLSID *pclsid)
{
    ThreadMgr *This = impl_from_ITfKeystrokeMgrVtbl(iface);
    TRACE("(%p) %p\n",This,pclsid);
    if (!pclsid)
        return E_INVALIDARG;

    if (IsEqualCLSID(&This->forgroundTextService,&GUID_NULL))
        return S_FALSE;

    *pclsid = This->forgroundTextService;
    return S_OK;
}

static HRESULT WINAPI KeystrokeMgr_TestKeyDown(ITfKeystrokeMgr *iface,
        WPARAM wParam, LPARAM lParam, BOOL *pfEaten)
{
    ThreadMgr *This = impl_from_ITfKeystrokeMgrVtbl(iface);
    FIXME("STUB:(%p)\n",This);
    return E_NOTIMPL;
}

static HRESULT WINAPI KeystrokeMgr_TestKeyUp(ITfKeystrokeMgr *iface,
        WPARAM wParam, LPARAM lParam, BOOL *pfEaten)
{
    ThreadMgr *This = impl_from_ITfKeystrokeMgrVtbl(iface);
    FIXME("STUB:(%p)\n",This);
    return E_NOTIMPL;
}

static HRESULT WINAPI KeystrokeMgr_KeyDown(ITfKeystrokeMgr *iface,
        WPARAM wParam, LPARAM lParam, BOOL *pfEaten)
{
    ThreadMgr *This = impl_from_ITfKeystrokeMgrVtbl(iface);
    FIXME("STUB:(%p)\n",This);
    return E_NOTIMPL;
}

static HRESULT WINAPI KeystrokeMgr_KeyUp(ITfKeystrokeMgr *iface,
        WPARAM wParam, LPARAM lParam, BOOL *pfEaten)
{
    ThreadMgr *This = impl_from_ITfKeystrokeMgrVtbl(iface);
    FIXME("STUB:(%p)\n",This);
    return E_NOTIMPL;
}

static HRESULT WINAPI KeystrokeMgr_GetPreservedKey(ITfKeystrokeMgr *iface,
        ITfContext *pic, const TF_PRESERVEDKEY *pprekey, GUID *pguid)
{
    ThreadMgr *This = impl_from_ITfKeystrokeMgrVtbl(iface);
    FIXME("STUB:(%p)\n",This);
    return E_NOTIMPL;
}

static HRESULT WINAPI KeystrokeMgr_IsPreservedKey(ITfKeystrokeMgr *iface,
        REFGUID rguid, const TF_PRESERVEDKEY *pprekey, BOOL *pfRegistered)
{
    ThreadMgr *This = impl_from_ITfKeystrokeMgrVtbl(iface);
    struct list *cursor;

    TRACE("(%p) %s (%x %x) %p\n",This,debugstr_guid(rguid), (pprekey)?pprekey->uVKey:0, (pprekey)?pprekey->uModifiers:0, pfRegistered);

    if (!rguid || !pprekey || !pfRegistered)
        return E_INVALIDARG;

    LIST_FOR_EACH(cursor, &This->CurrentPreservedKeys)
    {
        PreservedKey* key = LIST_ENTRY(cursor,PreservedKey,entry);
        if (IsEqualGUID(rguid,&key->guid) && pprekey->uVKey == key->prekey.uVKey && pprekey->uModifiers == key->prekey.uModifiers)
        {
            *pfRegistered = TRUE;
            return S_OK;
        }
    }

    *pfRegistered = FALSE;
    return S_FALSE;
}

static HRESULT WINAPI KeystrokeMgr_PreserveKey(ITfKeystrokeMgr *iface,
        TfClientId tid, REFGUID rguid, const TF_PRESERVEDKEY *prekey,
        const WCHAR *pchDesc, ULONG cchDesc)
{
    ThreadMgr *This = impl_from_ITfKeystrokeMgrVtbl(iface);
    struct list *cursor;
    PreservedKey *newkey;

    TRACE("(%p) %x %s (%x,%x) %s\n",This,tid, debugstr_guid(rguid),(prekey)?prekey->uVKey:0,(prekey)?prekey->uModifiers:0,debugstr_wn(pchDesc,cchDesc));

    if (!tid || ! rguid || !prekey || (cchDesc && !pchDesc))
        return E_INVALIDARG;

    LIST_FOR_EACH(cursor, &This->CurrentPreservedKeys)
    {
        PreservedKey* key = LIST_ENTRY(cursor,PreservedKey,entry);
        if (IsEqualGUID(rguid,&key->guid) && prekey->uVKey == key->prekey.uVKey && prekey->uModifiers == key->prekey.uModifiers)
            return TF_E_ALREADY_EXISTS;
    }

    newkey = HeapAlloc(GetProcessHeap(),0,sizeof(PreservedKey));
    if (!newkey)
        return E_OUTOFMEMORY;

    newkey->guid  = *rguid;
    newkey->prekey = *prekey;
    newkey->tid = tid;
    newkey->description = NULL;
    if (cchDesc)
    {
        newkey->description = HeapAlloc(GetProcessHeap(),0,cchDesc * sizeof(WCHAR));
        if (!newkey->description)
        {
            HeapFree(GetProcessHeap(),0,newkey);
            return E_OUTOFMEMORY;
        }
        memcpy(newkey->description, pchDesc, cchDesc*sizeof(WCHAR));
    }

    list_add_head(&This->CurrentPreservedKeys,&newkey->entry);

    return S_OK;
}

static HRESULT WINAPI KeystrokeMgr_UnpreserveKey(ITfKeystrokeMgr *iface,
        REFGUID rguid, const TF_PRESERVEDKEY *pprekey)
{
    ThreadMgr *This = impl_from_ITfKeystrokeMgrVtbl(iface);
    PreservedKey* key = NULL;
    struct list *cursor;
    TRACE("(%p) %s (%x %x)\n",This,debugstr_guid(rguid),(pprekey)?pprekey->uVKey:0, (pprekey)?pprekey->uModifiers:0);

    if (!pprekey || !rguid)
        return E_INVALIDARG;

    LIST_FOR_EACH(cursor, &This->CurrentPreservedKeys)
    {
        key = LIST_ENTRY(cursor,PreservedKey,entry);
        if (IsEqualGUID(rguid,&key->guid) && pprekey->uVKey == key->prekey.uVKey && pprekey->uModifiers == key->prekey.uModifiers)
            break;
        key = NULL;
    }

    if (!key)
        return CONNECT_E_NOCONNECTION;

    list_remove(&key->entry);
    HeapFree(GetProcessHeap(),0,key->description);
    HeapFree(GetProcessHeap(),0,key);

    return S_OK;
}

static HRESULT WINAPI KeystrokeMgr_SetPreservedKeyDescription(ITfKeystrokeMgr *iface,
        REFGUID rguid, const WCHAR *pchDesc, ULONG cchDesc)
{
    ThreadMgr *This = impl_from_ITfKeystrokeMgrVtbl(iface);
    FIXME("STUB:(%p)\n",This);
    return E_NOTIMPL;
}

static HRESULT WINAPI KeystrokeMgr_GetPreservedKeyDescription(ITfKeystrokeMgr *iface,
        REFGUID rguid, BSTR *pbstrDesc)
{
    ThreadMgr *This = impl_from_ITfKeystrokeMgrVtbl(iface);
    FIXME("STUB:(%p)\n",This);
    return E_NOTIMPL;
}

static HRESULT WINAPI KeystrokeMgr_SimulatePreservedKey(ITfKeystrokeMgr *iface,
        ITfContext *pic, REFGUID rguid, BOOL *pfEaten)
{
    ThreadMgr *This = impl_from_ITfKeystrokeMgrVtbl(iface);
    FIXME("STUB:(%p)\n",This);
    return E_NOTIMPL;
}

static const ITfKeystrokeMgrVtbl ThreadMgr_KeystrokeMgrVtbl =
{
    KeystrokeMgr_QueryInterface,
    KeystrokeMgr_AddRef,
    KeystrokeMgr_Release,

    KeystrokeMgr_AdviseKeyEventSink,
    KeystrokeMgr_UnadviseKeyEventSink,
    KeystrokeMgr_GetForeground,
    KeystrokeMgr_TestKeyDown,
    KeystrokeMgr_TestKeyUp,
    KeystrokeMgr_KeyDown,
    KeystrokeMgr_KeyUp,
    KeystrokeMgr_GetPreservedKey,
    KeystrokeMgr_IsPreservedKey,
    KeystrokeMgr_PreserveKey,
    KeystrokeMgr_UnpreserveKey,
    KeystrokeMgr_SetPreservedKeyDescription,
    KeystrokeMgr_GetPreservedKeyDescription,
    KeystrokeMgr_SimulatePreservedKey
};

/*****************************************************
 * ITfMessagePump functions
 *****************************************************/

static HRESULT WINAPI MessagePump_QueryInterface(ITfMessagePump *iface, REFIID iid, LPVOID *ppvOut)
{
    ThreadMgr *This = impl_from_ITfMessagePumpVtbl(iface);
    return ThreadMgr_QueryInterface((ITfThreadMgr *)This, iid, *ppvOut);
}

static ULONG WINAPI MessagePump_AddRef(ITfMessagePump *iface)
{
    ThreadMgr *This = impl_from_ITfMessagePumpVtbl(iface);
    return ThreadMgr_AddRef((ITfThreadMgr*)This);
}

static ULONG WINAPI MessagePump_Release(ITfMessagePump *iface)
{
    ThreadMgr *This = impl_from_ITfMessagePumpVtbl(iface);
    return ThreadMgr_Release((ITfThreadMgr *)This);
}

static HRESULT WINAPI MessagePump_PeekMessageA(ITfMessagePump *iface,
        LPMSG pMsg, HWND hwnd, UINT wMsgFilterMin, UINT wMsgFilterMax,
        UINT wRemoveMsg, BOOL *pfResult)
{
    if (!pfResult)
        return E_INVALIDARG;
    *pfResult = PeekMessageA(pMsg, hwnd, wMsgFilterMin, wMsgFilterMax, wRemoveMsg);
    return S_OK;
}

static HRESULT WINAPI MessagePump_GetMessageA(ITfMessagePump *iface,
        LPMSG pMsg, HWND hwnd, UINT wMsgFilterMin, UINT wMsgFilterMax,
        BOOL *pfResult)
{
    if (!pfResult)
        return E_INVALIDARG;
    *pfResult = GetMessageA(pMsg, hwnd, wMsgFilterMin, wMsgFilterMax);
    return S_OK;
}

static HRESULT WINAPI MessagePump_PeekMessageW(ITfMessagePump *iface,
        LPMSG pMsg, HWND hwnd, UINT wMsgFilterMin, UINT wMsgFilterMax,
        UINT wRemoveMsg, BOOL *pfResult)
{
    if (!pfResult)
        return E_INVALIDARG;
    *pfResult = PeekMessageW(pMsg, hwnd, wMsgFilterMin, wMsgFilterMax, wRemoveMsg);
    return S_OK;
}

static HRESULT WINAPI MessagePump_GetMessageW(ITfMessagePump *iface,
        LPMSG pMsg, HWND hwnd, UINT wMsgFilterMin, UINT wMsgFilterMax,
        BOOL *pfResult)
{
    if (!pfResult)
        return E_INVALIDARG;
    *pfResult = GetMessageW(pMsg, hwnd, wMsgFilterMin, wMsgFilterMax);
    return S_OK;
}

static const ITfMessagePumpVtbl ThreadMgr_MessagePumpVtbl =
{
    MessagePump_QueryInterface,
    MessagePump_AddRef,
    MessagePump_Release,

    MessagePump_PeekMessageA,
    MessagePump_GetMessageA,
    MessagePump_PeekMessageW,
    MessagePump_GetMessageW
};

/*****************************************************
 * ITfClientId functions
 *****************************************************/

static HRESULT WINAPI ClientId_QueryInterface(ITfClientId *iface, REFIID iid, LPVOID *ppvOut)
{
    ThreadMgr *This = impl_from_ITfClientIdVtbl(iface);
    return ThreadMgr_QueryInterface((ITfThreadMgr *)This, iid, *ppvOut);
}

static ULONG WINAPI ClientId_AddRef(ITfClientId *iface)
{
    ThreadMgr *This = impl_from_ITfClientIdVtbl(iface);
    return ThreadMgr_AddRef((ITfThreadMgr*)This);
}

static ULONG WINAPI ClientId_Release(ITfClientId *iface)
{
    ThreadMgr *This = impl_from_ITfClientIdVtbl(iface);
    return ThreadMgr_Release((ITfThreadMgr *)This);
}

static HRESULT WINAPI ClientId_GetClientId(ITfClientId *iface,
    REFCLSID rclsid, TfClientId *ptid)

{
    HRESULT hr;
    ITfCategoryMgr *catmgr;
    ThreadMgr *This = impl_from_ITfClientIdVtbl(iface);

    TRACE("(%p) %s\n",This,debugstr_guid(rclsid));

    CategoryMgr_Constructor(NULL,(IUnknown**)&catmgr);
    hr = ITfCategoryMgr_RegisterGUID(catmgr,rclsid,ptid);
    ITfCategoryMgr_Release(catmgr);

    return hr;
}

static const ITfClientIdVtbl ThreadMgr_ClientIdVtbl =
{
    ClientId_QueryInterface,
    ClientId_AddRef,
    ClientId_Release,

    ClientId_GetClientId
};

/*****************************************************
 * 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 HRESULT WINAPI 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 HRESULT WINAPI 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 HRESULT WINAPI 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 HRESULT WINAPI 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 HRESULT WINAPI 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
};

/*****************************************************
 * ITfSourceSingle functions
 *****************************************************/
static HRESULT WINAPI ThreadMgrSourceSingle_QueryInterface(ITfSourceSingle *iface, REFIID iid, LPVOID *ppvOut)
{
    ThreadMgr *This = impl_from_ITfSourceSingleVtbl(iface);
    return ThreadMgr_QueryInterface((ITfThreadMgr *)This, iid, *ppvOut);
}

static ULONG WINAPI ThreadMgrSourceSingle_AddRef(ITfSourceSingle *iface)
{
    ThreadMgr *This = impl_from_ITfSourceSingleVtbl(iface);
    return ThreadMgr_AddRef((ITfThreadMgr *)This);
}

static ULONG WINAPI ThreadMgrSourceSingle_Release(ITfSourceSingle *iface)
{
    ThreadMgr *This = impl_from_ITfSourceSingleVtbl(iface);
    return ThreadMgr_Release((ITfThreadMgr *)This);
}

static HRESULT WINAPI ThreadMgrSourceSingle_AdviseSingleSink( ITfSourceSingle *iface,
    TfClientId tid, REFIID riid, IUnknown *punk)
{
    ThreadMgr *This = impl_from_ITfSourceSingleVtbl(iface);
    FIXME("STUB:(%p) %i %s %p\n",This, tid, debugstr_guid(riid),punk);
    return E_NOTIMPL;
}

static HRESULT WINAPI ThreadMgrSourceSingle_UnadviseSingleSink( ITfSourceSingle *iface,
    TfClientId tid, REFIID riid)
{
    ThreadMgr *This = impl_from_ITfSourceSingleVtbl(iface);
    FIXME("STUB:(%p) %i %s\n",This, tid, debugstr_guid(riid));
    return E_NOTIMPL;
}

static const ITfSourceSingleVtbl ThreadMgr_SourceSingleVtbl =
{
    ThreadMgrSourceSingle_QueryInterface,
    ThreadMgrSourceSingle_AddRef,
    ThreadMgrSourceSingle_Release,

    ThreadMgrSourceSingle_AdviseSingleSink,
    ThreadMgrSourceSingle_UnadviseSingleSink,
};

HRESULT ThreadMgr_Constructor(IUnknown *pUnkOuter, IUnknown **ppOut)
{
    ThreadMgr *This;
    if (pUnkOuter)
        return CLASS_E_NOAGGREGATION;

    /* Only 1 ThreadMgr is created per thread */
    This = TlsGetValue(tlsIndex);
    if (This)
    {
        ThreadMgr_AddRef((ITfThreadMgr*)This);
        *ppOut = (IUnknown*)This;
        return S_OK;
    }

    This = HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,sizeof(ThreadMgr));
    if (This == NULL)
        return E_OUTOFMEMORY;

    This->ThreadMgrVtbl= &ThreadMgr_ThreadMgrVtbl;
    This->SourceVtbl = &ThreadMgr_SourceVtbl;
    This->KeystrokeMgrVtbl= &ThreadMgr_KeystrokeMgrVtbl;
    This->MessagePumpVtbl= &ThreadMgr_MessagePumpVtbl;
    This->ClientIdVtbl = &ThreadMgr_ClientIdVtbl;
    This->ThreadMgrEventSinkVtbl = &ThreadMgr_ThreadMgrEventSinkVtbl;
    This->SourceSingleVtbl = &ThreadMgr_SourceSingleVtbl;
    This->refCount = 1;
    TlsSetValue(tlsIndex,This);

    CompartmentMgr_Constructor((IUnknown*)This, &IID_IUnknown, (IUnknown**)&This->CompartmentMgr);

    list_init(&This->CurrentPreservedKeys);
    list_init(&This->CreatedDocumentMgrs);
    list_init(&This->AssociatedFocusWindows);

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

/**************************************************
 * IEnumTfDocumentMgrs implementation
 **************************************************/
static void EnumTfDocumentMgr_Destructor(EnumTfDocumentMgr *This)
{
    TRACE("destroying %p\n", This);
    HeapFree(GetProcessHeap(),0,This);
}

static HRESULT WINAPI EnumTfDocumentMgr_QueryInterface(IEnumTfDocumentMgrs *iface, REFIID iid, LPVOID *ppvOut)
{
    EnumTfDocumentMgr *This = (EnumTfDocumentMgr *)iface;
    *ppvOut = NULL;

    if (IsEqualIID(iid, &IID_IUnknown) || IsEqualIID(iid, &IID_IEnumTfDocumentMgrs))
    {
        *ppvOut = This;
    }

    if (*ppvOut)
    {
        IEnumTfDocumentMgrs_AddRef(iface);
        return S_OK;
    }

    WARN("unsupported interface: %s\n", debugstr_guid(iid));
    return E_NOINTERFACE;
}

static ULONG WINAPI EnumTfDocumentMgr_AddRef(IEnumTfDocumentMgrs *iface)
{
    EnumTfDocumentMgr *This = (EnumTfDocumentMgr*)iface;
    return InterlockedIncrement(&This->refCount);
}

static ULONG WINAPI EnumTfDocumentMgr_Release(IEnumTfDocumentMgrs *iface)
{
    EnumTfDocumentMgr *This = (EnumTfDocumentMgr *)iface;
    ULONG ret;

    ret = InterlockedDecrement(&This->refCount);
    if (ret == 0)
        EnumTfDocumentMgr_Destructor(This);
    return ret;
}

static HRESULT WINAPI EnumTfDocumentMgr_Next(IEnumTfDocumentMgrs *iface,
    ULONG ulCount, ITfDocumentMgr **rgDocumentMgr, ULONG *pcFetched)
{
    EnumTfDocumentMgr *This = (EnumTfDocumentMgr *)iface;
    ULONG fetched = 0;

    TRACE("(%p)\n",This);

    if (rgDocumentMgr == NULL) return E_POINTER;

    while (fetched < ulCount)
    {
        DocumentMgrEntry *mgrentry;
        if (This->index == NULL)
            break;

        mgrentry = LIST_ENTRY(This->index,DocumentMgrEntry,entry);
        if (mgrentry == NULL)
            break;

        *rgDocumentMgr = mgrentry->docmgr;
        ITfDocumentMgr_AddRef(*rgDocumentMgr);

        This->index = list_next(This->head, This->index);
        ++fetched;
        ++rgDocumentMgr;
    }

    if (pcFetched) *pcFetched = fetched;
    return fetched == ulCount ? S_OK : S_FALSE;
}

static HRESULT WINAPI EnumTfDocumentMgr_Skip( IEnumTfDocumentMgrs* iface, ULONG celt)
{
    INT i;
    EnumTfDocumentMgr *This = (EnumTfDocumentMgr *)iface;
    TRACE("(%p)\n",This);
    for(i = 0; i < celt && This->index != NULL; i++)
        This->index = list_next(This->head, This->index);
    return S_OK;
}

static HRESULT WINAPI EnumTfDocumentMgr_Reset( IEnumTfDocumentMgrs* iface)
{
    EnumTfDocumentMgr *This = (EnumTfDocumentMgr *)iface;
    TRACE("(%p)\n",This);
    This->index = list_head(This->head);
    return S_OK;
}

static HRESULT WINAPI EnumTfDocumentMgr_Clone( IEnumTfDocumentMgrs *iface,
    IEnumTfDocumentMgrs **ppenum)
{
    EnumTfDocumentMgr *This = (EnumTfDocumentMgr *)iface;
    HRESULT res;

    TRACE("(%p)\n",This);

    if (ppenum == NULL) return E_POINTER;

    res = EnumTfDocumentMgr_Constructor(This->head, ppenum);
    if (SUCCEEDED(res))
    {
        EnumTfDocumentMgr *new_This = (EnumTfDocumentMgr *)*ppenum;
        new_This->index = This->index;
    }
    return res;
}

static const IEnumTfDocumentMgrsVtbl IEnumTfDocumentMgrs_Vtbl ={
    EnumTfDocumentMgr_QueryInterface,
    EnumTfDocumentMgr_AddRef,
    EnumTfDocumentMgr_Release,

    EnumTfDocumentMgr_Clone,
    EnumTfDocumentMgr_Next,
    EnumTfDocumentMgr_Reset,
    EnumTfDocumentMgr_Skip
};

static HRESULT EnumTfDocumentMgr_Constructor(struct list* head, IEnumTfDocumentMgrs **ppOut)
{
    EnumTfDocumentMgr *This;

    This = HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,sizeof(EnumTfDocumentMgr));
    if (This == NULL)
        return E_OUTOFMEMORY;

    This->Vtbl= &IEnumTfDocumentMgrs_Vtbl;
    This->refCount = 1;
    This->head = head;
    This->index = list_head(This->head);

    TRACE("returning %p\n", This);
    *ppOut = (IEnumTfDocumentMgrs*)This;
    return S_OK;
}

void ThreadMgr_OnDocumentMgrDestruction(ITfThreadMgr *tm, ITfDocumentMgr *mgr)
{
    ThreadMgr *This = (ThreadMgr *)tm;
    struct list *cursor;
    LIST_FOR_EACH(cursor, &This->CreatedDocumentMgrs)
    {
        DocumentMgrEntry *mgrentry = LIST_ENTRY(cursor,DocumentMgrEntry,entry);
        if (mgrentry->docmgr == mgr)
        {
            list_remove(cursor);
            HeapFree(GetProcessHeap(),0,mgrentry);
            return;
        }
    }
    FIXME("ITfDocumentMgr %p not found in this thread\n",mgr);
}
