Aric Stewart : msctf: Hook up ITfTextEditSink::OnEndEdit.

Alexandre Julliard julliard at winehq.org
Sat Aug 29 11:35:50 CDT 2009


Module: wine
Branch: master
Commit: 0294cbc04803d6eb65e6cb6d0ed9d1d51da4a238
URL:    http://source.winehq.org/git/wine.git/?a=commit;h=0294cbc04803d6eb65e6cb6d0ed9d1d51da4a238

Author: Aric Stewart <aric at codeweavers.com>
Date:   Fri Aug 28 15:08:14 2009 -0500

msctf: Hook up ITfTextEditSink::OnEndEdit.

---

 dlls/msctf/context.c              |   26 +++++++++-
 dlls/msctf/tests/inputprocessor.c |  108 +++++++++++++++++++++++++++++++++++++
 2 files changed, 133 insertions(+), 1 deletions(-)

diff --git a/dlls/msctf/context.c b/dlls/msctf/context.c
index 5335940..c13235c 100644
--- a/dlls/msctf/context.c
+++ b/dlls/msctf/context.c
@@ -989,8 +989,9 @@ static HRESULT WINAPI TextStoreACPSink_OnLockGranted(ITextStoreACPSink *iface,
 {
     TextStoreACPSink *This = (TextStoreACPSink *)iface;
     HRESULT hr;
-    EditCookie *cookie;
+    EditCookie *cookie,*sinkcookie;
     TfEditCookie ec;
+    struct list *cursor;
 
     TRACE("(%p) %x\n",This, dwLockFlags);
 
@@ -1010,12 +1011,35 @@ static HRESULT WINAPI TextStoreACPSink_OnLockGranted(ITextStoreACPSink *iface,
     if (!cookie)
         return E_OUTOFMEMORY;
 
+    sinkcookie = HeapAlloc(GetProcessHeap(),0,sizeof(EditCookie));
+    if (!sinkcookie)
+        return E_OUTOFMEMORY;
+
     cookie->lockType = dwLockFlags;
     cookie->pOwningContext = This->pContext;
     ec = generate_Cookie(COOKIE_MAGIC_EDITCOOKIE, cookie);
 
     hr = ITfEditSession_DoEditSession(This->pContext->currentEditSession, ec);
 
+    if ((dwLockFlags&TS_LF_READWRITE) == TS_LF_READWRITE)
+    {
+        TfEditCookie sc;
+
+        sinkcookie->lockType = TS_LF_READ;
+        sinkcookie->pOwningContext = This->pContext;
+        sc = generate_Cookie(COOKIE_MAGIC_EDITCOOKIE, sinkcookie);
+
+        /*TODO: implement ITfEditRecord */
+        LIST_FOR_EACH(cursor, &This->pContext->pTextEditSink)
+        {
+            ContextSink* sink = LIST_ENTRY(cursor,ContextSink,entry);
+            ITfTextEditSink_OnEndEdit(sink->interfaces.pITfTextEditSink,
+                                      (ITfContext*) &This->pContext, sc, NULL);
+        }
+        sinkcookie = remove_Cookie(sc);
+    }
+    HeapFree(GetProcessHeap(),0,sinkcookie);
+
     ITfEditSession_Release(This->pContext->currentEditSession);
     This->pContext->currentEditSession = NULL;
 
diff --git a/dlls/msctf/tests/inputprocessor.c b/dlls/msctf/tests/inputprocessor.c
index d35d391..6e8bbdc 100644
--- a/dlls/msctf/tests/inputprocessor.c
+++ b/dlls/msctf/tests/inputprocessor.c
@@ -65,6 +65,7 @@ static INT  test_ACP_GetSelection = SINK_UNEXPECTED;
 static INT  test_DoEditSession = SINK_UNEXPECTED;
 static INT  test_ACP_InsertTextAtSelection = SINK_UNEXPECTED;
 static INT  test_ACP_SetSelection = SINK_UNEXPECTED;
+static INT  test_OnEndEdit = SINK_UNEXPECTED;
 
 
 /**********************************************************************
@@ -1181,6 +1182,90 @@ static inline int check_context_refcount(ITfContext *iface)
     return IUnknown_Release(iface);
 }
 
+
+/**********************************************************************
+ * ITfTextEditSink
+ **********************************************************************/
+typedef struct tagTextEditSink
+{
+    const ITfTextEditSinkVtbl *TextEditSinkVtbl;
+    LONG refCount;
+} TextEditSink;
+
+static void TextEditSink_Destructor(TextEditSink *This)
+{
+    HeapFree(GetProcessHeap(),0,This);
+}
+
+static HRESULT WINAPI TextEditSink_QueryInterface(ITfTextEditSink *iface, REFIID iid, LPVOID *ppvOut)
+{
+    TextEditSink *This = (TextEditSink *)iface;
+    *ppvOut = NULL;
+
+    if (IsEqualIID(iid, &IID_IUnknown) || IsEqualIID(iid, &IID_ITfTextEditSink))
+    {
+        *ppvOut = This;
+    }
+
+    if (*ppvOut)
+    {
+        IUnknown_AddRef(iface);
+        return S_OK;
+    }
+
+    return E_NOINTERFACE;
+}
+
+static ULONG WINAPI TextEditSink_AddRef(ITfTextEditSink *iface)
+{
+    TextEditSink *This = (TextEditSink *)iface;
+    return InterlockedIncrement(&This->refCount);
+}
+
+static ULONG WINAPI TextEditSink_Release(ITfTextEditSink *iface)
+{
+    TextEditSink *This = (TextEditSink *)iface;
+    ULONG ret;
+
+    ret = InterlockedDecrement(&This->refCount);
+    if (ret == 0)
+        TextEditSink_Destructor(This);
+    return ret;
+}
+
+static HRESULT WINAPI TextEditSink_OnEndEdit(ITfTextEditSink *iface,
+    ITfContext *pic, TfEditCookie ecReadOnly, ITfEditRecord *pEditRecord)
+{
+    ok(test_OnEndEdit == SINK_EXPECTED, "Unexpected OnEndEdit\n");
+    test_OnEndEdit = SINK_FIRED;
+    return S_OK;
+}
+
+static const ITfTextEditSinkVtbl TextEditSink_TextEditSinkVtbl =
+{
+    TextEditSink_QueryInterface,
+    TextEditSink_AddRef,
+    TextEditSink_Release,
+
+    TextEditSink_OnEndEdit
+};
+
+static HRESULT TextEditSink_Constructor(ITfTextEditSink **ppOut)
+{
+    TextEditSink *This;
+
+    *ppOut = NULL;
+    This = HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,sizeof(TextEditSink));
+    if (This == NULL)
+        return E_OUTOFMEMORY;
+
+    This->TextEditSinkVtbl = &TextEditSink_TextEditSinkVtbl;
+    This->refCount = 1;
+
+    *ppOut = (ITfTextEditSink*)This;
+    return S_OK;
+}
+
 static void test_startSession(void)
 {
     HRESULT hr;
@@ -1626,11 +1711,24 @@ static void test_TStoApplicationText(void)
     ITfEditSession *es;
     ITfContext *cxt;
     ITfDocumentMgr *dm;
+    ITfTextEditSink *sink;
+    ITfSource *source = NULL;
+    DWORD editSinkCookie = -1;
 
     ITfThreadMgr_GetFocus(g_tm, &dm);
     EditSession_Constructor(&es);
     ITfDocumentMgr_GetTop(dm,&cxt);
 
+    TextEditSink_Constructor(&sink);
+    hr = ITfContext_QueryInterface(cxt,&IID_ITfSource,(LPVOID*)&source);
+    ok(SUCCEEDED(hr),"Failed to get IID_ITfSource for Context\n");
+    if (source)
+    {
+        hr = ITfSource_AdviseSink(source, &IID_ITfTextEditSink, (LPVOID)sink, &editSinkCookie);
+        ok(SUCCEEDED(hr),"Failed to advise Sink\n");
+        ok(editSinkCookie != -1,"Failed to get sink cookie\n");
+    }
+
     hrSession = 0xfeedface;
     /* Test no premissions flags */
     hr = ITfContext_RequestEditSession(cxt, tid, es, TF_ES_SYNC, &hrSession);
@@ -1655,13 +1753,23 @@ static void test_TStoApplicationText(void)
     test_ACP_RequestLock = SINK_EXPECTED;
     test_DoEditSession = SINK_EXPECTED;
     hrSession = 0xfeedface;
+    test_OnEndEdit = SINK_EXPECTED;
     hr = ITfContext_RequestEditSession(cxt, tid, es, TF_ES_SYNC|TF_ES_READWRITE, &hrSession);
     ok(SUCCEEDED(hr),"ITfContext_RequestEditSession failed\n");
+    ok(test_OnEndEdit == SINK_FIRED, "OnEndEdit not fired as expected\n");
     ok(test_ACP_RequestLock == SINK_FIRED," expected RequestLock not fired\n");
     ok(test_DoEditSession == SINK_FIRED," expected DoEditSession not fired\n");
     ok(test_ACP_GetStatus == SINK_FIRED," expected GetStatus not fired\n");
     ok(hrSession == 0xdeadcafe,"Unexpected hrSession (%x)\n",hrSession);
 
+    if (source)
+    {
+        hr = ITfSource_UnadviseSink(source, editSinkCookie);
+        ok(SUCCEEDED(hr),"Failed to unadvise Sink\n");
+        ITfTextEditSink_Release(sink);
+        ITfSource_Release(source);
+    }
+
     ITfContext_Release(cxt);
     ITfDocumentMgr_Release(dm);
     ITfEditSession_Release(es);




More information about the wine-cvs mailing list