- Add msctf from Wine
authorDmitry Chapyshev <dmitry@reactos.org>
Thu, 26 Feb 2009 11:43:42 +0000 (11:43 +0000)
committerDmitry Chapyshev <dmitry@reactos.org>
Thu, 26 Feb 2009 11:43:42 +0000 (11:43 +0000)
svn path=/trunk/; revision=39769

17 files changed:
reactos/boot/bootdata/packages/reactos.dff
reactos/dll/win32/msctf/categorymgr.c [new file with mode: 0644]
reactos/dll/win32/msctf/context.c [new file with mode: 0644]
reactos/dll/win32/msctf/documentmgr.c [new file with mode: 0644]
reactos/dll/win32/msctf/inputprocessor.c [new file with mode: 0644]
reactos/dll/win32/msctf/msctf.c [new file with mode: 0644]
reactos/dll/win32/msctf/msctf.rbuild [new file with mode: 0644]
reactos/dll/win32/msctf/msctf.spec [new file with mode: 0644]
reactos/dll/win32/msctf/msctf_internal.h [new file with mode: 0644]
reactos/dll/win32/msctf/regsvr.c [new file with mode: 0644]
reactos/dll/win32/msctf/threadmgr.c [new file with mode: 0644]
reactos/dll/win32/win32.rbuild
reactos/include/psdk/msctf.idl [new file with mode: 0644]
reactos/include/psdk/psdk.rbuild
reactos/include/psdk/textstor.idl [new file with mode: 0644]
reactos/lib/sdk/uuid/uuid.c
reactos/media/doc/README.WINE

index 8984bd9..2faa17c 100644 (file)
@@ -302,6 +302,7 @@ dll\win32\msafd\msafd.dll                           1
 dll\win32\mscat32\mscat32.dll                       1
 dll\win32\mscms\mscms.dll                           1
 dll\win32\mscoree\mscoree.dll                       1
+dll\win32\msctf\msctf.dll                           1
 dll\win32\msftedit\msftedit.dll                     1
 dll\win32\msgina\msgina.dll                         1
 dll\win32\mshtml\mshtml.dll                         1
