WebKit/chromium/src/WebInputEventConversion.cpp
changeset 0 4f2f89ce4247
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/WebKit/chromium/src/WebInputEventConversion.cpp	Fri Sep 17 09:02:29 2010 +0300
@@ -0,0 +1,338 @@
+/*
+ * Copyright (C) 2009 Google 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:
+ *
+ *     * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *     * 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.
+ *     * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND 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 THE COPYRIGHT
+ * OWNER OR 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.
+ */
+
+#include "config.h"
+#include "WebInputEventConversion.h"
+
+#include "EventNames.h"
+#include "KeyboardCodes.h"
+#include "KeyboardEvent.h"
+#include "MouseEvent.h"
+#include "PlatformKeyboardEvent.h"
+#include "PlatformMouseEvent.h"
+#include "PlatformWheelEvent.h"
+#include "ScrollView.h"
+#include "WebInputEvent.h"
+#include "WheelEvent.h"
+#include "Widget.h"
+
+using namespace WebCore;
+
+namespace WebKit {
+
+// MakePlatformMouseEvent -----------------------------------------------------
+
+PlatformMouseEventBuilder::PlatformMouseEventBuilder(Widget* widget, const WebMouseEvent& e)
+{
+    // FIXME: widget is always toplevel, unless it's a popup.  We may be able
+    // to get rid of this once we abstract popups into a WebKit API.
+    m_position = widget->convertFromContainingWindow(IntPoint(e.x, e.y));
+    m_globalPosition = IntPoint(e.globalX, e.globalY);
+    m_button = static_cast<MouseButton>(e.button);
+    m_shiftKey = (e.modifiers & WebInputEvent::ShiftKey);
+    m_ctrlKey = (e.modifiers & WebInputEvent::ControlKey);
+    m_altKey = (e.modifiers & WebInputEvent::AltKey);
+    m_metaKey = (e.modifiers & WebInputEvent::MetaKey);
+    m_modifierFlags = e.modifiers;
+    m_timestamp = e.timeStampSeconds;
+    m_clickCount = e.clickCount;
+
+    switch (e.type) {
+    case WebInputEvent::MouseMove:
+    case WebInputEvent::MouseLeave:  // synthesize a move event
+        m_eventType = MouseEventMoved;
+        break;
+
+    case WebInputEvent::MouseDown:
+        m_eventType = MouseEventPressed;
+        break;
+
+    case WebInputEvent::MouseUp:
+        m_eventType = MouseEventReleased;
+        break;
+
+    default:
+        ASSERT_NOT_REACHED();
+    }
+}
+
+// PlatformWheelEventBuilder --------------------------------------------------
+
+PlatformWheelEventBuilder::PlatformWheelEventBuilder(Widget* widget, const WebMouseWheelEvent& e)
+{
+    m_position = widget->convertFromContainingWindow(IntPoint(e.x, e.y));
+    m_globalPosition = IntPoint(e.globalX, e.globalY);
+    m_deltaX = e.deltaX;
+    m_deltaY = e.deltaY;
+    m_wheelTicksX = e.wheelTicksX;
+    m_wheelTicksY = e.wheelTicksY;
+    m_isAccepted = false;
+    m_granularity = e.scrollByPage ?
+        ScrollByPageWheelEvent : ScrollByPixelWheelEvent;
+    m_shiftKey = (e.modifiers & WebInputEvent::ShiftKey);
+    m_ctrlKey = (e.modifiers & WebInputEvent::ControlKey);
+    m_altKey = (e.modifiers & WebInputEvent::AltKey);
+    m_metaKey = (e.modifiers & WebInputEvent::MetaKey);
+}
+
+// MakePlatformKeyboardEvent --------------------------------------------------
+
+static inline const PlatformKeyboardEvent::Type toPlatformKeyboardEventType(WebInputEvent::Type type)
+{
+    switch (type) {
+    case WebInputEvent::KeyUp:
+        return PlatformKeyboardEvent::KeyUp;
+    case WebInputEvent::KeyDown:
+        return PlatformKeyboardEvent::KeyDown;
+    case WebInputEvent::RawKeyDown:
+        return PlatformKeyboardEvent::RawKeyDown;
+    case WebInputEvent::Char:
+        return PlatformKeyboardEvent::Char;
+    default:
+        ASSERT_NOT_REACHED();
+    }
+    return PlatformKeyboardEvent::KeyDown;
+}
+
+PlatformKeyboardEventBuilder::PlatformKeyboardEventBuilder(const WebKeyboardEvent& e)
+{
+    m_type = toPlatformKeyboardEventType(e.type);
+    m_text = String(e.text);
+    m_unmodifiedText = String(e.unmodifiedText);
+    m_keyIdentifier = String(e.keyIdentifier);
+    m_autoRepeat = (e.modifiers & WebInputEvent::IsAutoRepeat);
+    m_windowsVirtualKeyCode = e.windowsKeyCode;
+    m_nativeVirtualKeyCode = e.nativeKeyCode;
+    m_isKeypad = (e.modifiers & WebInputEvent::IsKeyPad);
+    m_shiftKey = (e.modifiers & WebInputEvent::ShiftKey);
+    m_ctrlKey = (e.modifiers & WebInputEvent::ControlKey);
+    m_altKey = (e.modifiers & WebInputEvent::AltKey);
+    m_metaKey = (e.modifiers & WebInputEvent::MetaKey);
+    m_isSystemKey = e.isSystemKey;
+}
+
+void PlatformKeyboardEventBuilder::setKeyType(Type type)
+{
+    // According to the behavior of Webkit in Windows platform,
+    // we need to convert KeyDown to RawKeydown and Char events
+    // See WebKit/WebKit/Win/WebView.cpp
+    ASSERT(m_type == KeyDown);
+    ASSERT(type == RawKeyDown || type == Char);
+    m_type = type;
+
+    if (type == RawKeyDown) {
+        m_text = String();
+        m_unmodifiedText = String();
+    } else {
+        m_keyIdentifier = String();
+        m_windowsVirtualKeyCode = 0;
+    }
+}
+
+// Please refer to bug http://b/issue?id=961192, which talks about Webkit
+// keyboard event handling changes. It also mentions the list of keys
+// which don't have associated character events.
+bool PlatformKeyboardEventBuilder::isCharacterKey() const
+{
+    switch (windowsVirtualKeyCode()) {
+    case VKEY_BACK:
+    case VKEY_ESCAPE:
+        return false;
+    }
+    return true;
+}
+
+#if ENABLE(TOUCH_EVENTS)
+static inline TouchEventType toPlatformTouchEventType(const WebInputEvent::Type type)
+{
+    switch (type) {
+    case WebInputEvent::TouchStart:
+        return TouchStart;
+    case WebInputEvent::TouchMove:
+        return TouchMove;
+    case WebInputEvent::TouchEnd:
+        return TouchEnd;
+    case WebInputEvent::TouchCancel:
+        return TouchCancel;
+    default:
+        ASSERT_NOT_REACHED();
+    }
+    return TouchStart;
+}
+
+static inline PlatformTouchPoint::State toPlatformTouchPointState(const WebTouchPoint::State state)
+{
+    switch (state) {
+    case WebTouchPoint::StateReleased:
+        return PlatformTouchPoint::TouchReleased;
+    case WebTouchPoint::StatePressed:
+        return PlatformTouchPoint::TouchPressed;
+    case WebTouchPoint::StateMoved:
+        return PlatformTouchPoint::TouchMoved;
+    case WebTouchPoint::StateStationary:
+        return PlatformTouchPoint::TouchStationary;
+    case WebTouchPoint::StateCancelled:
+        return PlatformTouchPoint::TouchCancelled;
+    case WebTouchPoint::StateUndefined:
+        ASSERT_NOT_REACHED();
+    }
+    return PlatformTouchPoint::TouchReleased;
+}
+
+PlatformTouchPointBuilder::PlatformTouchPointBuilder(Widget* widget, const WebTouchPoint& point)
+{
+    m_id = point.id;
+    m_state = toPlatformTouchPointState(point.state);
+    m_pos = widget->convertFromContainingWindow(point.position);
+    m_screenPos = point.screenPosition;
+}
+
+PlatformTouchEventBuilder::PlatformTouchEventBuilder(Widget* widget, const WebTouchEvent& event)
+{
+    m_type = toPlatformTouchEventType(event.type);
+    m_ctrlKey = event.modifiers & WebInputEvent::ControlKey;
+    m_altKey = event.modifiers & WebInputEvent::AltKey;
+    m_shiftKey = event.modifiers & WebInputEvent::ShiftKey;
+    m_metaKey = event.modifiers & WebInputEvent::MetaKey;
+
+    for (int i = 0; i < event.touchPointsLength; ++i)
+        m_touchPoints.append(PlatformTouchPointBuilder(widget, event.touchPoints[i]));
+}
+#endif
+
+static int getWebInputModifiers(const UIEventWithKeyState& event)
+{
+    int modifiers = 0;
+    if (event.ctrlKey())
+        modifiers |= WebInputEvent::ControlKey;
+    if (event.shiftKey())
+        modifiers |= WebInputEvent::ShiftKey;
+    if (event.altKey())
+        modifiers |= WebInputEvent::AltKey;
+    if (event.metaKey())
+        modifiers |= WebInputEvent::MetaKey;
+    return modifiers;
+}
+
+WebMouseEventBuilder::WebMouseEventBuilder(const ScrollView* view, const MouseEvent& event)
+{
+    if (event.type() == eventNames().mousemoveEvent)
+        type = WebInputEvent::MouseMove;
+    else if (event.type() == eventNames().mouseoutEvent)
+        type = WebInputEvent::MouseLeave;
+    else if (event.type() == eventNames().mouseoverEvent)
+        type = WebInputEvent::MouseEnter;
+    else if (event.type() == eventNames().mousedownEvent)
+        type = WebInputEvent::MouseDown;
+    else if (event.type() == eventNames().mouseupEvent)
+        type = WebInputEvent::MouseUp;
+    else
+        return; // Skip all other mouse events.
+    timeStampSeconds = event.timeStamp() * 1.0e-3;
+    switch (event.button()) {
+    case LeftButton:
+        button = WebMouseEvent::ButtonLeft;
+        break;
+    case MiddleButton:
+        button = WebMouseEvent::ButtonMiddle;
+        break;
+    case RightButton:
+        button = WebMouseEvent::ButtonRight;
+        break;
+    }
+    modifiers = getWebInputModifiers(event);
+    if (event.buttonDown()) {
+        switch (event.button()) {
+        case LeftButton:
+            modifiers |= WebInputEvent::LeftButtonDown;
+            break;
+        case MiddleButton:
+            modifiers |= WebInputEvent::MiddleButtonDown;
+            break;
+        case RightButton:
+            modifiers |= WebInputEvent::RightButtonDown;
+            break;
+        }
+    }
+    IntPoint p = view->contentsToWindow(IntPoint(event.pageX(), event.pageY()));
+    globalX = event.screenX();
+    globalY = event.screenY();
+    windowX = p.x();
+    windowY = p.y();
+    x = event.offsetX();
+    y = event.offsetY();
+    clickCount = event.detail();
+}
+
+WebMouseWheelEventBuilder::WebMouseWheelEventBuilder(const ScrollView* view, const WheelEvent& event)
+{
+    if (event.type() != eventNames().mousewheelEvent)
+        return;
+    type = WebInputEvent::MouseWheel;
+    timeStampSeconds = event.timeStamp() * 1.0e-3;
+    modifiers = getWebInputModifiers(event);
+    IntPoint p = view->contentsToWindow(IntPoint(event.pageX(), event.pageY()));
+    globalX = event.screenX();
+    globalY = event.screenY();
+    windowX = p.x();
+    windowY = p.y();
+    x = event.offsetX();
+    y = event.offsetY();
+    deltaX = static_cast<float>(event.rawDeltaX());
+    deltaY = static_cast<float>(event.rawDeltaY());
+    // The 120 is from WheelEvent::initWheelEvent().
+    wheelTicksX = static_cast<float>(event.wheelDeltaX()) / 120;
+    wheelTicksY = static_cast<float>(event.wheelDeltaY()) / 120;
+    scrollByPage = event.granularity() == WheelEvent::Page;
+}
+
+WebKeyboardEventBuilder::WebKeyboardEventBuilder(const KeyboardEvent& event)
+{
+    if (event.type() == eventNames().keydownEvent)
+        type = KeyDown;
+    else if (event.type() == eventNames().keyupEvent)
+        type = WebInputEvent::KeyUp;
+    else if (event.type() == eventNames().keypressEvent)
+        type = WebInputEvent::Char;
+    else
+        return; // Skip all other keyboard events.
+    modifiers = getWebInputModifiers(event);
+    timeStampSeconds = event.timeStamp() * 1.0e-3;
+    windowsKeyCode = event.keyCode();
+    nativeKeyCode = event.keyEvent()->nativeVirtualKeyCode();
+    unsigned int numChars = std::min(event.keyEvent()->text().length(),
+        static_cast<unsigned int>(WebKeyboardEvent::textLengthCap));
+    for (unsigned int i = 0; i < numChars; i++) {
+        text[i] = event.keyEvent()->text()[i];
+        unmodifiedText[i] = event.keyEvent()->unmodifiedText()[i];
+    }
+}
+
+} // namespace WebKit