2 * Copyright (C) 2009 Google Inc. All rights reserved.
4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions are
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
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.
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.
32 #include "WebInputEventConversion.h"
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"
46 using namespace WebCore;
50 // MakePlatformMouseEvent -----------------------------------------------------
52 PlatformMouseEventBuilder::PlatformMouseEventBuilder(Widget* widget, const WebMouseEvent& e)
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;
68 case WebInputEvent::MouseMove:
69 case WebInputEvent::MouseLeave: // synthesize a move event
70 m_eventType = MouseEventMoved;
73 case WebInputEvent::MouseDown:
74 m_eventType = MouseEventPressed;
77 case WebInputEvent::MouseUp:
78 m_eventType = MouseEventReleased;
86 // PlatformWheelEventBuilder --------------------------------------------------
88 PlatformWheelEventBuilder::PlatformWheelEventBuilder(Widget* widget, const WebMouseWheelEvent& e)
90 m_position = widget->convertFromContainingWindow(IntPoint(e.x, e.y));
91 m_globalPosition = IntPoint(e.globalX, e.globalY);
94 m_wheelTicksX = e.wheelTicksX;
95 m_wheelTicksY = e.wheelTicksY;
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);
104 m_hasPreciseScrollingDeltas = e.hasPreciseScrollingDeltas;
105 m_phase = static_cast<WebCore::PlatformWheelEventPhase>(e.phase);
106 m_momentumPhase = static_cast<WebCore::PlatformWheelEventPhase>(e.momentumPhase);
107 m_timestamp = e.timeStampSeconds;
111 // PlatformGestureEventBuilder --------------------------------------------------
113 #if ENABLE(GESTURE_EVENTS)
114 PlatformGestureEventBuilder::PlatformGestureEventBuilder(Widget* widget, const WebGestureEvent& e)
117 case WebInputEvent::GestureScrollBegin:
118 m_type = PlatformGestureEvent::ScrollBeginType;
120 case WebInputEvent::GestureScrollEnd:
121 m_type = PlatformGestureEvent::ScrollEndType;
124 ASSERT_NOT_REACHED();
126 m_position = widget->convertFromContainingWindow(IntPoint(e.x, e.y));
127 m_globalPosition = IntPoint(e.globalX, e.globalY);
128 m_timestamp = e.timeStampSeconds;
129 m_shiftKey = (e.modifiers & WebInputEvent::ShiftKey);
130 m_ctrlKey = (e.modifiers & WebInputEvent::ControlKey);
131 m_altKey = (e.modifiers & WebInputEvent::AltKey);
132 m_metaKey = (e.modifiers & WebInputEvent::MetaKey);
136 // MakePlatformKeyboardEvent --------------------------------------------------
138 static inline PlatformKeyboardEvent::Type toPlatformKeyboardEventType(WebInputEvent::Type type)
141 case WebInputEvent::KeyUp:
142 return PlatformKeyboardEvent::KeyUp;
143 case WebInputEvent::KeyDown:
144 return PlatformKeyboardEvent::KeyDown;
145 case WebInputEvent::RawKeyDown:
146 return PlatformKeyboardEvent::RawKeyDown;
147 case WebInputEvent::Char:
148 return PlatformKeyboardEvent::Char;
150 ASSERT_NOT_REACHED();
152 return PlatformKeyboardEvent::KeyDown;
155 PlatformKeyboardEventBuilder::PlatformKeyboardEventBuilder(const WebKeyboardEvent& e)
157 m_type = toPlatformKeyboardEventType(e.type);
158 m_text = String(e.text);
159 m_unmodifiedText = String(e.unmodifiedText);
160 m_keyIdentifier = String(e.keyIdentifier);
161 m_autoRepeat = (e.modifiers & WebInputEvent::IsAutoRepeat);
162 m_windowsVirtualKeyCode = e.windowsKeyCode;
163 m_nativeVirtualKeyCode = e.nativeKeyCode;
164 m_isKeypad = (e.modifiers & WebInputEvent::IsKeyPad);
165 m_shiftKey = (e.modifiers & WebInputEvent::ShiftKey);
166 m_ctrlKey = (e.modifiers & WebInputEvent::ControlKey);
167 m_altKey = (e.modifiers & WebInputEvent::AltKey);
168 m_metaKey = (e.modifiers & WebInputEvent::MetaKey);
169 m_isSystemKey = e.isSystemKey;
172 void PlatformKeyboardEventBuilder::setKeyType(Type type)
174 // According to the behavior of Webkit in Windows platform,
175 // we need to convert KeyDown to RawKeydown and Char events
176 // See WebKit/WebKit/Win/WebView.cpp
177 ASSERT(m_type == KeyDown);
178 ASSERT(type == RawKeyDown || type == Char);
181 if (type == RawKeyDown) {
183 m_unmodifiedText = String();
185 m_keyIdentifier = String();
186 m_windowsVirtualKeyCode = 0;
190 // Please refer to bug http://b/issue?id=961192, which talks about Webkit
191 // keyboard event handling changes. It also mentions the list of keys
192 // which don't have associated character events.
193 bool PlatformKeyboardEventBuilder::isCharacterKey() const
195 switch (windowsVirtualKeyCode()) {
203 #if ENABLE(TOUCH_EVENTS)
204 static inline TouchEventType toPlatformTouchEventType(const WebInputEvent::Type type)
207 case WebInputEvent::TouchStart:
209 case WebInputEvent::TouchMove:
211 case WebInputEvent::TouchEnd:
213 case WebInputEvent::TouchCancel:
216 ASSERT_NOT_REACHED();
221 static inline PlatformTouchPoint::State toPlatformTouchPointState(const WebTouchPoint::State state)
224 case WebTouchPoint::StateReleased:
225 return PlatformTouchPoint::TouchReleased;
226 case WebTouchPoint::StatePressed:
227 return PlatformTouchPoint::TouchPressed;
228 case WebTouchPoint::StateMoved:
229 return PlatformTouchPoint::TouchMoved;
230 case WebTouchPoint::StateStationary:
231 return PlatformTouchPoint::TouchStationary;
232 case WebTouchPoint::StateCancelled:
233 return PlatformTouchPoint::TouchCancelled;
234 case WebTouchPoint::StateUndefined:
235 ASSERT_NOT_REACHED();
237 return PlatformTouchPoint::TouchReleased;
240 PlatformTouchPointBuilder::PlatformTouchPointBuilder(Widget* widget, const WebTouchPoint& point)
243 m_state = toPlatformTouchPointState(point.state);
244 m_pos = widget->convertFromContainingWindow(point.position);
245 m_screenPos = point.screenPosition;
246 m_radiusY = point.radiusY;
247 m_radiusX = point.radiusX;
248 m_rotationAngle = point.rotationAngle;
249 m_force = point.force;
252 PlatformTouchEventBuilder::PlatformTouchEventBuilder(Widget* widget, const WebTouchEvent& event)
254 m_type = toPlatformTouchEventType(event.type);
255 m_ctrlKey = event.modifiers & WebInputEvent::ControlKey;
256 m_altKey = event.modifiers & WebInputEvent::AltKey;
257 m_shiftKey = event.modifiers & WebInputEvent::ShiftKey;
258 m_metaKey = event.modifiers & WebInputEvent::MetaKey;
259 m_timestamp = event.timeStampSeconds;
261 for (int i = 0; i < event.touchPointsLength; ++i)
262 m_touchPoints.append(PlatformTouchPointBuilder(widget, event.touchPoints[i]));
266 static int getWebInputModifiers(const UIEventWithKeyState& event)
270 modifiers |= WebInputEvent::ControlKey;
271 if (event.shiftKey())
272 modifiers |= WebInputEvent::ShiftKey;
274 modifiers |= WebInputEvent::AltKey;
276 modifiers |= WebInputEvent::MetaKey;
280 WebMouseEventBuilder::WebMouseEventBuilder(const Widget* widget, const MouseEvent& event)
282 if (event.type() == eventNames().mousemoveEvent)
283 type = WebInputEvent::MouseMove;
284 else if (event.type() == eventNames().mouseoutEvent)
285 type = WebInputEvent::MouseLeave;
286 else if (event.type() == eventNames().mouseoverEvent)
287 type = WebInputEvent::MouseEnter;
288 else if (event.type() == eventNames().mousedownEvent)
289 type = WebInputEvent::MouseDown;
290 else if (event.type() == eventNames().mouseupEvent)
291 type = WebInputEvent::MouseUp;
292 else if (event.type() == eventNames().contextmenuEvent)
293 type = WebInputEvent::ContextMenu;
295 return; // Skip all other mouse events.
296 timeStampSeconds = event.timeStamp() * 1.0e-3;
297 switch (event.button()) {
299 button = WebMouseEvent::ButtonLeft;
302 button = WebMouseEvent::ButtonMiddle;
305 button = WebMouseEvent::ButtonRight;
308 modifiers = getWebInputModifiers(event);
309 if (event.buttonDown()) {
310 switch (event.button()) {
312 modifiers |= WebInputEvent::LeftButtonDown;
315 modifiers |= WebInputEvent::MiddleButtonDown;
318 modifiers |= WebInputEvent::RightButtonDown;
322 ScrollView* view = widget->parent();
323 IntPoint p = view->contentsToWindow(
324 IntPoint(event.absoluteLocation().x(), event.absoluteLocation().y()));
325 globalX = event.screenX();
326 globalY = event.screenY();
329 x = event.absoluteLocation().x() - widget->location().x();
330 y = event.absoluteLocation().y() - widget->location().y();
331 clickCount = event.detail();
334 WebMouseWheelEventBuilder::WebMouseWheelEventBuilder(const Widget* widget, const WheelEvent& event)
336 if (event.type() != eventNames().mousewheelEvent)
338 type = WebInputEvent::MouseWheel;
339 timeStampSeconds = event.timeStamp() * 1.0e-3;
340 modifiers = getWebInputModifiers(event);
341 ScrollView* view = widget->parent();
342 IntPoint p = view->contentsToWindow(
343 IntPoint(event.absoluteLocation().x(), event.absoluteLocation().y()));
344 globalX = event.screenX();
345 globalY = event.screenY();
348 x = event.absoluteLocation().x() - widget->location().x();
349 y = event.absoluteLocation().y() - widget->location().y();
350 deltaX = static_cast<float>(event.rawDeltaX());
351 deltaY = static_cast<float>(event.rawDeltaY());
352 // The 120 is from WheelEvent::initWheelEvent().
353 wheelTicksX = static_cast<float>(event.wheelDeltaX()) / 120;
354 wheelTicksY = static_cast<float>(event.wheelDeltaY()) / 120;
355 scrollByPage = event.granularity() == WheelEvent::Page;
358 WebKeyboardEventBuilder::WebKeyboardEventBuilder(const KeyboardEvent& event)
360 if (event.type() == eventNames().keydownEvent)
362 else if (event.type() == eventNames().keyupEvent)
363 type = WebInputEvent::KeyUp;
364 else if (event.type() == eventNames().keypressEvent)
365 type = WebInputEvent::Char;
367 return; // Skip all other keyboard events.
368 modifiers = getWebInputModifiers(event);
369 timeStampSeconds = event.timeStamp() * 1.0e-3;
370 windowsKeyCode = event.keyCode();
372 // The platform keyevent does not exist if the event was created using
373 // initKeyboardEvent.
374 if (!event.keyEvent())
376 nativeKeyCode = event.keyEvent()->nativeVirtualKeyCode();
377 unsigned int numChars = std::min(event.keyEvent()->text().length(),
378 static_cast<unsigned int>(WebKeyboardEvent::textLengthCap));
379 for (unsigned int i = 0; i < numChars; i++) {
380 text[i] = event.keyEvent()->text()[i];
381 unmodifiedText[i] = event.keyEvent()->unmodifiedText()[i];
385 } // namespace WebKit