/*
 *  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 {
    ITfThreadMgrEx ITfThreadMgrEx_iface;
    ITfSource ITfSource_iface;
    ITfKeystrokeMgr ITfKeystrokeMgr_iface;
    ITfMessagePump ITfMessagePump_iface;
    ITfClientId ITfClientId_iface;
    /* const ITfThreadMgrExVtbl *ThreadMgrExVtbl; */
    /* const ITfConfigureSystemKeystrokeFeedVtbl *ConfigureSystemKeystrokeFeedVtbl; */
    /* const ITfLangBarItemMgrVtbl *LangBarItemMgrVtbl; */
    ITfUIElementMgr ITfUIElementMgr_iface;
    ITfSourceSingle ITfSourceSingle_iface;
    LONG refCount;

    /* Aggregation */
    ITfCompartmentMgr  *CompartmentMgr;

    ITfThreadMgrEventSink ITfThreadMgrEventSink_iface; /* 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 {
    IEnumTfDocumentMgrs IEnumTfDocumentMgrs_iface;
    LONG refCount;

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

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

static inline ThreadMgr *impl_from_ITfThreadMgrEx(ITfThreadMgrEx *iface)
{
    return CONTAINING_RECORD(iface, ThreadMgr, ITfThreadMgrEx_iface);
}

static inline ThreadMgr *impl_from_ITfSource(ITfSource *iface)
{
    return CONTAINING_RECORD(iface, ThreadMgr, ITfSource_iface);
}

static inline ThreadMgr *impl_from_ITfKeystrokeMgr(ITfKeystrokeMgr *iface)
{
    return CONTAINING_RECORD(iface, ThreadMgr, ITfKeystrokeMgr_iface);
}

static inline ThreadMgr *impl_from_ITfMessagePump(ITfMessagePump *iface)
{
    return CONTAINING_RECORD(iface, ThreadMgr, ITfMessagePump_iface);
}

static inline ThreadMgr *impl_from_ITfClientId(ITfClientId *iface)
{
    return CONTAINING_RECORD(iface, ThreadMgr, ITfClientId_iface);
}

static inline ThreadMgr *impl_from_ITfThreadMgrEventSink(ITfThreadMgrEventSink *iface)
{
    return CONTAINING_RECORD(iface, ThreadMgr, ITfThreadMgrEventSink_iface);
}

static inline ThreadMgr *impl_from_ITfUIElementMgr(ITfUIElementMgr *iface)
{
    return CONTAINING_RECORD(iface, ThreadMgr, ITfUIElementMgr_iface);
}

static inline ThreadMgr *impl_from_ITfSourceSingle(ITfSourceSingle *iface)
{
    return CONTAINING_RECORD(iface, ThreadMgr, ITfSourceSingle_iface);
}

static inline EnumTfDocumentMgr *impl_from_IEnumTfDocumentMgrs(IEnumTfDocumentMgrs *iface)
{
    return CONTAINING_RECORD(iface, EnumTfDocumentMgr, IEnumTfDocumentMgrs_iface);
}

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(ITfThreadMgrEx *iface, REFIID iid, LPVOID *ppvOut)
{
    ThreadMgr *This = impl_from_ITfThreadMgrEx(iface);
    *ppvOut = NULL;

    if (IsEqualIID(iid, &IID_IUnknown) || IsEqualIID(iid, &IID_ITfThreadMgr)
        || IsEqualIID(iid, &IID_ITfThreadMgrEx))
    {
        *ppvOut = &This->ITfThreadMgrEx_iface;
    }
    else if (IsEqualIID(iid, &IID_ITfSource))
    {
        *ppvOut = &This->ITfSource_iface;
    }
    else if (IsEqualIID(iid, &IID_ITfKeystrokeMgr))
    {
        *ppvOut = &This->ITfKeystrokeMgr_iface;
    }
    else if (IsEqualIID(iid, &IID_ITfMessagePump))
    {
        *ppvOut = &This->ITfMessagePump_iface;
    }
    else if (IsEqualIID(iid, &IID_ITfClientId))
    {
        *ppvOut = &This->ITfClientId_iface;
    }
    else if (IsEqualIID(iid, &IID_ITfCompartmentMgr))
    {
        *ppvOut = This->CompartmentMgr;
    }
    else if (IsEqualIID(iid, &IID_ITfUIElementMgr))
    {
        *ppvOut = &This->ITfUIElementMgr_iface;
    }
    else if (IsEqualIID(iid, &IID_ITfSourceSingle))
    {
        *ppvOut = &This->ITfSourceSingle_iface;
    }

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

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

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

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

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

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

static HRESULT WINAPI ThreadMgr_Activate(ITfThreadMgrEx *iface, TfClientId *id)
{
    ThreadMgr *This = impl_from_ITfThreadMgrEx(iface);

    TRACE("(%p) %p\n", This, id);
    return ITfThreadMgrEx_ActivateEx(iface, id, 0);
}

static HRESULT WINAPI ThreadMgr_Deactivate(ITfThreadMgrEx *iface)
{
    ThreadMgr *This = impl_from_ITfThreadMgrEx(iface);
    TRACE("(%p)\n",This);

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

    This->activationCount --;

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

    deactivate_textservices();

    return S_OK;
}

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

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

    hr = DocumentMgr_Constructor(&This->ITfThreadMgrEventSink_iface, 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(ITfThreadMgrEx *iface, IEnumTfDocumentMgrs **ppEnum)
{
    ThreadMgr *This = impl_from_ITfThreadMgrEx(iface);
    TRACE("(%p) %p\n",This,ppEnum);

    if (!ppEnum)
        return E_INVALIDARG;

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

static HRESULT WINAPI ThreadMgr_GetFocus(ITfThreadMgrEx *iface, ITfDocumentMgr **ppdimFocus)
{
    ThreadMgr *This = impl_from_ITfThreadMgrEx(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(ITfThreadMgrEx *iface, ITfDocumentMgr *pdimFocus)
{
    ThreadMgr *This = impl_from_ITfThreadMgrEx(iface);
    ITfDocumentMgr *check;

    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(&This->ITfThreadMgrEventSink_iface, 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(&This->ITfThreadMgrEx_iface, 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(ITfThreadMgrEx *iface, HWND hwnd,
ITfDocumentMgr *pdimNew, ITfDocumentMgr **ppdimPrev)
{
    ThreadMgr *This = impl_from_ITfThreadMgrEx(iface);
    struct list *cursor, *cursor2;
    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(ITfThreadMgrEx *iface, BOOL *pfThreadFocus)
{
    ThreadMgr *This = impl_from_ITfThreadMgrEx(iface);
    HWND focus;

    TRACE("(%p) %p\n",This,pfThreadFocus);
    focus = GetFocus();
    *pfThreadFocus = (focus == NULL);
    return S_OK;
}

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

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

static HRESULT WINAPI ThreadMgr_GetGlobalCompartment(ITfThreadMgrEx *iface,
ITfCompartmentMgr **ppCompMgr)
{
    ThreadMgr *This = impl_from_ITfThreadMgrEx(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 HRESULT WINAPI ThreadMgr_ActivateEx(ITfThreadMgrEx *iface, TfClientId *id, DWORD flags)
{
    ThreadMgr *This = impl_from_ITfThreadMgrEx(iface);

    TRACE("(%p) %p, %#x\n", This, id, flags);

    if (!id)
        return E_INVALIDARG;

    if (flags)
        FIXME("Unimplemented flags %#x\n", flags);

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

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

static HRESULT WINAPI ThreadMgr_GetActiveFlags(ITfThreadMgrEx *iface, DWORD *flags)
{
    ThreadMgr *This = impl_from_ITfThreadMgrEx(iface);

    FIXME("STUB:(%p)\n", This);
    return E_NOTIMPL;
}

static const ITfThreadMgrExVtbl ThreadMgrExVtbl =
{
    ThreadMgr_QueryInterface,
    ThreadMgr_AddRef,
    ThreadMgr_Release,
    ThreadMgr_Activate,
    ThreadMgr_Deactivate,
    ThreadMgr_CreateDocumentMgr,
    ThreadMgr_EnumDocumentMgrs,
    ThreadMgr_GetFocus,
    ThreadMgr_SetFocus,
    ThreadMgr_AssociateFocus,
    ThreadMgr_IsThreadFocus,
    ThreadMgr_GetFunctionProvider,
    ThreadMgr_EnumFunctionProviders,
    ThreadMgr_GetGlobalCompartment,

    ThreadMgr_ActivateEx,
    ThreadMgr_GetActiveFlags
};

static HRESULT WINAPI Source_QueryInterface(ITfSource *iface, REFIID iid, LPVOID *ppvOut)
{
    ThreadMgr *This = impl_from_ITfSource(iface);
    return ITfThreadMgrEx_QueryInterface(&This->ITfThreadMgrEx_iface, iid, ppvOut);
}

static ULONG WINAPI Source_AddRef(ITfSource *iface)
{
    ThreadMgr *This = impl_from_ITfSource(iface);
    return ITfThreadMgrEx_AddRef(&This->ITfThreadMgrEx_iface);
}

static ULONG WINAPI Source_Release(ITfSource *iface)
{
    ThreadMgr *This = impl_from_ITfSource(iface);
    return ITfThreadMgrEx_Release(&This->ITfThreadMgrEx_iface);
}

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

    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)
{
    ThreadMgr *This = impl_from_ITfSource(iface);
    ThreadMgrSink *sink;

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

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

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

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

    return S_OK;
}

static const ITfSourceVtbl ThreadMgrSourceVtbl =
{
    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_ITfKeystrokeMgr(iface);
    return ITfThreadMgrEx_QueryInterface(&This->ITfThreadMgrEx_iface, iid, ppvOut);
}

static ULONG WINAPI KeystrokeMgr_AddRef(ITfKeystrokeMgr *iface)
{
    ThreadMgr *This = impl_from_ITfKeystrokeMgr(iface);
    return ITfThreadMgrEx_AddRef(&This->ITfThreadMgrEx_iface);
}

static ULONG WINAPI KeystrokeMgr_Release(ITfKeystrokeMgr *iface)
{
    ThreadMgr *This = impl_from_ITfKeystrokeMgr(iface);
    return ITfThreadMgrEx_Release(&This->ITfThreadMgrEx_iface);
}

static HRESULT WINAPI KeystrokeMgr_AdviseKeyEventSink(ITfKeystrokeMgr *iface,
        TfClientId tid, ITfKeyEventSink *pSink, BOOL fForeground)
{
    ThreadMgr *This = impl_from_ITfKeystrokeMgr(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_ITfKeystrokeMgr(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_ITfKeystrokeMgr(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_ITfKeystrokeMgr(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_ITfKeystrokeMgr(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_ITfKeystrokeMgr(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_ITfKeystrokeMgr(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_ITfKeystrokeMgr(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_ITfKeystrokeMgr(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_ITfKeystrokeMgr(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_ITfKeystrokeMgr(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_ITfKeystrokeMgr(iface);
    FIXME("STUB:(%p)\n",This);
    return E_NOTIMPL;
}

static HRESULT WINAPI KeystrokeMgr_GetPreservedKeyDescription(ITfKeystrokeMgr *iface,
        REFGUID rguid, BSTR *pbstrDesc)
{
    ThreadMgr *This = impl_from_ITfKeystrokeMgr(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_ITfKeystrokeMgr(iface);
    FIXME("STUB:(%p)\n",This);
    return E_NOTIMPL;
}

static const ITfKeystrokeMgrVtbl 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_ITfMessagePump(iface);
    return ITfThreadMgrEx_QueryInterface(&This->ITfThreadMgrEx_iface, iid, ppvOut);
}

static ULONG WINAPI MessagePump_AddRef(ITfMessagePump *iface)
{
    ThreadMgr *This = impl_from_ITfMessagePump(iface);
    return ITfThreadMgrEx_AddRef(&This->ITfThreadMgrEx_iface);
}

static ULONG WINAPI MessagePump_Release(ITfMessagePump *iface)
{
    ThreadMgr *This = impl_from_ITfMessagePump(iface);
    return ITfThreadMgrEx_Release(&This->ITfThreadMgrEx_iface);
}

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 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_ITfClientId(iface);
    return ITfThreadMgrEx_QueryInterface(&This->ITfThreadMgrEx_iface, iid, ppvOut);
}

static ULONG WINAPI ClientId_AddRef(ITfClientId *iface)
{
    ThreadMgr *This = impl_from_ITfClientId(iface);
    return ITfThreadMgrEx_AddRef(&This->ITfThreadMgrEx_iface);
}

static ULONG WINAPI ClientId_Release(ITfClientId *iface)
{
    ThreadMgr *This = impl_from_ITfClientId(iface);
    return ITfThreadMgrEx_Release(&This->ITfThreadMgrEx_iface);
}

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

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

    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 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 ITfThreadMgrEx_QueryInterface(&This->ITfThreadMgrEx_iface, iid, ppvOut);
}

static ULONG WINAPI ThreadMgrEventSink_AddRef(ITfThreadMgrEventSink *iface)
{
    ThreadMgr *This = impl_from_ITfThreadMgrEventSink(iface);
    return ITfThreadMgrEx_AddRef(&This->ITfThreadMgrEx_iface);
}

static ULONG WINAPI ThreadMgrEventSink_Release(ITfThreadMgrEventSink *iface)
{
    ThreadMgr *This = impl_from_ITfThreadMgrEventSink(iface);
    return ITfThreadMgrEx_Release(&This->ITfThreadMgrEx_iface);
}


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 ThreadMgrEventSinkVtbl =
{
    ThreadMgrEventSink_QueryInterface,
    ThreadMgrEventSink_AddRef,
    ThreadMgrEventSink_Release,
    ThreadMgrEventSink_OnInitDocumentMgr,
    ThreadMgrEventSink_OnUninitDocumentMgr,
    ThreadMgrEventSink_OnSetFocus,
    ThreadMgrEventSink_OnPushContext,
    ThreadMgrEventSink_OnPopContext
};

/*****************************************************
 * ITfUIElementMgr functions
 *****************************************************/
