[SCM] WebKit Debian packaging branch, debian/experimental, updated. upstream/1.3.3-10851-g50815da

enrica at apple.com enrica at apple.com
Wed Dec 22 18:42:16 UTC 2010


The following commit has been merged in the debian/experimental branch:
commit fb7e5f894bb9f85a83b2a47a64e5c2f5ebc2f202
Author: enrica at apple.com <enrica at apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Date:   Thu Dec 16 01:07:27 2010 +0000

    Add IME support to WebKit2 on Windows
    https://bugs.webkit.org/show_bug.cgi?id=51049
    The implementation is very close to the one in WebKit.
    The main change is the addition of handlers for WM_IME_STARTCOMPOSITION,
    WM_IME_REQUEST, WM_IME_COMPOSITION, WM_IME_ENDCOMPOSITION,
    WM_IME_SELECT, WM_IME_SETCONTEXT and a number of new messages
    between the UI process and the WebProcess to send/retrieve
    the data being handled by the messages listed above.
    
    Reviewed by Adam Roben.
    
    * UIProcess/PageClient.h: Added compositionSelectionChanged for Windows platform.
    * UIProcess/WebPageProxy.cpp:
    The following methods send synchronous messages to the WebProcess.
    (WebKit::WebPageProxy::firstRectForCharacterInSelectedRange): Retrieves the rectangle to position
    the cnadidates window.
    (WebKit::WebPageProxy::getSelectedText): Retrieves the currently selected text.
    The following methods send asynchronous messages to the WebProcess.
    (WebKit::WebPageProxy::confirmComposition):
    (WebKit::WebPageProxy::setComposition):
    (WebKit::WebPageProxy::didChangeSelection): Name changed.
    (WebKit::WebPageProxy::didChangeCompositionSelection): Called when there is a change
    in the composition selection.
    * UIProcess/WebPageProxy.messages.in: Added messages corresponding to the methods above.
    * UIProcess/win/WebView.cpp:
    (WebKit::WebView::wndProc): Added handling of messages for IME.
    The following are the handlers for the window message being sent during composition.
    (WebKit::WebView::onIMEComposition):
    (WebKit::WebView::onIMEEndComposition):
    (WebKit::WebView::onIMERequestCharPosition):
    (WebKit::WebView::onIMERequestReconvertString):
    (WebKit::WebView::onIMERequest):
    (WebKit::WebView::onIMESelect):
    (WebKit::WebView::onIMESetContext):
    * WebProcess/WebCoreSupport/WebEditorClient.cpp:
    (WebKit::WebEditorClient::respondToChangedSelection): Added notification
    of composition selection changed for Windows.
    * WebProcess/WebPage/win/WebPageWin.cpp:
    The following are the WebProcess counterparts of the new messages.
    (WebKit::WebPage::confirmComposition):
    (WebKit::WebPage::setComposition):
    (WebKit::WebPage::firstRectForCharacterInSelectedRange):
    (WebKit::WebPage::getSelectedText):
    
    
    
    git-svn-id: http://svn.webkit.org/repository/webkit/trunk@74164 268f45cc-cd09-0410-ab3c-d52691b4dbfc

diff --git a/WebKit2/ChangeLog b/WebKit2/ChangeLog
index e10f4bc..3f73ae3 100644
--- a/WebKit2/ChangeLog
+++ b/WebKit2/ChangeLog
@@ -1,3 +1,49 @@
+2010-12-14  Enrica Casucci  <enrica at apple.com>
+
+        Reviewed by Adam Roben.
+
+        Add IME support to WebKit2 on Windows
+        https://bugs.webkit.org/show_bug.cgi?id=51049
+        The implementation is very close to the one in WebKit.
+        The main change is the addition of handlers for WM_IME_STARTCOMPOSITION,
+        WM_IME_REQUEST, WM_IME_COMPOSITION, WM_IME_ENDCOMPOSITION,
+        WM_IME_SELECT, WM_IME_SETCONTEXT and a number of new messages
+        between the UI process and the WebProcess to send/retrieve
+        the data being handled by the messages listed above.
+
+        * UIProcess/PageClient.h: Added compositionSelectionChanged for Windows platform.
+        * UIProcess/WebPageProxy.cpp:
+        The following methods send synchronous messages to the WebProcess.
+        (WebKit::WebPageProxy::firstRectForCharacterInSelectedRange): Retrieves the rectangle to position
+        the cnadidates window.
+        (WebKit::WebPageProxy::getSelectedText): Retrieves the currently selected text.
+        The following methods send asynchronous messages to the WebProcess.
+        (WebKit::WebPageProxy::confirmComposition):
+        (WebKit::WebPageProxy::setComposition):
+        (WebKit::WebPageProxy::didChangeSelection): Name changed.
+        (WebKit::WebPageProxy::didChangeCompositionSelection): Called when there is a change
+        in the composition selection.
+        * UIProcess/WebPageProxy.messages.in: Added messages corresponding to the methods above.
+        * UIProcess/win/WebView.cpp:
+        (WebKit::WebView::wndProc): Added handling of messages for IME.
+        The following are the handlers for the window message being sent during composition.
+        (WebKit::WebView::onIMEComposition):
+        (WebKit::WebView::onIMEEndComposition):
+        (WebKit::WebView::onIMERequestCharPosition):
+        (WebKit::WebView::onIMERequestReconvertString):
+        (WebKit::WebView::onIMERequest):
+        (WebKit::WebView::onIMESelect):
+        (WebKit::WebView::onIMESetContext):
+        * WebProcess/WebCoreSupport/WebEditorClient.cpp:
+        (WebKit::WebEditorClient::respondToChangedSelection): Added notification
+        of composition selection changed for Windows.
+        * WebProcess/WebPage/win/WebPageWin.cpp:
+        The following are the WebProcess counterparts of the new messages.
+        (WebKit::WebPage::confirmComposition):
+        (WebKit::WebPage::setComposition):
+        (WebKit::WebPage::firstRectForCharacterInSelectedRange):
+        (WebKit::WebPage::getSelectedText):
+
 2010-12-15  Sam Weinig  <sam at webkit.org>
 
         Reviewed by Brady Eidson.