diff --git a/reactos/dll/win32/msctf/categorymgr.c b/reactos/dll/win32/msctf/categorymgr.c
new file mode 100644 (file)
index 0000000..2358072
--- /dev/null
@@ -0,0 +1,289 @@
+/*
+ *  ITfCategoryMgr implementation
+ *
+ *  Copyright 2009 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 "wine/unicode.h"
+
+#include "msctf.h"
+#include "msctf_internal.h"
+
+WINE_DEFAULT_DEBUG_CHANNEL(msctf);
+
+typedef struct tagCategoryMgr {
+    const ITfCategoryMgrVtbl *CategoryMgrVtbl;
+    LONG refCount;
+} CategoryMgr;
+
+static void CategoryMgr_Destructor(CategoryMgr *This)
+{
+    TRACE("destroying %p\n", This);
+    HeapFree(GetProcessHeap(),0,This);
+}
+
+static HRESULT WINAPI CategoryMgr_QueryInterface(ITfCategoryMgr *iface, REFIID iid, LPVOID *ppvOut)
+{
+    CategoryMgr *This = (CategoryMgr *)iface;
+    *ppvOut = NULL;
+
+    if (IsEqualIID(iid, &IID_IUnknown) || IsEqualIID(iid, &IID_ITfCategoryMgr))
+    {
+        *ppvOut = This;
+    }
+
+    if (*ppvOut)
+    {
+        IUnknown_AddRef(iface);
+        return S_OK;
+    }
+
+    WARN("unsupported interface: %s\n", debugstr_guid(iid));
+    return E_NOINTERFACE;
+}
+
+static ULONG WINAPI CategoryMgr_AddRef(ITfCategoryMgr *iface)
+{
+    CategoryMgr *This = (CategoryMgr *)iface;
+    return InterlockedIncrement(&This->refCount);
+}
+
+static ULONG WINAPI CategoryMgr_Release(ITfCategoryMgr *iface)
+{
+    CategoryMgr *This = (CategoryMgr *)iface;
+    ULONG ret;
+
+    ret = InterlockedDecrement(&This->refCount);
+    if (ret == 0)
+        CategoryMgr_Destructor(This);
+    return ret;
+}
+
+/*****************************************************
+ * ITfCategoryMgr functions
+ *****************************************************/
+
+static HRESULT WINAPI CategoryMgr_RegisterCategory ( ITfCategoryMgr *iface,
+        REFCLSID rclsid, REFGUID rcatid, REFGUID rguid)
+{
+    WCHAR fullkey[110];
+    WCHAR buf[39];
+    WCHAR buf2[39];
+    ULONG res;
+    HKEY tipkey,catkey,itmkey;
+    CategoryMgr *This = (CategoryMgr*)iface;
+
+    static const WCHAR ctg[] = {'C','a','t','e','g','o','r','y',0};
+    static const WCHAR itm[] = {'I','t','e','m',0};
+    static const WCHAR fmt[] = {'%','s','\\','%','s',0};
+    static const WCHAR fmt2[] = {'%','s','\\','%','s','\\','%','s','\\','%','s',0};
+
+    TRACE("(%p) %s %s %s\n",This,debugstr_guid(rclsid), debugstr_guid(rcatid), debugstr_guid(rguid));
+
+    StringFromGUID2(rclsid, buf, 39);
+    sprintfW(fullkey,fmt,szwSystemTIPKey,buf);
+
+    if (RegOpenKeyExW(HKEY_LOCAL_MACHINE,fullkey, 0, KEY_READ | KEY_WRITE,
+                &tipkey ) != ERROR_SUCCESS)
+        return E_FAIL;
+
+    StringFromGUID2(rcatid, buf, 39);
+    StringFromGUID2(rguid, buf2, 39);
+    sprintfW(fullkey,fmt2,ctg,ctg,buf,buf2);
+
+    res = RegCreateKeyExW(tipkey, fullkey, 0, NULL, 0, KEY_READ | KEY_WRITE,
+            NULL, &catkey, NULL);
+    RegCloseKey(catkey);
+
+    if (!res)
+    {
+        sprintfW(fullkey,fmt2,ctg,itm,buf2,buf);
+        res = RegCreateKeyExW(tipkey, fullkey, 0, NULL, 0, KEY_READ | KEY_WRITE,
+                NULL, &itmkey, NULL);
+
+        RegCloseKey(itmkey);
+    }
+
+    RegCloseKey(tipkey);
+
+    if (!res)
+        return S_OK;
+    else
+        return E_FAIL;
+}
+
+static HRESULT WINAPI CategoryMgr_UnregisterCategory ( ITfCategoryMgr *iface,
+        REFCLSID rclsid, REFGUID rcatid, REFGUID rguid)
+{
+    CategoryMgr *This = (CategoryMgr*)iface;
+    FIXME("STUB:(%p)\n",This);
+    return E_NOTIMPL;
+}
+
+static HRESULT WINAPI CategoryMgr_EnumCategoriesInItem ( ITfCategoryMgr *iface,
+        REFGUID rguid, IEnumGUID **ppEnum)
+{
+    CategoryMgr *This = (CategoryMgr*)iface;
+    FIXME("STUB:(%p)\n",This);
+    return E_NOTIMPL;
+}
+
+static HRESULT WINAPI CategoryMgr_EnumItemsInCategory ( ITfCategoryMgr *iface,
+        REFGUID rcatid, IEnumGUID **ppEnum)
+{
+    CategoryMgr *This = (CategoryMgr*)iface;
+    FIXME("STUB:(%p)\n",This);
+    return E_NOTIMPL;
+}
+
+static HRESULT WINAPI CategoryMgr_FindClosestCategory ( ITfCategoryMgr *iface,
+        REFGUID rguid, GUID *pcatid, const GUID **ppcatidList, ULONG ulCount)
+{
+    CategoryMgr *This = (CategoryMgr*)iface;
+    FIXME("STUB:(%p)\n",This);
+    return E_NOTIMPL;
+}
+
+static HRESULT WINAPI CategoryMgr_RegisterGUIDDescription (
+        ITfCategoryMgr *iface, REFCLSID rclsid, REFGUID rguid,
+        const WCHAR *pchDesc, ULONG cch)
+{
+    CategoryMgr *This = (CategoryMgr*)iface;
+    FIXME("STUB:(%p)\n",This);
+    return E_NOTIMPL;
+}
+
+static HRESULT WINAPI CategoryMgr_UnregisterGUIDDescription (
+        ITfCategoryMgr *iface, REFCLSID rclsid, REFGUID rguid)
+{
+    CategoryMgr *This = (CategoryMgr*)iface;
+    FIXME("STUB:(%p)\n",This);
+    return E_NOTIMPL;
+}
+
+static HRESULT WINAPI CategoryMgr_GetGUIDDescription ( ITfCategoryMgr *iface,
+        REFGUID rguid, BSTR *pbstrDesc)
+{
+    CategoryMgr *This = (CategoryMgr*)iface;
+    FIXME("STUB:(%p)\n",This);
+    return E_NOTIMPL;
+}
+
+static HRESULT WINAPI CategoryMgr_RegisterGUIDDWORD ( ITfCategoryMgr *iface,
+        REFCLSID rclsid, REFGUID rguid, DWORD dw)
+{
+    CategoryMgr *This = (CategoryMgr*)iface;
+    FIXME("STUB:(%p)\n",This);
+    return E_NOTIMPL;
+}
+
+static HRESULT WINAPI CategoryMgr_UnregisterGUIDDWORD ( ITfCategoryMgr *iface,
+        REFCLSID rclsid, REFGUID rguid)
+{
+    CategoryMgr *This = (CategoryMgr*)iface;
+    FIXME("STUB:(%p)\n",This);
+    return E_NOTIMPL;
+}
+
+static HRESULT WINAPI CategoryMgr_GetGUIDDWORD ( ITfCategoryMgr *iface,
+        REFGUID rguid, DWORD *pdw)
+{
+    CategoryMgr *This = (CategoryMgr*)iface;
+    FIXME("STUB:(%p)\n",This);
+    return E_NOTIMPL;
+}
+
+static HRESULT WINAPI CategoryMgr_RegisterGUID ( ITfCategoryMgr *iface,
+        REFGUID rguid, TfGuidAtom *pguidatom
+)
+{
+    CategoryMgr *This = (CategoryMgr*)iface;
+    FIXME("STUB:(%p)\n",This);
+    return E_NOTIMPL;
+}
+
+static HRESULT WINAPI CategoryMgr_GetGUID ( ITfCategoryMgr *iface,
+        TfGuidAtom guidatom, GUID *pguid)
+{
+    CategoryMgr *This = (CategoryMgr*)iface;
+    FIXME("STUB:(%p)\n",This);
+    return E_NOTIMPL;
+}
+
+static HRESULT WINAPI CategoryMgr_IsEqualTfGuidAtom ( ITfCategoryMgr *iface,
+        TfGuidAtom guidatom, REFGUID rguid, BOOL *pfEqual)
+{
+    CategoryMgr *This = (CategoryMgr*)iface;
+    FIXME("STUB:(%p)\n",This);
+    return E_NOTIMPL;
+}
+
+
+static const ITfCategoryMgrVtbl CategoryMgr_CategoryMgrVtbl =
+{
+    CategoryMgr_QueryInterface,
+    CategoryMgr_AddRef,
+    CategoryMgr_Release,
+
+    CategoryMgr_RegisterCategory,
+    CategoryMgr_UnregisterCategory,
+    CategoryMgr_EnumCategoriesInItem,
+    CategoryMgr_EnumItemsInCategory,
+    CategoryMgr_FindClosestCategory,
+    CategoryMgr_RegisterGUIDDescription,
+    CategoryMgr_UnregisterGUIDDescription,
+    CategoryMgr_GetGUIDDescription,
+    CategoryMgr_RegisterGUIDDWORD,
+    CategoryMgr_UnregisterGUIDDWORD,
+    CategoryMgr_GetGUIDDWORD,
+    CategoryMgr_RegisterGUID,
+    CategoryMgr_GetGUID,
+    CategoryMgr_IsEqualTfGuidAtom
+};
+
+HRESULT CategoryMgr_Constructor(IUnknown *pUnkOuter, IUnknown **ppOut)
+{
+    CategoryMgr *This;
+    if (pUnkOuter)
+        return CLASS_E_NOAGGREGATION;
+
+    This = HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,sizeof(CategoryMgr));
+    if (This == NULL)
+        return E_OUTOFMEMORY;
+
+    This->CategoryMgrVtbl= &CategoryMgr_CategoryMgrVtbl;
+    This->refCount = 1;
+
+    TRACE("returning %p\n", This);
+    *ppOut = (IUnknown *)This;
+    return S_OK;
+}
diff --git a/reactos/dll/win32/msctf/context.c b/reactos/dll/win32/msctf/context.c
new file mode 100644 (file)
index 0000000..2fc651f
--- /dev/null
@@ -0,0 +1,609 @@
+/*
+ *  ITfContext implementation
+ *
+ *  Copyright 2009 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 tagContextSink {
+    struct list         entry;
+    union {
+        /* Context Sinks */
+        IUnknown            *pIUnknown;
+        /* ITfContextKeyEventSink  *pITfContextKeyEventSink; */
+        /* ITfEditTransactionSink  *pITfEditTransactionSink; */
+        /* ITfStatusSink           *pITfStatusSink; */
+        ITfTextEditSink     *pITfTextEditSink;
+        /* ITfTextLayoutSink       *pITfTextLayoutSink; */
+    } interfaces;
+} ContextSink;
+
+typedef struct tagContext {
+    const ITfContextVtbl *ContextVtbl;
+    const ITfSourceVtbl *SourceVtbl;
+    LONG refCount;
+
+    TfClientId tidOwner;
+
+    ITextStoreACP   *pITextStoreACP;
+    ITfContextOwnerCompositionSink *pITfContextOwnerCompositionSink;
+
+    ITextStoreACPSink *pITextStoreACPSink;
+
+    /* kept as separate lists to reduce unnecessary iterations */
+    struct list     pContextKeyEventSink;
+    struct list     pEditTransactionSink;
+    struct list     pStatusSink;
+    struct list     pTextEditSink;
+    struct list     pTextLayoutSink;
+
+} Context;
+
+
+typedef struct tagTextStoreACPSink {
+    const ITextStoreACPSinkVtbl *TextStoreACPSinkVtbl;
+    LONG refCount;
+
+    Context *pContext;
+} TextStoreACPSink;
+
+
+static HRESULT TextStoreACPSink_Constructor(ITextStoreACPSink **ppOut, Context *pContext);
+
+static inline Context *impl_from_ITfSourceVtbl(ITfSource *iface)
+{
+    return (Context *)((char *)iface - FIELD_OFFSET(Context,SourceVtbl));
+}
+
+static void free_sink(ContextSink *sink)
+{
+        IUnknown_Release(sink->interfaces.pIUnknown);
+        HeapFree(GetProcessHeap(),0,sink);
+}
+
+static void Context_Destructor(Context *This)
+{
+    struct list *cursor, *cursor2;
+    TRACE("destroying %p\n", This);
+
+    if (This->pITextStoreACPSink)
+    {
+        ITextStoreACP_UnadviseSink(This->pITextStoreACP, (IUnknown*)This->pITextStoreACPSink);
+        ITextStoreACPSink_Release(This->pITextStoreACPSink);
+    }
+
+    if (This->pITextStoreACP)
+        ITextStoreACPSink_Release(This->pITextStoreACP);
+
+    if (This->pITfContextOwnerCompositionSink)
+        ITextStoreACPSink_Release(This->pITfContextOwnerCompositionSink);
+
+    LIST_FOR_EACH_SAFE(cursor, cursor2, &This->pContextKeyEventSink)
+    {
+        ContextSink* sink = LIST_ENTRY(cursor,ContextSink,entry);
+        list_remove(cursor);
+        free_sink(sink);
+    }
+    LIST_FOR_EACH_SAFE(cursor, cursor2, &This->pEditTransactionSink)
+    {
+        ContextSink* sink = LIST_ENTRY(cursor,ContextSink,entry);
+        list_remove(cursor);
+        free_sink(sink);
+    }
+    LIST_FOR_EACH_SAFE(cursor, cursor2, &This->pStatusSink)
+    {
+        ContextSink* sink = LIST_ENTRY(cursor,ContextSink,entry);
+        list_remove(cursor);
+        free_sink(sink);
+    }
+    LIST_FOR_EACH_SAFE(cursor, cursor2, &This->pTextEditSink)
+    {
+        ContextSink* sink = LIST_ENTRY(cursor,ContextSink,entry);
+        list_remove(cursor);
+        free_sink(sink);
+    }
+    LIST_FOR_EACH_SAFE(cursor, cursor2, &This->pTextLayoutSink)
+    {
+        ContextSink* sink = LIST_ENTRY(cursor,ContextSink,entry);
+        list_remove(cursor);
+        free_sink(sink);
+    }
+
+    HeapFree(GetProcessHeap(),0,This);
+}
+
+static HRESULT WINAPI Context_QueryInterface(ITfContext *iface, REFIID iid, LPVOID *ppvOut)
+{
+    Context *This = (Context *)iface;
+    *ppvOut = NULL;
+
+    if (IsEqualIID(iid, &IID_IUnknown) || IsEqualIID(iid, &IID_ITfContext))
+    {
+        *ppvOut = This;
+    }
+    else if (IsEqualIID(iid, &IID_ITfSource))
+    {
+        *ppvOut = &This->SourceVtbl;
+    }
+
+    if (*ppvOut)
+    {
+        IUnknown_AddRef(iface);
+        return S_OK;
+    }
+
+    WARN("unsupported interface: %s\n", debugstr_guid(iid));
+    return E_NOINTERFACE;
+}
+
+static ULONG WINAPI Context_AddRef(ITfContext *iface)
+{
+    Context *This = (Context *)iface;
+    return InterlockedIncrement(&This->refCount);
+}
+
+static ULONG WINAPI Context_Release(ITfContext *iface)
+{
+    Context *This = (Context *)iface;
+    ULONG ret;
+
+    ret = InterlockedDecrement(&This->refCount);
+    if (ret == 0)
+        Context_Destructor(This);
+    return ret;
+}
+
+/*****************************************************
+ * ITfContext functions
+ *****************************************************/
+static HRESULT WINAPI Context_RequestEditSession (ITfContext *iface,
+        TfClientId tid, ITfEditSession *pes, DWORD dwFlags,
+        HRESULT *phrSession)
+{
+    Context *This = (Context *)iface;
+    FIXME("STUB:(%p)\n",This);
+    return E_NOTIMPL;
+}
+
+static HRESULT WINAPI Context_InWriteSession (ITfContext *iface,
+         TfClientId tid,
+         BOOL *pfWriteSession)
+{
+    Context *This = (Context *)iface;
+    FIXME("STUB:(%p)\n",This);
+    return E_NOTIMPL;
+}
+
+static HRESULT WINAPI Context_GetSelection (ITfContext *iface,
+        TfEditCookie ec, ULONG ulIndex, ULONG ulCount,
+        TF_SELECTION *pSelection, ULONG *pcFetched)
+{
+    Context *This = (Context *)iface;
+    FIXME("STUB:(%p)\n",This);
+    return E_NOTIMPL;
+}
+
+static HRESULT WINAPI Context_SetSelection (ITfContext *iface,
+        TfEditCookie ec, ULONG ulCount, const TF_SELECTION *pSelection)
+{
+    Context *This = (Context *)iface;
+    FIXME("STUB:(%p)\n",This);
+    return E_NOTIMPL;
+}
+
+static HRESULT WINAPI Context_GetStart (ITfContext *iface,
+        TfEditCookie ec, ITfRange **ppStart)
+{
+    Context *This = (Context *)iface;
+    FIXME("STUB:(%p)\n",This);
+    return E_NOTIMPL;
+}
+
+static HRESULT WINAPI Context_GetEnd (ITfContext *iface,
+        TfEditCookie ec, ITfRange **ppEnd)
+{
+    Context *This = (Context *)iface;
+    FIXME("STUB:(%p)\n",This);
+    return E_NOTIMPL;
+}
+
+static HRESULT WINAPI Context_GetActiveView (ITfContext *iface,
+  ITfContextView **ppView)
+{
+    Context *This = (Context *)iface;
+    FIXME("STUB:(%p)\n",This);
+    return E_NOTIMPL;
+}
+
+static HRESULT WINAPI Context_EnumViews (ITfContext *iface,
+        IEnumTfContextViews **ppEnum)
+{
+    Context *This = (Context *)iface;
+    FIXME("STUB:(%p)\n",This);
+    return E_NOTIMPL;
+}
+
+static HRESULT WINAPI Context_GetStatus (ITfContext *iface,
+        TF_STATUS *pdcs)
+{
+    Context *This = (Context *)iface;
+    FIXME("STUB:(%p)\n",This);
+    return E_NOTIMPL;
+}
+
+static HRESULT WINAPI Context_GetProperty (ITfContext *iface,
+        REFGUID guidProp, ITfProperty **ppProp)
+{
+    Context *This = (Context *)iface;
+    FIXME("STUB:(%p)\n",This);
+    return E_NOTIMPL;
+}
+
+static HRESULT WINAPI Context_GetAppProperty (ITfContext *iface,
+        REFGUID guidProp, ITfReadOnlyProperty **ppProp)
+{
+    Context *This = (Context *)iface;
+    FIXME("STUB:(%p)\n",This);
+    return E_NOTIMPL;
+}
+
+static HRESULT WINAPI Context_TrackProperties (ITfContext *iface,
+        const GUID **prgProp, ULONG cProp, const GUID **prgAppProp,
+        ULONG cAppProp, ITfReadOnlyProperty **ppProperty)
+{
+    Context *This = (Context *)iface;
+    FIXME("STUB:(%p)\n",This);
+    return E_NOTIMPL;
+}
+
+static HRESULT WINAPI Context_EnumProperties (ITfContext *iface,
+        IEnumTfProperties **ppEnum)
+{
+    Context *This = (Context *)iface;
+    FIXME("STUB:(%p)\n",This);
+    return E_NOTIMPL;
+}
+
+static HRESULT WINAPI Context_GetDocumentMgr (ITfContext *iface,
+        ITfDocumentMgr **ppDm)
+{
+    Context *This = (Context *)iface;
+    FIXME("STUB:(%p)\n",This);
+    return E_NOTIMPL;
+}
+
+static HRESULT WINAPI Context_CreateRangeBackup (ITfContext *iface,
+        TfEditCookie ec, ITfRange *pRange, ITfRangeBackup **ppBackup)
+{
+    Context *This = (Context *)iface;
+    FIXME("STUB:(%p)\n",This);
+    return E_NOTIMPL;
+}
+
+static const ITfContextVtbl Context_ContextVtbl =
+{
+    Context_QueryInterface,
+    Context_AddRef,
+    Context_Release,
+
+    Context_RequestEditSession,
+    Context_InWriteSession,
+    Context_GetSelection,
+    Context_SetSelection,
+    Context_GetStart,
+    Context_GetEnd,
+    Context_GetActiveView,
+    Context_EnumViews,
+    Context_GetStatus,
+    Context_GetProperty,
+    Context_GetAppProperty,
+    Context_TrackProperties,
+    Context_EnumProperties,
+    Context_GetDocumentMgr,
+    Context_CreateRangeBackup
+};
+
+static HRESULT WINAPI Source_QueryInterface(ITfSource *iface, REFIID iid, LPVOID *ppvOut)
+{
+    Context *This = impl_from_ITfSourceVtbl(iface);
+    return Context_QueryInterface((ITfContext *)This, iid, *ppvOut);
+}
+
+static ULONG WINAPI Source_AddRef(ITfSource *iface)
+{
+    Context *This = impl_from_ITfSourceVtbl(iface);
+    return Context_AddRef((ITfContext *)This);
+}
+
+static ULONG WINAPI Source_Release(ITfSource *iface)
+{
+    Context *This = impl_from_ITfSourceVtbl(iface);
+    return Context_Release((ITfContext *)This);
+}
+
+/*****************************************************
+ * ITfSource functions
+ *****************************************************/
+static WINAPI HRESULT ContextSource_AdviseSink(ITfSource *iface,
+        REFIID riid, IUnknown *punk, DWORD *pdwCookie)
+{
+    ContextSink *es;
+    Context *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_ITfTextEditSink))
+    {
+        es = HeapAlloc(GetProcessHeap(),0,sizeof(ContextSink));
+        if (!es)
+            return E_OUTOFMEMORY;
+        if (!SUCCEEDED(IUnknown_QueryInterface(punk, riid, (LPVOID*)&es->interfaces.pITfTextEditSink)))
+        {
+            HeapFree(GetProcessHeap(),0,es);
+            return CONNECT_E_CANNOTCONNECT;
+        }
+        list_add_head(&This->pTextEditSink ,&es->entry);
+        *pdwCookie = (DWORD)es;
+    }
+    else
+    {
+        FIXME("(%p) Unhandled Sink: %s\n",This,debugstr_guid(riid));
+        return E_NOTIMPL;
+    }
+
+    TRACE("cookie %x\n",*pdwCookie);
+    return S_OK;
+}
+
+static WINAPI HRESULT ContextSource_UnadviseSink(ITfSource *iface, DWORD pdwCookie)
+{
+    ContextSink *sink = (ContextSink*)pdwCookie;
+    Context *This = impl_from_ITfSourceVtbl(iface);
+    TRACE("(%p) %x\n",This,pdwCookie);
+
+    list_remove(&sink->entry);
+    free_sink(sink);
+
+    return S_OK;
+}
+
+static const ITfSourceVtbl Context_SourceVtbl =
+{
+    Source_QueryInterface,
+    Source_AddRef,
+    Source_Release,
+
+    ContextSource_AdviseSink,
+    ContextSource_UnadviseSink,
+};
+
+HRESULT Context_Constructor(TfClientId tidOwner, IUnknown *punk, ITfContext **ppOut, TfEditCookie *pecTextStore)
+{
+    Context *This;
+
+    This = HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,sizeof(Context));
+    if (This == NULL)
+        return E_OUTOFMEMORY;
+
+    TRACE("(%p) %x %p %p %p\n",This, tidOwner, punk, ppOut, pecTextStore);
+
+    This->ContextVtbl= &Context_ContextVtbl;
+    This->SourceVtbl = &Context_SourceVtbl;
+    This->refCount = 1;
+    This->tidOwner = tidOwner;
+
+    if (punk)
+    {
+        if (SUCCEEDED(IUnknown_QueryInterface(punk, &IID_ITextStoreACP,
+                          (LPVOID*)&This->pITextStoreACP)))
+        {
+            if (SUCCEEDED(TextStoreACPSink_Constructor(&This->pITextStoreACPSink, This)))
+                ITextStoreACP_AdviseSink(This->pITextStoreACP, &IID_ITextStoreACPSink,
+                                        (IUnknown*)This->pITextStoreACPSink, TS_AS_ALL_SINKS);
+        }
+
+        IUnknown_QueryInterface(punk, &IID_ITfContextOwnerCompositionSink,
+                                (LPVOID*)&This->pITfContextOwnerCompositionSink);
+
+        if (!This->pITextStoreACP && !This->pITfContextOwnerCompositionSink)
+            FIXME("Unhandled pUnk\n");
+    }
+
+    TRACE("returning %p\n", This);
+    *ppOut = (ITfContext*)This;
+    /* FIXME */
+    *pecTextStore = 0xdeaddead;
+
+    list_init(&This->pContextKeyEventSink);
+    list_init(&This->pEditTransactionSink);
+    list_init(&This->pStatusSink);
+    list_init(&This->pTextEditSink);
+    list_init(&This->pTextLayoutSink);
+
+    return S_OK;
+}
+
+/**************************************************************************
+ *  ITextStoreACPSink
+ **************************************************************************/
+
+static void TextStoreACPSink_Destructor(TextStoreACPSink *This)
+{
+    TRACE("destroying %p\n", This);
+    HeapFree(GetProcessHeap(),0,This);
+}
+
+static HRESULT WINAPI TextStoreACPSink_QueryInterface(ITextStoreACPSink *iface, REFIID iid, LPVOID *ppvOut)
+{
+    TextStoreACPSink *This = (TextStoreACPSink *)iface;
+    *ppvOut = NULL;
+
+    if (IsEqualIID(iid, &IID_IUnknown) || IsEqualIID(iid, &IID_ITextStoreACPSink))
+    {
+        *ppvOut = This;
+    }
+
+    if (*ppvOut)
+    {
+        IUnknown_AddRef(iface);
+        return S_OK;
+    }
+
+    WARN("unsupported interface: %s\n", debugstr_guid(iid));
+    return E_NOINTERFACE;
+}
+
+static ULONG WINAPI TextStoreACPSink_AddRef(ITextStoreACPSink *iface)
+{
+    TextStoreACPSink *This = (TextStoreACPSink *)iface;
+    return InterlockedIncrement(&This->refCount);
+}
+
+static ULONG WINAPI TextStoreACPSink_Release(ITextStoreACPSink *iface)
+{
+    TextStoreACPSink *This = (TextStoreACPSink *)iface;
+    ULONG ret;
+
+    ret = InterlockedDecrement(&This->refCount);
+    if (ret == 0)
+        TextStoreACPSink_Destructor(This);
+    return ret;
+}
+
+/*****************************************************
+ * ITextStoreACPSink functions
+ *****************************************************/
+
+static HRESULT WINAPI TextStoreACPSink_OnTextChange(ITextStoreACPSink *iface,
+        DWORD dwFlags, const TS_TEXTCHANGE *pChange)
+{
+    TextStoreACPSink *This = (TextStoreACPSink *)iface;
+    FIXME("STUB:(%p)\n",This);
+    return E_NOTIMPL;
+}
+
+static HRESULT WINAPI TextStoreACPSink_OnSelectionChange(ITextStoreACPSink *iface)
+{
+    TextStoreACPSink *This = (TextStoreACPSink *)iface;
+    FIXME("STUB:(%p)\n",This);
+    return E_NOTIMPL;
+}
+
+static HRESULT WINAPI TextStoreACPSink_OnLayoutChange(ITextStoreACPSink *iface,
+    TsLayoutCode lcode, TsViewCookie vcView)
+{
+    TextStoreACPSink *This = (TextStoreACPSink *)iface;
+    FIXME("STUB:(%p)\n",This);
+    return E_NOTIMPL;
+}
+
+static HRESULT WINAPI TextStoreACPSink_OnStatusChange(ITextStoreACPSink *iface,
+        DWORD dwFlags)
+{
+    TextStoreACPSink *This = (TextStoreACPSink *)iface;
+    FIXME("STUB:(%p)\n",This);
+    return E_NOTIMPL;
+}
+
+static HRESULT WINAPI TextStoreACPSink_OnAttrsChange(ITextStoreACPSink *iface,
+        LONG acpStart, LONG acpEnd, ULONG cAttrs, const TS_ATTRID *paAttrs)
+{
+    TextStoreACPSink *This = (TextStoreACPSink *)iface;
+    FIXME("STUB:(%p)\n",This);
+    return E_NOTIMPL;
+}
+
+static HRESULT WINAPI TextStoreACPSink_OnLockGranted(ITextStoreACPSink *iface,
+        DWORD dwLockFlags)
+{
+    TextStoreACPSink *This = (TextStoreACPSink *)iface;
+    FIXME("STUB:(%p)\n",This);
+    return E_NOTIMPL;
+}
+
+static HRESULT WINAPI TextStoreACPSink_OnStartEditTransaction(ITextStoreACPSink *iface)
+{
+    TextStoreACPSink *This = (TextStoreACPSink *)iface;
+    FIXME("STUB:(%p)\n",This);
+    return E_NOTIMPL;
+}
+
+static HRESULT WINAPI TextStoreACPSink_OnEndEditTransaction(ITextStoreACPSink *iface)
+{
+    TextStoreACPSink *This = (TextStoreACPSink *)iface;
+    FIXME("STUB:(%p)\n",This);
+    return E_NOTIMPL;
+}
+
+static const ITextStoreACPSinkVtbl TextStoreACPSink_TextStoreACPSinkVtbl =
+{
+    TextStoreACPSink_QueryInterface,
+    TextStoreACPSink_AddRef,
+    TextStoreACPSink_Release,
+
+    TextStoreACPSink_OnTextChange,
+    TextStoreACPSink_OnSelectionChange,
+    TextStoreACPSink_OnLayoutChange,
+    TextStoreACPSink_OnStatusChange,
+    TextStoreACPSink_OnAttrsChange,
+    TextStoreACPSink_OnLockGranted,
+    TextStoreACPSink_OnStartEditTransaction,
+    TextStoreACPSink_OnEndEditTransaction
+};
+
+static HRESULT TextStoreACPSink_Constructor(ITextStoreACPSink **ppOut, Context *pContext)
+{
+    TextStoreACPSink *This;
+
+    This = HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,sizeof(TextStoreACPSink));
+    if (This == NULL)
+        return E_OUTOFMEMORY;
+
+    This->TextStoreACPSinkVtbl= &TextStoreACPSink_TextStoreACPSinkVtbl;
+    This->refCount = 1;
+
+    This->pContext = pContext;
+
+    TRACE("returning %p\n", This);
+    *ppOut = (ITextStoreACPSink*)This;
+    return S_OK;
+}
diff --git a/reactos/dll/win32/msctf/documentmgr.c b/reactos/dll/win32/msctf/documentmgr.c
new file mode 100644 (file)
index 0000000..c875145
--- /dev/null
@@ -0,0 +1,280 @@
+/*
+ *  ITfDocumentMgr implementation
+ *
+ *  Copyright 2009 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 "wine/unicode.h"
+
+#include "msctf.h"
+#include "msctf_internal.h"
+
+WINE_DEFAULT_DEBUG_CHANNEL(msctf);
+
+typedef struct tagDocumentMgr {
+    const ITfDocumentMgrVtbl *DocumentMgrVtbl;
+    const ITfSourceVtbl *SourceVtbl;
+    LONG refCount;
+
+    ITfContext*  contextStack[2]; /* limit of 2 contexts */
+} DocumentMgr;
+
+static inline DocumentMgr *impl_from_ITfSourceVtbl(ITfSource *iface)
+{
+    return (DocumentMgr *)((char *)iface - FIELD_OFFSET(DocumentMgr,SourceVtbl));
+}
+
+static void DocumentMgr_Destructor(DocumentMgr *This)
+{
+    TRACE("destroying %p\n", This);
+    if (This->contextStack[0])
+        ITfContext_Release(This->contextStack[0]);
+    if (This->contextStack[1])
+        ITfContext_Release(This->contextStack[1]);
+    HeapFree(GetProcessHeap(),0,This);
+}
+
+static HRESULT WINAPI DocumentMgr_QueryInterface(ITfDocumentMgr *iface, REFIID iid, LPVOID *ppvOut)
+{
+    DocumentMgr *This = (DocumentMgr *)iface;
+    *ppvOut = NULL;
+
+    if (IsEqualIID(iid, &IID_IUnknown) || IsEqualIID(iid, &IID_ITfDocumentMgr))
+    {
+        *ppvOut = This;
+    }
+    else if (IsEqualIID(iid, &IID_ITfSource))
+    {
+        *ppvOut = &This->SourceVtbl;
+    }
+
+    if (*ppvOut)
+    {
+        IUnknown_AddRef(iface);
+        return S_OK;
+    }
+
+    WARN("unsupported interface: %s\n", debugstr_guid(iid));
+    return E_NOINTERFACE;
+}
+
+static ULONG WINAPI DocumentMgr_AddRef(ITfDocumentMgr *iface)
+{
+    DocumentMgr *This = (DocumentMgr *)iface;
+    return InterlockedIncrement(&This->refCount);
+}
+
+static ULONG WINAPI DocumentMgr_Release(ITfDocumentMgr *iface)
+{
+    DocumentMgr *This = (DocumentMgr *)iface;
+    ULONG ret;
+
+    ret = InterlockedDecrement(&This->refCount);
+    if (ret == 0)
+        DocumentMgr_Destructor(This);
+    return ret;
+}
+
+/*****************************************************
+ * ITfDocumentMgr functions
+ *****************************************************/
+static HRESULT WINAPI DocumentMgr_CreateContext(ITfDocumentMgr *iface,
+        TfClientId tidOwner,
+        DWORD dwFlags, IUnknown *punk, ITfContext **ppic,
+        TfEditCookie *pecTextStore)
+{
+    DocumentMgr *This = (DocumentMgr *)iface;
+    TRACE("(%p) 0x%x 0x%x %p %p %p\n",This,tidOwner,dwFlags,punk,ppic,pecTextStore);
+    return Context_Constructor(tidOwner, punk, ppic, pecTextStore);
+}
+
+static HRESULT WINAPI DocumentMgr_Push(ITfDocumentMgr *iface, ITfContext *pic)
+{
+    DocumentMgr *This = (DocumentMgr *)iface;
+    ITfContext *check;
+
+    TRACE("(%p) %p\n",This,pic);
+
+    if (This->contextStack[1])  /* FUll */
+        return TF_E_STACKFULL;
+
+    if (!pic || FAILED(IUnknown_QueryInterface(pic,&IID_ITfContext,(LPVOID*) &check)))
+        return E_INVALIDARG;
+
+    This->contextStack[1] = This->contextStack[0];
+    This->contextStack[0] = check;
+
+    return S_OK;
+}
+
+static HRESULT WINAPI DocumentMgr_Pop(ITfDocumentMgr *iface, DWORD dwFlags)
+{
+    DocumentMgr *This = (DocumentMgr *)iface;
+    TRACE("(%p) 0x%x\n",This,dwFlags);
+
+    if (dwFlags == TF_POPF_ALL)
+    {
+        if (This->contextStack[0])
+            ITfContext_Release(This->contextStack[0]);
+        if (This->contextStack[1])
+            ITfContext_Release(This->contextStack[1]);
+        This->contextStack[0] = This->contextStack[1] = NULL;
+        return S_OK;
+    }
+
+    if (dwFlags)
+        return E_INVALIDARG;
+
+    if (This->contextStack[0] == NULL) /* Cannot pop last context */
+        return E_FAIL;
+
+    ITfContext_Release(This->contextStack[0]);
+    This->contextStack[0] = This->contextStack[1];
+    This->contextStack[1] = NULL;
+
+    return S_OK;
+}
+
+static HRESULT WINAPI DocumentMgr_GetTop(ITfDocumentMgr *iface, ITfContext **ppic)
+{
+    DocumentMgr *This = (DocumentMgr *)iface;
+    TRACE("(%p)\n",This);
+    if (!ppic)
+        return E_INVALIDARG;
+
+    if (This->contextStack[0])
+        ITfContext_AddRef(This->contextStack[0]);
+
+    *ppic = This->contextStack[0];
+
+    return S_OK;
+}
+
+static HRESULT WINAPI DocumentMgr_GetBase(ITfDocumentMgr *iface, ITfContext **ppic)
+{
+    DocumentMgr *This = (DocumentMgr *)iface;
+    TRACE("(%p)\n",This);
+    if (!ppic)
+        return E_INVALIDARG;
+
+    if (This->contextStack[1])
+        ITfContext_AddRef(This->contextStack[1]);
+
+    *ppic = This->contextStack[1];
+
+    return S_OK;
+}
+
+static HRESULT WINAPI DocumentMgr_EnumContexts(ITfDocumentMgr *iface, IEnumTfContexts **ppEnum)
+{
+    DocumentMgr *This = (DocumentMgr *)iface;
+    FIXME("STUB:(%p)\n",This);
+    return E_NOTIMPL;
+}
+
+static const ITfDocumentMgrVtbl DocumentMgr_DocumentMgrVtbl =
+{
+    DocumentMgr_QueryInterface,
+    DocumentMgr_AddRef,
+    DocumentMgr_Release,
+
+    DocumentMgr_CreateContext,
+    DocumentMgr_Push,
+    DocumentMgr_Pop,
+    DocumentMgr_GetTop,
+    DocumentMgr_GetBase,
+    DocumentMgr_EnumContexts
+};
+
+
+static HRESULT WINAPI Source_QueryInterface(ITfSource *iface, REFIID iid, LPVOID *ppvOut)
+{
+    DocumentMgr *This = impl_from_ITfSourceVtbl(iface);
+    return DocumentMgr_QueryInterface((ITfDocumentMgr*)This, iid, *ppvOut);
+}
+
+static ULONG WINAPI Source_AddRef(ITfSource *iface)
+{
+    DocumentMgr *This = impl_from_ITfSourceVtbl(iface);
+    return DocumentMgr_AddRef((ITfDocumentMgr*)This);
+}
+
+static ULONG WINAPI Source_Release(ITfSource *iface)
+{
+    DocumentMgr *This = impl_from_ITfSourceVtbl(iface);
+    return DocumentMgr_Release((ITfDocumentMgr*)This);
+}
+
+/*****************************************************
+ * ITfSource functions
+ *****************************************************/
+static WINAPI HRESULT DocumentMgrSource_AdviseSink(ITfSource *iface,
+        REFIID riid, IUnknown *punk, DWORD *pdwCookie)
+{
+    DocumentMgr *This = impl_from_ITfSourceVtbl(iface);
+    FIXME("STUB:(%p)\n",This);
+    return E_NOTIMPL;
+}
+
+static WINAPI HRESULT DocumentMgrSource_UnadviseSink(ITfSource *iface, DWORD pdwCookie)
+{
+    DocumentMgr *This = impl_from_ITfSourceVtbl(iface);
+    FIXME("STUB:(%p)\n",This);
+    return E_NOTIMPL;
+}
+
+static const ITfSourceVtbl DocumentMgr_SourceVtbl =
+{
+    Source_QueryInterface,
+    Source_AddRef,
+    Source_Release,
+
+    DocumentMgrSource_AdviseSink,
+    DocumentMgrSource_UnadviseSink,
+};
+
+HRESULT DocumentMgr_Constructor(ITfDocumentMgr **ppOut)
+{
+    DocumentMgr *This;
+
+    This = HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,sizeof(DocumentMgr));
+    if (This == NULL)
+        return E_OUTOFMEMORY;
+
+    This->DocumentMgrVtbl= &DocumentMgr_DocumentMgrVtbl;
+    This->SourceVtbl = &DocumentMgr_SourceVtbl;
+    This->refCount = 1;
+
+    TRACE("returning %p\n", This);
+    *ppOut = (ITfDocumentMgr*)This;
+    return S_OK;
+}
diff --git a/reactos/dll/win32/msctf/inputprocessor.c b/reactos/dll/win32/msctf/inputprocessor.c
new file mode 100644 (file)
index 0000000..de39af9
--- /dev/null
@@ -0,0 +1,885 @@
+/*
+ *  ITfInputProcessorProfiles implementation
+ *
+ *  Copyright 2009 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 "wine/unicode.h"
+
+#include "msctf.h"
+#include "msctf_internal.h"
+
+WINE_DEFAULT_DEBUG_CHANNEL(msctf);
+
+static const WCHAR szwLngp[] = {'L','a','n','g','u','a','g','e','P','r','o','f','i','l','e',0};
+static const WCHAR szwEnabled[] = {'E','n','a','b','l','e','d',0};
+static const WCHAR szwTipfmt[] = {'%','s','\\','%','s',0};
+static const WCHAR szwFullLangfmt[] = {'%','s','\\','%','s','\\','%','s','\\','0','x','%','0','8','x','\\','%','s',0};
+
+typedef struct tagInputProcessorProfiles {
+    const ITfInputProcessorProfilesVtbl *InputProcessorProfilesVtbl;
+    LONG refCount;
+
+    LANGID  currentLanguage;
+} InputProcessorProfiles;
+
+typedef struct tagProfilesEnumGuid {
+    const IEnumGUIDVtbl *Vtbl;
+    LONG refCount;
+
+    HKEY key;
+    DWORD next_index;
+} ProfilesEnumGuid;
+
+typedef struct tagEnumTfLanguageProfiles {
+    const IEnumTfLanguageProfilesVtbl *Vtbl;
+    LONG refCount;
+
+    HKEY    tipkey;
+    DWORD   tip_index;
+    WCHAR   szwCurrentClsid[39];
+
+    HKEY    langkey;
+    DWORD   lang_index;
+
+    LANGID  langid;
+} EnumTfLanguageProfiles;
+
+static HRESULT ProfilesEnumGuid_Constructor(IEnumGUID **ppOut);
+static HRESULT EnumTfLanguageProfiles_Constructor(LANGID langid, IEnumTfLanguageProfiles **ppOut);
+
+static void InputProcessorProfiles_Destructor(InputProcessorProfiles *This)
+{
+    TRACE("destroying %p\n", This);
+    HeapFree(GetProcessHeap(),0,This);
+}
+
+static void add_userkey( REFCLSID rclsid, LANGID langid,
+                                REFGUID guidProfile)
+{
+    HKEY key;
+    WCHAR buf[39];
+    WCHAR buf2[39];
+    WCHAR fullkey[168];
+    DWORD disposition = 0;
+    ULONG res;
+
+    TRACE("\n");
+
+    StringFromGUID2(rclsid, buf, 39);
+    StringFromGUID2(guidProfile, buf2, 39);
+    sprintfW(fullkey,szwFullLangfmt,szwSystemTIPKey,buf,szwLngp,langid,buf2);
+
+    res = RegCreateKeyExW(HKEY_CURRENT_USER,fullkey, 0, NULL, 0,
+                   KEY_READ | KEY_WRITE, NULL, &key, &disposition);
+
+    if (!res && disposition == REG_CREATED_NEW_KEY)
+    {
+        DWORD zero = 0x0;
+        RegSetValueExW(key, szwEnabled, 0, REG_DWORD, (LPBYTE)&zero, sizeof(DWORD));
+    }
+
+    if (!res)
+        RegCloseKey(key);
+}
+
+static HRESULT WINAPI InputProcessorProfiles_QueryInterface(ITfInputProcessorProfiles *iface, REFIID iid, LPVOID *ppvOut)
+{
+    InputProcessorProfiles *This = (InputProcessorProfiles *)iface;
+    *ppvOut = NULL;
+
+    if (IsEqualIID(iid, &IID_IUnknown) || IsEqualIID(iid, &IID_ITfInputProcessorProfiles))
+    {
+        *ppvOut = This;
+    }
+
+    if (*ppvOut)
+    {
+        IUnknown_AddRef(iface);
+        return S_OK;
+    }
+
+    WARN("unsupported interface: %s\n", debugstr_guid(iid));
+    return E_NOINTERFACE;
+}
+
+static ULONG WINAPI InputProcessorProfiles_AddRef(ITfInputProcessorProfiles *iface)
+{
+    InputProcessorProfiles *This = (InputProcessorProfiles *)iface;
+    return InterlockedIncrement(&This->refCount);
+}
+
+static ULONG WINAPI InputProcessorProfiles_Release(ITfInputProcessorProfiles *iface)
+{
+    InputProcessorProfiles *This = (InputProcessorProfiles *)iface;
+    ULONG ret;
+
+    ret = InterlockedDecrement(&This->refCount);
+    if (ret == 0)
+        InputProcessorProfiles_Destructor(This);
+    return ret;
+}
+
+/*****************************************************
+ * ITfInputProcessorProfiles functions
+ *****************************************************/
+static HRESULT WINAPI InputProcessorProfiles_Register(
+        ITfInputProcessorProfiles *iface, REFCLSID rclsid)
+{
+    InputProcessorProfiles *This = (InputProcessorProfiles*)iface;
+    HKEY tipkey;
+    WCHAR buf[39];
+    WCHAR fullkey[68];
+
+    TRACE("(%p) %s\n",This,debugstr_guid(rclsid));
+
+    StringFromGUID2(rclsid, buf, 39);
+    sprintfW(fullkey,szwTipfmt,szwSystemTIPKey,buf);
+
+    if (RegCreateKeyExW(HKEY_LOCAL_MACHINE,fullkey, 0, NULL, 0,
+                    KEY_READ | KEY_WRITE, NULL, &tipkey, NULL) != ERROR_SUCCESS)
+        return E_FAIL;
+
+    RegCloseKey(tipkey);
+
+    return S_OK;
+}
+
+static HRESULT WINAPI InputProcessorProfiles_Unregister(
+        ITfInputProcessorProfiles *iface, REFCLSID rclsid)
+{
+    WCHAR buf[39];
+    WCHAR fullkey[68];
+    InputProcessorProfiles *This = (InputProcessorProfiles*)iface;
+
+    TRACE("(%p) %s\n",This,debugstr_guid(rclsid));
+
+    StringFromGUID2(rclsid, buf, 39);
+    sprintfW(fullkey,szwTipfmt,szwSystemTIPKey,buf);
+
+    RegDeleteTreeW(HKEY_LOCAL_MACHINE, fullkey);
+    RegDeleteTreeW(HKEY_CURRENT_USER, fullkey);
+
+    return S_OK;
+}
+
+static HRESULT WINAPI InputProcessorProfiles_AddLanguageProfile(
+        ITfInputProcessorProfiles *iface, REFCLSID rclsid,
+        LANGID langid, REFGUID guidProfile, const WCHAR *pchDesc,
+        ULONG cchDesc, const WCHAR *pchIconFile, ULONG cchFile,
+        ULONG uIconIndex)
+{
+    HKEY tipkey,fmtkey;
+    WCHAR buf[39];
+    WCHAR fullkey[100];
+    ULONG res;
+    DWORD disposition = 0;
+
+    static const WCHAR fmt2[] = {'%','s','\\','0','x','%','0','8','x','\\','%','s',0};
+    static const WCHAR desc[] = {'D','e','s','c','r','i','p','t','i','o','n',0};
+    static const WCHAR icnf[] = {'I','c','o','n','F','i','l','e',0};
+    static const WCHAR icni[] = {'I','c','o','n','I','n','d','e','x',0};
+
+    InputProcessorProfiles *This = (InputProcessorProfiles*)iface;
+
+    TRACE("(%p) %s %x %s %s %s %i\n",This,debugstr_guid(rclsid), langid,
+            debugstr_guid(guidProfile), debugstr_wn(pchDesc,cchDesc),
+            debugstr_wn(pchIconFile,cchFile),uIconIndex);
+
+    StringFromGUID2(rclsid, buf, 39);
+    sprintfW(fullkey,szwTipfmt,szwSystemTIPKey,buf);
+
+    if (RegOpenKeyExW(HKEY_LOCAL_MACHINE,fullkey, 0, KEY_READ | KEY_WRITE,
+                &tipkey ) != ERROR_SUCCESS)
+        return E_FAIL;
+
+    StringFromGUID2(guidProfile, buf, 39);
+    sprintfW(fullkey,fmt2,szwLngp,langid,buf);
+
+    res = RegCreateKeyExW(tipkey,fullkey, 0, NULL, 0, KEY_READ | KEY_WRITE,
+            NULL, &fmtkey, &disposition);
+
+    if (!res)
+    {
+        DWORD zero = 0x0;
+        RegSetValueExW(fmtkey, desc, 0, REG_SZ, (LPBYTE)pchDesc, cchDesc * sizeof(WCHAR));
+        RegSetValueExW(fmtkey, icnf, 0, REG_SZ, (LPBYTE)pchIconFile, cchFile * sizeof(WCHAR));
+        RegSetValueExW(fmtkey, icni, 0, REG_DWORD, (LPBYTE)&uIconIndex, sizeof(DWORD));
+        if (disposition == REG_CREATED_NEW_KEY)
+            RegSetValueExW(fmtkey, szwEnabled, 0, REG_DWORD, (LPBYTE)&zero, sizeof(DWORD));
+        RegCloseKey(fmtkey);
+
+        add_userkey(rclsid, langid, guidProfile);
+    }
+    RegCloseKey(tipkey);
+
+    if (!res)
+        return S_OK;
+    else
+        return E_FAIL;
+}
+
+static HRESULT WINAPI InputProcessorProfiles_RemoveLanguageProfile(
+        ITfInputProcessorProfiles *iface, REFCLSID rclsid, LANGID langid,
+        REFGUID guidProfile)
+{
+    InputProcessorProfiles *This = (InputProcessorProfiles*)iface;
+    FIXME("STUB:(%p)\n",This);
+    return E_NOTIMPL;
+}
+
+static HRESULT WINAPI InputProcessorProfiles_EnumInputProcessorInfo(
+        ITfInputProcessorProfiles *iface, IEnumGUID **ppEnum)
+{
+    InputProcessorProfiles *This = (InputProcessorProfiles*)iface;
+    TRACE("(%p) %p\n",This,ppEnum);
+    return ProfilesEnumGuid_Constructor(ppEnum);
+}
+
+static HRESULT WINAPI InputProcessorProfiles_GetDefaultLanguageProfile(
+        ITfInputProcessorProfiles *iface, LANGID langid, REFGUID catid,
+        CLSID *pclsid, GUID *pguidProfile)
+{
+    InputProcessorProfiles *This = (InputProcessorProfiles*)iface;
+    FIXME("STUB:(%p)\n",This);
+    return E_NOTIMPL;
+}
+
+static HRESULT WINAPI InputProcessorProfiles_SetDefaultLanguageProfile(
+        ITfInputProcessorProfiles *iface, LANGID langid, REFCLSID rclsid,
+        REFGUID guidProfiles)
+{
+    InputProcessorProfiles *This = (InputProcessorProfiles*)iface;
+    FIXME("STUB:(%p)\n",This);
+    return E_NOTIMPL;
+}
+
+static HRESULT WINAPI InputProcessorProfiles_ActivateLanguageProfile(
+        ITfInputProcessorProfiles *iface, REFCLSID rclsid, LANGID langid,
+        REFGUID guidProfiles)
+{
+    InputProcessorProfiles *This = (InputProcessorProfiles*)iface;
+    FIXME("STUB:(%p)\n",This);
+    return E_NOTIMPL;
+}
+
+static HRESULT WINAPI InputProcessorProfiles_GetActiveLanguageProfile(
+        ITfInputProcessorProfiles *iface, REFCLSID rclsid, LANGID *plangid,
+        GUID *pguidProfile)
+{
+    InputProcessorProfiles *This = (InputProcessorProfiles*)iface;
+    FIXME("STUB:(%p)\n",This);
+    return E_NOTIMPL;
+}
+
+static HRESULT WINAPI InputProcessorProfiles_GetLanguageProfileDescription(
+        ITfInputProcessorProfiles *iface, REFCLSID rclsid, LANGID langid,
+        REFGUID guidProfile, BSTR *pbstrProfile)
+{
+    InputProcessorProfiles *This = (InputProcessorProfiles*)iface;
+    FIXME("STUB:(%p)\n",This);
+    return E_NOTIMPL;
+}
+
+static HRESULT WINAPI InputProcessorProfiles_GetCurrentLanguage(
+        ITfInputProcessorProfiles *iface, LANGID *plangid)
+{
+    InputProcessorProfiles *This = (InputProcessorProfiles*)iface;
+    TRACE("(%p) 0x%x\n",This,This->currentLanguage);
+
+    if (!plangid)
+        return E_INVALIDARG;
+
+    *plangid = This->currentLanguage;
+
+    return S_OK;
+}
+
+static HRESULT WINAPI InputProcessorProfiles_ChangeCurrentLanguage(
+        ITfInputProcessorProfiles *iface, LANGID langid)
+{
+    InputProcessorProfiles *This = (InputProcessorProfiles*)iface;
+    FIXME("STUB:(%p)\n",This);
+    return E_NOTIMPL;
+}
+
+static HRESULT WINAPI InputProcessorProfiles_GetLanguageList(
+        ITfInputProcessorProfiles *iface, LANGID **ppLangId, ULONG *pulCount)
+{
+    InputProcessorProfiles *This = (InputProcessorProfiles*)iface;
+    FIXME("STUB:(%p)\n",This);
+    return E_NOTIMPL;
+}
+
+static HRESULT WINAPI InputProcessorProfiles_EnumLanguageProfiles(
+        ITfInputProcessorProfiles *iface, LANGID langid,
+        IEnumTfLanguageProfiles **ppEnum)
+{
+    InputProcessorProfiles *This = (InputProcessorProfiles*)iface;
+    TRACE("(%p) %x %p\n",This,langid,ppEnum);
+    return EnumTfLanguageProfiles_Constructor(langid, ppEnum);
+}
+
+static HRESULT WINAPI InputProcessorProfiles_EnableLanguageProfile(
+        ITfInputProcessorProfiles *iface, REFCLSID rclsid, LANGID langid,
+        REFGUID guidProfile, BOOL fEnable)
+{
+    HKEY key;
+    WCHAR buf[39];
+    WCHAR buf2[39];
+    WCHAR fullkey[168];
+    ULONG res;
+
+    InputProcessorProfiles *This = (InputProcessorProfiles*)iface;
+    TRACE("(%p) %s %x %s %i\n",This, debugstr_guid(rclsid), langid, debugstr_guid(guidProfile), fEnable);
+
+    StringFromGUID2(rclsid, buf, 39);
+    StringFromGUID2(guidProfile, buf2, 39);
+    sprintfW(fullkey,szwFullLangfmt,szwSystemTIPKey,buf,szwLngp,langid,buf2);
+
+    res = RegOpenKeyExW(HKEY_CURRENT_USER, fullkey, 0, KEY_READ | KEY_WRITE, &key);
+
+    if (!res)
+    {
+        RegSetValueExW(key, szwEnabled, 0, REG_DWORD, (LPBYTE)&fEnable, sizeof(DWORD));
+        RegCloseKey(key);
+    }
+    else
+        return E_FAIL;
+
+    return S_OK;
+}
+
+static HRESULT WINAPI InputProcessorProfiles_IsEnabledLanguageProfile(
+        ITfInputProcessorProfiles *iface, REFCLSID rclsid, LANGID langid,
+        REFGUID guidProfile, BOOL *pfEnable)
+{
+    HKEY key;
+    WCHAR buf[39];
+    WCHAR buf2[39];
+    WCHAR fullkey[168];
+    ULONG res;
+
+    InputProcessorProfiles *This = (InputProcessorProfiles*)iface;
+    TRACE("(%p) %s, %i, %s, %p\n",This,debugstr_guid(rclsid),langid,debugstr_guid(guidProfile),pfEnable);
+
+    if (!pfEnable)
+        return E_INVALIDARG;
+
+    StringFromGUID2(rclsid, buf, 39);
+    StringFromGUID2(guidProfile, buf2, 39);
+    sprintfW(fullkey,szwFullLangfmt,szwSystemTIPKey,buf,szwLngp,langid,buf2);
+
+    res = RegOpenKeyExW(HKEY_CURRENT_USER, fullkey, 0, KEY_READ | KEY_WRITE, &key);
+
+    if (!res)
+    {
+        DWORD count = sizeof(DWORD);
+        res = RegQueryValueExW(key, szwEnabled, 0, NULL, (LPBYTE)pfEnable, &count);
+        RegCloseKey(key);
+    }
+
+    if (res)  /* Try Default */
+    {
+        res = RegOpenKeyExW(HKEY_LOCAL_MACHINE, fullkey, 0, KEY_READ | KEY_WRITE, &key);
+
+        if (!res)
+        {
+            DWORD count = sizeof(DWORD);
+            res = RegQueryValueExW(key, szwEnabled, 0, NULL, (LPBYTE)pfEnable, &count);
+            RegCloseKey(key);
+        }
+    }
+
+    if (!res)
+        return S_OK;
+    else
+        return E_FAIL;
+}
+
+static HRESULT WINAPI InputProcessorProfiles_EnableLanguageProfileByDefault(
+        ITfInputProcessorProfiles *iface, REFCLSID rclsid, LANGID langid,
+        REFGUID guidProfile, BOOL fEnable)
+{
+    HKEY key;
+    WCHAR buf[39];
+    WCHAR buf2[39];
+    WCHAR fullkey[168];
+    ULONG res;
+
+    InputProcessorProfiles *This = (InputProcessorProfiles*)iface;
+    TRACE("(%p) %s %x %s %i\n",This,debugstr_guid(rclsid),langid,debugstr_guid(guidProfile),fEnable);
+
+    StringFromGUID2(rclsid, buf, 39);
+    StringFromGUID2(guidProfile, buf2, 39);
+    sprintfW(fullkey,szwFullLangfmt,szwSystemTIPKey,buf,szwLngp,langid,buf2);
+
+    res = RegOpenKeyExW(HKEY_LOCAL_MACHINE, fullkey, 0, KEY_READ | KEY_WRITE, &key);
+
+    if (!res)
+    {
+        RegSetValueExW(key, szwEnabled, 0, REG_DWORD, (LPBYTE)&fEnable, sizeof(DWORD));
+        RegCloseKey(key);
+    }
+    else
+        return E_FAIL;
+
+    return S_OK;
+}
+
+static HRESULT WINAPI InputProcessorProfiles_SubstituteKeyboardLayout(
+        ITfInputProcessorProfiles *iface, REFCLSID rclsid, LANGID langid,
+        REFGUID guidProfile, HKL hKL)
+{
+    InputProcessorProfiles *This = (InputProcessorProfiles*)iface;
+    FIXME("STUB:(%p)\n",This);
+    return E_NOTIMPL;
+}
+
+
+static const ITfInputProcessorProfilesVtbl InputProcessorProfiles_InputProcessorProfilesVtbl =
+{
+    InputProcessorProfiles_QueryInterface,
+    InputProcessorProfiles_AddRef,
+    InputProcessorProfiles_Release,
+
+    InputProcessorProfiles_Register,
+    InputProcessorProfiles_Unregister,
+    InputProcessorProfiles_AddLanguageProfile,
+    InputProcessorProfiles_RemoveLanguageProfile,
+    InputProcessorProfiles_EnumInputProcessorInfo,
+    InputProcessorProfiles_GetDefaultLanguageProfile,
+    InputProcessorProfiles_SetDefaultLanguageProfile,
+    InputProcessorProfiles_ActivateLanguageProfile,
+    InputProcessorProfiles_GetActiveLanguageProfile,
+    InputProcessorProfiles_GetLanguageProfileDescription,
+    InputProcessorProfiles_GetCurrentLanguage,
+    InputProcessorProfiles_ChangeCurrentLanguage,
+    InputProcessorProfiles_GetLanguageList,
+    InputProcessorProfiles_EnumLanguageProfiles,
+    InputProcessorProfiles_EnableLanguageProfile,
+    InputProcessorProfiles_IsEnabledLanguageProfile,
+    InputProcessorProfiles_EnableLanguageProfileByDefault,
+    InputProcessorProfiles_SubstituteKeyboardLayout
+};
+
+HRESULT InputProcessorProfiles_Constructor(IUnknown *pUnkOuter, IUnknown **ppOut)
+{
+    InputProcessorProfiles *This;
+    if (pUnkOuter)
+        return CLASS_E_NOAGGREGATION;
+
+    This = HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,sizeof(InputProcessorProfiles));
+    if (This == NULL)
+        return E_OUTOFMEMORY;
+
+    This->InputProcessorProfilesVtbl= &InputProcessorProfiles_InputProcessorProfilesVtbl;
+    This->refCount = 1;
+    This->currentLanguage = GetUserDefaultLCID();
+
+    TRACE("returning %p\n", This);
+    *ppOut = (IUnknown *)This;
+    return S_OK;
+}
+
+/**************************************************
+ * IEnumGUID implementaion for ITfInputProcessorProfiles::EnumInputProcessorInfo
+ **************************************************/
+static void ProfilesEnumGuid_Destructor(ProfilesEnumGuid *This)
+{
+    TRACE("destroying %p\n", This);
+    RegCloseKey(This->key);
+    HeapFree(GetProcessHeap(),0,This);
+}
+
+static HRESULT WINAPI ProfilesEnumGuid_QueryInterface(IEnumGUID *iface, REFIID iid, LPVOID *ppvOut)
+{
+    ProfilesEnumGuid *This = (ProfilesEnumGuid *)iface;
+    *ppvOut = NULL;
+
+    if (IsEqualIID(iid, &IID_IUnknown) || IsEqualIID(iid, &IID_IEnumGUID))
+    {
+        *ppvOut = This;
+    }
+
+    if (*ppvOut)
+    {
+        IUnknown_AddRef(iface);
+        return S_OK;
+    }
+
+    WARN("unsupported interface: %s\n", debugstr_guid(iid));
+    return E_NOINTERFACE;
+}
+
+static ULONG WINAPI ProfilesEnumGuid_AddRef(IEnumGUID *iface)
+{
+    ProfilesEnumGuid *This = (ProfilesEnumGuid*)iface;
+    return InterlockedIncrement(&This->refCount);
+}
+
+static ULONG WINAPI ProfilesEnumGuid_Release(IEnumGUID *iface)
+{
+    ProfilesEnumGuid *This = (ProfilesEnumGuid *)iface;
+    ULONG ret;
+
+    ret = InterlockedDecrement(&This->refCount);
+    if (ret == 0)
+        ProfilesEnumGuid_Destructor(This);
+    return ret;
+}
+
+/*****************************************************
+ * IEnumGuid functions
+ *****************************************************/
+static HRESULT WINAPI ProfilesEnumGuid_Next( LPENUMGUID iface,
+    ULONG celt, GUID *rgelt, ULONG *pceltFetched)
+{
+    ProfilesEnumGuid *This = (ProfilesEnumGuid *)iface;
+    ULONG fetched = 0;
+
+    TRACE("(%p)\n",This);
+
+    if (rgelt == NULL) return E_POINTER;
+
+    if (This->key) while (fetched < celt)
+    {
+        LSTATUS res;
+        HRESULT hr;
+        WCHAR catid[39];
+        DWORD cName = 39;
+
+        res = RegEnumKeyExW(This->key, This->next_index, catid, &cName,
+                    NULL, NULL, NULL, NULL);
+        if (res != ERROR_SUCCESS && res != ERROR_MORE_DATA) break;
+        ++(This->next_index);
+
+        hr = CLSIDFromString(catid, rgelt);
+        if (FAILED(hr)) continue;
+
+        ++fetched;
+        ++rgelt;
+    }
+
+    if (pceltFetched) *pceltFetched = fetched;
+    return fetched == celt ? S_OK : S_FALSE;
+}
+
+static HRESULT WINAPI ProfilesEnumGuid_Skip( LPENUMGUID iface, ULONG celt)
+{
+    ProfilesEnumGuid *This = (ProfilesEnumGuid *)iface;
+    TRACE("(%p)\n",This);
+
+    This->next_index += celt;
+    return S_OK;
+}
+
+static HRESULT WINAPI ProfilesEnumGuid_Reset( LPENUMGUID iface)
+{
+    ProfilesEnumGuid *This = (ProfilesEnumGuid *)iface;
+    TRACE("(%p)\n",This);
+    This->next_index = 0;
+    return S_OK;
+}
+
+static HRESULT WINAPI ProfilesEnumGuid_Clone( LPENUMGUID iface,
+    IEnumGUID **ppenum)
+{
+    ProfilesEnumGuid *This = (ProfilesEnumGuid *)iface;
+    HRESULT res;
+
+    TRACE("(%p)\n",This);
+
+    if (ppenum == NULL) return E_POINTER;
+
+    res = ProfilesEnumGuid_Constructor(ppenum);
+    if (SUCCEEDED(res))
+    {
+        ProfilesEnumGuid *new_This = (ProfilesEnumGuid *)*ppenum;
+        new_This->next_index = This->next_index;
+    }
+    return res;
+}
+
+static const IEnumGUIDVtbl IEnumGUID_Vtbl ={
+    ProfilesEnumGuid_QueryInterface,
+    ProfilesEnumGuid_AddRef,
+    ProfilesEnumGuid_Release,
+
+    ProfilesEnumGuid_Next,
+    ProfilesEnumGuid_Skip,
+    ProfilesEnumGuid_Reset,
+    ProfilesEnumGuid_Clone
+};
+
+static HRESULT ProfilesEnumGuid_Constructor(IEnumGUID **ppOut)
+{
+    ProfilesEnumGuid *This;
+
+    This = HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,sizeof(ProfilesEnumGuid));
+    if (This == NULL)
+        return E_OUTOFMEMORY;
+
+    This->Vtbl= &IEnumGUID_Vtbl;
+    This->refCount = 1;
+
+    if (RegCreateKeyExW(HKEY_LOCAL_MACHINE, szwSystemTIPKey, 0, NULL, 0,
+                    KEY_READ | KEY_WRITE, NULL, &This->key, NULL) != ERROR_SUCCESS)
+        return E_FAIL;
+
+    TRACE("returning %p\n", This);
+    *ppOut = (IEnumGUID*)This;
+    return S_OK;
+}
+
+/**************************************************
+ * IEnumTfLanguageProfiles implementaion
+ **************************************************/
+static void EnumTfLanguageProfiles_Destructor(EnumTfLanguageProfiles *This)
+{
+    TRACE("destroying %p\n", This);
+    RegCloseKey(This->tipkey);
+    if (This->langkey)
+        RegCloseKey(This->langkey);
+    HeapFree(GetProcessHeap(),0,This);
+}
+
+static HRESULT WINAPI EnumTfLanguageProfiles_QueryInterface(IEnumTfLanguageProfiles *iface, REFIID iid, LPVOID *ppvOut)
+{
+    EnumTfLanguageProfiles *This = (EnumTfLanguageProfiles *)iface;
+    *ppvOut = NULL;
+
+    if (IsEqualIID(iid, &IID_IUnknown) || IsEqualIID(iid, &IID_IEnumTfLanguageProfiles))
+    {
+        *ppvOut = This;
+    }
+
+    if (*ppvOut)
+    {
+        IUnknown_AddRef(iface);
+        return S_OK;
+    }
+
+    WARN("unsupported interface: %s\n", debugstr_guid(iid));
+    return E_NOINTERFACE;
+}
+
+static ULONG WINAPI EnumTfLanguageProfiles_AddRef(IEnumTfLanguageProfiles *iface)
+{
+    EnumTfLanguageProfiles *This = (EnumTfLanguageProfiles*)iface;
+    return InterlockedIncrement(&This->refCount);
+}
+
+static ULONG WINAPI EnumTfLanguageProfiles_Release(IEnumTfLanguageProfiles *iface)
+{
+    EnumTfLanguageProfiles *This = (EnumTfLanguageProfiles *)iface;
+    ULONG ret;
+
+    ret = InterlockedDecrement(&This->refCount);
+    if (ret == 0)
+        EnumTfLanguageProfiles_Destructor(This);
+    return ret;
+}
+
+/*****************************************************
+ * IEnumGuid functions
+ *****************************************************/
+static INT next_LanguageProfile(EnumTfLanguageProfiles *This, CLSID clsid, TF_LANGUAGEPROFILE *tflp)
+{
+    WCHAR fullkey[168];
+    ULONG res;
+    WCHAR profileid[39];
+    DWORD cName = 39;
+    GUID  profile;
+
+    static const WCHAR fmt[] = {'%','s','\\','%','s','\\','0','x','%','0','8','x',0};
+
+    if (This->langkey == NULL)
+    {
+        sprintfW(fullkey,fmt,This->szwCurrentClsid,szwLngp,This->langid);
+        res = RegOpenKeyExW(This->tipkey, fullkey, 0, KEY_READ | KEY_WRITE, &This->langkey);
+        if (res)
+        {
+            This->langkey = NULL;
+            return -1;
+        }
+        This->lang_index = 0;
+    }
+    res = RegEnumKeyExW(This->langkey, This->lang_index, profileid, &cName,
+                NULL, NULL, NULL, NULL);
+    if (res != ERROR_SUCCESS && res != ERROR_MORE_DATA)
+    {
+        RegCloseKey(This->langkey);
+        This->langkey = NULL;
+        return -1;
+    }
+    ++(This->lang_index);
+
+    if (tflp)
+    {
+        res = CLSIDFromString(profileid, &profile);
+        if (FAILED(res)) return 0;
+
+        tflp->clsid = clsid;
+        tflp->langid = This->langid;
+        /* FIXME */
+        tflp->fActive = FALSE;
+        tflp->guidProfile = profile;
+        /* FIXME set catid */
+    }
+
+    return 1;
+}
+
+static HRESULT WINAPI EnumTfLanguageProfiles_Next(IEnumTfLanguageProfiles *iface,
+    ULONG ulCount, TF_LANGUAGEPROFILE *pProfile, ULONG *pcFetch)
+{
+    EnumTfLanguageProfiles *This = (EnumTfLanguageProfiles *)iface;
+    ULONG fetched = 0;
+
+    TRACE("(%p)\n",This);
+
+    if (pProfile == NULL) return E_POINTER;
+
+    if (This->tipkey) while (fetched < ulCount)
+    {
+        LSTATUS res;
+        HRESULT hr;
+        DWORD cName = 39;
+        GUID clsid;
+
+        res = RegEnumKeyExW(This->tipkey, This->tip_index,
+                    This->szwCurrentClsid, &cName, NULL, NULL, NULL, NULL);
+        if (res != ERROR_SUCCESS && res != ERROR_MORE_DATA) break;
+        ++(This->tip_index);
+        hr = CLSIDFromString(This->szwCurrentClsid, &clsid);
+        if (FAILED(hr)) continue;
+
+        while ( fetched < ulCount)
+        {
+            INT res = next_LanguageProfile(This, clsid, pProfile);
+            if (res == 1)
+            {
+                ++fetched;
+                ++pProfile;
+            }
+            else if (res == -1)
+                break;
+            else
+                continue;
+        }
+    }
+
+    if (pcFetch) *pcFetch = fetched;
+    return fetched == ulCount ? S_OK : S_FALSE;
+}
+
+static HRESULT WINAPI EnumTfLanguageProfiles_Skip( IEnumTfLanguageProfiles* iface, ULONG celt)
+{
+    EnumTfLanguageProfiles *This = (EnumTfLanguageProfiles *)iface;
+    FIXME("STUB (%p)\n",This);
+    return E_NOTIMPL;
+}
+
+static HRESULT WINAPI EnumTfLanguageProfiles_Reset( IEnumTfLanguageProfiles* iface)
+{
+    EnumTfLanguageProfiles *This = (EnumTfLanguageProfiles *)iface;
+    TRACE("(%p)\n",This);
+    This->tip_index = 0;
+    if (This->langkey)
+        RegCloseKey(This->langkey);
+    This->langkey = NULL;
+    This->lang_index = 0;
+    return S_OK;
+}
+
+static HRESULT WINAPI EnumTfLanguageProfiles_Clone( IEnumTfLanguageProfiles *iface,
+    IEnumTfLanguageProfiles **ppenum)
+{
+    EnumTfLanguageProfiles *This = (EnumTfLanguageProfiles *)iface;
+    HRESULT res;
+
+    TRACE("(%p)\n",This);
+
+    if (ppenum == NULL) return E_POINTER;
+
+    res = EnumTfLanguageProfiles_Constructor(This->langid, ppenum);
+    if (SUCCEEDED(res))
+    {
+        EnumTfLanguageProfiles *new_This = (EnumTfLanguageProfiles *)*ppenum;
+        new_This->tip_index = This->tip_index;
+        lstrcpynW(new_This->szwCurrentClsid,This->szwCurrentClsid,39);
+
+        if (This->langkey)
+        {
+            WCHAR fullkey[168];
+            static const WCHAR fmt[] = {'%','s','\\','%','s','\\','0','x','%','0','8','x',0};
+
+            sprintfW(fullkey,fmt,This->szwCurrentClsid,szwLngp,This->langid);
+            res = RegOpenKeyExW(new_This->tipkey, fullkey, 0, KEY_READ | KEY_WRITE, &This->langkey);
+            new_This->lang_index = This->lang_index;
+        }
+    }
+    return res;
+}
+
+static const IEnumTfLanguageProfilesVtbl IEnumTfLanguageProfiles_Vtbl ={
+    EnumTfLanguageProfiles_QueryInterface,
+    EnumTfLanguageProfiles_AddRef,
+    EnumTfLanguageProfiles_Release,
+
+    EnumTfLanguageProfiles_Clone,
+    EnumTfLanguageProfiles_Next,
+    EnumTfLanguageProfiles_Reset,
+    EnumTfLanguageProfiles_Skip
+};
+
+static HRESULT EnumTfLanguageProfiles_Constructor(LANGID langid, IEnumTfLanguageProfiles **ppOut)
+{
+    EnumTfLanguageProfiles *This;
+
+    This = HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,sizeof(EnumTfLanguageProfiles));
+    if (This == NULL)
+        return E_OUTOFMEMORY;
+
+    This->Vtbl= &IEnumTfLanguageProfiles_Vtbl;
+    This->refCount = 1;
+    This->langid = langid;
+
+    if (RegCreateKeyExW(HKEY_LOCAL_MACHINE, szwSystemTIPKey, 0, NULL, 0,
+                    KEY_READ | KEY_WRITE, NULL, &This->tipkey, NULL) != ERROR_SUCCESS)
+        return E_FAIL;
+
+    TRACE("returning %p\n", This);
+    *ppOut = (IEnumTfLanguageProfiles*)This;
+    return S_OK;
+}
diff --git a/reactos/dll/win32/msctf/msctf.c b/reactos/dll/win32/msctf/msctf.c
new file mode 100644 (file)
index 0000000..1f5e35b
--- /dev/null
@@ -0,0 +1,252 @@
+/*
+ * MSCTF Server DLL
+ *
+ * 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>
+#include <stdio.h>
+
+#define COBJMACROS
+
+#include "wine/debug.h"
+#include "windef.h"
+#include "winbase.h"
+#include "winreg.h"
+#include "shlwapi.h"
+#include "shlguid.h"
+#include "comcat.h"
+#include "initguid.h"
+#include "msctf.h"
+
+#include "msctf_internal.h"
+
+WINE_DEFAULT_DEBUG_CHANNEL(msctf);
+
+static LONG MSCTF_refCount;
+
+static HINSTANCE MSCTF_hinstance;
+
+DWORD tlsIndex = 0;
+
+const WCHAR szwSystemTIPKey[] = {'S','O','F','T','W','A','R','E','\\','M','i','c','r','o','s','o','f','t','\\','C','T','F','\\','T','I','P',0};
+
+typedef HRESULT (*LPFNCONSTRUCTOR)(IUnknown *pUnkOuter, IUnknown **ppvOut);
+
+static const struct {
+    REFCLSID clsid;
+    LPFNCONSTRUCTOR ctor;
+} ClassesTable[] = {
+    {&CLSID_TF_ThreadMgr, ThreadMgr_Constructor},
+    {&CLSID_TF_InputProcessorProfiles, InputProcessorProfiles_Constructor},
+    {&CLSID_TF_CategoryMgr, CategoryMgr_Constructor},
+    {NULL, NULL}
+};
+
+typedef struct tagClassFactory
+{
+    const IClassFactoryVtbl *vtbl;
+    LONG   ref;
+    LPFNCONSTRUCTOR ctor;
+} ClassFactory;
+
+static void ClassFactory_Destructor(ClassFactory *This)
+{
+    TRACE("Destroying class factory %p\n", This);
+    HeapFree(GetProcessHeap(),0,This);
+    MSCTF_refCount--;
+}
+
+static HRESULT WINAPI ClassFactory_QueryInterface(IClassFactory *iface, REFIID riid, LPVOID *ppvOut)
+{
+    *ppvOut = NULL;
+    if (IsEqualIID(riid, &IID_IClassFactory) || IsEqualIID(riid, &IID_IUnknown)) {
+        IClassFactory_AddRef(iface);
+        *ppvOut = iface;
+        return S_OK;
+    }
+
+    WARN("Unknown interface %s\n", debugstr_guid(riid));
+    return E_NOINTERFACE;
+}
+
+static ULONG WINAPI ClassFactory_AddRef(IClassFactory *iface)
+{
+    ClassFactory *This = (ClassFactory *)iface;
+    return InterlockedIncrement(&This->ref);
+}
+
+static ULONG WINAPI ClassFactory_Release(IClassFactory *iface)
+{
+    ClassFactory *This = (ClassFactory *)iface;
+    ULONG ret = InterlockedDecrement(&This->ref);
+
+    if (ret == 0)
+        ClassFactory_Destructor(This);
+    return ret;
+}
+
+static HRESULT WINAPI ClassFactory_CreateInstance(IClassFactory *iface, IUnknown *punkOuter, REFIID iid, LPVOID *ppvOut)
+{
+    ClassFactory *This = (ClassFactory *)iface;
+    HRESULT ret;
+    IUnknown *obj;
+
+    TRACE("(%p, %p, %s, %p)\n", iface, punkOuter, debugstr_guid(iid), ppvOut);
+    ret = This->ctor(punkOuter, &obj);
+    if (FAILED(ret))
+        return ret;
+    ret = IUnknown_QueryInterface(obj, iid, ppvOut);
+    IUnknown_Release(obj);
+    return ret;
+}
+
+static HRESULT WINAPI ClassFactory_LockServer(IClassFactory *iface, BOOL fLock)
+{
+    ClassFactory *This = (ClassFactory *)iface;
+
+    TRACE("(%p)->(%x)\n", This, fLock);
+
+    if(fLock)
+        InterlockedIncrement(&MSCTF_refCount);
+    else
+        InterlockedDecrement(&MSCTF_refCount);
+
+    return S_OK;
+}
+
+static const IClassFactoryVtbl ClassFactoryVtbl = {
+    /* IUnknown */
+    ClassFactory_QueryInterface,
+    ClassFactory_AddRef,
+    ClassFactory_Release,
+
+    /* IClassFactory*/
+    ClassFactory_CreateInstance,
+    ClassFactory_LockServer
+};
+
+static HRESULT ClassFactory_Constructor(LPFNCONSTRUCTOR ctor, LPVOID *ppvOut)
+{
+    ClassFactory *This = HeapAlloc(GetProcessHeap(),0,sizeof(ClassFactory));
+    This->vtbl = &ClassFactoryVtbl;
+    This->ref = 1;
+    This->ctor = ctor;
+    *ppvOut = (LPVOID)This;
+    TRACE("Created class factory %p\n", This);
+    MSCTF_refCount++;
+    return S_OK;
+}
+
+/*************************************************************************
+ * MSCTF DllMain
+ */
+BOOL WINAPI DllMain(HINSTANCE hinst, DWORD fdwReason, LPVOID fImpLoad)
+{
+    TRACE("%p 0x%x %p\n", hinst, fdwReason, fImpLoad);
+    switch (fdwReason)
+    {
+        case DLL_WINE_PREATTACH:
+            return FALSE;   /* prefer native version */
+        case DLL_PROCESS_ATTACH:
+            MSCTF_hinstance = hinst;
+            tlsIndex = TlsAlloc();
+            break;
+        case DLL_PROCESS_DETACH:
+            TlsFree(tlsIndex);
+            break;
+    }
+    return TRUE;
+}
+
+/*************************************************************************
+ *              DllCanUnloadNow (MSCTF.@)
+ */
+HRESULT WINAPI DllCanUnloadNow(void)
+{
+    return MSCTF_refCount ? S_FALSE : S_OK;
+}
+
+/***********************************************************************
+ *              DllGetClassObject (MSCTF.@)
+ */
+HRESULT WINAPI DllGetClassObject(REFCLSID clsid, REFIID iid, LPVOID *ppvOut)
+{
+    int i;
+
+    *ppvOut = NULL;
+    if (!IsEqualIID(iid, &IID_IUnknown) && !IsEqualIID(iid, &IID_IClassFactory))
+        return E_NOINTERFACE;
+
+    for (i = 0; ClassesTable[i].clsid != NULL; i++)
+        if (IsEqualCLSID(ClassesTable[i].clsid, clsid)) {
+            return ClassFactory_Constructor(ClassesTable[i].ctor, ppvOut);
+        }
+    FIXME("CLSID %s not supported\n", debugstr_guid(clsid));
+    return CLASS_E_CLASSNOTAVAILABLE;
+}
+
+/***********************************************************************
+ *              TF_CreateThreadMgr (MSCTF.@)
+ */
+HRESULT WINAPI TF_CreateThreadMgr(ITfThreadMgr **pptim)
+{
+    TRACE("\n");
+    return ThreadMgr_Constructor(NULL,(IUnknown**)pptim);
+}
+
+/***********************************************************************
+ *              TF_GetThreadMgr (MSCTF.@)
+ */
+HRESULT WINAPI TF_GetThreadMgr(ITfThreadMgr **pptim)
+{
+    TRACE("\n");
+    *pptim = (ITfThreadMgr*)TlsGetValue(tlsIndex);
+
+    if (*pptim)
+        ITfThreadMgr_AddRef(*pptim);
+
+    return S_OK;
+}
+
+/***********************************************************************
+ *              SetInputScope(MSCTF.@)
+ */
+HRESULT WINAPI SetInputScope(HWND hwnd, INT inputscope)
+{
+    FIXME("STUB: %p %i\n",hwnd,inputscope);
+    return S_OK;
+}
+
+/***********************************************************************
+ *              SetInputScopes(MSCTF.@)
+ */
+HRESULT WINAPI SetInputScopes(HWND hwnd, const INT *pInputScopes,
+                              UINT cInputScopes, WCHAR **ppszPhraseList,
+                              UINT cPhrases, WCHAR *pszRegExp, WCHAR *pszSRGS)
+{
+    int i;
+    FIXME("STUB: %p ... %s %s\n",hwnd, debugstr_w(pszRegExp), debugstr_w(pszSRGS));
+    for (i = 0; i < cInputScopes; i++)
+        TRACE("\tScope[%i] = %i\n",i,pInputScopes[i]);
+    for (i = 0; i < cPhrases; i++)
+        TRACE("\tPhrase[%i] = %s\n",i,debugstr_w(ppszPhraseList[i]));
+
+    return S_OK;
+}
diff --git a/reactos/dll/win32/msctf/msctf.rbuild b/reactos/dll/win32/msctf/msctf.rbuild
new file mode 100644 (file)
index 0000000..c2ae048
--- /dev/null
@@ -0,0 +1,22 @@
+<module name="msctf" type="win32dll" baseaddress="${BASEADDRESS_MSCTF}" installbase="system32" installname="msctf.dll" allowwarnings="true">
+       <autoregister infsection="OleControlDlls" type="DllRegisterServer" />
+       <importlibrary definition="msctf.spec" />
+       <include base="msctf">.</include>
+       <include base="ReactOS">include/reactos/wine</include>
+       <define name="__WINESRC__" />
+       <define name="_WIN32_WINNT">0x600</define>
+       <file>categorymgr.c</file>
+       <file>context.c</file>
+       <file>documentmgr.c</file>
+       <file>inputprocessor.c</file>
+       <file>msctf.c</file>
+       <file>regsvr.c</file>
+       <file>threadmgr.c</file>
+       <library>wine</library>
+       <library>uuid</library>
+       <library>ole32</library>
+       <library>user32</library>
+       <library>advapi32</library>
+       <library>kernel32</library>
+       <library>ntdll</library>
+</module>
diff --git a/reactos/dll/win32/msctf/msctf.spec b/reactos/dll/win32/msctf/msctf.spec
new file mode 100644 (file)
index 0000000..1c8bb37
--- /dev/null
@@ -0,0 +1,34 @@
+@ stdcall -private DllCanUnloadNow()
+@ stdcall -private DllGetClassObject(ptr ptr ptr)
+@ stdcall -private DllRegisterServer()
+@ stdcall -private DllUnregisterServer()
+@ stdcall SetInputScope(long long)
+@ stub SetInputScopeXML
+@ stdcall SetInputScopes(long ptr long ptr long wstr wstr)
+@ stub TF_CUASAppFix
+@ stub TF_CheckThreadInputIdle
+@ stub TF_ClearLangBarAddIns
+@ stub TF_CreateCategoryMgr
+@ stub TF_CreateCicLoadMutex
+@ stub TF_CreateDisplayAttributeMgr
+@ stub TF_CreateInputProcessorProfiles
+@ stub TF_CreateLangBarItemMgr
+@ stub TF_CreateLangBarMgr
+@ stdcall TF_CreateThreadMgr(ptr)
+@ stub TF_DllDetachInOther
+@ stub TF_GetGlobalCompartment
+@ stub TF_GetInputScope
+@ stub TF_GetLangIcon
+@ stub TF_GetMlngHKL
+@ stub TF_GetMlngIconIndex
+@ stub TF_GetThreadFlags
+@ stdcall TF_GetThreadMgr(ptr)
+@ stub TF_InatExtractIcon
+@ stub TF_InitMlngInfo
+@ stub TF_InitSystem
+@ stub TF_InvalidAssemblyListCache
+@ stub TF_InvalidAssemblyListCacheIfExist
+@ stub TF_IsCtfmonRunning
+@ stub TF_IsInMarshaling
+@ stub TF_MlngInfoCount
+@ stub TF_RunInputCPL
diff --git a/reactos/dll/win32/msctf/msctf_internal.h b/reactos/dll/win32/msctf/msctf_internal.h
new file mode 100644 (file)
index 0000000..4d83aa3
--- /dev/null
@@ -0,0 +1,32 @@
+/*
+ * Internal header for msctf.dll
+ *
+ * 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
+ */
+
+#ifndef __WINE_MSCTF_I_H
+#define __WINE_MSCTF_I_H
+extern DWORD tlsIndex;
+
+extern HRESULT ThreadMgr_Constructor(IUnknown *pUnkOuter, IUnknown **ppOut);
+extern HRESULT DocumentMgr_Constructor(ITfDocumentMgr **ppOut);
+extern HRESULT Context_Constructor(TfClientId tidOwner, IUnknown *punk, ITfContext **ppOut, TfEditCookie *pecTextStore);
+extern HRESULT InputProcessorProfiles_Constructor(IUnknown *pUnkOuter, IUnknown **ppOut);
+extern HRESULT CategoryMgr_Constructor(IUnknown *pUnkOuter, IUnknown **ppOut);
+
+extern const WCHAR szwSystemTIPKey[];
+#endif /* __WINE_MSCTF_I_H */
diff --git a/reactos/dll/win32/msctf/regsvr.c b/reactos/dll/win32/msctf/regsvr.c
new file mode 100644 (file)
index 0000000..a47d984
--- /dev/null
@@ -0,0 +1,504 @@
+/*
+ *     self-registerable dll functions for msctf
+ *
+ * Copyright (C) 2004 Stefan Leichter
+ *
+ * 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 <stdarg.h>
+#include <string.h>
+
+#include "windef.h"
+#include "winbase.h"
+#include "winuser.h"
+#include "wingdi.h"
+#include "winreg.h"
+#include "winerror.h"
+
+#include "ole2.h"
+#include "shlguid.h"
+#include "msctf.h"
+
+#include "wine/debug.h"
+
+WINE_DEFAULT_DEBUG_CHANNEL(msctf);
+
+/*
+ * Near the bottom of this file are the exported DllRegisterServer and
+ * DllUnregisterServer, which make all this worthwhile.
+ */
+
+/***********************************************************************
+ *             interface for self-registering
+ */
+struct regsvr_interface
+{
+    IID const *iid;            /* NULL for end of list */
+    LPCSTR name;               /* can be NULL to omit */
+    IID const *base_iid;       /* can be NULL to omit */
+    int num_methods;           /* can be <0 to omit */
+    CLSID const *ps_clsid;     /* can be NULL to omit */
+    CLSID const *ps_clsid32;   /* can be NULL to omit */
+};
+
+static HRESULT register_interfaces(struct regsvr_interface const *list);
+static HRESULT unregister_interfaces(struct regsvr_interface const *list);
+
+struct regsvr_coclass
+{
+    CLSID const *clsid;                /* NULL for end of list */
+    LPCSTR name;               /* can be NULL to omit */
+    LPCSTR ips;                        /* can be NULL to omit */
+    LPCSTR ips32;              /* can be NULL to omit */
+    LPCSTR ips32_tmodel;       /* can be NULL to omit */
+    LPCSTR progid;             /* can be NULL to omit */
+    LPCSTR viprogid;           /* can be NULL to omit */
+    LPCSTR progid_extra;       /* can be NULL to omit */
+};
+
+static HRESULT register_coclasses(struct regsvr_coclass const *list);
+static HRESULT unregister_coclasses(struct regsvr_coclass const *list);
+
+/***********************************************************************
+ *             static string constants
+ */
+static WCHAR const interface_keyname[10] = {
+    'I', 'n', 't', 'e', 'r', 'f', 'a', 'c', 'e', 0 };
+static WCHAR const base_ifa_keyname[14] = {
+    'B', 'a', 's', 'e', 'I', 'n', 't', 'e', 'r', 'f', 'a', 'c',
+    'e', 0 };
+static WCHAR const num_methods_keyname[11] = {
+    'N', 'u', 'm', 'M', 'e', 't', 'h', 'o', 'd', 's', 0 };
+static WCHAR const ps_clsid_keyname[15] = {
+    'P', 'r', 'o', 'x', 'y', 'S', 't', 'u', 'b', 'C', 'l', 's',
+    'i', 'd', 0 };
+static WCHAR const ps_clsid32_keyname[17] = {
+    'P', 'r', 'o', 'x', 'y', 'S', 't', 'u', 'b', 'C', 'l', 's',
+    'i', 'd', '3', '2', 0 };
+static WCHAR const clsid_keyname[6] = {
+    'C', 'L', 'S', 'I', 'D', 0 };
+static WCHAR const curver_keyname[7] = {
+    'C', 'u', 'r', 'V', 'e', 'r', 0 };
+static WCHAR const ips_keyname[13] = {
+    'I', 'n', 'P', 'r', 'o', 'c', 'S', 'e', 'r', 'v', 'e', 'r',
+    0 };
+static WCHAR const ips32_keyname[15] = {
+    'I', 'n', 'P', 'r', 'o', 'c', 'S', 'e', 'r', 'v', 'e', 'r',
+    '3', '2', 0 };
+static WCHAR const progid_keyname[7] = {
+    'P', 'r', 'o', 'g', 'I', 'D', 0 };
+static WCHAR const viprogid_keyname[25] = {
+    'V', 'e', 'r', 's', 'i', 'o', 'n', 'I', 'n', 'd', 'e', 'p',
+    'e', 'n', 'd', 'e', 'n', 't', 'P', 'r', 'o', 'g', 'I', 'D',
+    0 };
+static char const tmodel_valuename[] = "ThreadingModel";
+
+/***********************************************************************
+ *             static helper functions
+ */
+static LONG register_key_guid(HKEY base, WCHAR const *name, GUID const *guid);
+static LONG register_key_defvalueW(HKEY base, WCHAR const *name,
+                                  WCHAR const *value);
+static LONG register_key_defvalueA(HKEY base, WCHAR const *name,
+                                  char const *value);
+static LONG register_progid(WCHAR const *clsid,
+                           char const *progid, char const *curver_progid,
+                           char const *name, char const *extra);
+
+/***********************************************************************
+ *             register_interfaces
+ */
+static HRESULT register_interfaces(struct regsvr_interface const *list)
+{
+    LONG res = ERROR_SUCCESS;
+    HKEY interface_key;
+
+    res = RegCreateKeyExW(HKEY_CLASSES_ROOT, interface_keyname, 0, NULL, 0,
+                         KEY_READ | KEY_WRITE, NULL, &interface_key, NULL);
+    if (res != ERROR_SUCCESS) goto error_return;
+
+    for (; res == ERROR_SUCCESS && list->iid; ++list) {
+       WCHAR buf[39];
+       HKEY iid_key;
+
+       StringFromGUID2(list->iid, buf, 39);
+       res = RegCreateKeyExW(interface_key, buf, 0, NULL, 0,
+                             KEY_READ | KEY_WRITE, NULL, &iid_key, NULL);
+       if (res != ERROR_SUCCESS) goto error_close_interface_key;
+
+       if (list->name) {
+           res = RegSetValueExA(iid_key, NULL, 0, REG_SZ,
+                                (CONST BYTE*)(list->name),
+                                strlen(list->name) + 1);
+           if (res != ERROR_SUCCESS) goto error_close_iid_key;
+       }
+
+       if (list->base_iid) {
+           res = register_key_guid(iid_key, base_ifa_keyname, list->base_iid);
+           if (res != ERROR_SUCCESS) goto error_close_iid_key;
+       }
+
+       if (0 <= list->num_methods) {
+           static WCHAR const fmt[3] = { '%', 'd', 0 };
+           HKEY key;
+
+           res = RegCreateKeyExW(iid_key, num_methods_keyname, 0, NULL, 0,
+                                 KEY_READ | KEY_WRITE, NULL, &key, NULL);
+           if (res != ERROR_SUCCESS) goto error_close_iid_key;
+
+           wsprintfW(buf, fmt, list->num_methods);
+           res = RegSetValueExW(key, NULL, 0, REG_SZ,
+                                (CONST BYTE*)buf,
+                                (lstrlenW(buf) + 1) * sizeof(WCHAR));
+           RegCloseKey(key);
+
+           if (res != ERROR_SUCCESS) goto error_close_iid_key;
+       }
+
+       if (list->ps_clsid) {
+           res = register_key_guid(iid_key, ps_clsid_keyname, list->ps_clsid);
+           if (res != ERROR_SUCCESS) goto error_close_iid_key;
+       }
+
+       if (list->ps_clsid32) {
+           res = register_key_guid(iid_key, ps_clsid32_keyname, list->ps_clsid32);
+           if (res != ERROR_SUCCESS) goto error_close_iid_key;
+       }
+
+    error_close_iid_key:
+       RegCloseKey(iid_key);
+    }
+
+error_close_interface_key:
+    RegCloseKey(interface_key);
+error_return:
+    return res != ERROR_SUCCESS ? HRESULT_FROM_WIN32(res) : S_OK;
+}
+
+/***********************************************************************
+ *             unregister_interfaces
+ */
+static HRESULT unregister_interfaces(struct regsvr_interface const *list)
+{
+    LONG res = ERROR_SUCCESS;
+    HKEY interface_key;
+
+    res = RegOpenKeyExW(HKEY_CLASSES_ROOT, interface_keyname, 0,
+                       KEY_READ | KEY_WRITE, &interface_key);
+    if (res == ERROR_FILE_NOT_FOUND) return S_OK;
+    if (res != ERROR_SUCCESS) goto error_return;
+
+    for (; res == ERROR_SUCCESS && list->iid; ++list) {
+       WCHAR buf[39];
+
+       StringFromGUID2(list->iid, buf, 39);
+       res = RegDeleteTreeW(interface_key, buf);
+       if (res == ERROR_FILE_NOT_FOUND) res = ERROR_SUCCESS;
+    }
+
+    RegCloseKey(interface_key);
+error_return:
+    return res != ERROR_SUCCESS ? HRESULT_FROM_WIN32(res) : S_OK;
+}
+
+/***********************************************************************
+ *             register_coclasses
+ */
+static HRESULT register_coclasses(struct regsvr_coclass const *list)
+{
+    LONG res = ERROR_SUCCESS;
+    HKEY coclass_key;
+
+    res = RegCreateKeyExW(HKEY_CLASSES_ROOT, clsid_keyname, 0, NULL, 0,
+                         KEY_READ | KEY_WRITE, NULL, &coclass_key, NULL);
+    if (res != ERROR_SUCCESS) goto error_return;
+
+    for (; res == ERROR_SUCCESS && list->clsid; ++list) {
+       WCHAR buf[39];
+       HKEY clsid_key;
+
+       StringFromGUID2(list->clsid, buf, 39);
+       res = RegCreateKeyExW(coclass_key, buf, 0, NULL, 0,
+                             KEY_READ | KEY_WRITE, NULL, &clsid_key, NULL);
+       if (res != ERROR_SUCCESS) goto error_close_coclass_key;
+
+       if (list->name) {
+           res = RegSetValueExA(clsid_key, NULL, 0, REG_SZ,
+                                (CONST BYTE*)(list->name),
+                                strlen(list->name) + 1);
+           if (res != ERROR_SUCCESS) goto error_close_clsid_key;
+       }
+
+       if (list->ips) {
+           res = register_key_defvalueA(clsid_key, ips_keyname, list->ips);
+           if (res != ERROR_SUCCESS) goto error_close_clsid_key;
+       }
+
+       if (list->ips32) {
+           HKEY ips32_key;
+
+           res = RegCreateKeyExW(clsid_key, ips32_keyname, 0, NULL, 0,
+                                 KEY_READ | KEY_WRITE, NULL,
+                                 &ips32_key, NULL);
+           if (res != ERROR_SUCCESS) goto error_close_clsid_key;
+
+           res = RegSetValueExA(ips32_key, NULL, 0, REG_SZ,
+                                (CONST BYTE*)list->ips32,
+                                lstrlenA(list->ips32) + 1);
+           if (res == ERROR_SUCCESS && list->ips32_tmodel)
+               res = RegSetValueExA(ips32_key, tmodel_valuename, 0, REG_SZ,
+                                    (CONST BYTE*)list->ips32_tmodel,
+                                    strlen(list->ips32_tmodel) + 1);
+           RegCloseKey(ips32_key);
+           if (res != ERROR_SUCCESS) goto error_close_clsid_key;
+       }
+
+       if (list->progid) {
+           res = register_key_defvalueA(clsid_key, progid_keyname,
+                                        list->progid);
+           if (res != ERROR_SUCCESS) goto error_close_clsid_key;
+
+           res = register_progid(buf, list->progid, NULL,
+                                 list->name, list->progid_extra);
+           if (res != ERROR_SUCCESS) goto error_close_clsid_key;
+       }
+
+       if (list->viprogid) {
+           res = register_key_defvalueA(clsid_key, viprogid_keyname,
+                                        list->viprogid);
+           if (res != ERROR_SUCCESS) goto error_close_clsid_key;
+
+           res = register_progid(buf, list->viprogid, list->progid,
+                                 list->name, list->progid_extra);
+           if (res != ERROR_SUCCESS) goto error_close_clsid_key;
+       }
+
+    error_close_clsid_key:
+       RegCloseKey(clsid_key);
+    }
+
+error_close_coclass_key:
+    RegCloseKey(coclass_key);
+error_return:
+    return res != ERROR_SUCCESS ? HRESULT_FROM_WIN32(res) : S_OK;
+}
+
+/***********************************************************************
+ *             unregister_coclasses
+ */
+static HRESULT unregister_coclasses(struct regsvr_coclass const *list)
+{
+    LONG res = ERROR_SUCCESS;
+    HKEY coclass_key;
+
+    res = RegOpenKeyExW(HKEY_CLASSES_ROOT, clsid_keyname, 0,
+                       KEY_READ | KEY_WRITE, &coclass_key);
+    if (res == ERROR_FILE_NOT_FOUND) return S_OK;
+    if (res != ERROR_SUCCESS) goto error_return;
+
+    for (; res == ERROR_SUCCESS && list->clsid; ++list) {
+       WCHAR buf[39];
+
+       StringFromGUID2(list->clsid, buf, 39);
+       res = RegDeleteTreeW(coclass_key, buf);
+       if (res == ERROR_FILE_NOT_FOUND) res = ERROR_SUCCESS;
+       if (res != ERROR_SUCCESS) goto error_close_coclass_key;
+
+       if (list->progid) {
+           res = RegDeleteTreeA(HKEY_CLASSES_ROOT, list->progid);
+           if (res == ERROR_FILE_NOT_FOUND) res = ERROR_SUCCESS;
+           if (res != ERROR_SUCCESS) goto error_close_coclass_key;
+       }
+
+       if (list->viprogid) {
+           res = RegDeleteTreeA(HKEY_CLASSES_ROOT, list->viprogid);
+           if (res == ERROR_FILE_NOT_FOUND) res = ERROR_SUCCESS;
+           if (res != ERROR_SUCCESS) goto error_close_coclass_key;
+       }
+    }
+
+error_close_coclass_key:
+    RegCloseKey(coclass_key);
+error_return:
+    return res != ERROR_SUCCESS ? HRESULT_FROM_WIN32(res) : S_OK;
+}
+
+/***********************************************************************
+ *             regsvr_key_guid
+ */
+static LONG register_key_guid(HKEY base, WCHAR const *name, GUID const *guid)
+{
+    WCHAR buf[39];
+
+    StringFromGUID2(guid, buf, 39);
+    return register_key_defvalueW(base, name, buf);
+}
+
+/***********************************************************************
+ *             regsvr_key_defvalueW
+ */
+static LONG register_key_defvalueW(
+    HKEY base,
+    WCHAR const *name,
+    WCHAR const *value)
+{
+    LONG res;
+    HKEY key;
+
+    res = RegCreateKeyExW(base, name, 0, NULL, 0,
+                         KEY_READ | KEY_WRITE, NULL, &key, NULL);
+    if (res != ERROR_SUCCESS) return res;
+    res = RegSetValueExW(key, NULL, 0, REG_SZ, (CONST BYTE*)value,
+                        (lstrlenW(value) + 1) * sizeof(WCHAR));
+    RegCloseKey(key);
+    return res;
+}
+
+/***********************************************************************
+ *             regsvr_key_defvalueA
+ */
+static LONG register_key_defvalueA(
+    HKEY base,
+    WCHAR const *name,
+    char const *value)
+{
+    LONG res;
+    HKEY key;
+
+    res = RegCreateKeyExW(base, name, 0, NULL, 0,
+                         KEY_READ | KEY_WRITE, NULL, &key, NULL);
+    if (res != ERROR_SUCCESS) return res;
+    res = RegSetValueExA(key, NULL, 0, REG_SZ, (CONST BYTE*)value,
+                        lstrlenA(value) + 1);
+    RegCloseKey(key);
+    return res;
+}
+
+/***********************************************************************
+ *             regsvr_progid
+ */
+static LONG register_progid(
+    WCHAR const *clsid,
+    char const *progid,
+    char const *curver_progid,
+    char const *name,
+    char const *extra)
+{
+    LONG res;
+    HKEY progid_key;
+
+    res = RegCreateKeyExA(HKEY_CLASSES_ROOT, progid, 0,
+                         NULL, 0, KEY_READ | KEY_WRITE, NULL,
+                         &progid_key, NULL);
+    if (res != ERROR_SUCCESS) return res;
+
+    if (name) {
+       res = RegSetValueExA(progid_key, NULL, 0, REG_SZ,
+                            (CONST BYTE*)name, strlen(name) + 1);
+       if (res != ERROR_SUCCESS) goto error_close_progid_key;
+    }
+
+    if (clsid) {
+       res = register_key_defvalueW(progid_key, clsid_keyname, clsid);
+       if (res != ERROR_SUCCESS) goto error_close_progid_key;
+    }
+
+    if (curver_progid) {
+       res = register_key_defvalueA(progid_key, curver_keyname,
+                                    curver_progid);
+       if (res != ERROR_SUCCESS) goto error_close_progid_key;
+    }
+
+    if (extra) {
+       HKEY extra_key;
+
+       res = RegCreateKeyExA(progid_key, extra, 0,
+                             NULL, 0, KEY_READ | KEY_WRITE, NULL,
+                             &extra_key, NULL);
+       if (res == ERROR_SUCCESS)
+           RegCloseKey(extra_key);
+    }
+
+error_close_progid_key:
+    RegCloseKey(progid_key);
+    return res;
+}
+
+/***********************************************************************
+ *             coclass list
+ */
+static struct regsvr_coclass const coclass_list[] = {
+    {
+        &CLSID_TF_ThreadMgr,
+        "TF_ThreadMgr",
+        NULL,
+        "msctf.dll",
+        "Apartment"
+    },
+    {
+        &CLSID_TF_InputProcessorProfiles,
+        "TF_InputProcessorProfiles",
+        NULL,
+        "msctf.dll",
+        "Apartment"
+    },
+    {
+        &CLSID_TF_CategoryMgr,
+        "TF_CategoryMgr",
+        NULL,
+        "msctf.dll",
+        "Apartment"
+    },
+    { NULL }                   /* list terminator */
+};
+
+/***********************************************************************
+ *             interface list
+ */
+
+static struct regsvr_interface const interface_list[] = {
+    { NULL }                   /* list terminator */
+};
+
+/***********************************************************************
+ *             DllRegisterServer (HHCTRL.@)
+ */
+HRESULT WINAPI DllRegisterServer(void)
+{
+    HRESULT hr;
+
+    TRACE("\n");
+
+    hr = register_coclasses(coclass_list);
+    if (SUCCEEDED(hr))
+       hr = register_interfaces(interface_list);
+    return hr;
+}
+
+/***********************************************************************
+ *             DllUnregisterServer (HHCTRL.@)
+ */
+HRESULT WINAPI DllUnregisterServer(void)
+{
+    HRESULT hr;
+
+    TRACE("\n");
+
+    hr = unregister_coclasses(coclass_list);
+    if (SUCCEEDED(hr))
+       hr = unregister_interfaces(interface_list);
+    return hr;
+}
diff --git a/reactos/dll/win32/msctf/threadmgr.c b/reactos/dll/win32/msctf/threadmgr.c
new file mode 100644 (file)
index 0000000..76c1fd6
--- /dev/null
@@ -0,0 +1,309 @@
+/*
+ *  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 "wine/unicode.h"
+
+#include "msctf.h"
+#include "msctf_internal.h"
+
+WINE_DEFAULT_DEBUG_CHANNEL(msctf);
+
+typedef struct tagACLMulti {
+    const ITfThreadMgrVtbl *ThreadMgrVtbl;
+    const ITfSourceVtbl *SourceVtbl;
+    LONG refCount;
+
+    ITfDocumentMgr *focus;
+} ThreadMgr;
+
+static inline ThreadMgr *impl_from_ITfSourceVtbl(ITfSource *iface)
+{
+    return (ThreadMgr *)((char *)iface - FIELD_OFFSET(ThreadMgr,SourceVtbl));
+}
+
+static void ThreadMgr_Destructor(ThreadMgr *This)
+{
+    TlsSetValue(tlsIndex,NULL);
+    TRACE("destroying %p\n", This);
+    if (This->focus)
+        ITfDocumentMgr_Release(This->focus);
+    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;
+    }
+
+    if (*ppvOut)
+    {
+        IUnknown_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;
+    FIXME("STUB:(%p)\n",This);
+    return E_NOTIMPL;
+}
+
+static HRESULT WINAPI ThreadMgr_fnDeactivate( ITfThreadMgr* iface)
+{
+    ThreadMgr *This = (ThreadMgr *)iface;
+    FIXME("STUB:(%p)\n",This);
+    return E_NOTIMPL;
+}
+
+static HRESULT WINAPI ThreadMgr_CreateDocumentMgr( ITfThreadMgr* iface, ITfDocumentMgr
+**ppdim)
+{
+    TRACE("(%p)\n",iface);
+    return DocumentMgr_Constructor(ppdim);
+}
+
+static HRESULT WINAPI ThreadMgr_EnumDocumentMgrs( ITfThreadMgr* iface, IEnumTfDocumentMgrs
+**ppEnum)
+{
+    ThreadMgr *This = (ThreadMgr *)iface;
+    FIXME("STUB:(%p)\n",This);
+    return E_NOTIMPL;
+}
+
+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 || FAILED(IUnknown_QueryInterface(pdimFocus,&IID_ITfDocumentMgr,(LPVOID*) &check)))
+        return E_INVALIDARG;
+
+    if (This->focus)
+        ITfDocumentMgr_Release(This->focus);
+
+    This->focus = check;
+    return S_OK;
+}
+
+static HRESULT WINAPI ThreadMgr_AssociateFocus( ITfThreadMgr* iface, HWND hwnd,
+ITfDocumentMgr *pdimNew, ITfDocumentMgr **ppdimPrev)
+{
+    ThreadMgr *This = (ThreadMgr *)iface;
+    FIXME("STUB:(%p)\n",This);
+    return E_NOTIMPL;
+}
+
+static HRESULT WINAPI ThreadMgr_IsThreadFocus( ITfThreadMgr* iface, BOOL *pfThreadFocus)
+{
+    ThreadMgr *This = (ThreadMgr *)iface;
+    FIXME("STUB:(%p)\n",This);
+    return E_NOTIMPL;
+}
+
+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;
+    FIXME("STUB:(%p)\n",This);
+    return E_NOTIMPL;
+}
+
+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 WINAPI HRESULT ThreadMgrSource_AdviseSink(ITfSource *iface,
+        REFIID riid, IUnknown *punk, DWORD *pdwCookie)
+{
+    ThreadMgr *This = impl_from_ITfSourceVtbl(iface);
+    FIXME("STUB:(%p)\n",This);
+    return E_NOTIMPL;
+}
+
+static WINAPI HRESULT ThreadMgrSource_UnadviseSink(ITfSource *iface, DWORD pdwCookie)
+{
+    ThreadMgr *This = impl_from_ITfSourceVtbl(iface);
+    FIXME("STUB:(%p)\n",This);
+    return E_NOTIMPL;
+}
+
+static const ITfSourceVtbl ThreadMgr_SourceVtbl =
+{
+    Source_QueryInterface,
+    Source_AddRef,
+    Source_Release,
+
+    ThreadMgrSource_AdviseSink,
+    ThreadMgrSource_UnadviseSink,
+};
+
+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->refCount = 1;
+    TlsSetValue(tlsIndex,This);
+
+    TRACE("returning %p\n", This);
+    *ppOut = (IUnknown *)This;
+    return S_OK;
+}
index f8d4f00..5bc9c67 100644 (file)
 <directory name="mscoree">
        <xi:include href="mscoree/mscoree.rbuild" />
 </directory>
+<directory name="msctf">
+       <xi:include href="msctf/msctf.rbuild" />
+</directory>
 <directory name="msftedit">
        <xi:include href="msftedit/msftedit.rbuild" />
 </directory>
diff --git a/reactos/include/psdk/msctf.idl b/reactos/include/psdk/msctf.idl
new file mode 100644 (file)
index 0000000..6a488cb
--- /dev/null
@@ -0,0 +1,478 @@
+/*
+ * 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
+ */
+
+#ifndef DO_NO_IMPORTS
+import "oaidl.idl";
+import "comcat.idl";
+import "textstor.idl";
+/* import "ctfutb.idl"; */
+#endif
+
+/* FIXME: LANGID is defined in winnt.h and mlang.h in the platform SDK */
+cpp_quote("#ifndef _WINNT_H")
+typedef WORD LANGID;
+cpp_quote("#endif")
+
+cpp_quote("#define TF_E_STACKFULL MAKE_HRESULT(SEVERITY_ERROR, FACILITY_ITF, 0x0501)")
+cpp_quote("EXTERN_C const CLSID CLSID_TF_ThreadMgr;")
+cpp_quote("EXTERN_C const CLSID CLSID_TF_InputProcessorProfiles;")
+cpp_quote("EXTERN_C const CLSID CLSID_TF_CategoryMgr;")
+
+/* GUIDs for Categories */
+cpp_quote("EXTERN_C const GUID GUID_TFCAT_TIP_KEYBOARD;")
+cpp_quote("EXTERN_C const GUID GUID_TFCAT_TIP_SPEECH;")
+cpp_quote("EXTERN_C const GUID GUID_TFCAT_TIP_HANDWRITING;")
+cpp_quote("EXTERN_C const GUID GUID_TFCAT_DISPLAYATTRIBUTEPROVIDER;")
+
+typedef [uuid(7213778c-7bb0-4270-b050-6189ee594e97)]  DWORD TfEditCookie;
+typedef [uuid(de403c21-89fd-4f85-8b87-64584d063fbc)] DWORD TfClientId;
+typedef [uuid(88a9c478-f3ec-4763-8345-cd9250443f8d)] DWORD TfGuidAtom;
+
+interface ITfDocumentMgr;
+interface ITfContext;
+interface IEnumTfDocumentMgrs;
+interface IEnumTfContexts;
+interface ITfFunctionProvider;
+interface IEnumTfFunctionProviders;
+interface ITfCompartmentMgr;
+interface ITfEditSession;
+interface ITfRange;
+interface ITfContextView;
+interface IEnumTfContextViews;
+interface ITfProperty;
+interface ITfReadOnlyProperty;
+interface IEnumTfProperties;
+interface ITfRangeBackup;
+interface IEnumTfLanguageProfiles;
+interface ITfEditRecord;
+interface ITfCompositionView;
+
+typedef [uuid(e1b5808d-1e46-4c19-84dc-68c5f5978cc8)] struct TF_LANGUAGEPROFILE
+{
+    CLSID clsid;
+    LANGID langid;
+    GUID catid;
+    BOOL fActive;
+    GUID guidProfile;
+} TF_LANGUAGEPROFILE;
+
+[
+    object,
+    uuid(aa80e801-2021-11d2-93e0-0060b067b86e),
+    pointer_default(unique)
+]
+interface ITfThreadMgr: IUnknown
+{
+    HRESULT Activate(
+        [out] TfClientId *ptid);
+
+    HRESULT Deactivate();
+
+    HRESULT CreateDocumentMgr(
+        [out] ITfDocumentMgr **ppdim);
+
+    HRESULT EnumDocumentMgrs(
+        [out] IEnumTfDocumentMgrs **ppEnum);
+
+    HRESULT GetFocus(
+        [out] ITfDocumentMgr **ppdimFocus);
+
+    HRESULT SetFocus(
+        [in] ITfDocumentMgr *pdimFocus);
+
+    HRESULT AssociateFocus(
+        [in] HWND hwnd,
+        [in, unique] ITfDocumentMgr *pdimNew,
+        [out] ITfDocumentMgr **ppdimPrev);
+
+    HRESULT IsThreadFocus(
+        [out] BOOL *pfThreadFocus);
+
+    HRESULT GetFunctionProvider(
+        [in] REFCLSID clsid,
+        [out] ITfFunctionProvider **ppFuncProv);
+
+    HRESULT EnumFunctionProviders(
+        [out] IEnumTfFunctionProviders **ppEnum);
+
+    HRESULT GetGlobalCompartment(
+        [out] ITfCompartmentMgr **ppCompMgr);
+};
+
+
+[
+    object,
+    uuid(aa80e7f4-2021-11d2-93e0-0060b067b86e),
+    pointer_default(unique)
+]
+interface ITfDocumentMgr: IUnknown
+{
+    HRESULT CreateContext(
+        [in] TfClientId tidOwner,
+        [in] DWORD dwFlags,
+        [in, unique] IUnknown *punk,
+        [out] ITfContext **ppic,
+        [out] TfEditCookie *pecTextStore);
+
+    HRESULT Push(
+        [in] ITfContext *pic);
+
+    const DWORD TF_POPF_ALL = 0x0001;
+
+    HRESULT Pop(
+        [in] DWORD dwFlags);
+
+    HRESULT GetTop(
+        [out] ITfContext **ppic);
+
+    HRESULT GetBase(
+        [out] ITfContext **ppic);
+
+    HRESULT EnumContexts(
+        [out] IEnumTfContexts **ppEnum);
+};
+
+[
+    object,
+    uuid(aa80e7fd-2021-11d2-93e0-0060b067b86e),
+    pointer_default(unique)
+]
+interface ITfContext : IUnknown
+{
+    const DWORD TF_ES_ASYNCDONTCARE = 0x0;
+    const DWORD TF_ES_SYNC          = 0x1;
+    const DWORD TF_ES_READ          = 0x2;
+    const DWORD TF_ES_READWRITE     = 0x6;
+    const DWORD TF_ES_ASYNC         = 0x8;
+
+    HRESULT RequestEditSession(
+        [in] TfClientId tid,
+        [in] ITfEditSession *pes,
+        [in] DWORD dwFlags,
+        [out] HRESULT *phrSession);
+
+    HRESULT InWriteSession(
+        [in] TfClientId tid,
+        [out] BOOL *pfWriteSession);
+
+    typedef [uuid(1690be9b-d3e9-49f6-8d8b-51b905af4c43)] enum { TF_AE_NONE, TF_AE_START, TF_AE_END } TfActiveSelEnd;
+
+    typedef [uuid(36ae42a4-6989-4bdc-b48a-6137b7bf2e42)] struct TF_SELECTIONSTYLE
+    {
+        TfActiveSelEnd ase;
+        BOOL fInterimChar;
+    } TF_SELECTIONSTYLE;
+
+    typedef [uuid(75eb22f2-b0bf-46a8-8006-975a3b6efcf1)] struct TF_SELECTION
+    {
+        ITfRange *range;
+        TF_SELECTIONSTYLE style;
+    } TF_SELECTION;
+
+    const ULONG TF_DEFAULT_SELECTION =  TS_DEFAULT_SELECTION;
+
+    HRESULT GetSelection(
+        [in] TfEditCookie ec,
+        [in] ULONG ulIndex,
+        [in] ULONG ulCount,
+        [out, size_is(ulCount), length_is(*pcFetched)] TF_SELECTION *pSelection,
+        [out] ULONG *pcFetched);
+
+    HRESULT SetSelection(
+        [in] TfEditCookie ec,
+        [in] ULONG ulCount,
+        [in, size_is(ulCount)] const TF_SELECTION *pSelection);
+
+    HRESULT GetStart(
+        [in] TfEditCookie ec,
+        [out] ITfRange **ppStart);
+
+    HRESULT GetEnd(
+        [in] TfEditCookie ec,
+        [out] ITfRange **ppEnd);
+
+    typedef [uuid(bc7d979a-846a-444d-afef-0a9bfa82b961)] TS_STATUS TF_STATUS;
+    const DWORD TF_SD_READONLY    = TS_SD_READONLY;
+    const DWORD TF_SD_LOADING     = TS_SD_LOADING;
+    const DWORD TF_SS_DISJOINTSEL = TS_SS_DISJOINTSEL;
+    const DWORD TF_SS_REGIONS     = TS_SS_REGIONS;
+    const DWORD TF_SS_TRANSITORY  = TS_SS_TRANSITORY;
+
+
+    HRESULT GetActiveView(
+        [out] ITfContextView **ppView);
+
+    HRESULT EnumViews(
+        [out] IEnumTfContextViews **ppEnum);
+
+    HRESULT GetStatus(
+        [out] TF_STATUS *pdcs);
+
+    HRESULT GetProperty(
+        [in] REFGUID guidProp,
+        [out] ITfProperty **ppProp);
+
+    HRESULT GetAppProperty(
+        [in] REFGUID guidProp,
+        [out] ITfReadOnlyProperty **ppProp);
+
+    HRESULT TrackProperties(
+        [in, size_is(cProp)] const GUID **prgProp,
+        [in] ULONG cProp,
+        [in, size_is(cAppProp)] const GUID **prgAppProp,
+        [in] ULONG cAppProp,
+        [out] ITfReadOnlyProperty **ppProperty);
+
+    HRESULT EnumProperties(
+        [out] IEnumTfProperties **ppEnum);
+
+    HRESULT GetDocumentMgr(
+        [out] ITfDocumentMgr **ppDm);
+
+    HRESULT CreateRangeBackup(
+        [in] TfEditCookie ec,
+        [in] ITfRange *pRange,
+        [out] ITfRangeBackup **ppBackup);
+
+};
+
+[
+  object,
+  uuid(4ea48a35-60ae-446f-8fd6-e6a8d82459f7),
+  pointer_default(unique)
+]
+interface ITfSource : IUnknown
+{
+    HRESULT AdviseSink(
+        [in] REFIID riid,
+        [in, iid_is(riid)] IUnknown *punk,
+        [out] DWORD *pdwCookie);
+
+    HRESULT UnadviseSink(
+        [in] DWORD dwCookie);
+};
+
+[
+  object,
+  local,
+  uuid(1F02B6C5-7842-4EE6-8A0B-9A24183A95CA),
+  pointer_default(unique)
+]
+interface ITfInputProcessorProfiles : IUnknown
+{
+    HRESULT Register(
+        [in] REFCLSID rclsid);
+
+    HRESULT Unregister(
+        [in] REFCLSID rclsid);
+
+    HRESULT AddLanguageProfile(
+        [in] REFCLSID rclsid,
+        [in] LANGID langid,
+        [in] REFGUID guidProfile,
+        [in, size_is(cchDesc)] const WCHAR *pchDesc,
+        [in] ULONG cchDesc,
+        [in, size_is(cchFile)] const WCHAR *pchIconFile,
+        [in] ULONG cchFile,
+        [in] ULONG uIconIndex);
+
+    HRESULT RemoveLanguageProfile(
+        [in] REFCLSID rclsid,
+        [in] LANGID langid,
+        [in] REFGUID guidProfile);
+
+    HRESULT EnumInputProcessorInfo(
+        [out] IEnumGUID **ppEnum);
+
+    HRESULT GetDefaultLanguageProfile(
+        [in] LANGID langid,
+        [in] REFGUID catid,
+        [out] CLSID *pclsid,
+        [out] GUID *pguidProfile);
+
+    HRESULT SetDefaultLanguageProfile(
+        [in] LANGID langid,
+        [in] REFCLSID rclsid,
+        [in] REFGUID guidProfiles);
+
+    HRESULT ActivateLanguageProfile(
+        [in] REFCLSID rclsid,
+        [in] LANGID langid,
+        [in] REFGUID guidProfiles);
+
+    HRESULT GetActiveLanguageProfile(
+        [in] REFCLSID rclsid,
+        [out] LANGID *plangid,
+        [out] GUID *pguidProfile);
+
+    HRESULT GetLanguageProfileDescription(
+        [in] REFCLSID rclsid,
+        [in] LANGID langid,
+        [in] REFGUID guidProfile,
+        [out] BSTR *pbstrProfile);
+
+    HRESULT GetCurrentLanguage(
+        [out] LANGID *plangid);
+
+    HRESULT ChangeCurrentLanguage(
+        [in] LANGID langid);
+
+    HRESULT GetLanguageList(
+        [out] LANGID **ppLangId,
+        [out] ULONG *pulCount);
+
+    HRESULT EnumLanguageProfiles(
+        [in] LANGID langid,
+        [out] IEnumTfLanguageProfiles **ppEnum);
+
+    HRESULT EnableLanguageProfile(
+        [in] REFCLSID rclsid,
+        [in] LANGID langid,
+        [in] REFGUID guidProfile,
+        [in] BOOL fEnable);
+
+    HRESULT IsEnabledLanguageProfile(
+        [in] REFCLSID rclsid,
+        [in] LANGID langid,
+        [in] REFGUID guidProfile,
+        [out] BOOL *pfEnable);
+
+    HRESULT EnableLanguageProfileByDefault(
+        [in] REFCLSID rclsid,
+        [in] LANGID langid,
+        [in] REFGUID guidProfile,
+        [in] BOOL fEnable);
+
+    HRESULT SubstituteKeyboardLayout(
+        [in] REFCLSID rclsid,
+        [in] LANGID langid,
+        [in] REFGUID guidProfile,
+        [in] HKL hKL);
+};
+
+[
+  object,
+  local,
+  uuid(c3acefb5-f69d-4905-938f-fcadcf4be830),
+  pointer_default(unique)
+]
+interface ITfCategoryMgr : IUnknown
+{
+    HRESULT RegisterCategory([in] REFCLSID rclsid,
+                             [in] REFGUID rcatid,
+                             [in] REFGUID rguid);
+
+    HRESULT UnregisterCategory([in] REFCLSID rclsid,
+                               [in] REFGUID rcatid,
+                               [in] REFGUID rguid);
+
+    HRESULT EnumCategoriesInItem([in] REFGUID rguid,
+                                 [out] IEnumGUID **ppEnum);
+
+    HRESULT EnumItemsInCategory([in] REFGUID rcatid,
+                                [out] IEnumGUID **ppEnum);
+
+    HRESULT FindClosestCategory([in] REFGUID rguid,
+                                [out] GUID *pcatid,
+                                [in, size_is(ulCount)] const GUID **ppcatidList,
+                                [in] ULONG ulCount);
+
+    HRESULT RegisterGUIDDescription([in] REFCLSID rclsid,
+                                    [in] REFGUID rguid,
+                                    [in, size_is(cch)] const WCHAR *pchDesc,
+                                    [in] ULONG cch);
+
+    HRESULT UnregisterGUIDDescription([in] REFCLSID rclsid,
+                                      [in] REFGUID rguid);
+
+    HRESULT GetGUIDDescription([in] REFGUID rguid,
+                               [out] BSTR *pbstrDesc);
+
+    HRESULT RegisterGUIDDWORD([in] REFCLSID rclsid,
+                              [in] REFGUID rguid,
+                              [in] DWORD dw);
+
+    HRESULT UnregisterGUIDDWORD([in] REFCLSID rclsid,
+                                [in] REFGUID rguid);
+
+    HRESULT GetGUIDDWORD([in] REFGUID rguid,
+                         [out] DWORD *pdw);
+
+    HRESULT RegisterGUID([in] REFGUID rguid,
+                         [out] TfGuidAtom *pguidatom);
+
+    HRESULT GetGUID([in] TfGuidAtom guidatom,
+                    [out] GUID *pguid);
+
+    HRESULT IsEqualTfGuidAtom([in] TfGuidAtom guidatom,
+                              [in] REFGUID rguid,
+                              [out] BOOL *pfEqual);
+};
+
+[
+  object,
+  uuid(8127d409-ccd3-4683-967a-b43d5b482bf7),
+  pointer_default(unique)
+]
+interface ITfTextEditSink : IUnknown
+{
+    HRESULT OnEndEdit(
+        [in] ITfContext *pic,
+        [in] TfEditCookie ecReadOnly,
+        [in] ITfEditRecord *pEditRecord);
+};
+
+[
+    object,
+    uuid(5F20AA40-B57A-4F34-96AB-3576F377CC79),
+    pointer_default(unique)
+]
+interface ITfContextOwnerCompositionSink : IUnknown
+{
+    HRESULT OnStartComposition(
+        [in] ITfCompositionView *pComposition,
+        [out] BOOL *pfOk);
+
+    HRESULT OnUpdateComposition(
+        [in] ITfCompositionView *pComposition,
+        [in] ITfRange *pRangeNew);
+
+    HRESULT OnEndComposition(
+        [in] ITfCompositionView *pComposition);
+};
+
+[
+  object,
+  uuid(3d61bf11-ac5f-42c8-a4cb-931bcc28c744),
+  pointer_default(unique)
+]
+interface IEnumTfLanguageProfiles : IUnknown
+{
+    HRESULT Clone(
+        [out] IEnumTfLanguageProfiles **ppEnum);
+
+    HRESULT Next(
+        [in] ULONG ulCount,
+        [out, size_is(ulCount), length_is(*pcFetch)] TF_LANGUAGEPROFILE *pProfile,
+        [out] ULONG *pcFetch);
+
+    HRESULT Reset();
+
+    HRESULT Skip(
+        [in] ULONG ulCount);
+};
index 9b57f3a..9a62691 100644 (file)
@@ -21,6 +21,7 @@
        <file>indexsrv.idl</file>
        <file>mimeinfo.idl</file>
        <file>mlang.idl</file>
