WebKit/chromium/src/WebInputEventConversion.cpp
changeset 0 4f2f89ce4247
equal deleted inserted replaced
-1:000000000000 0:4f2f89ce4247
       
     1 /*
       
     2  * Copyright (C) 2009 Google Inc. All rights reserved.
       
     3  *
       
     4  * Redistribution and use in source and binary forms, with or without
       
     5  * modification, are permitted provided that the following conditions are
       
     6  * met:
       
     7  *
       
     8  *     * Redistributions of source code must retain the above copyright
       
     9  * notice, this list of conditions and the following disclaimer.
       
    10  *     * Redistributions in binary form must reproduce the above
       
    11  * copyright notice, this list of conditions and the following disclaimer
       
    12  * in the documentation and/or other materials provided with the
       
    13  * distribution.
       
    14  *     * Neither the name of Google Inc. nor the names of its
       
    15  * contributors may be used to endorse or promote products derived from
       
    16  * this software without specific prior written permission.
       
    17  *
       
    18  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
       
    19  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
       
    20  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
       
    21  * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
       
    22  * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
       
    23  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
       
    24  * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
       
    25  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
       
    26  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
       
    27  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
       
    28  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
       
    29  */
       
    30 
       
    31 #include "config.h"
       
    32 #include "WebInputEventConversion.h"
       
    33 
       
    34 #include "EventNames.h"
       
    35 #include "KeyboardCodes.h"
       
    36 #include "KeyboardEvent.h"
       
    37 #include "MouseEvent.h"
       
    38 #include "PlatformKeyboardEvent.h"
       
    39 #include "PlatformMouseEvent.h"
       
    40 #include "PlatformWheelEvent.h"
       
    41 #include "ScrollView.h"
       
    42 #include "WebInputEvent.h"
       
    43 #include "WheelEvent.h"
       
    44 #include "Widget.h"
       
    45 
       
    46 using namespace WebCore;
       
    47 
       
    48 namespace WebKit {
       
    49 
       
    50 // MakePlatformMouseEvent -----------------------------------------------------
       
    51 
       
    52 PlatformMouseEventBuilder::PlatformMouseEventBuilder(Widget* widget, const WebMouseEvent& e)
       
    53 {
       
    54     // FIXME: widget is always toplevel, unless it's a popup.  We may be able
       
    55     // to get rid of this once we abstract popups into a WebKit API.
       
    56     m_position = widget->convertFromContainingWindow(IntPoint(e.x, e.y));
       
    57     m_globalPosition = IntPoint(e.globalX, e.globalY);
       
    58     m_button = static_cast<MouseButton>(e.button);
       
    59     m_shiftKey = (e.modifiers & WebInputEvent::ShiftKey);
       
    60     m_ctrlKey = (e.modifiers & WebInputEvent::ControlKey);
       
    61     m_altKey = (e.modifiers & WebInputEvent::AltKey);
       
    62     m_metaKey = (e.modifiers & WebInputEvent::MetaKey);
       
    63     m_modifierFlags = e.modifiers;
       
    64     m_timestamp = e.timeStampSeconds;
       
    65     m_clickCount = e.clickCount;
       
    66 
       
    67     switch (e.type) {
       
    68     case WebInputEvent::MouseMove:
       
    69     case WebInputEvent::MouseLeave:  // synthesize a move event
       
    70         m_eventType = MouseEventMoved;
       
    71         break;
       
    72 
       
    73     case WebInputEvent::MouseDown:
       
    74         m_eventType = MouseEventPressed;
       
    75         break;
       
    76 
       
    77     case WebInputEvent::MouseUp:
       
    78         m_eventType = MouseEventReleased;
       
    79         break;
       
    80 
       
    81     default:
       
    82         ASSERT_NOT_REACHED();
       
    83     }
       
    84 }
       
    85 
       
    86 // PlatformWheelEventBuilder --------------------------------------------------
       
    87 
       
    88 PlatformWheelEventBuilder::PlatformWheelEventBuilder(Widget* widget, const WebMouseWheelEvent& e)
       
    89 {
       
    90     m_position = widget->convertFromContainingWindow(IntPoint(e.x, e.y));
       
    91     m_globalPosition = IntPoint(e.globalX, e.globalY);
       
    92     m_deltaX = e.deltaX;
       
    93     m_deltaY = e.deltaY;
       
    94     m_wheelTicksX = e.wheelTicksX;
       
    95     m_wheelTicksY = e.wheelTicksY;
       
    96     m_isAccepted = false;
       
    97     m_granularity = e.scrollByPage ?
       
    98         ScrollByPageWheelEvent : ScrollByPixelWheelEvent;
       
    99     m_shiftKey = (e.modifiers & WebInputEvent::ShiftKey);
       
   100     m_ctrlKey = (e.modifiers & WebInputEvent::ControlKey);
       
   101     m_altKey = (e.modifiers & WebInputEvent::AltKey);
       
   102     m_metaKey = (e.modifiers & WebInputEvent::MetaKey);
       
   103 }
       
   104 
       
   105 // MakePlatformKeyboardEvent --------------------------------------------------
       
   106 
       
   107 static inline const PlatformKeyboardEvent::Type toPlatformKeyboardEventType(WebInputEvent::Type type)
       
   108 {
       
   109     switch (type) {
       
   110     case WebInputEvent::KeyUp:
       
   111         return PlatformKeyboardEvent::KeyUp;
       
   112     case WebInputEvent::KeyDown:
       
   113         return PlatformKeyboardEvent::KeyDown;
       
   114     case WebInputEvent::RawKeyDown:
       
   115         return PlatformKeyboardEvent::RawKeyDown;
       
   116     case WebInputEvent::Char:
       
   117         return PlatformKeyboardEvent::Char;
       
   118     default:
       
   119         ASSERT_NOT_REACHED();
       
   120     }
       
   121     return PlatformKeyboardEvent::KeyDown;
       
   122 }
       
   123 
       
   124 PlatformKeyboardEventBuilder::PlatformKeyboardEventBuilder(const WebKeyboardEvent& e)
       
   125 {
       
   126     m_type = toPlatformKeyboardEventType(e.type);
       
   127     m_text = String(e.text);
       
   128     m_unmodifiedText = String(e.unmodifiedText);
       
   129     m_keyIdentifier = String(e.keyIdentifier);
       
   130     m_autoRepeat = (e.modifiers & WebInputEvent::IsAutoRepeat);
       
   131     m_windowsVirtualKeyCode = e.windowsKeyCode;
       
   132     m_nativeVirtualKeyCode = e.nativeKeyCode;
       
   133     m_isKeypad = (e.modifiers & WebInputEvent::IsKeyPad);
       
   134     m_shiftKey = (e.modifiers & WebInputEvent::ShiftKey);
       
   135     m_ctrlKey = (e.modifiers & WebInputEvent::ControlKey);
       
   136     m_altKey = (e.modifiers & WebInputEvent::AltKey);
       
   137     m_metaKey = (e.modifiers & WebInputEvent::MetaKey);
       
   138     m_isSystemKey = e.isSystemKey;
       
   139 }
       
   140 
       
   141 void PlatformKeyboardEventBuilder::setKeyType(Type type)
       
   142 {
       
   143     // According to the behavior of Webkit in Windows platform,
       
   144     // we need to convert KeyDown to RawKeydown and Char events
       
   145     // See WebKit/WebKit/Win/WebView.cpp
       
   146     ASSERT(m_type == KeyDown);
       
   147     ASSERT(type == RawKeyDown || type == Char);
       
   148     m_type = type;
       
   149 
       
   150     if (type == RawKeyDown) {
       
   151         m_text = String();
       
   152         m_unmodifiedText = String();
       
   153     } else {
       
   154         m_keyIdentifier = String();
       
   155         m_windowsVirtualKeyCode = 0;
       
   156     }
       
   157 }
       
   158 
       
   159 // Please refer to bug http://b/issue?id=961192, which talks about Webkit
       
   160 // keyboard event handling changes. It also mentions the list of keys
       
   161 // which don't have associated character events.
       
   162 bool PlatformKeyboardEventBuilder::isCharacterKey() const
       
   163 {
       
   164     switch (windowsVirtualKeyCode()) {
       
   165     case VKEY_BACK:
       
   166     case VKEY_ESCAPE:
       
   167         return false;
       
   168     }
       
   169     return true;
       
   170 }
       
   171 
       
   172 #if ENABLE(TOUCH_EVENTS)
       
   173 static inline TouchEventType toPlatformTouchEventType(const WebInputEvent::Type type)
       
   174 {
       
   175     switch (type) {
       
   176     case WebInputEvent::TouchStart:
       
   177         return TouchStart;
       
   178     case WebInputEvent::TouchMove:
       
   179         return TouchMove;
       
   180     case WebInputEvent::TouchEnd:
       
   181         return TouchEnd;
       
   182     case WebInputEvent::TouchCancel:
       
   183         return TouchCancel;
       
   184     default:
       
   185         ASSERT_NOT_REACHED();
       
   186     }
       
   187     return TouchStart;
       
   188 }
       
   189 
       
   190 static inline PlatformTouchPoint::State toPlatformTouchPointState(const WebTouchPoint::State state)
       
   191 {
       
   192     switch (state) {
       
   193     case WebTouchPoint::StateReleased:
       
   194         return PlatformTouchPoint::TouchReleased;
       
   195     case WebTouchPoint::StatePressed:
       
   196         return PlatformTouchPoint::TouchPressed;
       
   197     case WebTouchPoint::StateMoved:
       
   198         return PlatformTouchPoint::TouchMoved;
       
   199     case WebTouchPoint::StateStationary:
       
   200         return PlatformTouchPoint::TouchStationary;
       
   201     case WebTouchPoint::StateCancelled:
       
   202         return PlatformTouchPoint::TouchCancelled;
       
   203     case WebTouchPoint::StateUndefined:
       
   204         ASSERT_NOT_REACHED();
       
   205     }
       
   206     return PlatformTouchPoint::TouchReleased;
       
   207 }
       
   208 
       
   209 PlatformTouchPointBuilder::PlatformTouchPointBuilder(Widget* widget, const WebTouchPoint& point)
       
   210 {
       
   211     m_id = point.id;
       
   212     m_state = toPlatformTouchPointState(point.state);
       
   213     m_pos = widget->convertFromContainingWindow(point.position);
       
   214     m_screenPos = point.screenPosition;
       
   215 }
       
   216 
       
   217 PlatformTouchEventBuilder::PlatformTouchEventBuilder(Widget* widget, const WebTouchEvent& event)
       
   218 {
       
   219     m_type = toPlatformTouchEventType(event.type);
       
   220     m_ctrlKey = event.modifiers & WebInputEvent::ControlKey;
       
   221     m_altKey = event.modifiers & WebInputEvent::AltKey;
       
   222     m_shiftKey = event.modifiers & WebInputEvent::ShiftKey;
       
   223     m_metaKey = event.modifiers & WebInputEvent::MetaKey;
       
   224 
       
   225     for (int i = 0; i < event.touchPointsLength; ++i)
       
   226         m_touchPoints.append(PlatformTouchPointBuilder(widget, event.touchPoints[i]));
       
   227 }
       
   228 #endif
       
   229 
       
   230 static int getWebInputModifiers(const UIEventWithKeyState& event)
       
   231 {
       
   232     int modifiers = 0;
       
   233     if (event.ctrlKey())
       
   234         modifiers |= WebInputEvent::ControlKey;
       
   235     if (event.shiftKey())
       
   236         modifiers |= WebInputEvent::ShiftKey;
       
   237     if (event.altKey())
       
   238         modifiers |= WebInputEvent::AltKey;
       
   239     if (event.metaKey())
       
   240         modifiers |= WebInputEvent::MetaKey;
       
   241     return modifiers;
       
   242 }
       
   243 
       
   244 WebMouseEventBuilder::WebMouseEventBuilder(const ScrollView* view, const MouseEvent& event)
       
   245 {
       
   246     if (event.type() == eventNames().mousemoveEvent)
       
   247         type = WebInputEvent::MouseMove;
       
   248     else if (event.type() == eventNames().mouseoutEvent)
       
   249         type = WebInputEvent::MouseLeave;
       
   250     else if (event.type() == eventNames().mouseoverEvent)
       
   251         type = WebInputEvent::MouseEnter;
       
   252     else if (event.type() == eventNames().mousedownEvent)
       
   253         type = WebInputEvent::MouseDown;
       
   254     else if (event.type() == eventNames().mouseupEvent)
       
   255         type = WebInputEvent::MouseUp;
       
   256     else
       
   257         return; // Skip all other mouse events.
       
   258     timeStampSeconds = event.timeStamp() * 1.0e-3;
       
   259     switch (event.button()) {
       
   260     case LeftButton:
       
   261         button = WebMouseEvent::ButtonLeft;
       
   262         break;
       
   263     case MiddleButton:
       
   264         button = WebMouseEvent::ButtonMiddle;
       
   265         break;
       
   266     case RightButton:
       
   267         button = WebMouseEvent::ButtonRight;
       
   268         break;
       
   269     }
       
   270     modifiers = getWebInputModifiers(event);
       
   271     if (event.buttonDown()) {
       
   272         switch (event.button()) {
       
   273         case LeftButton:
       
   274             modifiers |= WebInputEvent::LeftButtonDown;
       
   275             break;
       
   276         case MiddleButton:
       
   277             modifiers |= WebInputEvent::MiddleButtonDown;
       
   278             break;
       
   279         case RightButton:
       
   280             modifiers |= WebInputEvent::RightButtonDown;
       
   281             break;
       
   282         }
       
   283     }
       
   284     IntPoint p = view->contentsToWindow(IntPoint(event.pageX(), event.pageY()));
       
   285     globalX = event.screenX();
       
   286     globalY = event.screenY();
       
   287     windowX = p.x();
       
   288     windowY = p.y();
       
   289     x = event.offsetX();
       
   290     y = event.offsetY();
       
   291     clickCount = event.detail();
       
   292 }
       
   293 
       
   294 WebMouseWheelEventBuilder::WebMouseWheelEventBuilder(const ScrollView* view, const WheelEvent& event)
       
   295 {
       
   296     if (event.type() != eventNames().mousewheelEvent)
       
   297         return;
       
   298     type = WebInputEvent::MouseWheel;
       
   299     timeStampSeconds = event.timeStamp() * 1.0e-3;
       
   300     modifiers = getWebInputModifiers(event);
       
   301     IntPoint p = view->contentsToWindow(IntPoint(event.pageX(), event.pageY()));
       
   302     globalX = event.screenX();
       
   303     globalY = event.screenY();
       
   304     windowX = p.x();
       
   305     windowY = p.y();
       
   306     x = event.offsetX();
       
   307     y = event.offsetY();
       
   308     deltaX = static_cast<float>(event.rawDeltaX());
       
   309     deltaY = static_cast<float>(event.rawDeltaY());
       
   310     // The 120 is from WheelEvent::initWheelEvent().
       
   311     wheelTicksX = static_cast<float>(event.wheelDeltaX()) / 120;
       
   312     wheelTicksY = static_cast<float>(event.wheelDeltaY()) / 120;
       
   313     scrollByPage = event.granularity() == WheelEvent::Page;
       
   314 }
       
   315 
       
   316 WebKeyboardEventBuilder::WebKeyboardEventBuilder(const KeyboardEvent& event)
       
   317 {
       
   318     if (event.type() == eventNames().keydownEvent)
       
   319         type = KeyDown;
       
   320     else if (event.type() == eventNames().keyupEvent)
       
   321         type = WebInputEvent::KeyUp;
       
   322     else if (event.type() == eventNames().keypressEvent)
       
   323         type = WebInputEvent::Char;
       
   324     else
       
   325         return; // Skip all other keyboard events.
       
   326     modifiers = getWebInputModifiers(event);
       
   327     timeStampSeconds = event.timeStamp() * 1.0e-3;
       
   328     windowsKeyCode = event.keyCode();
       
   329     nativeKeyCode = event.keyEvent()->nativeVirtualKeyCode();
       
   330     unsigned int numChars = std::min(event.keyEvent()->text().length(),
       
   331         static_cast<unsigned int>(WebKeyboardEvent::textLengthCap));
       
   332     for (unsigned int i = 0; i < numChars; i++) {
       
   333         text[i] = event.keyEvent()->text()[i];
       
   334         unmodifiedText[i] = event.keyEvent()->unmodifiedText()[i];
       
   335     }
       
   336 }
       
   337 
       
   338 } // namespace WebKit