diff --git a/WebKit2/UIProcess/PageClient.h b/WebKit2/UIProcess/PageClient.h
index a111648..3a94e45 100644
--- a/WebKit2/UIProcess/PageClient.h
+++ b/WebKit2/UIProcess/PageClient.h
@@ -74,6 +74,9 @@ public:
 #else
     virtual void selectionChanged(bool, bool, bool, bool) = 0;
 #endif
+#if PLATFORM(WIN)
+    virtual void compositionSelectionChanged(bool) = 0;
+#endif
     virtual WebCore::FloatRect convertToDeviceSpace(const WebCore::FloatRect&) = 0;
     virtual WebCore::FloatRect convertToUserSpace(const WebCore::FloatRect&) = 0;
 
diff --git a/WebKit2/UIProcess/WebPageProxy.cpp b/WebKit2/UIProcess/WebPageProxy.cpp
index 8f6c298..2f868f3 100644
--- a/WebKit2/UIProcess/WebPageProxy.cpp
+++ b/WebKit2/UIProcess/WebPageProxy.cpp
@@ -506,7 +506,21 @@ WebCore::IntRect WebPageProxy::firstRectForCharacterRange(uint64_t location, uin
     IntRect resultRect;
     process()->sendSync(Messages::WebPage::FirstRectForCharacterRange(location, length), Messages::WebPage::FirstRectForCharacterRange::Reply(resultRect), m_pageID);
     return resultRect;
-}    
+}
+#elif PLATFORM(WIN)
+WebCore::IntRect WebPageProxy::firstRectForCharacterInSelectedRange(int characterPosition)
+{
+    IntRect resultRect;
+    process()->sendSync(Messages::WebPage::FirstRectForCharacterInSelectedRange(characterPosition), Messages::WebPage::FirstRectForCharacterInSelectedRange::Reply(resultRect), m_pageID);
+    return resultRect;
+}
+
+String WebPageProxy::getSelectedText()
+{
+    String text;
+    process()->sendSync(Messages::WebPage::GetSelectedText(), Messages::WebPage::GetSelectedText::Reply(text), m_pageID);
+    return text;
+}
 #endif
 
 #if ENABLE(TILED_BACKING_STORE)
@@ -1355,11 +1369,28 @@ void WebPageProxy::sendComplexTextInputToPlugin(uint64_t pluginComplexTextInputI
 }
     
 #else    
-void WebPageProxy::didSelectionChange(bool isNone, bool isContentEditable, bool isPasswordField, bool hasComposition)
+void WebPageProxy::didChangeSelection(bool isNone, bool isContentEditable, bool isPasswordField, bool hasComposition)
 {
     m_pageClient->selectionChanged(isNone, isContentEditable, isPasswordField, hasComposition);
 }
 #endif
+
+#if PLATFORM(WIN)
+void WebPageProxy::didChangeCompositionSelection(bool hasComposition)
+{
+    m_pageClient->compositionSelectionChanged(hasComposition);
+}
+
+void WebPageProxy::confirmComposition(const String& compositionString)
+{
+    process()->send(Messages::WebPage::ConfirmComposition(compositionString), m_pageID);
+}
+
+void WebPageProxy::setComposition(const String& compositionString, Vector<WebCore::CompositionUnderline>& underlines, int cursorPosition)
+{
+    process()->send(Messages::WebPage::SetComposition(compositionString, underlines, cursorPosition), m_pageID);
+}
+#endif
     
 // Undo management
 
diff --git a/WebKit2/UIProcess/WebPageProxy.h b/WebKit2/UIProcess/WebPageProxy.h
index 977ef2b..73c15a8 100644
--- a/WebKit2/UIProcess/WebPageProxy.h
+++ b/WebKit2/UIProcess/WebPageProxy.h
@@ -183,9 +183,15 @@ public:
     void sendComplexTextInputToPlugin(uint64_t pluginComplexTextInputIdentifier, const String& textInput);
 
 #else
-    void didSelectionChange(bool, bool, bool, bool);
+    void didChangeSelection(bool, bool, bool, bool);
+#endif
+#if PLATFORM(WIN)
+    void didChangeCompositionSelection(bool);
+    void confirmComposition(const String&);
+    void setComposition(const String&, Vector<WebCore::CompositionUnderline>&, int);
+    WebCore::IntRect firstRectForCharacterInSelectedRange(int);
+    String getSelectedText();
 #endif
-
 #if ENABLE(TILED_BACKING_STORE)
     void setActualVisibleContentRect(const WebCore::IntRect& rect);
 #endif
