[ros-diffs] [dchapyshev] 41065: - Sync msctf, mlang, inetmib1, inetcomm with Wine 1.1.22

dchapyshev at svn.reactos.org dchapyshev at svn.reactos.org
Sat May 23 12:31:02 CEST 2009


Author: dchapyshev
Date: Sat May 23 14:31:01 2009
New Revision: 41065

URL: http://svn.reactos.org/svn/reactos?rev=41065&view=rev
Log:
- Sync msctf, mlang, inetmib1, inetcomm with Wine 1.1.22

Added:
    trunk/reactos/dll/win32/msctf/range.c   (with props)
Modified:
    trunk/reactos/dll/win32/inetcomm/smtptransport.c
    trunk/reactos/dll/win32/inetmib1/main.c
    trunk/reactos/dll/win32/mlang/mlang.c
    trunk/reactos/dll/win32/msctf/context.c
    trunk/reactos/dll/win32/msctf/documentmgr.c
    trunk/reactos/dll/win32/msctf/inputprocessor.c
    trunk/reactos/dll/win32/msctf/msctf.c
    trunk/reactos/dll/win32/msctf/msctf.rbuild
    trunk/reactos/dll/win32/msctf/msctf_internal.h
    trunk/reactos/dll/win32/msctf/threadmgr.c

Modified: trunk/reactos/dll/win32/inetcomm/smtptransport.c
URL: http://svn.reactos.org/svn/reactos/trunk/reactos/dll/win32/inetcomm/smtptransport.c?rev=41065&r1=41064&r2=41065&view=diff
==============================================================================
--- trunk/reactos/dll/win32/inetcomm/smtptransport.c [iso-8859-1] (original)
+++ trunk/reactos/dll/win32/inetcomm/smtptransport.c [iso-8859-1] Sat May 23 14:31:01 2009
@@ -732,7 +732,7 @@
     SMTPTransport *This = (SMTPTransport *)iface;
     const char szCommandFormat[] = "MAIL FROM: <%s>\n";
     char *szCommand;
-    int len = sizeof(szCommandFormat) - 2 /* "%s" */ + strlen(pszEmailFrom);
+    int len;
     HRESULT hr;
 
     TRACE("(%s)\n", debugstr_a(pszEmailFrom));
@@ -740,6 +740,7 @@
     if (!pszEmailFrom)
         return E_INVALIDARG;
 
+    len = sizeof(szCommandFormat) - 2 /* "%s" */ + strlen(pszEmailFrom);
     szCommand = HeapAlloc(GetProcessHeap(), 0, len);
     if (!szCommand)
         return E_OUTOFMEMORY;
@@ -758,7 +759,7 @@
     SMTPTransport *This = (SMTPTransport *)iface;
     const char szCommandFormat[] = "RCPT TO: <%s>\n";
     char *szCommand;
-    int len = sizeof(szCommandFormat) - 2 /* "%s" */ + strlen(pszEmailTo);
+    int len;
     HRESULT hr;
 
     TRACE("(%s)\n", debugstr_a(pszEmailTo));
@@ -766,6 +767,7 @@
     if (!pszEmailTo)
         return E_INVALIDARG;
 
+    len = sizeof(szCommandFormat) - 2 /* "%s" */ + strlen(pszEmailTo);
     szCommand = HeapAlloc(GetProcessHeap(), 0, len);
     if (!szCommand)
         return E_OUTOFMEMORY;
@@ -833,7 +835,7 @@
     SMTPTransport *This = (SMTPTransport *)iface;
     const char szCommandFormat[] = "AUTH %s\n";
     char *szCommand;
-    int len = sizeof(szCommandFormat) - 2 /* "%s" */ + strlen(pszAuthType);
+    int len;
     HRESULT hr;
 
     TRACE("(%s)\n", debugstr_a(pszAuthType));
@@ -841,6 +843,7 @@
     if (!pszAuthType)
         return E_INVALIDARG;
 
+    len = sizeof(szCommandFormat) - 2 /* "%s" */ + strlen(pszAuthType);
     szCommand = HeapAlloc(GetProcessHeap(), 0, len);
     if (!szCommand)
         return E_OUTOFMEMORY;

Modified: trunk/reactos/dll/win32/inetmib1/main.c
URL: http://svn.reactos.org/svn/reactos/trunk/reactos/dll/win32/inetmib1/main.c?rev=41065&r1=41064&r2=41065&view=diff
==============================================================================
--- trunk/reactos/dll/win32/inetmib1/main.c [iso-8859-1] (original)
+++ trunk/reactos/dll/win32/inetmib1/main.c [iso-8859-1] Sat May 23 14:31:01 2009
@@ -143,7 +143,10 @@
 
             copyInt(&pVarBind->value, &numIfs);
             if (bPduType == SNMP_PDU_GETNEXT)
+            {
+                SnmpUtilOidFree(&pVarBind->name);
                 SnmpUtilOidCpy(&pVarBind->name, &numberOid);
+            }
             *pErrorStatus = SNMP_ERRORSTATUS_NOERROR;
         }
         else
@@ -320,7 +323,27 @@
 typedef void (*oidToKeyFunc)(AsnObjectIdentifier *oid, void *dst);
 typedef int (*compareFunc)(const void *key, const void *value);
 
