Upstream version 10.39.225.0
[platform/framework/web/crosswalk.git] / src / third_party / WebKit / Source / core / inspector / InspectorInputAgent.cpp
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