diff --git a/WebKit2/UIProcess/WebPageProxy.messages.in b/WebKit2/UIProcess/WebPageProxy.messages.in
index d450c14..a3e2b64 100644
--- a/WebKit2/UIProcess/WebPageProxy.messages.in
+++ b/WebKit2/UIProcess/WebPageProxy.messages.in
@@ -126,9 +126,11 @@ messages -> WebPageProxy {
     DidSelectionChange(bool isNone, bool isContentEditable, bool isPasswordField, bool hasComposition, uint64_t location, uint64_t length)
 #endif
 #if !PLATFORM(MAC)
-    DidSelectionChange(bool isNone, bool isContentEditable, bool isPasswordField, bool hasComposition)
+    DidChangeSelection(bool isNone, bool isContentEditable, bool isPasswordField, bool hasComposition)
+#endif
+#if PLATFORM(WIN)
+    DidChangeCompositionSelection(bool hasChanged)
 #endif
-
     # Find.
     DidCountStringMatches(WTF::String string, uint32_t matchCount)
     SetFindIndicator(WebCore::FloatRect selectionRect, Vector<WebCore::FloatRect> textRects, WebKit::SharedMemory::Handle contentImageHandle, bool fadeOut)
diff --git a/WebKit2/UIProcess/win/WebView.cpp b/WebKit2/UIProcess/win/WebView.cpp
index 38cb966..f73826f 100644
--- a/WebKit2/UIProcess/win/WebView.cpp
+++ b/WebKit2/UIProcess/win/WebView.cpp
@@ -28,6 +28,7 @@
 #include "ChunkedUpdateDrawingAreaProxy.h"
 #include "FindIndicator.h"
 #include "LayerBackedDrawingAreaProxy.h"
+#include "Logging.h"
 #include "RunLoop.h"
 #include "NativeWebKeyboardEvent.h"
 #include "WebContext.h"
@@ -40,10 +41,25 @@
 #include <WebCore/Cursor.h>
 #include <WebCore/FloatRect.h>
 #include <WebCore/IntRect.h>
+#include <WebCore/SoftLinking.h>
 #include <WebCore/WebCoreInstanceHandle.h>
 #include <WebCore/WindowMessageBroadcaster.h>
 #include <wtf/text/WTFString.h>
 
+namespace Ime {
+    // We need these functions in a separate namespace, because in the global namespace they conflict
+    // with the definitions in imm.h only by the type modifier (the macro defines them as static) and
+    // imm.h is included by windows.h
+    SOFT_LINK_LIBRARY(IMM32)
+    SOFT_LINK(IMM32, ImmGetContext, HIMC, WINAPI, (HWND hwnd), (hwnd))
+    SOFT_LINK(IMM32, ImmReleaseContext, BOOL, WINAPI, (HWND hWnd, HIMC hIMC), (hWnd, hIMC))
+    SOFT_LINK(IMM32, ImmGetCompositionStringW, LONG, WINAPI, (HIMC hIMC, DWORD dwIndex, LPVOID lpBuf, DWORD dwBufLen), (hIMC, dwIndex, lpBuf, dwBufLen))
+    SOFT_LINK(IMM32, ImmSetCandidateWindow, BOOL, WINAPI, (HIMC hIMC, LPCANDIDATEFORM lpCandidate), (hIMC, lpCandidate))
+    SOFT_LINK(IMM32, ImmSetOpenStatus, BOOL, WINAPI, (HIMC hIMC, BOOL fOpen), (hIMC, fOpen))
+    SOFT_LINK(IMM32, ImmNotifyIME, BOOL, WINAPI, (HIMC hIMC, DWORD dwAction, DWORD dwIndex, DWORD dwValue), (hIMC, dwAction, dwIndex, dwValue))
+    SOFT_LINK(IMM32, ImmAssociateContextEx, BOOL, WINAPI, (HWND hWnd, HIMC hIMC, DWORD dwFlags), (hWnd, hIMC, dwFlags))
+};
+
 using namespace WebCore;
 
 namespace WebKit {
@@ -146,6 +162,24 @@ LRESULT WebView::wndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
         case WM_SETCURSOR:
             lResult = onSetCursor(hWnd, message, wParam, lParam, handled);
             break;
+        case WM_IME_STARTCOMPOSITION:
+            handled = onIMEStartComposition();
+            break;
+        case WM_IME_REQUEST:
+            lResult = onIMERequest(wParam, lParam);
+            break;
+        case WM_IME_COMPOSITION:
+            handled = onIMEComposition(lParam);
+            break;
+        case WM_IME_ENDCOMPOSITION:
+            handled = onIMEEndComposition();
+            break;
+        case WM_IME_SELECT:
+            handled = onIMESelect(wParam, lParam);
+            break;
+        case WM_IME_SETCONTEXT:
+            handled = onIMESetContext(wParam, lParam);
+            break;
         default:
             handled = false;
             break;
@@ -191,6 +225,11 @@ WebView::WebView(RECT rect, WebContext* context, WebPageGroup* pageGroup, HWND p
     , m_overrideCursor(0)
     , m_trackingMouseLeave(false)
     , m_isBeingDestroyed(false)
+    , m_selectionIsNone(true)
+    , m_selectionIsEditable(false)
+    , m_selectionInPasswordField(false)
+    , m_hasMarkedText(false)
+    , m_inIMEComposition(0)
 {
     registerWebViewWindowClass();
 
@@ -615,9 +654,269 @@ FloatRect WebView::convertToUserSpace(const FloatRect& rect)
     return rect;
 }
 
-void WebView::selectionChanged(bool, bool, bool, bool)
+HIMC WebView::getIMMContext() 
 {
-    // FIXME: Implement.
+    return Ime::ImmGetContext(m_window);
+}
+
+void WebView::prepareCandidateWindow(HIMC hInputContext) 
+{
+    IntRect caret = m_page->firstRectForCharacterInSelectedRange(0);
+    CANDIDATEFORM form;
+    form.dwIndex = 0;
+    form.dwStyle = CFS_EXCLUDE;
+    form.ptCurrentPos.x = caret.x();
+    form.ptCurrentPos.y = caret.bottom();
+    form.rcArea.top = caret.y();
+    form.rcArea.bottom = caret.bottom();
+    form.rcArea.left = caret.x();
+    form.rcArea.right = caret.right();
+    Ime::ImmSetCandidateWindow(hInputContext, &form);
+}
+
+void WebView::resetIME()
+{
+    HIMC hInputContext = getIMMContext();
+    if (!hInputContext)
+        return;
+    Ime::ImmNotifyIME(hInputContext, NI_COMPOSITIONSTR, CPS_CANCEL, 0);
+    Ime::ImmReleaseContext(m_window, hInputContext);
+}
+
+void WebView::setInputMethodState(bool enabled)
+{
+    Ime::ImmAssociateContextEx(m_window, 0, enabled ? IACE_DEFAULT : 0);
+}
+
+void WebView::selectionChanged(bool isNone, bool isEditable, bool isPasswordField, bool hasComposition)
+{
+    m_selectionIsNone = isNone;
+    m_selectionIsEditable = isEditable;
+    m_selectionInPasswordField = isPasswordField;
+    m_hasMarkedText = hasComposition;
+}
+
+void WebView::compositionSelectionChanged(bool hasChanged)
+{
+    if (m_hasMarkedText && !hasChanged)
+        resetIME();
+}
+
+bool WebView::onIMEStartComposition()
+{
+    LOG(TextInput, "onIMEStartComposition");
+    m_inIMEComposition++;
+
+    HIMC hInputContext = getIMMContext();
+    if (!hInputContext)
+        return false;
+    prepareCandidateWindow(hInputContext);
+    Ime::ImmReleaseContext(m_window, hInputContext);
+    return true;
+}
+
+static bool getCompositionString(HIMC hInputContext, DWORD type, String& result)
+{
+    LONG compositionLength = Ime::ImmGetCompositionStringW(hInputContext, type, 0, 0);
+    if (compositionLength <= 0)
+        return false;
+    Vector<UChar> compositionBuffer(compositionLength / 2);
+    compositionLength = Ime::ImmGetCompositionStringW(hInputContext, type, compositionBuffer.data(), compositionLength);
+    result = String::adopt(compositionBuffer);
+    return true;
+}
+
+static void compositionToUnderlines(const Vector<DWORD>& clauses, const Vector<BYTE>& attributes, Vector<CompositionUnderline>& underlines)
+{
+    if (clauses.isEmpty()) {
+        underlines.clear();
+        return;
+    }
+  
+    size_t numBoundaries = clauses.size() - 1;
+    underlines.resize(numBoundaries);
+    for (unsigned i = 0; i < numBoundaries; ++i) {
+        underlines[i].startOffset = clauses[i];
+        underlines[i].endOffset = clauses[i + 1];
+        BYTE attribute = attributes[clauses[i]];
+        underlines[i].thick = attribute == ATTR_TARGET_CONVERTED || attribute == ATTR_TARGET_NOTCONVERTED;
+        underlines[i].color = Color::black;
+    }
+}
+
+#if !LOG_DISABLED
+#define APPEND_ARGUMENT_NAME(name) \
+    if (lparam & name) { \
+        if (needsComma) \
+            result += ", "; \
+            result += #name; \
+        needsComma = true; \
+    }
+
+static String imeCompositionArgumentNames(LPARAM lparam)
+{
+    String result;
+    bool needsComma = false;
+
+    APPEND_ARGUMENT_NAME(GCS_COMPATTR);
+    APPEND_ARGUMENT_NAME(GCS_COMPCLAUSE);
+    APPEND_ARGUMENT_NAME(GCS_COMPREADSTR);
+    APPEND_ARGUMENT_NAME(GCS_COMPREADATTR);
+    APPEND_ARGUMENT_NAME(GCS_COMPREADCLAUSE);
+    APPEND_ARGUMENT_NAME(GCS_COMPSTR);
+    APPEND_ARGUMENT_NAME(GCS_CURSORPOS);
+    APPEND_ARGUMENT_NAME(GCS_DELTASTART);
+    APPEND_ARGUMENT_NAME(GCS_RESULTCLAUSE);
+    APPEND_ARGUMENT_NAME(GCS_RESULTREADCLAUSE);
+    APPEND_ARGUMENT_NAME(GCS_RESULTREADSTR);
+    APPEND_ARGUMENT_NAME(GCS_RESULTSTR);
+    APPEND_ARGUMENT_NAME(CS_INSERTCHAR);
+    APPEND_ARGUMENT_NAME(CS_NOMOVECARET);
+
+    return result;
+}
+
+static String imeRequestName(WPARAM wparam)
+{
+    switch (wparam) {
+    case IMR_CANDIDATEWINDOW:
+        return "IMR_CANDIDATEWINDOW";
+    case IMR_COMPOSITIONFONT:
+        return "IMR_COMPOSITIONFONT";
+    case IMR_COMPOSITIONWINDOW:
+        return "IMR_COMPOSITIONWINDOW";
+    case IMR_CONFIRMRECONVERTSTRING:
+        return "IMR_CONFIRMRECONVERTSTRING";
+    case IMR_DOCUMENTFEED:
+        return "IMR_DOCUMENTFEED";
+    case IMR_QUERYCHARPOSITION:
+        return "IMR_QUERYCHARPOSITION";
+    case IMR_RECONVERTSTRING:
+        return "IMR_RECONVERTSTRING";
+    default:
+        return "Unknown (" + String::number(wparam) + ")";
+    }
+}
+#endif
+
+bool WebView::onIMEComposition(LPARAM lparam)
+{
+    LOG(TextInput, "onIMEComposition %s", imeCompositionArgumentNames(lparam).latin1().data());
+    HIMC hInputContext = getIMMContext();
+    if (!hInputContext)
+        return true;
+
+    if (!m_selectionIsEditable)
+        return true;
+
+    prepareCandidateWindow(hInputContext);
+
+    if (lparam & GCS_RESULTSTR || !lparam) {
+        String compositionString;
+        if (!getCompositionString(hInputContext, GCS_RESULTSTR, compositionString) && lparam)
+            return true;
+        
+        m_page->confirmComposition(compositionString);
+        return true;
+    }
+
+    String compositionString;
+    if (!getCompositionString(hInputContext, GCS_COMPSTR, compositionString))
+        return true;
+    
+    // Composition string attributes
+    int numAttributes = Ime::ImmGetCompositionStringW(hInputContext, GCS_COMPATTR, 0, 0);
+    Vector<BYTE> attributes(numAttributes);
+    Ime::ImmGetCompositionStringW(hInputContext, GCS_COMPATTR, attributes.data(), numAttributes);
+
+    // Get clauses
+    int numBytes = Ime::ImmGetCompositionStringW(hInputContext, GCS_COMPCLAUSE, 0, 0);
+    Vector<DWORD> clauses(numBytes / sizeof(DWORD));
+    Ime::ImmGetCompositionStringW(hInputContext, GCS_COMPCLAUSE, clauses.data(), numBytes);
+
+    Vector<CompositionUnderline> underlines;
+    compositionToUnderlines(clauses, attributes, underlines);
+
+    int cursorPosition = LOWORD(Ime::ImmGetCompositionStringW(hInputContext, GCS_CURSORPOS, 0, 0));
+
+    m_page->setComposition(compositionString, underlines, cursorPosition);
+
+    return true;
+}
+
+bool WebView::onIMEEndComposition()
+{
+    LOG(TextInput, "onIMEEndComposition");
+    // If the composition hasn't been confirmed yet, it needs to be cancelled.
+    // This happens after deleting the last character from inline input hole.
+    if (m_hasMarkedText)
+        m_page->confirmComposition(String());
+
+    if (m_inIMEComposition)
+        m_inIMEComposition--;
+
+    return true;
+}
+
+LRESULT WebView::onIMERequestCharPosition(IMECHARPOSITION* charPos)
+{
+    if (charPos->dwCharPos && !m_hasMarkedText)
+        return 0;
+    IntRect caret = m_page->firstRectForCharacterInSelectedRange(charPos->dwCharPos);
+    charPos->pt.x = caret.x();
+    charPos->pt.y = caret.y();
+    ::ClientToScreen(m_window, &charPos->pt);
+    charPos->cLineHeight = caret.height();
+    ::GetWindowRect(m_window, &charPos->rcDocument);
+    return true;
+}
+
+LRESULT WebView::onIMERequestReconvertString(RECONVERTSTRING* reconvertString)
+{
+    String text = m_page->getSelectedText();
+    unsigned totalSize = sizeof(RECONVERTSTRING) + text.length() * sizeof(UChar);
+    
+    if (!reconvertString)
+        return totalSize;
+
+    if (totalSize > reconvertString->dwSize)
+        return 0;
+    reconvertString->dwCompStrLen = text.length();
+    reconvertString->dwStrLen = text.length();
+    reconvertString->dwTargetStrLen = text.length();
+    reconvertString->dwStrOffset = sizeof(RECONVERTSTRING);
+    memcpy(reconvertString + 1, text.characters(), text.length() * sizeof(UChar));
+    return totalSize;
+}
+
+LRESULT WebView::onIMERequest(WPARAM request, LPARAM data)
+{
+    LOG(TextInput, "onIMERequest %s", imeRequestName(request).latin1().data());
+    if (!m_selectionIsEditable)
+        return 0;
+
+    switch (request) {
+        case IMR_RECONVERTSTRING:
+            return onIMERequestReconvertString(reinterpret_cast<RECONVERTSTRING*>(data));
+
+        case IMR_QUERYCHARPOSITION:
+            return onIMERequestCharPosition(reinterpret_cast<IMECHARPOSITION*>(data));
+    }
+    return 0;
+}
+
+bool WebView::onIMESelect(WPARAM wparam, LPARAM lparam)
+{
+    UNUSED_PARAM(wparam);
+    UNUSED_PARAM(lparam);
+    LOG(TextInput, "onIMESelect locale %ld %s", lparam, wparam ? "select" : "deselect");
+    return false;
+}
+
+bool WebView::onIMESetContext(WPARAM wparam, LPARAM)
+{
+    LOG(TextInput, "onIMESetContext %s", wparam ? "active" : "inactive");
+    return false;
 }
 
 void WebView::didNotHandleKeyEvent(const NativeWebKeyboardEvent& event)
diff --git a/WebKit2/UIProcess/win/WebView.h b/WebKit2/UIProcess/win/WebView.h
index dcc8814..2141076 100644
--- a/WebKit2/UIProcess/win/WebView.h
+++ b/WebKit2/UIProcess/win/WebView.h
@@ -77,6 +77,18 @@ private:
     LRESULT onTimerEvent(HWND hWnd, UINT message, WPARAM, LPARAM, bool& handled);
     LRESULT onShowWindowEvent(HWND hWnd, UINT message, WPARAM, LPARAM, bool& handled);
     LRESULT onSetCursor(HWND hWnd, UINT message, WPARAM, LPARAM, bool& handled);
+    bool onIMEStartComposition();
+    bool onIMEComposition(LPARAM);
+    bool onIMEEndComposition();
+    LRESULT onIMERequest(WPARAM, LPARAM);
+    bool onIMESelect(WPARAM, LPARAM);
+    bool onIMESetContext(WPARAM, LPARAM);
+    void resetIME();
+    void setInputMethodState(bool);
+    HIMC getIMMContext();
+    void prepareCandidateWindow(HIMC);
+    LRESULT onIMERequestCharPosition(IMECHARPOSITION*);
+    LRESULT onIMERequestReconvertString(RECONVERTSTRING*);
 
     bool isActive();
     void updateActiveState();
@@ -105,6 +117,7 @@ private:
     virtual WebCore::FloatRect convertToUserSpace(const WebCore::FloatRect&);
     virtual void didNotHandleKeyEvent(const NativeWebKeyboardEvent&);
     virtual void selectionChanged(bool, bool, bool, bool);
+    virtual void compositionSelectionChanged(bool);
     virtual PassRefPtr<WebPopupMenuProxy> createPopupMenuProxy();
     virtual PassRefPtr<WebContextMenuProxy> createContextMenuProxy(WebPageProxy*);
     virtual void setFindIndicator(PassRefPtr<FindIndicator>, bool fadeOut);
@@ -136,6 +149,13 @@ private:
     bool m_isBeingDestroyed;
 
     RefPtr<WebPageProxy> m_page;
+
+    // Text input state values
+    bool m_selectionIsNone;
+    bool m_selectionIsEditable;
+    bool m_selectionInPasswordField;
+    bool m_hasMarkedText;
+    unsigned m_inIMEComposition;
 };
 
 } // namespace WebKit
diff --git a/WebKit2/WebProcess/WebCoreSupport/WebEditorClient.cpp b/WebKit2/WebProcess/WebCoreSupport/WebEditorClient.cpp
index 563e248..92feab8 100644
--- a/WebKit2/WebProcess/WebCoreSupport/WebEditorClient.cpp
+++ b/WebKit2/WebProcess/WebCoreSupport/WebEditorClient.cpp
@@ -186,7 +186,16 @@ void WebEditorClient::respondToChangedSelection()
     Frame* frame = m_page->corePage()->focusController()->focusedFrame();
     if (!frame)
         return;
-    m_page->send(Messages::WebPageProxy::DidSelectionChange(frame->selection()->isNone(), frame->selection()->isContentEditable(), frame->selection()->isInPasswordField(), frame->editor()->hasComposition()));
+
+    m_page->send(Messages::WebPageProxy::DidChangeSelection(frame->selection()->isNone(), frame->selection()->isContentEditable(), frame->selection()->isInPasswordField(), frame->editor()->hasComposition()));
+#if PLATFORM(WIN)
+    if (!frame->editor()->hasComposition() || frame->editor()->ignoreCompositionSelectionChange())
+        return;
+
+    unsigned start;
+    unsigned end;
+    m_page->send(Messages::WebPageProxy::DidChangeCompositionSelection(frame->editor()->getCompositionSelection(start, end)));
+#endif
 }
 #endif
     
