Home | History | Annotate | Download | only in inspector
      1 /*
      2  * Copyright (C) 2012 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 "core/inspector/InspectorInputAgent.h"
     33 
     34 #include "core/frame/FrameView.h"
     35 #include "core/frame/LocalFrame.h"
     36 #include "core/inspector/InspectorClient.h"
     37 #include "core/page/Chrome.h"
     38 #include "core/page/EventHandler.h"
     39 #include "core/page/Page.h"
     40 #include "platform/JSONValues.h"
     41 #include "platform/PlatformKeyboardEvent.h"
     42 #include "platform/PlatformMouseEvent.h"
     43 #include "platform/PlatformTouchEvent.h"
     44 #include "platform/PlatformTouchPoint.h"
     45 #include "platform/geometry/FloatSize.h"
     46 #include "platform/geometry/IntPoint.h"
     47 #include "platform/geometry/IntRect.h"
     48 #include "platform/geometry/IntSize.h"
     49 #include "wtf/CurrentTime.h"
     50 
     51 namespace {
     52 
     53 class SyntheticInspectorTouchPoint : public blink::PlatformTouchPoint {
     54 public:
     55     SyntheticInspectorTouchPoint(unsigned id, State state, const blink::IntPoint& screenPos, const blink::IntPoint& pos, int radiusX, int radiusY, double rotationAngle, double force)
     56     {
     57         m_id = id;
     58         m_screenPos = screenPos;
     59         m_pos = pos;
     60         m_state = state;
     61         m_radius = blink::FloatSize(radiusX, radiusY);
     62         m_rotationAngle = rotationAngle;
     63         m_force = force;
     64     }
     65 };
     66 
     67 class SyntheticInspectorTouchEvent : public blink::PlatformTouchEvent {
     68 public:
     69     SyntheticInspectorTouchEvent(const blink::PlatformEvent::Type type, unsigned modifiers, double timestamp)
     70     {
     71         m_type = type;
     72         m_modifiers = modifiers;
     73         m_timestamp = timestamp;
     74     }
     75 
     76     void append(const blink::PlatformTouchPoint& point)
     77     {
     78         m_touchPoints.append(point);
     79     }
     80 };
     81 
     82 void ConvertInspectorPoint(blink::Page* page, const blink::IntPoint& point, blink::IntPoint* convertedPoint, blink::IntPoint* globalPoint)
     83 {
     84     *convertedPoint = page->deprecatedLocalMainFrame()->view()->convertToContainingWindow(point);
     85     *globalPoint = page->chrome().rootViewToScreen(blink::IntRect(point, blink::IntSize(0, 0))).location();
     86 }
     87 
     88 } // namespace
     89 
     90 namespace blink {
     91 
     92 InspectorInputAgent::InspectorInputAgent(Page* page, InspectorClient* client)
     93     : InspectorBaseAgent<InspectorInputAgent>("Input")
     94     , m_page(page), m_client(client)
     95 {
     96 }
     97 
     98 InspectorInputAgent::~InspectorInputAgent()
     99 {
    100 }
    101 
    102 void InspectorInputAgent::dispatchKeyEvent(ErrorString* error, const String& type, const int* modifiers, const double* timestamp, const String* text, const String* unmodifiedText, const String* keyIdentifier, const int* windowsVirtualKeyCode, const int* nativeVirtualKeyCode, const bool* autoRepeat, const bool* isKeypad, const bool* isSystemKey)
    103 {
    104     PlatformEvent::Type convertedType;
    105     if (type == "keyDown")
    106         convertedType = PlatformEvent::KeyDown;
    107     else if (type == "keyUp")
    108         convertedType = PlatformEvent::KeyUp;
    109     else if (type == "char")
    110         convertedType = PlatformEvent::Char;
    111     else if (type == "rawKeyDown")
    112         convertedType = PlatformEvent::RawKeyDown;
    113     else {
    114         *error = "Unrecognized type: " + type;
    115         return;
    116     }
    117 
    118     PlatformKeyboardEvent event(
    119         convertedType,
    120         text ? *text : "",
    121         unmodifiedText ? *unmodifiedText : "",
    122         keyIdentifier ? *keyIdentifier : "",
    123         windowsVirtualKeyCode ? *windowsVirtualKeyCode : 0,
    124         nativeVirtualKeyCode ? *nativeVirtualKeyCode : 0,
    125         asBool(autoRepeat),
    126         asBool(isKeypad),
    127         asBool(isSystemKey),
    128         static_cast<PlatformEvent::Modifiers>(modifiers ? *modifiers : 0),
    129         timestamp ? *timestamp : currentTime());
    130     m_client->dispatchKeyEvent(event);
    131 }
    132 
    133 void InspectorInputAgent::dispatchMouseEvent(ErrorString* error, const String& type, int x, int y, const int* modifiers, const double* timestamp, const String* button, const int* clickCount)
    134 {
    135     PlatformEvent::Type convertedType;
    136     if (type == "mousePressed")
    137         convertedType = PlatformEvent::MousePressed;
    138     else if (type == "mouseReleased")
    139         convertedType = PlatformEvent::MouseReleased;
    140     else if (type == "mouseMoved")
    141         convertedType = PlatformEvent::MouseMoved;
    142     else {
    143         *error = "Unrecognized type: " + type;
    144         return;
    145     }
    146 
    147     int convertedModifiers = modifiers ? *modifiers : 0;
    148 
    149     MouseButton convertedButton = NoButton;
    150     if (button) {
    151         if (*button == "left")
    152             convertedButton = LeftButton;
    153         else if (*button == "middle")
    154             convertedButton = MiddleButton;
    155         else if (*button == "right")
    156             convertedButton = RightButton;
    157         else if (*button != "none") {
    158             *error = "Unrecognized button: " + *button;
    159             return;
    160         }
    161     }
    162 
    163     // Some platforms may have flipped coordinate systems, but the given coordinates
    164     // assume the origin is in the top-left of the window. Convert.
    165     IntPoint convertedPoint, globalPoint;
    166     ConvertInspectorPoint(m_page, IntPoint(x, y), &convertedPoint, &globalPoint);
    167 
    168     PlatformMouseEvent event(
    169         convertedPoint,
    170         globalPoint,
    171         convertedButton,
    172         convertedType,
    173         clickCount ? *clickCount : 0,
    174         convertedModifiers & PlatformEvent::ShiftKey,
    175         convertedModifiers & PlatformEvent::CtrlKey,
    176         convertedModifiers & PlatformEvent::AltKey,
    177         convertedModifiers & PlatformEvent::MetaKey,
    178         PlatformMouseEvent::RealOrIndistinguishable,
    179         timestamp ? *timestamp : currentTime());
    180 
    181     m_client->dispatchMouseEvent(event);
    182 }
    183 
    184 void InspectorInputAgent::dispatchTouchEvent(ErrorString* error, const String& type, const RefPtr<JSONArray>& touchPoints, const int* modifiers, const double* timestamp)
    185 {
    186     PlatformEvent::Type convertedType;
    187     if (type == "touchStart") {
    188         convertedType = PlatformEvent::TouchStart;
    189     } else if (type == "touchEnd") {
    190         convertedType = PlatformEvent::TouchEnd;
    191     } else if (type == "touchMove") {
    192         convertedType = PlatformEvent::TouchMove;
    193     } else {
    194         *error = "Unrecognized type: " + type;
    195         return;
    196     }
    197 
    198     unsigned convertedModifiers = modifiers ? *modifiers : 0;
    199 
    200     SyntheticInspectorTouchEvent event(convertedType, convertedModifiers, timestamp ? *timestamp : currentTime());
    201 
    202     int autoId = 0;
    203     JSONArrayBase::iterator iter;
    204     for (iter = touchPoints->begin(); iter != touchPoints->end(); ++iter) {
    205         RefPtr<JSONObject> pointObj;
    206         String state;
    207         int x, y, radiusX, radiusY, id;
    208         double rotationAngle, force;
    209         (*iter)->asObject(&pointObj);
    210         if (!pointObj->getString("state", &state)) {
    211             *error = "TouchPoint missing 'state'";
    212             return;
    213         }
    214         if (!pointObj->getNumber("x", &x)) {
    215             *error = "TouchPoint missing 'x' coordinate";
    216             return;
    217         }
    218         if (!pointObj->getNumber("y", &y)) {
    219             *error = "TouchPoint missing 'y' coordinate";
    220             return;
    221         }
    222         if (!pointObj->getNumber("radiusX", &radiusX))
    223             radiusX = 1;
    224         if (!pointObj->getNumber("radiusY", &radiusY))
    225             radiusY = 1;
    226         if (!pointObj->getNumber("rotationAngle", &rotationAngle))
    227             rotationAngle = 0.0f;
    228         if (!pointObj->getNumber("force", &force))
    229             force = 1.0f;
    230         if (pointObj->getNumber("id", &id)) {
    231             if (autoId > 0)
    232                 id = -1;
    233             autoId = -1;
    234         } else {
    235             id = autoId++;
    236         }
    237         if (id < 0) {
    238             *error = "All or none of the provided TouchPoints must supply positive integer ids.";
    239             return;
    240         }
    241 
    242         PlatformTouchPoint::State convertedState;
    243         if (state == "touchPressed") {
    244             convertedState = PlatformTouchPoint::TouchPressed;
    245         } else if (state == "touchReleased") {
    246             convertedState = PlatformTouchPoint::TouchReleased;
    247         } else if (state == "touchMoved") {
    248             convertedState = PlatformTouchPoint::TouchMoved;
    249         } else if (state == "touchStationary") {
    250             convertedState = PlatformTouchPoint::TouchStationary;
    251         } else if (state == "touchCancelled") {
    252             convertedState = PlatformTouchPoint::TouchCancelled;
    253         } else {
    254             *error = "Unrecognized state: " + state;
    255             return;
    256         }
    257 
    258         // Some platforms may have flipped coordinate systems, but the given coordinates
    259         // assume the origin is in the top-left of the window. Convert.
    260         IntPoint convertedPoint, globalPoint;
    261         ConvertInspectorPoint(m_page, IntPoint(x, y), &convertedPoint, &globalPoint);
    262 
    263         SyntheticInspectorTouchPoint point(id++, convertedState, globalPoint, convertedPoint, radiusX, radiusY, rotationAngle, force);
    264         event.append(point);
    265     }
    266 
    267     m_page->deprecatedLocalMainFrame()->eventHandler().handleTouchEvent(event);
    268 }
    269 
    270 void InspectorInputAgent::trace(Visitor* visitor)
    271 {
    272     visitor->trace(m_page);
    273     InspectorBaseAgent::trace(visitor);
    274 }
    275 
    276 } // namespace blink
    277 
    278