+       <file>msctf.idl</file>
        <file>mshtml.idl</file>
        <file>mstask.idl</file>
        <file>msxml.idl</file>
@@ -43,6 +44,7 @@
        <file>shobjidl.idl</file>
        <file>shtypes.idl</file>
        <file>strmif.idl</file>
+       <file>textstor.idl</file>
        <file>tom.idl</file>
        <file>unknwn.idl</file>
        <file>urlhist.idl</file>
diff --git a/reactos/include/psdk/textstor.idl b/reactos/include/psdk/textstor.idl
new file mode 100644 (file)
index 0000000..08ee21d
--- /dev/null
@@ -0,0 +1,277 @@
+/*
+ * Copyright 2009 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
+ */
+
+#ifndef DO_NO_IMPORTS
+import "oaidl.idl";
+#endif
+
+const ULONG TS_DEFAULT_SELECTION = ~0u;
+
+const DWORD TS_SD_READONLY     = 0x001;
+const DWORD TS_SD_LOADING      = 0x002;
+
+const DWORD TS_SS_DISJOINTSEL  = 0x001;
+const DWORD TS_SS_REGIONS      = 0x002;
+const DWORD TS_SS_TRANSITORY   = 0x004;
+const DWORD TS_SS_NOHIDDENTEXT = 0x008;
+
+const DWORD TS_AS_TEXT_CHANGE      = 0x01;
+const DWORD TS_AS_SEL_CHANGE       = 0x02;
+const DWORD TS_AS_LAYOUT_CHANGE    = 0x04;
+const DWORD TS_AS_ATTR_CHANGE      = 0x08;
+const DWORD TS_AS_STATUS_CHANGE    = 0x10;
+
+const DWORD TS_AS_ALL_SINKS = (TS_AS_TEXT_CHANGE | TS_AS_SEL_CHANGE | TS_AS_LAYOUT_CHANGE | TS_AS_ATTR_CHANGE | TS_AS_STATUS_CHANGE);
+
+
+typedef [uuid(05fcf85b-5e9c-4c3e-ab71-29471d4f38e7)]  enum { TS_AE_NONE, TS_AE_START, TS_AE_END } TsActiveSelEnd;
+typedef [uuid(033b0df0-f193-4170-b47b-141afc247878)]  enum { TS_RT_PLAIN, TS_RT_HIDDEN, TS_RT_OPAQUE } TsRunType;
+typedef [uuid(ef3457d9-8446-49a7-a9e6-b50d9d5f3fd9)]  GUID TS_ATTRID;
+
+typedef [uuid(fec4f516-c503-45b1-a5fd-7a3d8ab07049)] struct TS_STATUS
+{
+    DWORD dwDynamicFlags;
+    DWORD dwStaticFlags;
+} TS_STATUS;
+
+typedef [uuid(f3181bd6-bcf0-41d3-a81c-474b17ec38fb)]  struct TS_TEXTCHANGE
+{
+    LONG acpStart;
+    LONG acpOldEnd;
+    LONG acpNewEnd;
+} TS_TEXTCHANGE;
+
+typedef [uuid(7ecc3ffa-8f73-4d91-98ed-76f8ac5b1600)]  struct TS_SELECTIONSTYLE
+{
+    TsActiveSelEnd ase;
+    BOOL fInterimChar;
+} TS_SELECTIONSTYLE;
+
+typedef [uuid(c4b9c33b-8a0d-4426-bebe-d444a4701fe9)]  struct TS_SELECTION_ACP
+{
+    LONG acpStart;
+    LONG acpEnd;
+    TS_SELECTIONSTYLE style;
+} TS_SELECTION_ACP;
+
+typedef [uuid(a6231949-37c5-4b74-a24e-2a26c327201d)]  struct TS_RUNINFO
+{
+    ULONG uCount;
+    TsRunType type;
+} TS_RUNINFO;
+
+typedef [uuid(2cc2b33f-1174-4507-b8d9-5bc0eb37c197)]  struct TS_ATTRVAL
+{
+    TS_ATTRID idAttr;
+    DWORD dwOverlapId;
+    VARIANT varValue;
+} TS_ATTRVAL;
+
+typedef [uuid(7899d7c4-5f07-493c-a89a-fac8e777f476)]  enum { TS_LC_CREATE, TS_LC_CHANGE, TS_LC_DESTROY } TsLayoutCode;
+typedef [uuid(1faf509e-44c1-458e-950a-38a96705a62b)]  DWORD TsViewCookie;
+
+[
+  object,
+  uuid(22d44c94-a419-4542-a272-ae26093ececf),
+  pointer_default(unique)
+]
+interface ITextStoreACPSink : IUnknown
+{
+    HRESULT OnTextChange(
+        [in] DWORD dwFlags,
+        [in] const TS_TEXTCHANGE *pChange);
+
+    HRESULT OnSelectionChange();
+
+    HRESULT OnLayoutChange(
+        [in] TsLayoutCode lcode,
+        [in] TsViewCookie vcView);
+
+    HRESULT OnStatusChange(
+        [in] DWORD dwFlags);
+
+    HRESULT OnAttrsChange(
+        [in] LONG acpStart,
+        [in] LONG acpEnd,
+        [in] ULONG cAttrs,
+        [in, size_is(cAttrs)] const TS_ATTRID *paAttrs);
+
+    HRESULT OnLockGranted(
+        [in] DWORD dwLockFlags);
+
+    HRESULT OnStartEditTransaction();
+
+    HRESULT OnEndEditTransaction();
+};
+
+[
+  object,
+  uuid(28888fe3-c2a0-483a-a3ea-8cb1ce51ff3d),
+  pointer_default(unique)
+]
+interface ITextStoreACP : IUnknown
+{
+    HRESULT AdviseSink(
+        [in] REFIID riid,
+        [in, iid_is(riid)] IUnknown *punk,
+        [in] DWORD dwMask);
+
+    HRESULT UnadviseSink(
+        [in] IUnknown *punk);
+
+    HRESULT RequestLock(
+        [in] DWORD dwLockFlags,
+        [out] HRESULT *phrSession);
+
+    HRESULT GetStatus(
+        [out] TS_STATUS *pdcs);
+
+    HRESULT QueryInsert(
+        [in] LONG acpTestStart,
+        [in] LONG acpTestEnd,
+        [in] ULONG cch,
+        [out] LONG *pacpResultStart,
+        [out] LONG *pacpResultEnd);
+
+    HRESULT GetSelection(
+        [in] ULONG ulIndex,
+        [in] ULONG ulCount,
+        [out, size_is(ulCount), length_is(*pcFetched)] TS_SELECTION_ACP *pSelection,
+        [out] ULONG *pcFetched);
+
+    HRESULT SetSelection(
+        [in] ULONG ulCount,
+        [in, size_is(ulCount)] const TS_SELECTION_ACP *pSelection);
+
+    HRESULT GetText(
+        [in] LONG acpStart,
+        [in] LONG acpEnd,
+        [out, size_is(cchPlainReq), length_is(*pcchPlainRet)] WCHAR *pchPlain,
+        [in] ULONG cchPlainReq,
+        [out] ULONG *pcchPlainRet,
+        [out, size_is(cRunInfoReq), length_is(*pcRunInfoRet)] TS_RUNINFO *prgRunInfo,
+        [in] ULONG cRunInfoReq,
+        [out] ULONG *pcRunInfoRet,
+        [out] LONG *pacpNext);
+
+    HRESULT SetText(
+        [in] DWORD dwFlags,
+        [in] LONG acpStart,
+        [in] LONG acpEnd,
+        [in, size_is(cch)] const WCHAR *pchText,
+        [in] ULONG cch,
+        [out] TS_TEXTCHANGE *pChange);
+
+    HRESULT GetFormattedText(
+        [in] LONG acpStart,
+        [in] LONG acpEnd,
+        [out] IDataObject **ppDataObject);
+
+    HRESULT GetEmbedded(
+        [in] LONG acpPos,
+        [in] REFGUID rguidService,
+        [in] REFIID riid,
+        [out, iid_is(riid)] IUnknown **ppunk);
+
+    HRESULT QueryInsertEmbedded(
+        [in] const GUID *pguidService,
+        [in] const FORMATETC *pFormatEtc,
+        [out] BOOL *pfInsertable);
+
+    HRESULT InsertEmbedded(
+        [in] DWORD dwFlags,
+        [in] LONG acpStart,
+        [in] LONG acpEnd,
+        [in] IDataObject *pDataObject,
+        [out] TS_TEXTCHANGE *pChange);
+
+
+    HRESULT InsertTextAtSelection(
+        [in] DWORD dwFlags,
+        [in, size_is(cch)] const WCHAR *pchText,
+        [in] ULONG cch,
+        [out] LONG *pacpStart,
+        [out] LONG *pacpEnd,
+        [out] TS_TEXTCHANGE *pChange);
+
+    HRESULT InsertEmbeddedAtSelection(
+        [in] DWORD dwFlags,
+        [in] IDataObject *pDataObject,
+        [out] LONG *pacpStart,
+        [out] LONG *pacpEnd,
+        [out] TS_TEXTCHANGE *pChange);
+
+    HRESULT RequestSupportedAttrs(
+        [in] DWORD dwFlags,
+        [in] ULONG cFilterAttrs,
+        [in, size_is(cFilterAttrs), unique] const TS_ATTRID *paFilterAttrs);
+
+    HRESULT RequestAttrsAtPosition(
+        [in] LONG acpPos,
+        [in] ULONG cFilterAttrs,
+        [in, size_is(cFilterAttrs), unique] const TS_ATTRID *paFilterAttrs,
+        [in] DWORD dwFlags);
+
+    HRESULT RequestAttrsTransitioningAtPosition(
+        [in] LONG acpPos,
+        [in] ULONG cFilterAttrs,
+        [in, size_is(cFilterAttrs), unique] const TS_ATTRID *paFilterAttrs,
+        [in] DWORD dwFlags);
+
+    HRESULT FindNextAttrTransition(
+        [in] LONG acpStart,
+        [in] LONG acpHalt,
+        [in] ULONG cFilterAttrs,
+        [in, size_is(cFilterAttrs), unique] const TS_ATTRID *paFilterAttrs,
+        [in] DWORD dwFlags,
+        [out] LONG *pacpNext,
+        [out] BOOL *pfFound,
+        [out] LONG *plFoundOffset);
+
+    HRESULT RetrieveRequestedAttrs(
+        [in] ULONG ulCount,
+        [out, size_is(ulCount), length_is(*pcFetched)] TS_ATTRVAL *paAttrVals,
+        [out] ULONG *pcFetched);
+
+    HRESULT GetEndACP(
+        [out] LONG *pacp);
+
+    HRESULT GetActiveView(
+        [out] TsViewCookie *pvcView);
+
+    HRESULT GetACPFromPoint(
+        [in] TsViewCookie vcView,
+        [in] const POINT *ptScreen,
+        [in] DWORD dwFlags,
+        [out] LONG *pacp);
+
+    HRESULT GetTextExt(
+        [in] TsViewCookie vcView,
+        [in] LONG acpStart,
+        [in] LONG acpEnd,
+        [out] RECT *prc,
+        [out] BOOL *pfClipped);
+
+    HRESULT GetScreenExt(
+        [in] TsViewCookie vcView,
+        [out] RECT *prc);
+
+    HRESULT GetWnd(
+        [in] TsViewCookie vcView,
+        [out] HWND *phwnd);
+};
index 0b347c8..942189b 100644 (file)
@@ -143,6 +143,9 @@ DEFINE_GUID(CLSID_StdEvent,               0x0000032b,0x0000,0x0000,0xc0,0x00,0x0
 DEFINE_GUID(CLSID_ManualResetEvent,       0x0000032c,0x0000,0x0000,0xc0,0x00,0x00,0x00,0x00,0x00,0x00,0x46);
 DEFINE_GUID(CLSID_SynchronizeContainer,   0x0000032d,0x0000,0x0000,0xc0,0x00,0x00,0x00,0x00,0x00,0x00,0x46);
 DEFINE_GUID(CLSID_InProcFreeMarshaler,    0x0000033a,0x0000,0x0000,0xc0,0x00,0x00,0x00,0x00,0x00,0x00,0x46);
+DEFINE_GUID(CLSID_TF_ThreadMgr,           0x529a9e6b,0x6587,0x4f23,0xab,0x9e,0x9c,0x7d,0x68,0x3e,0x3c,0x50);
+DEFINE_GUID(CLSID_TF_InputProcessorProfiles, 0x33c53a50,0xf456,0x4884,0xb0,0x49,0x85,0xfd,0x64,0x3e,0xcf,0xed);
+DEFINE_GUID(CLSID_TF_CategoryMgr,         0xA4B544A1,0x438D,0x4B41,0x93,0x25,0x86,0x95,0x23,0xE2,0xD6,0xC7);
 DEFINE_GUID(CLSID_ConnectionManager,      0xBA126AD1,0x2166,0x11D1,0xB1,0xD0,0x0,0x80,0x5F,0xC1,0x27,0x0E);
 DEFINE_GUID(CLSID_CNetCfg,                0x5B035261,0x40F9,0x11D1,0xAA,0xEC,0x00,0x80,0x5F,0xC1,0x27,0x0E);
 
index dcd9ec7..3111864 100644 (file)
@@ -69,6 +69,7 @@ reactos/dll/win32/msacm32         # Out of sync
 reactos/dll/win32/mscat32         # Autosync
 reactos/dll/win32/mscms           # Autosync
 reactos/dll/win32/mscoree         # Autosync
+reactos/dll/win32/msctf           # Autosync
 reactos/dll/win32/msftedit        # Autosync
 reactos/dll/win32/mshtml          # Autosync
 reactos/dll/win32/msimg32         # Autosync