-static UINT findValueInTable(AsnObjectIdentifier *oid,
+/* Finds the first value in the table that matches key.  Returns its 1-based
+ * index if found, or 0 if not found.
+ */
+static UINT findValueInTable(const void *key,
+    struct GenericTable *table, size_t tableEntrySize, compareFunc compare)
+{
+    UINT index = 0;
+    void *value;
+
+    value = bsearch(key, table->entries, table->numEntries, tableEntrySize,
+        compare);
+    if (value)
+        index = ((BYTE *)value - (BYTE *)table->entries) / tableEntrySize + 1;
+    return index;
+}
+
+/* Finds the first value in the table that matches oid, using makeKey to
+ * convert the oid to a key for comparison.  Returns the value's 1-based
+ * index if found, or 0 if not found.
+ */
+static UINT findOidInTable(AsnObjectIdentifier *oid,
     struct GenericTable *table, size_t tableEntrySize, oidToKeyFunc makeKey,
     compareFunc compare)
 {
@@ -329,14 +352,50 @@
 
     if (key)
     {
-        void *value;
-
         makeKey(oid, key);
-        value = bsearch(key, table->entries, table->numEntries, tableEntrySize,
-            compare);
-        if (value)
-            index = ((BYTE *)value - (BYTE *)table->entries) / tableEntrySize
-                + 1;
+        index = findValueInTable(key, table, tableEntrySize, compare);
+        HeapFree(GetProcessHeap(), 0, key);
+    }
+    return index;
+}
+
+/* Finds the first successor to the value in the table that does matches oid,
+ * using makeKey to convert the oid to a key for comparison.  A successor is
+ * a value that does not match oid, so if multiple entries match an oid, only
+ * the first will ever be returned using this method.
+ * Returns the successor's 1-based index if found, or 0 if not found.
+ */
+static UINT findNextOidInTable(AsnObjectIdentifier *oid,
+    struct GenericTable *table, size_t tableEntrySize, oidToKeyFunc makeKey,
+    compareFunc compare)
+{
+    UINT index = 0;
+    void *key = HeapAlloc(GetProcessHeap(), 0, tableEntrySize);
+
+    if (key)
+    {
+        makeKey(oid, key);
+        index = findValueInTable(key, table, tableEntrySize, compare);
+        if (index == 0)
+        {
+            /* Not found in table.  If it's less than the first entry, return
+             * the first index.  Otherwise just return 0 and let the caller
+             * handle finding the successor.
+             */
+            if (compare(key, table->entries) < 0)
+                index = 1;
+        }
+        else
+        {
+            /* Skip any entries that match the same key.  This enumeration will
+             * be incomplete, but it's what Windows appears to do if there are
+             * multiple entries with the same index in a table, and it avoids
+             * an infinite loop.
+             */
+            for (++index; index <= table->numEntries && compare(key,
+                &table->entries[tableEntrySize * index]) == 0; ++index)
+                ;
+        }
         HeapFree(GetProcessHeap(), 0, key);
     }
     return index;
@@ -397,12 +456,12 @@
             }
             else
             {
-                AsnObjectIdentifier ipOid = { instanceLen,
+                AsnObjectIdentifier instanceOid = { instanceLen,
                     oid->ids + base->idLength + 1 };
 
-                *instance = findValueInTable(&ipOid, table, tableEntrySize,
-                    makeKey, compare) + 1;
-                if (*instance > table->numEntries)
+                *instance = findNextOidInTable(&instanceOid, table,
+                    tableEntrySize, makeKey, compare);
+                if (!*instance || *instance > table->numEntries)
                     ret = SNMP_ERRORSTATUS_NOSUCHNAME;
             }
         }
@@ -418,10 +477,10 @@
                 ret = SNMP_ERRORSTATUS_NOSUCHNAME;
             else
             {
-                AsnObjectIdentifier ipOid = { instanceLen,
+                AsnObjectIdentifier instanceOid = { instanceLen,
                     oid->ids + base->idLength + 1 };
 
-                *instance = findValueInTable(&ipOid, table, tableEntrySize,
+                *instance = findOidInTable(&instanceOid, table, tableEntrySize,
                     makeKey, compare);
                 if (!*instance)
                     ret = SNMP_ERRORSTATUS_NOSUCHNAME;
@@ -440,6 +499,7 @@
     AsnObjectIdentifier oid;
     INT ret;
 
+    SnmpUtilOidFree(dst);
     ret = SnmpUtilOidCpy(dst, base);
     if (ret)
     {
@@ -1311,7 +1371,7 @@
                  * so we have to continue until an implementation handles the
                  * query or we exhaust the table of supported OIDs.
                  */
-                for (; error == SNMP_ERRORSTATUS_NOSUCHNAME &&
+                for (matchingIndex++; error == SNMP_ERRORSTATUS_NOSUCHNAME &&
                     matchingIndex < DEFINE_SIZEOF(supportedIDs);
                     matchingIndex++)
                 {

Modified: trunk/reactos/dll/win32/mlang/mlang.c
URL: http://svn.reactos.org/svn/reactos/trunk/reactos/dll/win32/mlang/mlang.c?rev=41065&r1=41064&r2=41065&view=diff
==============================================================================
--- trunk/reactos/dll/win32/mlang/mlang.c [iso-8859-1] (original)
+++ trunk/reactos/dll/win32/mlang/mlang.c [iso-8859-1] Sat May 23 14:31:01 2009
@@ -1939,7 +1939,7 @@
     }
 
     if (pdwCodePages) *pdwCodePages = cps;
-    if (pcchCodePages) *pcchCodePages = i;
+    if (pcchCodePages) *pcchCodePages = min( i + 1, cchSrc );
     return S_OK;
 }
 

Modified: trunk/reactos/dll/win32/msctf/context.c
URL: http://svn.reactos.org/svn/reactos/trunk/reactos/dll/win32/msctf/context.c?rev=41065&r1=41064&r2=41065&view=diff
==============================================================================
--- trunk/reactos/dll/win32/msctf/context.c [iso-8859-1] (original)
+++ trunk/reactos/dll/win32/msctf/context.c [iso-8859-1] Sat May 23 14:31:01 2009
@@ -58,14 +58,24 @@
 typedef struct tagContext {
     const ITfContextVtbl *ContextVtbl;
     const ITfSourceVtbl *SourceVtbl;
+    /* const ITfContextCompositionVtbl *ContextCompositionVtbl; */
+    /* const ITfContextOwnerCompositionServicesVtbl *ContextOwnerCompositionServicesVtbl; */
+    /* const ITfContextOwnerServicesVtbl *ContextOwnerServicesVtbl; */
+    /* const ITfInsertAtSelectionVtbl *InsertAtSelectionVtbl; */
+    /* const ITfMouseTrackerVtbl *MouseTrackerVtbl; */
+    /* const ITfQueryEmbeddedVtbl *QueryEmbeddedVtbl; */
+    /* const ITfSourceSingleVtbl *SourceSingleVtbl; */
     LONG refCount;
+    BOOL connected;
 
     TfClientId tidOwner;
+    TfEditCookie defaultCookie;
 
     ITextStoreACP   *pITextStoreACP;
     ITfContextOwnerCompositionSink *pITfContextOwnerCompositionSink;
 
     ITextStoreACPSink *pITextStoreACPSink;
+    ITfEditSession* currentEditSession;
 
     /* kept as separate lists to reduce unnecessary iterations */
     struct list     pContextKeyEventSink;
@@ -76,9 +86,14 @@
 
 } Context;
 
+typedef struct tagEditCookie {
+    DWORD lockType;
+    Context *pOwningContext;
+} EditCookie;
 
 typedef struct tagTextStoreACPSink {
     const ITextStoreACPSinkVtbl *TextStoreACPSinkVtbl;
+    /* const ITextStoreACPServicesVtbl *TextStoreACPServicesVtbl; */
     LONG refCount;
 
     Context *pContext;
@@ -101,6 +116,7 @@
 static void Context_Destructor(Context *This)
 {
     struct list *cursor, *cursor2;
+    EditCookie *cookie;
     TRACE("destroying %p\n", This);
 
     if (This->pITextStoreACPSink)
@@ -114,6 +130,13 @@
 
     if (This->pITfContextOwnerCompositionSink)
         ITextStoreACPSink_Release(This->pITfContextOwnerCompositionSink);
+
+    if (This->defaultCookie)
+    {
+        cookie = remove_Cookie(This->defaultCookie);
+        HeapFree(GetProcessHeap(),0,cookie);
+        This->defaultCookie = 0;
+    }
 
     LIST_FOR_EACH_SAFE(cursor, cursor2, &This->pContextKeyEventSink)
     {
@@ -197,9 +220,53 @@
         TfClientId tid, ITfEditSession *pes, DWORD dwFlags,
         HRESULT *phrSession)
 {
-    Context *This = (Context *)iface;
-    FIXME("STUB:(%p)\n",This);
-    return E_NOTIMPL;
+    HRESULT hr;
+    Context *This = (Context *)iface;
+    DWORD  dwLockFlags = 0x0;
+    TS_STATUS status;
+
+    TRACE("(%p) %i %p %x %p\n",This, tid, pes, dwFlags, phrSession);
+
+    if (!(dwFlags & TF_ES_READ) && !(dwFlags & TF_ES_READWRITE))
+    {
+        *phrSession = E_FAIL;
+        return E_INVALIDARG;
+    }
+
+    if (!This->pITextStoreACP)
+    {
+        FIXME("No ITextStoreACP avaliable\n");
+        *phrSession = E_FAIL;
+        return E_FAIL;
+    }
+
+    if (!(dwFlags & TF_ES_ASYNC))
+        dwLockFlags |= TS_LF_SYNC;
+
+    if ((dwFlags & TF_ES_READWRITE) == TF_ES_READWRITE)
+        dwLockFlags |= TS_LF_READWRITE;
+    else if (dwFlags & TF_ES_READ)
+        dwLockFlags |= TS_LF_READ;
+
+    /* TODO: cache this */
+    ITextStoreACP_GetStatus(This->pITextStoreACP, &status);
+
+    if (((dwFlags & TF_ES_READWRITE) == TF_ES_READWRITE) && (status.dwDynamicFlags & TS_SD_READONLY))
+    {
+        *phrSession = TS_E_READONLY;
+        return S_OK;
+    }
+
+    if (FAILED (ITfEditSession_QueryInterface(pes, &IID_ITfEditSession, (LPVOID*)&This->currentEditSession)))
+    {
+        *phrSession = E_FAIL;
+        return E_INVALIDARG;
+    }
+
+
+    hr = ITextStoreACP_RequestLock(This->pITextStoreACP, dwLockFlags, phrSession);
+
+    return hr;
 }
 
 static HRESULT WINAPI Context_InWriteSession (ITfContext *iface,
@@ -216,8 +283,59 @@
         TF_SELECTION *pSelection, ULONG *pcFetched)
 {
     Context *This = (Context *)iface;
-    FIXME("STUB:(%p)\n",This);
-    return E_NOTIMPL;
+    EditCookie *cookie;
+    ULONG count, i;
+    ULONG totalFetched = 0;
+    HRESULT hr = S_OK;
+
+    if (!pSelection || !pcFetched)
+        return E_INVALIDARG;
+
+    *pcFetched = 0;
+
+    if (!This->connected)
+        return TF_E_DISCONNECTED;
+
+    if (get_Cookie_magic(ec)!=COOKIE_MAGIC_EDITCOOKIE)
+        return TF_E_NOLOCK;
+
+    if (!This->pITextStoreACP)
+    {
+        FIXME("Context does not have a ITextStoreACP\n");
+        return E_NOTIMPL;
+    }
+
+    cookie = get_Cookie_data(ec);
+
+    if (ulIndex == TF_DEFAULT_SELECTION)
+        count = 1;
+    else
+        count = ulCount;
+
+    for (i = 0; i < count; i++)
+    {
+        DWORD fetched;
+        TS_SELECTION_ACP acps;
+
+        hr = ITextStoreACP_GetSelection(This->pITextStoreACP, ulIndex + i,
+                1, &acps, &fetched);
+
+        if (hr == TS_E_NOLOCK)
+            return TF_E_NOLOCK;
+        else if (SUCCEEDED(hr))
+        {
+            pSelection[totalFetched].style.ase = acps.style.ase;
+            pSelection[totalFetched].style.fInterimChar = acps.style.fInterimChar;
+            Range_Constructor(iface, This->pITextStoreACP, cookie->lockType, acps.acpStart, acps.acpEnd, &pSelection[totalFetched].range);
+            totalFetched ++;
+        }
+        else
+            break;
+    }
+
+    *pcFetched = totalFetched;
+
+    return hr;
 }
 
 static HRESULT WINAPI Context_SetSelection (ITfContext *iface,
@@ -232,16 +350,53 @@
         TfEditCookie ec, ITfRange **ppStart)
 {
     Context *This = (Context *)iface;
-    FIXME("STUB:(%p)\n",This);
-    return E_NOTIMPL;
+    EditCookie *cookie;
+    TRACE("(%p) %i %p\n",This,ec,ppStart);
+
+    if (!ppStart)
+        return E_INVALIDARG;
+
+    *ppStart = NULL;
+
+    if (!This->connected)
+        return TF_E_DISCONNECTED;
+
+    if (get_Cookie_magic(ec)!=COOKIE_MAGIC_EDITCOOKIE)
+        return TF_E_NOLOCK;
+
+    cookie = get_Cookie_data(ec);
+    return Range_Constructor(iface, This->pITextStoreACP, cookie->lockType, 0, 0, ppStart);
 }
 
 static HRESULT WINAPI Context_GetEnd (ITfContext *iface,
         TfEditCookie ec, ITfRange **ppEnd)
 {
     Context *This = (Context *)iface;
-    FIXME("STUB:(%p)\n",This);
-    return E_NOTIMPL;
+    EditCookie *cookie;
+    LONG end;
+    TRACE("(%p) %i %p\n",This,ec,ppEnd);
+
+    if (!ppEnd)
+        return E_INVALIDARG;
+
+    *ppEnd = NULL;
+
+    if (!This->connected)
+        return TF_E_DISCONNECTED;
+
+    if (get_Cookie_magic(ec)!=COOKIE_MAGIC_EDITCOOKIE)
+        return TF_E_NOLOCK;
+
+    if (!This->pITextStoreACP)
+    {
+        FIXME("Context does not have a ITextStoreACP\n");
+        return E_NOTIMPL;
+    }
+
+    cookie = get_Cookie_data(ec);
+    ITextStoreACP_GetEndACP(This->pITextStoreACP,&end);
+
+    return Range_Constructor(iface, This->pITextStoreACP, cookie->lockType, end, end, ppEnd);
 }
 
 static HRESULT WINAPI Context_GetActiveView (ITfContext *iface,
@@ -376,7 +531,7 @@
         es = HeapAlloc(GetProcessHeap(),0,sizeof(ContextSink));
         if (!es)
             return E_OUTOFMEMORY;
-        if (!SUCCEEDED(IUnknown_QueryInterface(punk, riid, (LPVOID*)&es->interfaces.pITfTextEditSink)))
+        if (FAILED(IUnknown_QueryInterface(punk, riid, (LPVOID *)&es->interfaces.pITfTextEditSink)))
         {
             HeapFree(GetProcessHeap(),0,es);
             return CONNECT_E_CANNOTCONNECT;
@@ -427,10 +582,18 @@
 HRESULT Context_Constructor(TfClientId tidOwner, IUnknown *punk, ITfContext **ppOut, TfEditCookie *pecTextStore)
 {
     Context *This;
+    EditCookie *cookie;
 
     This = HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,sizeof(Context));
     if (This == NULL)
         return E_OUTOFMEMORY;
+
+    cookie = HeapAlloc(GetProcessHeap(),0,sizeof(EditCookie));
+    if (cookie == NULL)
+    {
+        HeapFree(GetProcessHeap(),0,This);
+        return E_OUTOFMEMORY;
+    }
 
     TRACE("(%p) %x %p %p %p\n",This, tidOwner, punk, ppOut, pecTextStore);
 
@@ -438,16 +601,15 @@
     This->SourceVtbl = &Context_SourceVtbl;
     This->refCount = 1;
     This->tidOwner = tidOwner;
+    This->connected = FALSE;
+
+    cookie->lockType = TF_ES_READ;
+    cookie->pOwningContext = This;
 
     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_ITextStoreACP,
+                          (LPVOID*)&This->pITextStoreACP);
 
         IUnknown_QueryInterface(punk, &IID_ITfContextOwnerCompositionSink,
                                 (LPVOID*)&This->pITfContextOwnerCompositionSink);
@@ -456,10 +618,8 @@
             FIXME("Unhandled pUnk\n");
     }
 
-    TRACE("returning %p\n", This);
-    *ppOut = (ITfContext*)This;
-    /* FIXME */
-    *pecTextStore = 0xdeaddead;
+    This->defaultCookie = generate_Cookie(COOKIE_MAGIC_EDITCOOKIE,cookie);
+    *pecTextStore = This->defaultCookie;
 
     list_init(&This->pContextKeyEventSink);
     list_init(&This->pEditTransactionSink);
@@ -467,6 +627,37 @@
     list_init(&This->pTextEditSink);
     list_init(&This->pTextLayoutSink);
 
+    *ppOut = (ITfContext*)This;
+    TRACE("returning %p\n", This);
+
+    return S_OK;
+}
+
+HRESULT Context_Initialize(ITfContext *iface)
+{
+    Context *This = (Context *)iface;
+
+    if (This->pITextStoreACP)
+    {
+        if (SUCCEEDED(TextStoreACPSink_Constructor(&This->pITextStoreACPSink, This)))
+            ITextStoreACP_AdviseSink(This->pITextStoreACP, &IID_ITextStoreACPSink,
+                            (IUnknown*)This->pITextStoreACPSink, TS_AS_ALL_SINKS);
+    }
+    This->connected = TRUE;
+    return S_OK;
+}
+
+HRESULT Context_Uninitialize(ITfContext *iface)
+{
+    Context *This = (Context *)iface;
+
+    if (This->pITextStoreACPSink)
+    {
+        ITextStoreACP_UnadviseSink(This->pITextStoreACP, (IUnknown*)This->pITextStoreACPSink);
+        if (ITextStoreACPSink_Release(This->pITextStoreACPSink) == 0)
+            This->pITextStoreACPSink = NULL;
+    }
+    This->connected = FALSE;
     return S_OK;
 }
 
@@ -564,8 +755,36 @@
         DWORD dwLockFlags)
 {
     TextStoreACPSink *This = (TextStoreACPSink *)iface;
-    FIXME("STUB:(%p)\n",This);
-    return E_NOTIMPL;
+    HRESULT hr;
+    EditCookie *cookie;
+    TfEditCookie ec;
+
+    TRACE("(%p) %x\n",This, dwLockFlags);
+
+    if (!This->pContext || !This->pContext->currentEditSession)
+    {
+        ERR("OnLockGranted called on a context without a current edit session\n");
+        return E_FAIL;
+    }
+
+    cookie = HeapAlloc(GetProcessHeap(),0,sizeof(EditCookie));
+    if (!cookie)
+        return E_OUTOFMEMORY;
+
+    cookie->lockType = dwLockFlags;
+    cookie->pOwningContext = This->pContext;
+    ec = generate_Cookie(COOKIE_MAGIC_EDITCOOKIE, cookie);
+
+    hr = ITfEditSession_DoEditSession(This->pContext->currentEditSession, ec);
+
+    ITfEditSession_Release(This->pContext->currentEditSession);
+    This->pContext->currentEditSession = NULL;
+
+    /* Edit Cookie is only valid during the edit session */
+    cookie = remove_Cookie(ec);
+    HeapFree(GetProcessHeap(),0,cookie);
+
+    return hr;
 }
 
 static HRESULT WINAPI TextStoreACPSink_OnStartEditTransaction(ITextStoreACPSink *iface)

Modified: trunk/reactos/dll/win32/msctf/documentmgr.c
URL: http://svn.reactos.org/svn/reactos/trunk/reactos/dll/win32/msctf/documentmgr.c?rev=41065&r1=41064&r2=41065&view=diff
==============================================================================
--- trunk/reactos/dll/win32/msctf/documentmgr.c [iso-8859-1] (original)
+++ trunk/reactos/dll/win32/msctf/documentmgr.c [iso-8859-1] Sat May 23 14:31:01 2009
@@ -138,6 +138,7 @@
     This->contextStack[0] = check;
 
     ITfThreadMgrEventSink_OnPushContext(This->ThreadMgrSink,check);
+    Context_Initialize(check);
 
     return S_OK;
 }
@@ -153,11 +154,13 @@
         {
             ITfThreadMgrEventSink_OnPopContext(This->ThreadMgrSink,This->contextStack[0]);
             ITfContext_Release(This->contextStack[0]);
+            Context_Uninitialize(This->contextStack[0]);
         }
         if (This->contextStack[1])
         {
             ITfThreadMgrEventSink_OnPopContext(This->ThreadMgrSink,This->contextStack[1]);
             ITfContext_Release(This->contextStack[1]);
+            Context_Uninitialize(This->contextStack[1]);
         }
         This->contextStack[0] = This->contextStack[1] = NULL;
         ITfThreadMgrEventSink_OnUninitDocumentMgr(This->ThreadMgrSink, iface);
@@ -172,6 +175,7 @@
 
     ITfThreadMgrEventSink_OnPopContext(This->ThreadMgrSink,This->contextStack[0]);
     ITfContext_Release(This->contextStack[0]);
+    Context_Uninitialize(This->contextStack[0]);
     This->contextStack[0] = This->contextStack[1];
     This->contextStack[1] = NULL;
 

Modified: trunk/reactos/dll/win32/msctf/inputprocessor.c
URL: http://svn.reactos.org/svn/reactos/trunk/reactos/dll/win32/msctf/inputprocessor.c?rev=41065&r1=41064&r2=41065&view=diff
==============================================================================
--- trunk/reactos/dll/win32/msctf/inputprocessor.c [iso-8859-1] (original)
+++ trunk/reactos/dll/win32/msctf/inputprocessor.c [iso-8859-1] Sat May 23 14:31:01 2009
@@ -32,8 +32,10 @@
 #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"
@@ -45,11 +47,26 @@
 static const WCHAR szwTipfmt[] = {'%','s','\\','%','s',0};
 static const WCHAR szwFullLangfmt[] = {'%','s','\\','%','s','\\','%','s','\\','0','x','%','0','8','x','\\','%','s',0};
 
+typedef struct tagInputProcessorProfilesSink {
+    struct list         entry;
+    union {
+        /* InputProcessorProfile Sinks */
+        IUnknown            *pIUnknown;
+        ITfLanguageProfileNotifySink *pITfLanguageProfileNotifySink;
+    } interfaces;
+} InputProcessorProfilesSink;
+
 typedef struct tagInputProcessorProfiles {
     const ITfInputProcessorProfilesVtbl *InputProcessorProfilesVtbl;
+    const ITfSourceVtbl *SourceVtbl;
+    /* const ITfInputProcessorProfileMgrVtbl *InputProcessorProfileMgrVtbl; */
+    /* const ITfInputProcessorProfilesExVtbl *InputProcessorProfilesExVtbl; */
+    /* const ITfInputProcessorProfileSubstituteLayoutVtbl *InputProcessorProfileSubstituteLayoutVtbl; */
     LONG refCount;
 
     LANGID  currentLanguage;
+
+    struct list     LanguageProfileNotifySink;
 } InputProcessorProfiles;
 
 typedef struct tagProfilesEnumGuid {
@@ -78,9 +95,30 @@
 static HRESULT ProfilesEnumGuid_Constructor(IEnumGUID **ppOut);
 static HRESULT EnumTfLanguageProfiles_Constructor(LANGID langid, IEnumTfLanguageProfiles **ppOut);
 
+static inline InputProcessorProfiles *impl_from_ITfSourceVtbl(ITfSource *iface)
+{
+    return (InputProcessorProfiles *)((char *)iface - FIELD_OFFSET(InputProcessorProfiles,SourceVtbl));
+}
+
+static void free_sink(InputProcessorProfilesSink *sink)
+{
+        IUnknown_Release(sink->interfaces.pIUnknown);
+        HeapFree(GetProcessHeap(),0,sink);
+}
+
 static void InputProcessorProfiles_Destructor(InputProcessorProfiles *This)
 {
+    struct list *cursor, *cursor2;
     TRACE("destroying %p\n", This);
+
+    /* free sinks */
+    LIST_FOR_EACH_SAFE(cursor, cursor2, &This->LanguageProfileNotifySink)
+    {
+        InputProcessorProfilesSink* sink = LIST_ENTRY(cursor,InputProcessorProfilesSink,entry);
+        list_remove(cursor);
+        free_sink(sink);
+    }
+
     HeapFree(GetProcessHeap(),0,This);
 }
 
@@ -121,6 +159,10 @@
     if (IsEqualIID(iid, &IID_IUnknown) || IsEqualIID(iid, &IID_ITfInputProcessorProfiles))
     {
         *ppvOut = This;
+    }
+    else if (IsEqualIID(iid, &IID_ITfSource))
+    {
+        *ppvOut = &This->SourceVtbl;
     }
 
     if (*ppvOut)
@@ -536,6 +578,92 @@
     InputProcessorProfiles_SubstituteKeyboardLayout
 };
 
+/*****************************************************
+ * ITfSource functions
+ *****************************************************/
+static HRESULT WINAPI IPPSource_QueryInterface(ITfSource *iface, REFIID iid, LPVOID *ppvOut)
+{
+    InputProcessorProfiles *This = impl_from_ITfSourceVtbl(iface);
+    return InputProcessorProfiles_QueryInterface((ITfInputProcessorProfiles *)This, iid, *ppvOut);
+}
+
+static ULONG WINAPI IPPSource_AddRef(ITfSource *iface)
+{
+    InputProcessorProfiles *This = impl_from_ITfSourceVtbl(iface);
+    return InputProcessorProfiles_AddRef((ITfInputProcessorProfiles*)This);
+}
+
+static ULONG WINAPI IPPSource_Release(ITfSource *iface)
+{
+    InputProcessorProfiles *This = impl_from_ITfSourceVtbl(iface);
+    return InputProcessorProfiles_Release((ITfInputProcessorProfiles *)This);
+}
+
+static WINAPI HRESULT IPPSource_AdviseSink(ITfSource *iface,
+        REFIID riid, IUnknown *punk, DWORD *pdwCookie)
+{
+    InputProcessorProfilesSink *ipps;
+    InputProcessorProfiles *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_ITfLanguageProfileNotifySink))
+    {
+        ipps = HeapAlloc(GetProcessHeap(),0,sizeof(InputProcessorProfilesSink));
+        if (!ipps)
+            return E_OUTOFMEMORY;
+        if (FAILED(IUnknown_QueryInterface(punk, riid, (LPVOID *)&ipps->interfaces.pITfLanguageProfileNotifySink)))
+        {
+            HeapFree(GetProcessHeap(),0,ipps);
+            return CONNECT_E_CANNOTCONNECT;
+        }
+        list_add_head(&This->LanguageProfileNotifySink,&ipps->entry);
+        *pdwCookie = generate_Cookie(COOKIE_MAGIC_IPPSINK, ipps);
+    }
+    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 IPPSource_UnadviseSink(ITfSource *iface, DWORD pdwCookie)
+{
+    InputProcessorProfilesSink *sink;
+    InputProcessorProfiles *This = impl_from_ITfSourceVtbl(iface);
+
+    TRACE("(%p) %x\n",This,pdwCookie);
+
+    if (get_Cookie_magic(pdwCookie)!=COOKIE_MAGIC_IPPSINK)
+        return E_INVALIDARG;
+
+    sink = (InputProcessorProfilesSink*)remove_Cookie(pdwCookie);
+    if (!sink)
+        return CONNECT_E_NOCONNECTION;
+
+    list_remove(&sink->entry);
+    free_sink(sink);
+
+    return S_OK;
+}
+
+static const ITfSourceVtbl InputProcessorProfiles_SourceVtbl =
+{
+    IPPSource_QueryInterface,
+    IPPSource_AddRef,
+    IPPSource_Release,
+
+    IPPSource_AdviseSink,
+    IPPSource_UnadviseSink,
+};
+
 HRESULT InputProcessorProfiles_Constructor(IUnknown *pUnkOuter, IUnknown **ppOut)
 {
     InputProcessorProfiles *This;
@@ -547,8 +675,11 @@
         return E_OUTOFMEMORY;
 
     This->InputProcessorProfilesVtbl= &InputProcessorProfiles_InputProcessorProfilesVtbl;
+    This->SourceVtbl = &InputProcessorProfiles_SourceVtbl;
     This->refCount = 1;
     This->currentLanguage = GetUserDefaultLCID();
+
+    list_init(&This->LanguageProfileNotifySink);
 
     TRACE("returning %p\n", This);
     *ppOut = (IUnknown *)This;

Modified: trunk/reactos/dll/win32/msctf/msctf.c
URL: http://svn.reactos.org/svn/reactos/trunk/reactos/dll/win32/msctf/msctf.c?rev=41065&r1=41064&r2=41065&view=diff
==============================================================================
--- trunk/reactos/dll/win32/msctf/msctf.c [iso-8859-1] (original)
+++ trunk/reactos/dll/win32/msctf/msctf.c [iso-8859-1] Sat May 23 14:31:01 2009
@@ -55,6 +55,7 @@
     TF_LANGUAGEPROFILE      LanguageProfile;
     ITfTextInputProcessor   *pITfTextInputProcessor;
     ITfThreadMgr            *pITfThreadMgr;
+    ITfKeyEventSink         *pITfKeyEventSink;
     TfClientId              tid;
 } ActivatedTextService;
 
@@ -357,14 +358,6 @@
     actsvr = HeapAlloc(GetProcessHeap(),0,sizeof(ActivatedTextService));
     if (!actsvr) return E_OUTOFMEMORY;
 
-    entry = HeapAlloc(GetProcessHeap(),0,sizeof(AtsEntry));
-
-    if (!entry)
-    {
-        HeapFree(GetProcessHeap(),0,actsvr);
-        return E_OUTOFMEMORY;
-    }
-
     ITfThreadMgr_QueryInterface(tm,&IID_ITfClientId,(LPVOID)&clientid);
     ITfClientId_GetClientId(clientid, &lp->clsid, &actsvr->tid);
     ITfClientId_Release(clientid);
@@ -378,6 +371,7 @@
     actsvr->pITfTextInputProcessor = NULL;
     actsvr->LanguageProfile = *lp;
     actsvr->LanguageProfile.fActive = TRUE;
+    actsvr->pITfKeyEventSink = NULL;
 
     /* get TIP category */
     if (SUCCEEDED(CategoryMgr_Constructor(NULL,(IUnknown**)&catmgr)))
@@ -401,6 +395,14 @@
 
     if (activated > 0)
         activate_given_ts(actsvr, tm);
+
+    entry = HeapAlloc(GetProcessHeap(),0,sizeof(AtsEntry));
+
+    if (!entry)
+    {
+        HeapFree(GetProcessHeap(),0,actsvr);
+        return E_OUTOFMEMORY;
+    }
 
     entry->ats = actsvr;
     list_add_head(&AtsList, &entry->entry);
@@ -454,6 +456,50 @@
             deactivate_given_ts(ats->ats);
 
     return S_OK;
+}
+
+CLSID get_textservice_clsid(TfClientId tid)
+{
+    AtsEntry *ats;
+
+    LIST_FOR_EACH_ENTRY(ats, &AtsList, AtsEntry, entry)
+        if (ats->ats->tid == tid)
+            return ats->ats->LanguageProfile.clsid;
+    return GUID_NULL;
+}
+
+HRESULT get_textservice_sink(TfClientId tid, REFCLSID iid, IUnknown **sink)
+{
+    AtsEntry *ats;
+
+    if (!IsEqualCLSID(iid,&IID_ITfKeyEventSink))
+        return E_NOINTERFACE;
+
+    LIST_FOR_EACH_ENTRY(ats, &AtsList, AtsEntry, entry)
+        if (ats->ats->tid == tid)
+        {
+            *sink = (IUnknown*)ats->ats->pITfKeyEventSink;
+            return S_OK;
+        }
+
+    return E_FAIL;
+}
+
+HRESULT set_textservice_sink(TfClientId tid, REFCLSID iid, IUnknown* sink)
+{
+    AtsEntry *ats;
+
+    if (!IsEqualCLSID(iid,&IID_ITfKeyEventSink))
+        return E_NOINTERFACE;
+
+    LIST_FOR_EACH_ENTRY(ats, &AtsList, AtsEntry, entry)
+        if (ats->ats->tid == tid)
+        {
+            ats->ats->pITfKeyEventSink = (ITfKeyEventSink*)sink;
+            return S_OK;
+        }
+
+    return E_FAIL;
 }
 
 /*************************************************************************

Modified: trunk/reactos/dll/win32/msctf/msctf.rbuild
URL: http://svn.reactos.org/svn/reactos/trunk/reactos/dll/win32/msctf/msctf.rbuild?rev=41065&r1=41064&r2=41065&view=diff
==============================================================================
--- trunk/reactos/dll/win32/msctf/msctf.rbuild [iso-8859-1] (original)
+++ trunk/reactos/dll/win32/msctf/msctf.rbuild [iso-8859-1] Sat May 23 14:31:01 2009
@@ -13,6 +13,7 @@
 	<file>documentmgr.c</file>
 	<file>inputprocessor.c</file>
 	<file>msctf.c</file>
+	<file>range.c</file>
 	<file>regsvr.c</file>
 	<file>threadmgr.c</file>
 	<file>version.rc</file>

Modified: trunk/reactos/dll/win32/msctf/msctf_internal.h
URL: http://svn.reactos.org/svn/reactos/trunk/reactos/dll/win32/msctf/msctf_internal.h?rev=41065&r1=41064&r2=41065&view=diff
==============================================================================
--- trunk/reactos/dll/win32/msctf/msctf_internal.h [iso-8859-1] (original)
+++ trunk/reactos/dll/win32/msctf/msctf_internal.h [iso-8859-1] Sat May 23 14:31:01 2009
@@ -24,6 +24,8 @@
 #define COOKIE_MAGIC_TMSINK  0x0010
 #define COOKIE_MAGIC_CONTEXTSINK 0x0020
 #define COOKIE_MAGIC_GUIDATOM 0x0030
+#define COOKIE_MAGIC_IPPSINK 0x0040
+#define COOKIE_MAGIC_EDITCOOKIE 0x0050
 
 extern DWORD tlsIndex;
 extern TfClientId processId;
@@ -33,6 +35,10 @@
 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 HRESULT Range_Constructor(ITfContext *context, ITextStoreACP *textstore, DWORD lockType, DWORD anchorStart, DWORD anchorEnd, ITfRange **ppOut);
+
+extern HRESULT Context_Initialize(ITfContext *cxt);
+extern HRESULT Context_Uninitialize(ITfContext *cxt);
 
 /* cookie function */
 extern DWORD  generate_Cookie(DWORD magic, LPVOID data);
@@ -47,5 +53,9 @@
 extern HRESULT activate_textservices(ITfThreadMgr *tm);
 extern HRESULT deactivate_textservices(void);
 
+extern CLSID get_textservice_clsid(TfClientId tid);
+extern HRESULT get_textservice_sink(TfClientId tid, REFCLSID iid, IUnknown** sink);
+extern HRESULT set_textservice_sink(TfClientId tid, REFCLSID iid, IUnknown* sink);
+
 extern const WCHAR szwSystemTIPKey[];
 #endif /* __WINE_MSCTF_I_H */

Added: trunk/reactos/dll/win32/msctf/range.c
URL: http://svn.reactos.org/svn/reactos/trunk/reactos/dll/win32/msctf/range.c?rev=41065&view=auto
==============================================================================
--- trunk/reactos/dll/win32/msctf/range.c (added)
+++ trunk/reactos/dll/win32/msctf/range.c [iso-8859-1] Sat May 23 14:31:01 2009
@@ -1,0 +1,333 @@
+/*
+ *  ITfRange 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 tagRange {
+    const ITfRangeVtbl *RangeVtbl;
+    /* const ITfRangeACPVtb *RangeACPVtbl; */
+    LONG refCount;
+
+    ITextStoreACP   *pITextStoreACP;
+    ITfContext      *pITfContext;
+
+    DWORD lockType;
+    TfGravity gravityStart, gravityEnd;
+    DWORD anchorStart, anchorEnd;
+
+} Range;
+
+static void Range_Destructor(Range *This)
+{
+    TRACE("destroying %p\n", This);
+    HeapFree(GetProcessHeap(),0,This);
+}
+
+static HRESULT WINAPI Range_QueryInterface(ITfRange *iface, REFIID iid, LPVOID *ppvOut)
+{
+    Range *This = (Range*)iface;
+    *ppvOut = NULL;
+
+    if (IsEqualIID(iid, &IID_IUnknown) || IsEqualIID(iid, &IID_ITfRange))
+    {
+        *ppvOut = This;
+    }
+
+    if (*ppvOut)
+    {
+        IUnknown_AddRef(iface);
+        return S_OK;
+    }
+
+    WARN("unsupported interface: %s\n", debugstr_guid(iid));
+    return E_NOINTERFACE;
+}
+
+static ULONG WINAPI Range_AddRef(ITfRange *iface)
+{
+    Range *This = (Range *)iface;
+    return InterlockedIncrement(&This->refCount);
+}
+
+static ULONG WINAPI Range_Release(ITfRange *iface)
+{
+    Range *This = (Range *)iface;
+    ULONG ret;
+
+    ret = InterlockedDecrement(&This->refCount);
+    if (ret == 0)
+        Range_Destructor(This);
+    return ret;
+}
+
+/*****************************************************
+ * ITfRange functions
+ *****************************************************/
+
+static HRESULT WINAPI Range_GetText(ITfRange *iface, TfEditCookie ec,
+        DWORD dwFlags, WCHAR *pchText, ULONG cchMax, ULONG *pcch)
+{
+    Range *This = (Range *)iface;
+    FIXME("STUB:(%p)\n",This);
+    return E_NOTIMPL;
+}
+
+static HRESULT WINAPI Range_SetText(ITfRange *iface, TfEditCookie ec,
+         DWORD dwFlags, const WCHAR *pchText, LONG cch)
+{
+    Range *This = (Range *)iface;
+    FIXME("STUB:(%p)\n",This);
+    return E_NOTIMPL;
+}
+
+static HRESULT WINAPI Range_GetFormattedText(ITfRange *iface, TfEditCookie ec,
+        IDataObject **ppDataObject)
+{
+    Range *This = (Range *)iface;
+    FIXME("STUB:(%p)\n",This);
+    return E_NOTIMPL;
+}
+
+static HRESULT WINAPI Range_GetEmbedded(ITfRange *iface, TfEditCookie ec,
+        REFGUID rguidService, REFIID riid, IUnknown **ppunk)
+{
+    Range *This = (Range *)iface;
+    FIXME("STUB:(%p)\n",This);
+    return E_NOTIMPL;
+}
+
+static HRESULT WINAPI Range_InsertEmbedded(ITfRange *iface, TfEditCookie ec,
+        DWORD dwFlags, IDataObject *pDataObject)
+{
+    Range *This = (Range *)iface;
+    FIXME("STUB:(%p)\n",This);
+    return E_NOTIMPL;
+}
+
+static HRESULT WINAPI Range_ShiftStart(ITfRange *iface, TfEditCookie ec,
+        LONG cchReq, LONG *pcch, const TF_HALTCOND *pHalt)
+{
+    Range *This = (Range *)iface;
+    FIXME("STUB:(%p)\n",This);
+    return E_NOTIMPL;
+}
+
+static HRESULT WINAPI Range_ShiftEnd(ITfRange *iface, TfEditCookie ec,
+        LONG cchReq, LONG *pcch, const TF_HALTCOND *pHalt)
+{
+    Range *This = (Range *)iface;
+    FIXME("STUB:(%p)\n",This);
+    return E_NOTIMPL;
+}
+
+static HRESULT WINAPI Range_ShiftStartToRange(ITfRange *iface, TfEditCookie ec,
+        ITfRange *pRange, TfAnchor aPos)
+{
+    Range *This = (Range *)iface;
+    FIXME("STUB:(%p)\n",This);
+    return E_NOTIMPL;
+}
+
+static HRESULT WINAPI Range_ShiftEndToRange(ITfRange *iface, TfEditCookie ec,
+        ITfRange *pRange, TfAnchor aPos)
+{
+    Range *This = (Range *)iface;
+    FIXME("STUB:(%p)\n",This);
+    return E_NOTIMPL;
+}
+
+static HRESULT WINAPI Range_ShiftStartRegion(ITfRange *iface, TfEditCookie ec,
+        TfShiftDir dir, BOOL *pfNoRegion)
+{
+    Range *This = (Range *)iface;
+    FIXME("STUB:(%p)\n",This);
+    return E_NOTIMPL;
+}
+
+static HRESULT WINAPI Range_ShiftEndRegion(ITfRange *iface, TfEditCookie ec,
+        TfShiftDir dir, BOOL *pfNoRegion)
+{
+    Range *This = (Range *)iface;
+    FIXME("STUB:(%p)\n",This);
+    return E_NOTIMPL;
+}
+
+static HRESULT WINAPI Range_IsEmpty(ITfRange *iface, TfEditCookie ec,
+        BOOL *pfEmpty)
+{
+    Range *This = (Range *)iface;
+    FIXME("STUB:(%p)\n",This);
+    return E_NOTIMPL;
+}
+
+static HRESULT WINAPI Range_Collapse(ITfRange *iface, TfEditCookie ec,
+        TfAnchor aPos)
+{
+    Range *This = (Range *)iface;
+    FIXME("STUB:(%p)\n",This);
+    return E_NOTIMPL;
+}
+
+static HRESULT WINAPI Range_IsEqualStart(ITfRange *iface, TfEditCookie ec,
+        ITfRange *pWith, TfAnchor aPos, BOOL *pfEqual)
+{
+    Range *This = (Range *)iface;
+    FIXME("STUB:(%p)\n",This);
+    return E_NOTIMPL;
+}
+
+static HRESULT WINAPI Range_IsEqualEnd(ITfRange *iface, TfEditCookie ec,
+        ITfRange *pWith, TfAnchor aPos, BOOL *pfEqual)
+{
+    Range *This = (Range *)iface;
+    FIXME("STUB:(%p)\n",This);
+    return E_NOTIMPL;
+}
+
+static HRESULT WINAPI Range_CompareStart(ITfRange *iface, TfEditCookie ec,
+        ITfRange *pWith, TfAnchor aPos, LONG *plResult)
+{
+    Range *This = (Range *)iface;
+    FIXME("STUB:(%p)\n",This);
+    return E_NOTIMPL;
+}
+
+static HRESULT WINAPI Range_CompareEnd(ITfRange *iface, TfEditCookie ec,
+        ITfRange *pWith, TfAnchor aPos, LONG *plResult)
+{
+    Range *This = (Range *)iface;
+    FIXME("STUB:(%p)\n",This);
+    return E_NOTIMPL;
+}
+
+static HRESULT WINAPI Range_AdjustForInsert(ITfRange *iface, TfEditCookie ec,
+        ULONG cchInsert, BOOL *pfInsertOk)
+{
+    Range *This = (Range *)iface;
+    FIXME("STUB:(%p)\n",This);
+    return E_NOTIMPL;
+}
+
+static HRESULT WINAPI Range_GetGravity(ITfRange *iface,
+        TfGravity *pgStart, TfGravity *pgEnd)
+{
+    Range *This = (Range *)iface;
+    FIXME("STUB:(%p)\n",This);
+    return E_NOTIMPL;
+}
+
+static HRESULT WINAPI Range_SetGravity(ITfRange *iface, TfEditCookie ec,
+         TfGravity gStart, TfGravity gEnd)
+{
+    Range *This = (Range *)iface;
+    FIXME("STUB:(%p)\n",This);
+    return E_NOTIMPL;
+}
+
+static HRESULT WINAPI Range_Clone(ITfRange *iface, ITfRange **ppClone)
+{
+    Range *This = (Range *)iface;
+    FIXME("STUB:(%p)\n",This);
+    return E_NOTIMPL;
+}
+
+static HRESULT WINAPI Range_GetContext(ITfRange *iface, ITfContext **ppContext)
+{
+    Range *This = (Range *)iface;
+    TRACE("(%p)\n",This);
+    if (!ppContext)
+        return E_INVALIDARG;
+    *ppContext = This->pITfContext;
+    return S_OK;
+}
+
+static const ITfRangeVtbl Range_RangeVtbl =
+{
+    Range_QueryInterface,
+    Range_AddRef,
+    Range_Release,
+
+    Range_GetText,
+    Range_SetText,
+    Range_GetFormattedText,
+    Range_GetEmbedded,
+    Range_InsertEmbedded,
+    Range_ShiftStart,
+    Range_ShiftEnd,
+    Range_ShiftStartToRange,
+    Range_ShiftEndToRange,
+    Range_ShiftStartRegion,
+    Range_ShiftEndRegion,
+    Range_IsEmpty,
+    Range_Collapse,
+    Range_IsEqualStart,
+    Range_IsEqualEnd,
+    Range_CompareStart,
+    Range_CompareEnd,
+    Range_AdjustForInsert,
+    Range_GetGravity,
+    Range_SetGravity,
+    Range_Clone,
+    Range_GetContext
+};
+
+HRESULT Range_Constructor(ITfContext *context, ITextStoreACP *textstore, DWORD lockType, DWORD anchorStart, DWORD anchorEnd, ITfRange **ppOut)
+{
+    Range *This;
+
+    This = HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,sizeof(Range));
+    if (This == NULL)
+        return E_OUTOFMEMORY;
+
+    TRACE("(%p) %p %p\n",This, context, textstore);
+
+    This->RangeVtbl= &Range_RangeVtbl;
+    This->refCount = 1;
+    This->pITfContext = context;
+    This->pITextStoreACP = textstore;
+    This->lockType = lockType;
+    This->anchorStart = anchorStart;
+    This->anchorEnd = anchorEnd;
+
+    *ppOut = (ITfRange*)This;
+    TRACE("returning %p\n", This);
+
+    return S_OK;
+}