diff --git a/WebKit2/WebProcess/WebPage/WebPage.cpp b/WebKit2/WebProcess/WebPage/WebPage.cpp
index c52b8a5..f24a32e 100644
--- a/WebKit2/WebProcess/WebPage/WebPage.cpp
+++ b/WebKit2/WebProcess/WebPage/WebPage.cpp
@@ -1029,7 +1029,7 @@ bool WebPage::handleEditingKeyboardEvent(KeyboardEvent* evt)
     return frame->editor()->insertText(evt->keyEvent()->text(), evt);
 }
 #endif
-    
+
 WebEditCommand* WebPage::webEditCommand(uint64_t commandID)
 {
     return m_editCommandMap.get(commandID).get();
diff --git a/WebKit2/WebProcess/WebPage/WebPage.h b/WebKit2/WebProcess/WebPage/WebPage.h
index bc87a99..b6c7b75 100644
--- a/WebKit2/WebProcess/WebPage/WebPage.h
+++ b/WebKit2/WebProcess/WebPage/WebPage.h
@@ -38,6 +38,7 @@
 #include "Plugin.h"
 #include "SandboxExtension.h"
 #include "WebEditCommand.h"
+#include <WebCore/Editor.h>
 #include <WebCore/FrameLoaderTypes.h>
 #include <WebCore/IntRect.h>
 #include <wtf/HashMap.h>
@@ -251,6 +252,11 @@ public:
     void characterIndexForPoint(const WebCore::IntPoint point, uint64_t& result);
     void firstRectForCharacterRange(uint64_t location, uint64_t length, WebCore::IntRect& resultRect);
     static void convertRangeToPlatformRange(WebCore::Frame* frame, WebCore::Range *range, uint64_t& location, uint64_t& length);
+#elif PLATFORM(WIN)
+    void confirmComposition(const String& compositionString);
+    void setComposition(const WTF::String& compositionString, const WTF::Vector<WebCore::CompositionUnderline>& underlines, uint64_t cursorPosition);
+    void firstRectForCharacterInSelectedRange(const uint64_t characterPosition, WebCore::IntRect& resultRect);
+    void getSelectedText(WTF::String&);
 #endif
     void dummy(bool&);
 
diff --git a/WebKit2/WebProcess/WebPage/WebPage.messages.in b/WebKit2/WebProcess/WebPage/WebPage.messages.in
index 0380b67..404095a 100644
--- a/WebKit2/WebProcess/WebPage/WebPage.messages.in
+++ b/WebKit2/WebProcess/WebPage/WebPage.messages.in
@@ -1,117 +1,123 @@
-# Copyright (C) 2010 Apple Inc. All rights reserved.
-#
-# Redistribution and use in source and binary forms, with or without
-# modification, are permitted provided that the following conditions
-# are met:
-# 1.  Redistributions of source code must retain the above copyright
-#     notice, this list of conditions and the following disclaimer.
-# 2.  Redistributions in binary form must reproduce the above copyright
-#     notice, this list of conditions and the following disclaimer in the
-#     documentation and/or other materials provided with the distribution.
-#
-# THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS'' AND
-# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
-# WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
-# DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS BE LIABLE FOR
-# ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
-# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
-# SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
-# CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
-# OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-
-messages -> WebPage {
-    SetActive(bool active)
-    SetFocused(bool focused)
-    SetIsInWindow(bool isInWindow)
-
-    SetDrawsBackground(bool drawsBackground)
-    SetDrawsTransparentBackground(bool drawsTransparentBackground)
-
-    KeyEvent(WebKit::WebKeyboardEvent event)
-    MouseEvent(WebKit::WebMouseEvent event)
-    WheelEvent(WebKit::WebWheelEvent event)
-#if ENABLE(TOUCH_EVENTS)
-    TouchEvent(WebKit::WebTouchEvent event)
-#endif
-
-    GoBack(uint64_t backForwardItemID)
-    GoForward(uint64_t backForwardItemID)
-    GoToBackForwardItem(uint64_t backForwardItemID)
-    LoadHTMLString(WTF::String htmlString, WTF::String baseURL)
-    LoadAlternateHTMLString(WTF::String htmlString, WTF::String baseURL, WTF::String unreachableURL); 
-    LoadPlainTextString(WTF::String string)
-    LoadURL(WTF::String url, WebKit::SandboxExtension::Handle sandboxExtensionHandle)
-    LoadURLRequest(WebCore::ResourceRequest request, WebKit::SandboxExtension::Handle sandboxExtensionHandle)
-    Reload(bool reloadFromOrigin)
-    StopLoading()
-
-    DidReceivePolicyDecision(uint64_t frameID, uint64_t listenerID, uint32_t policyAction, uint64_t downloadID)
-
-    # Callbacks.
-    GetRenderTreeExternalRepresentation(uint64_t callbackID)
-    GetContentsAsString(uint64_t callbackID)
-    GetSourceForFrame(uint64_t frameID, uint64_t callbackID)
-    RunJavaScriptInMainFrame(WTF::String script, uint64_t callbackID)
-
-    PreferencesDidChange(WebKit::WebPreferencesStore store)
-
-    SetUserAgent(WTF::String userAgent)
-
-#if ENABLE(TILED_BACKING_STORE)
-    SetActualVisibleContentRect(WebCore::IntRect rect)
-    SetResizesToContentsUsingLayoutSize(WebCore::IntSize size)
-#endif
-
-    Close()
-    TryClose()
-
-    ValidateMenuItem(WTF::String name)
-    ExecuteEditCommand(WTF::String name)
-
-    DidRemoveEditCommand(uint64_t commandID)
-    ReapplyEditCommand(uint64_t commandID)
-    UnapplyEditCommand(uint64_t commandID)
-
-    SetPageAndTextZoomFactors(double pageZoomFactor, double textZoomFactor)
-    SetPageZoomFactor(double zoomFactor)
-    SetTextZoomFactor(double zoomFactor)
-
-    ScaleWebView(double scale, WebCore::IntPoint origin)
-
-    # Find.
-    FindString(WTF::String string, uint32_t findOptions, unsigned maxMatchCount)
-    HideFindUI()
-    CountStringMatches(WTF::String string, uint32_t findOptions, unsigned maxMatchCount)
-
-    # Popup menu.
-    DidChangeSelectedIndexForActivePopupMenu(int32_t newIndex);
-    
-    # Context menu.
-    DidSelectItemFromActiveContextMenu(WebKit::WebContextMenuItemData menuItem);
-
-    # Open panel.
-    DidChooseFilesForOpenPanel(Vector<WTF::String> fileURLs)
-    DidCancelForOpenPanel()
-
-    SetWindowResizerSize(WebCore::IntSize intersectsView)
-
-#if PLATFORM(MAC)
-    # Complex text input support for plug-ins.
-    SendComplexTextInputToPlugin(uint64_t pluginComplexTextInputIdentifier, String textInput)
-
-    SetWindowIsVisible(bool windowIsVisible)
-    WindowAndViewFramesChanged(WebCore::IntRect windowFrameInScreenCoordinates, WebCore::IntRect viewFrameInWindowCoordinates)
-    GetMarkedRange() -> (uint64_t location, uint64_t length)
-    CharacterIndexForPoint(WebCore::IntPoint point) -> (uint64_t result)
-    FirstRectForCharacterRange(uint64_t location, uint64_t length) -> (WebCore::IntRect resultRect)
-#endif
-
-#if PLATFORM(QT)
-    FindZoomableAreaForPoint(WebCore::IntPoint point)
-#endif
-
-    // This is a dummy message to avoid breaking the build for platforms that don't require 
-    // synchronous messages.
-    Dummy() -> (bool dummyReturn)
-}
+# Copyright (C) 2010 Apple Inc. All rights reserved.
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions
+# are met:
+# 1.  Redistributions of source code must retain the above copyright
+#     notice, this list of conditions and the following disclaimer.
+# 2.  Redistributions in binary form must reproduce the above copyright
+#     notice, this list of conditions and the following disclaimer in the
+#     documentation and/or other materials provided with the distribution.
+#
+# THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS'' AND
+# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+# WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+# DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS BE LIABLE FOR
+# ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+# SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+# CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+# OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+messages -> WebPage {
+    SetActive(bool active)
+    SetFocused(bool focused)
+    SetIsInWindow(bool isInWindow)
+
+    SetDrawsBackground(bool drawsBackground)
+    SetDrawsTransparentBackground(bool drawsTransparentBackground)
+
+    KeyEvent(WebKit::WebKeyboardEvent event)
+    MouseEvent(WebKit::WebMouseEvent event)
+    WheelEvent(WebKit::WebWheelEvent event)
+#if ENABLE(TOUCH_EVENTS)
+    TouchEvent(WebKit::WebTouchEvent event)
+#endif
+
+    GoBack(uint64_t backForwardItemID)
+    GoForward(uint64_t backForwardItemID)
+    GoToBackForwardItem(uint64_t backForwardItemID)
+    LoadHTMLString(WTF::String htmlString, WTF::String baseURL)
+    LoadAlternateHTMLString(WTF::String htmlString, WTF::String baseURL, WTF::String unreachableURL); 
+    LoadPlainTextString(WTF::String string)
+    LoadURL(WTF::String url, WebKit::SandboxExtension::Handle sandboxExtensionHandle)
+    LoadURLRequest(WebCore::ResourceRequest request, WebKit::SandboxExtension::Handle sandboxExtensionHandle)
+    Reload(bool reloadFromOrigin)
+    StopLoading()
+
+    DidReceivePolicyDecision(uint64_t frameID, uint64_t listenerID, uint32_t policyAction, uint64_t downloadID)
+
+    # Callbacks.
+    GetRenderTreeExternalRepresentation(uint64_t callbackID)
+    GetContentsAsString(uint64_t callbackID)
+    GetSourceForFrame(uint64_t frameID, uint64_t callbackID)
+    RunJavaScriptInMainFrame(WTF::String script, uint64_t callbackID)
+
+    PreferencesDidChange(WebKit::WebPreferencesStore store)
+
+    SetUserAgent(WTF::String userAgent)
+
+#if ENABLE(TILED_BACKING_STORE)
+    SetActualVisibleContentRect(WebCore::IntRect rect)
+    SetResizesToContentsUsingLayoutSize(WebCore::IntSize size)
+#endif
+
+    Close()
+    TryClose()
+
+    ValidateMenuItem(WTF::String name)
+    ExecuteEditCommand(WTF::String name)
+
+    DidRemoveEditCommand(uint64_t commandID)
+    ReapplyEditCommand(uint64_t commandID)
+    UnapplyEditCommand(uint64_t commandID)
+
+    SetPageAndTextZoomFactors(double pageZoomFactor, double textZoomFactor)
+    SetPageZoomFactor(double zoomFactor)
+    SetTextZoomFactor(double zoomFactor)
+
+    ScaleWebView(double scale, WebCore::IntPoint origin)
+
+    # Find.
+    FindString(WTF::String string, uint32_t findOptions, unsigned maxMatchCount)
+    HideFindUI()
+    CountStringMatches(WTF::String string, uint32_t findOptions, unsigned maxMatchCount)
+
+    # Popup menu.
+    DidChangeSelectedIndexForActivePopupMenu(int32_t newIndex);
+    
+    # Context menu.
+    DidSelectItemFromActiveContextMenu(WebKit::WebContextMenuItemData menuItem);
+
+    # Open panel.
+    DidChooseFilesForOpenPanel(Vector<WTF::String> fileURLs)
+    DidCancelForOpenPanel()
+
+    SetWindowResizerSize(WebCore::IntSize intersectsView)
+
+	// This is a dummy message to avoid breaking the build for platforms that don't require
+	// synchronous messages.
+    // FIXME: should be removed when <rdar://problem/8775115> is fixed.
+	Dummy() -> (bool dummyReturn)
+	
+#if PLATFORM(MAC)
+    # Complex text input support for plug-ins.
+    SendComplexTextInputToPlugin(uint64_t pluginComplexTextInputIdentifier, String textInput)
+
+    SetWindowIsVisible(bool windowIsVisible)
+    WindowAndViewFramesChanged(WebCore::IntRect windowFrameInScreenCoordinates, WebCore::IntRect viewFrameInWindowCoordinates)
+    GetMarkedRange() -> (uint64_t location, uint64_t length)
+    CharacterIndexForPoint(WebCore::IntPoint point) -> (uint64_t result)
+    FirstRectForCharacterRange(uint64_t location, uint64_t length) -> (WebCore::IntRect resultRect)
+#endif
+#if PLATFORM(WIN)
+    ConfirmComposition(WTF::String compositionString)
+    SetComposition(WTF::String compositionString, WTF::Vector<WebCore::CompositionUnderline> underlines, uint64_t cursorPosition)
+    FirstRectForCharacterInSelectedRange(uint64_t characterPosition) -> (WebCore::IntRect resultRect)
+    GetSelectedText() -> (WTF::String text)
+#endif
+#if PLATFORM(QT)
+    FindZoomableAreaForPoint(WebCore::IntPoint point)
+#endif
+}
diff --git a/WebKit2/WebProcess/WebPage/win/WebPageWin.cpp b/WebKit2/WebProcess/WebPage/win/WebPageWin.cpp
index 20b95ee..72554f8 100644
--- a/WebKit2/WebProcess/WebPage/win/WebPageWin.cpp
+++ b/WebKit2/WebProcess/WebPage/win/WebPageWin.cpp
@@ -31,6 +31,7 @@
 #include <WebCore/FocusController.h>
 #include <WebCore/FontRenderingMode.h>
 #include <WebCore/Frame.h>