static HRESULT WINAPI UIElementMgr_QueryInterface(ITfUIElementMgr *iface, REFIID iid, void **ppvOut)
{
    ThreadMgr *This = impl_from_ITfUIElementMgr(iface);

    return ITfThreadMgrEx_QueryInterface(&This->ITfThreadMgrEx_iface, iid, *ppvOut);
}

static ULONG WINAPI UIElementMgr_AddRef(ITfUIElementMgr *iface)
{
    ThreadMgr *This = impl_from_ITfUIElementMgr(iface);

    return ITfThreadMgrEx_AddRef(&This->ITfThreadMgrEx_iface);
}

static ULONG WINAPI UIElementMgr_Release(ITfUIElementMgr *iface)
{
    ThreadMgr *This = impl_from_ITfUIElementMgr(iface);

    return ITfThreadMgrEx_Release(&This->ITfThreadMgrEx_iface);
}

static HRESULT WINAPI UIElementMgr_BeginUIElement(ITfUIElementMgr *iface, ITfUIElement *element,
                                                  BOOL *show, DWORD *id)
{
    ThreadMgr *This = impl_from_ITfUIElementMgr(iface);

    FIXME("STUB:(%p)\n", This);
    return E_NOTIMPL;
}

static HRESULT WINAPI UIElementMgr_UpdateUIElement(ITfUIElementMgr *iface, DWORD id)
{
    ThreadMgr *This = impl_from_ITfUIElementMgr(iface);

    FIXME("STUB:(%p)\n", This);
    return E_NOTIMPL;
}