Propchange: trunk/reactos/dll/win32/msctf/range.c
------------------------------------------------------------------------------
    svn:eol-style = native

Modified: trunk/reactos/dll/win32/msctf/threadmgr.c
URL: http://svn.reactos.org/svn/reactos/trunk/reactos/dll/win32/msctf/threadmgr.c?rev=41065&r1=41064&r2=41065&view=diff
==============================================================================
--- trunk/reactos/dll/win32/msctf/threadmgr.c [iso-8859-1] (original)
+++ trunk/reactos/dll/win32/msctf/threadmgr.c [iso-8859-1] Sat May 23 14:31:01 2009
@@ -71,12 +71,20 @@
     const ITfKeystrokeMgrVtbl *KeystrokeMgrVtbl;
     const ITfMessagePumpVtbl *MessagePumpVtbl;
     const ITfClientIdVtbl *ClientIdVtbl;
+    /* const ITfThreadMgrExVtbl *ThreadMgrExVtbl; */
+    /* const ITfConfigureSystemKeystrokeFeedVtbl *ConfigureSystemKeystrokeFeedVtbl; */
+    /* const ITfLangBarItemMgrVtbl *LangBarItemMgrVtbl; */
+    /* const ITfUIElementMgrVtbl *UIElementMgrVtbl; */
+    /* const ITfSourceSingleVtbl *SourceSingleVtbl; */
     LONG refCount;
 
     const ITfThreadMgrEventSinkVtbl *ThreadMgrEventSinkVtbl; /* internal */
 
     ITfDocumentMgr *focus;
     LONG activationCount;