+#include <WebCore/FrameView.h>
 #include <WebCore/KeyboardEvent.h>
 #include <WebCore/Page.h>
 #include <WebCore/PlatformKeyboardEvent.h>
@@ -266,4 +267,40 @@ bool WebPage::canHandleRequest(const WebCore::ResourceRequest& request)
     return CFURLProtocolCanHandleRequest(request.cfURLRequest());
 }
 
+void WebPage::confirmComposition(const String& compositionString)
+{
+    Frame* frame = m_page->focusController()->focusedOrMainFrame();
+    if (!frame || !frame->editor()->canEdit())
+        return;
+    frame->editor()->confirmComposition(compositionString);
+}
+
+void WebPage::setComposition(const String& compositionString, const Vector<WebCore::CompositionUnderline>& underlines, uint64_t cursorPosition)
+{
+    Frame* frame = m_page->focusController()->focusedOrMainFrame();
+    if (!frame || !frame->editor()->canEdit())
+        return;
+    frame->editor()->setComposition(compositionString, underlines, cursorPosition, 0);
+}
+
+void WebPage::firstRectForCharacterInSelectedRange(const uint64_t characterPosition, WebCore::IntRect& resultRect)
+{
+    Frame* frame = m_page->focusController()->focusedOrMainFrame();
+    IntRect rect;
+    if (RefPtr<Range> range = frame->editor()->hasComposition() ? frame->editor()->compositionRange() : frame->selection()->selection().toNormalizedRange()) {
+        ExceptionCode ec = 0;
+        RefPtr<Range> tempRange = range->cloneRange(ec);
+        tempRange->setStart(tempRange->startContainer(ec), tempRange->startOffset(ec) + characterPosition, ec);
+        rect = frame->editor()->firstRectForRange(tempRange.get());
+    }
+    resultRect = frame->view()->contentsToWindow(rect);
+}
+
+void WebPage::getSelectedText(String& text)
+{
+    Frame* frame = m_page->focusController()->focusedOrMainFrame();
+    RefPtr<Range> selectedRange = frame->selection()->toNormalizedRange();
+    text = selectedRange->text();
+}
+
 } // namespace WebKit

-- 
WebKit Debian packaging



More information about the Pkg-webkit-commits mailing list