Home | History | Annotate | Download | only in src
      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 "Widget.h"
     44 
     45 using namespace WebCore;
     46 
     47 namespace WebKit {
     48 
     49 // MakePlatformMouseEvent -----------------------------------------------------
     50 
     51 PlatformMouseEventBuilder::PlatformMouseEventBuilder(Widget* widget, const WebMouseEvent& e)
     52 {
     53     // FIXME: widget is always toplevel, unless it's a popup.  We may be able
     54     // to get rid of this once we abstract popups into a WebKit API.
     55     m_position = widget->convertFromContainingWindow(IntPoint(e.x, e.y));
     56     m_globalPosition = IntPoint(e.globalX, e.globalY);
     57     m_button = static_cast<MouseButton>(e.button);
     58     m_shiftKey = (e.modifiers & WebInputEvent::ShiftKey);
     59     m_ctrlKey = (e.modifiers & WebInputEvent::ControlKey);
     60     m_altKey = (e.modifiers & WebInputEvent::AltKey);
     61     m_metaKey = (e.modifiers & WebInputEvent::MetaKey);
     62     m_modifierFlags = e.modifiers;
     63     m_timestamp = e.timeStampSeconds;
     64     m_clickCount = e.clickCount;
     65 
     66     switch (e.type) {
     67     case WebInputEvent::MouseMove:
     68     case WebInputEvent::MouseLeave:  // synthesize a move event
     69         m_eventType = MouseEventMoved;
     70         break;
     71 
     72     case WebInputEvent::MouseDown:
     73         m_eventType = MouseEventPressed;
     74         break;
     75 
     76     case WebInputEvent::MouseUp:
     77         m_eventType = MouseEventReleased;
     78         break;
     79 
     80     default:
     81         ASSERT_NOT_REACHED();
     82     }
     83 }
     84 
     85 // PlatformWheelEventBuilder --------------------------------------------------
     86 
     87 PlatformWheelEventBuilder::PlatformWheelEventBuilder(Widget* widget, const WebMouseWheelEvent& e)
     88 {
     89     m_position = widget->convertFromContainingWindow(IntPoint(e.x, e.y));
     90     m_globalPosition = IntPoint(e.globalX, e.globalY);
     91     m_deltaX = e.deltaX;
     92     m_deltaY = e.deltaY;
     93     m_wheelTicksX = e.wheelTicksX;
     94     m_wheelTicksY = e.wheelTicksY;
     95     m_isAccepted = false;
     96     m_granularity = e.scrollByPage ?
     97         ScrollByPageWheelEvent : ScrollByPixelWheelEvent;
     98     m_shiftKey = (e.modifiers & WebInputEvent::ShiftKey);
     99     m_ctrlKey = (e.modifiers & WebInputEvent::ControlKey);
    100     m_altKey = (e.modifiers & WebInputEvent::AltKey);
    101     m_metaKey = (e.modifiers & WebInputEvent::MetaKey);
    102 }
    103 
    104 // MakePlatformKeyboardEvent --------------------------------------------------
    105 
    106 static inline const PlatformKeyboardEvent::Type toPlatformKeyboardEventType(WebInputEvent::Type type)
    107 {
    108     switch (type) {
    109     case WebInputEvent::KeyUp:
    110         return PlatformKeyboardEvent::KeyUp;
    111     case WebInputEvent::KeyDown:
    112         return PlatformKeyboardEvent::KeyDown;
    113     case WebInputEvent::RawKeyDown:
    114         return PlatformKeyboardEvent::RawKeyDown;
    115     case WebInputEvent::Char:
    116         return PlatformKeyboardEvent::Char;
    117     default:
    118         ASSERT_NOT_REACHED();
    119     }
    120     return PlatformKeyboardEvent::KeyDown;
    121 }
    122 
    123 PlatformKeyboardEventBuilder::PlatformKeyboardEventBuilder(const WebKeyboardEvent& e)
    124 {
    125     m_type = toPlatformKeyboardEventType(e.type);
    126     m_text = String(e.text);
    127     m_unmodifiedText = String(e.unmodifiedText);
    128     m_keyIdentifier = String(e.keyIdentifier);
    129     m_autoRepeat = (e.modifiers & WebInputEvent::IsAutoRepeat);
    130     m_windowsVirtualKeyCode = e.windowsKeyCode;
    131     m_nativeVirtualKeyCode = e.nativeKeyCode;
    132     m_isKeypad = (e.modifiers & WebInputEvent::IsKeyPad);
    133     m_shiftKey = (e.modifiers & WebInputEvent::ShiftKey);
    134     m_ctrlKey = (e.modifiers & WebInputEvent::ControlKey);
    135     m_altKey = (e.modifiers & WebInputEvent::AltKey);
    136     m_metaKey = (e.modifiers & WebInputEvent::MetaKey);
    137     m_isSystemKey = e.isSystemKey;
    138 }
    139 
    140 void PlatformKeyboardEventBuilder::setKeyType(Type type)
    141 {
    142     // According to the behavior of Webkit in Windows platform,
    143     // we need to convert KeyDown to RawKeydown and Char events
    144     // See WebKit/WebKit/Win/WebView.cpp
    145     ASSERT(m_type == KeyDown);
    146     ASSERT(type == RawKeyDown || type == Char);
    147     m_type = type;
    148 
    149     if (type == RawKeyDown) {
    150         m_text = String();
    151         m_unmodifiedText = String();
    152     } else {
    153         m_keyIdentifier = String();
    154         m_windowsVirtualKeyCode = 0;
    155     }
    156 }
    157 
    158 // Please refer to bug http://b/issue?id=961192, which talks about Webkit
    159 // keyboard event handling changes. It also mentions the list of keys
    160 // which don't have associated character events.
    161 bool PlatformKeyboardEventBuilder::isCharacterKey() const
    162 {
    163     switch (windowsVirtualKeyCode()) {
    164     case VKEY_BACK:
    165     case VKEY_ESCAPE:
    166         return false;
    167     }
    168     return true;
    169 }
    170 
    171 static int getWebInputModifiers(const UIEventWithKeyState& event)
    172 {
    173     int modifiers = 0;
    174     if (event.ctrlKey())
    175         modifiers |= WebInputEvent::ControlKey;
    176     if (event.shiftKey())
    177         modifiers |= WebInputEvent::ShiftKey;
    178     if (event.altKey())
    179         modifiers |= WebInputEvent::AltKey;
    180     if (event.metaKey())
    181         modifiers |= WebInputEvent::MetaKey;
    182     return modifiers;
    183 }
    184 
    185 WebMouseEventBuilder::WebMouseEventBuilder(const ScrollView* view, const MouseEvent& event)
    186 {
    187     if (event.type() == eventNames().mousemoveEvent)
    188         type = WebInputEvent::MouseMove;
    189     else if (event.type() == eventNames().mouseoutEvent)
    190         type = WebInputEvent::MouseLeave;
    191     else if (event.type() == eventNames().mouseoverEvent)
    192         type = WebInputEvent::MouseEnter;
    193     else if (event.type() == eventNames().mousedownEvent)
    194         type = WebInputEvent::MouseDown;
    195     else if (event.type() == eventNames().mouseupEvent)
    196         type = WebInputEvent::MouseUp;
    197     else
    198         return; // Skip all other mouse events.
    199     timeStampSeconds = event.timeStamp() * 1.0e-3;
    200     switch (event.button()) {
    201     case LeftButton:
    202         button = WebMouseEvent::ButtonLeft;
    203         break;
    204     case MiddleButton:
    205         button = WebMouseEvent::ButtonMiddle;
    206         break;
    207     case RightButton:
    208         button = WebMouseEvent::ButtonRight;
    209         break;
    210     }
    211     modifiers = getWebInputModifiers(event);
    212     if (event.buttonDown()) {
    213         switch (event.button()) {
    214         case LeftButton:
    215             modifiers |= WebInputEvent::LeftButtonDown;
    216             break;
    217         case MiddleButton:
    218             modifiers |= WebInputEvent::MiddleButtonDown;
    219             break;
    220         case RightButton:
    221             modifiers |= WebInputEvent::RightButtonDown;
    222             break;
    223         }
    224     }
    225     IntPoint p = view->contentsToWindow(IntPoint(event.pageX(), event.pageY()));
    226     globalX = event.screenX();
    227     globalY = event.screenY();
    228     windowX = p.x();
    229     windowY = p.y();
    230     x = event.offsetX();
    231     y = event.offsetY();
    232     clickCount = event.detail();
    233 }
    234 
    235 WebKeyboardEventBuilder::WebKeyboardEventBuilder(const KeyboardEvent& event)
    236 {
    237     if (event.type() == eventNames().keydownEvent)
    238         type = KeyDown;
    239     else if (event.type() == eventNames().keyupEvent)
    240         type = WebInputEvent::KeyUp;
    241     else if (event.type() == eventNames().keypressEvent)
    242         type = WebInputEvent::Char;
    243     else
    244         return; // Skip all other keyboard events.
    245     modifiers = getWebInputModifiers(event);
    246     timeStampSeconds = event.timeStamp() * 1.0e-3;
    247     windowsKeyCode = event.keyCode();
    248     nativeKeyCode = event.keyEvent()->nativeVirtualKeyCode();
    249     unsigned int numChars = std::min(event.keyEvent()->text().length(),
    250         static_cast<unsigned int>(WebKeyboardEvent::textLengthCap));
    251     for (unsigned int i = 0; i < numChars; i++) {
    252         text[i] = event.keyEvent()->text()[i];
    253         unmodifiedText[i] = event.keyEvent()->unmodifiedText()[i];
    254     }
    255 }
    256 
    257 } // namespace WebKit
    258