static HRESULT WINAPI UIElementMgr_EndUIElement(ITfUIElementMgr *iface, DWORD id)
{
    ThreadMgr *This = impl_from_ITfUIElementMgr(iface);

    FIXME("STUB:(%p)\n", This);
    return E_NOTIMPL;
}

static HRESULT WINAPI UIElementMgr_GetUIElement(ITfUIElementMgr *iface, DWORD id,
                                                ITfUIElement **element)
{
    ThreadMgr *This = impl_from_ITfUIElementMgr(iface);

    FIXME("STUB:(%p)\n", This);
    return E_NOTIMPL;
}

static HRESULT WINAPI UIElementMgr_EnumUIElements(ITfUIElementMgr *iface,
                                                  IEnumTfUIElements **enum_elements)
{
    ThreadMgr *This = impl_from_ITfUIElementMgr(iface);

    FIXME("STUB:(%p)\n", This);
    return E_NOTIMPL;
}

static const ITfUIElementMgrVtbl ThreadMgrUIElementMgrVtbl =
{
    UIElementMgr_QueryInterface,
    UIElementMgr_AddRef,
    UIElementMgr_Release,

    UIElementMgr_BeginUIElement,
    UIElementMgr_UpdateUIElement,
    UIElementMgr_EndUIElement,
    UIElementMgr_GetUIElement,
    UIElementMgr_EnumUIElements
};