+
+    ITfKeyEventSink *forgroundKeyEventSink;
+    CLSID forgroundTextService;
 
     struct list CurrentPreservedKeys;
 
@@ -434,7 +442,7 @@
         tms = HeapAlloc(GetProcessHeap(),0,sizeof(ThreadMgrSink));
         if (!tms)
             return E_OUTOFMEMORY;
-        if (!SUCCEEDED(IUnknown_QueryInterface(punk, riid, (LPVOID*)&tms->interfaces.pITfThreadMgrEventSink)))
+        if (FAILED(IUnknown_QueryInterface(punk, riid, (LPVOID *)&tms->interfaces.pITfThreadMgrEventSink)))
         {
             HeapFree(GetProcessHeap(),0,tms);
             return CONNECT_E_CANNOTCONNECT;
@@ -509,24 +517,87 @@
         TfClientId tid, ITfKeyEventSink *pSink, BOOL fForeground)
 {
     ThreadMgr *This = impl_from_ITfKeystrokeMgrVtbl(iface);
-    FIXME("STUB:(%p)\n",This);
-    return E_NOTIMPL;
+    CLSID textservice;
+    ITfKeyEventSink *check = NULL;
+
+    TRACE("(%p) %x %p %i\n",This,tid,pSink,fForeground);
+
+    if (!tid || !pSink)
+        return E_INVALIDARG;
+
+    textservice = get_textservice_clsid(tid);
+    if (IsEqualCLSID(&GUID_NULL,&textservice))
+        return E_INVALIDARG;
+
+    get_textservice_sink(tid, &IID_ITfKeyEventSink, (IUnknown**)&check);
+    if (check != NULL)
+        return CONNECT_E_ADVISELIMIT;
+
+    if (FAILED(IUnknown_QueryInterface(pSink,&IID_ITfKeyEventSink,(LPVOID*) &check)))
+        return E_INVALIDARG;
+
+    set_textservice_sink(tid, &IID_ITfKeyEventSink, (IUnknown*)check);
+
+    if (fForeground)
+    {
+        if (This->forgroundKeyEventSink)
+        {
+            ITfKeyEventSink_OnSetFocus(This->forgroundKeyEventSink, FALSE);
+            ITfKeyEventSink_Release(This->forgroundKeyEventSink);
+        }
+        ITfKeyEventSink_AddRef(check);
+        ITfKeyEventSink_OnSetFocus(check, TRUE);
+        This->forgroundKeyEventSink = check;
+        This->forgroundTextService = textservice;
+    }
+    return S_OK;
 }
 
 static HRESULT WINAPI KeystrokeMgr_UnadviseKeyEventSink(ITfKeystrokeMgr *iface,
         TfClientId tid)
 {
     ThreadMgr *This = impl_from_ITfKeystrokeMgrVtbl(iface);
-    FIXME("STUB:(%p)\n",This);
-    return E_NOTIMPL;
+    CLSID textservice;
+    ITfKeyEventSink *check = NULL;
+    TRACE("(%p) %x\n",This,tid);
+
+    if (!tid)
+        return E_INVALIDARG;
+
+    textservice = get_textservice_clsid(tid);
+    if (IsEqualCLSID(&GUID_NULL,&textservice))
+        return E_INVALIDARG;
+
+    get_textservice_sink(tid, &IID_ITfKeyEventSink, (IUnknown**)&check);
+
+    if (!check)
+        return CONNECT_E_NOCONNECTION;
+
+    set_textservice_sink(tid, &IID_ITfKeyEventSink, NULL);
+    ITfKeyEventSink_Release(check);
+
+    if (This->forgroundKeyEventSink == check)
+    {
+        ITfKeyEventSink_Release(This->forgroundKeyEventSink);
+        This->forgroundKeyEventSink = NULL;
+        This->forgroundTextService = GUID_NULL;
+    }
+    return S_OK;
 }
 
 static HRESULT WINAPI KeystrokeMgr_GetForeground(ITfKeystrokeMgr *iface,
         CLSID *pclsid)
 {
     ThreadMgr *This = impl_from_ITfKeystrokeMgrVtbl(iface);
-    FIXME("STUB:(%p)\n",This);
-    return E_NOTIMPL;
+    TRACE("(%p) %p\n",This,pclsid);
+    if (!pclsid)
+        return E_INVALIDARG;
+
+    if (IsEqualCLSID(&This->forgroundTextService,&GUID_NULL))
+        return S_FALSE;
+
+    *pclsid = This->forgroundTextService;
+    return S_OK;
 }
 
 static HRESULT WINAPI KeystrokeMgr_TestKeyDown(ITfKeystrokeMgr *iface,



More information about the Ros-diffs mailing list