/*****************************************************
 * ITfSourceSingle functions
 *****************************************************/
static HRESULT WINAPI ThreadMgrSourceSingle_QueryInterface(ITfSourceSingle *iface, REFIID iid, LPVOID *ppvOut)
{
    ThreadMgr *This = impl_from_ITfSourceSingle(iface);
    return ITfThreadMgrEx_QueryInterface(&This->ITfThreadMgrEx_iface, iid, ppvOut);
}

static ULONG WINAPI ThreadMgrSourceSingle_AddRef(ITfSourceSingle *iface)
{
    ThreadMgr *This = impl_from_ITfSourceSingle(iface);
    return ITfThreadMgrEx_AddRef(&This->ITfThreadMgrEx_iface);
}

static ULONG WINAPI ThreadMgrSourceSingle_Release(ITfSourceSingle *iface)
{
    ThreadMgr *This = impl_from_ITfSourceSingle(iface);
    return ITfThreadMgrEx_Release(&This->ITfThreadMgrEx_iface);
}

static HRESULT WINAPI ThreadMgrSourceSingle_AdviseSingleSink( ITfSourceSingle *iface,
    TfClientId tid, REFIID riid, IUnknown *punk)
{
    ThreadMgr *This = impl_from_ITfSourceSingle(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_ITfSourceSingle(iface);
    FIXME("STUB:(%p) %i %s\n",This, tid, debugstr_guid(riid));
    return E_NOTIMPL;
}

static const ITfSourceSingleVtbl 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(&This->ITfThreadMgrEx_iface);
        *ppOut = (IUnknown*)&This->ITfThreadMgrEx_iface;
        return S_OK;
    }

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

    This->ITfThreadMgrEx_iface.lpVtbl = &ThreadMgrExVtbl;
    This->ITfSource_iface.lpVtbl = &ThreadMgrSourceVtbl;
    This->ITfKeystrokeMgr_iface.lpVtbl = &KeystrokeMgrVtbl;
    This->ITfMessagePump_iface.lpVtbl = &MessagePumpVtbl;
    This->ITfClientId_iface.lpVtbl = &ClientIdVtbl;
    This->ITfThreadMgrEventSink_iface.lpVtbl = &ThreadMgrEventSinkVtbl;
    This->ITfUIElementMgr_iface.lpVtbl = &ThreadMgrUIElementMgrVtbl;
    This->ITfSourceSingle_iface.lpVtbl = &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->ITfThreadMgrEx_iface;
    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 = impl_from_IEnumTfDocumentMgrs(iface);
    *ppvOut = NULL;

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

    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 = impl_from_IEnumTfDocumentMgrs(iface);
    return InterlockedIncrement(&This->refCount);
}

static ULONG WINAPI EnumTfDocumentMgr_Release(IEnumTfDocumentMgrs *iface)
{
    EnumTfDocumentMgr *This = impl_from_IEnumTfDocumentMgrs(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 = impl_from_IEnumTfDocumentMgrs(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)
{
    EnumTfDocumentMgr *This = impl_from_IEnumTfDocumentMgrs(iface);
    ULONG i;

    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 = impl_from_IEnumTfDocumentMgrs(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 = impl_from_IEnumTfDocumentMgrs(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 = impl_from_IEnumTfDocumentMgrs(*ppenum);
        new_This->index = This->index;
    }
    return res;
}

static const IEnumTfDocumentMgrsVtbl EnumTfDocumentMgrsVtbl =
{
    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->IEnumTfDocumentMgrs_iface.lpVtbl= &EnumTfDocumentMgrsVtbl;
    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 *iface, ITfDocumentMgr *mgr)
{
    ThreadMgr *This = impl_from_ITfThreadMgrEx((ITfThreadMgrEx *)iface);
    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);
}
