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 "web/WebInputEventConversion.h"
34 #include "core/dom/Touch.h"
35 #include "core/dom/TouchList.h"
36 #include "core/events/GestureEvent.h"
37 #include "core/events/KeyboardEvent.h"
38 #include "core/events/MouseEvent.h"
39 #include "core/events/TouchEvent.h"
40 #include "core/events/WheelEvent.h"
41 #include "core/frame/FrameHost.h"
42 #include "core/frame/FrameView.h"
43 #include "core/frame/PinchViewport.h"
44 #include "core/page/Page.h"
45 #include "core/rendering/RenderObject.h"
46 #include "platform/KeyboardCodes.h"
47 #include "platform/Widget.h"
51 static const double millisPerSecond = 1000.0;
53 static float scaleDeltaToWindow(const Widget* widget, float delta)
57 FrameView* rootView = toFrameView(widget->root());
59 scale = rootView->inputEventsScaleFactor();
64 static FloatSize scaleSizeToWindow(const Widget* widget, FloatSize size)
66 return FloatSize(scaleDeltaToWindow(widget, size.width()), scaleDeltaToWindow(widget, size.height()));
69 static FloatPoint convertHitPointToWindow(const Widget* widget, FloatPoint point)
73 IntPoint pinchViewport;
75 FrameView* rootView = toFrameView(widget->root());
77 scale = rootView->inputEventsScaleFactor();
78 offset = rootView->inputEventsOffsetForEmulation();
79 pinchViewport = flooredIntPoint(rootView->page()->frameHost().pinchViewport().visibleRect().location());
83 (point.x() - offset.width()) / scale + pinchViewport.x(),
84 (point.y() - offset.height()) / scale + pinchViewport.y());
87 // MakePlatformMouseEvent -----------------------------------------------------
89 PlatformMouseEventBuilder::PlatformMouseEventBuilder(Widget* widget, const WebMouseEvent& e)
91 // FIXME: Widget is always toplevel, unless it's a popup. We may be able
92 // to get rid of this once we abstract popups into a WebKit API.
93 m_position = widget->convertFromContainingWindow(flooredIntPoint(convertHitPointToWindow(widget, IntPoint(e.x, e.y))));
94 m_globalPosition = IntPoint(e.globalX, e.globalY);
95 m_movementDelta = IntPoint(scaleDeltaToWindow(widget, e.movementX), scaleDeltaToWindow(widget, e.movementY));
96 m_button = static_cast<MouseButton>(e.button);
99 if (e.modifiers & WebInputEvent::ShiftKey)
100 m_modifiers |= PlatformEvent::ShiftKey;
101 if (e.modifiers & WebInputEvent::ControlKey)
102 m_modifiers |= PlatformEvent::CtrlKey;
103 if (e.modifiers & WebInputEvent::AltKey)
104 m_modifiers |= PlatformEvent::AltKey;
105 if (e.modifiers & WebInputEvent::MetaKey)
106 m_modifiers |= PlatformEvent::MetaKey;
108 m_modifierFlags = e.modifiers;
109 m_timestamp = e.timeStampSeconds;
110 m_clickCount = e.clickCount;
113 case WebInputEvent::MouseMove:
114 case WebInputEvent::MouseLeave: // synthesize a move event
115 m_type = PlatformEvent::MouseMoved;
118 case WebInputEvent::MouseDown:
119 m_type = PlatformEvent::MousePressed;
122 case WebInputEvent::MouseUp:
123 m_type = PlatformEvent::MouseReleased;
127 ASSERT_NOT_REACHED();
131 // PlatformWheelEventBuilder --------------------------------------------------
133 PlatformWheelEventBuilder::PlatformWheelEventBuilder(Widget* widget, const WebMouseWheelEvent& e)
135 m_position = widget->convertFromContainingWindow(flooredIntPoint(convertHitPointToWindow(widget, FloatPoint(e.x, e.y))));
136 m_globalPosition = IntPoint(e.globalX, e.globalY);
139 m_wheelTicksX = e.wheelTicksX;
140 m_wheelTicksY = e.wheelTicksY;
141 m_granularity = e.scrollByPage ?
142 ScrollByPageWheelEvent : ScrollByPixelWheelEvent;
144 m_type = PlatformEvent::Wheel;
147 if (e.modifiers & WebInputEvent::ShiftKey)
148 m_modifiers |= PlatformEvent::ShiftKey;
149 if (e.modifiers & WebInputEvent::ControlKey)
150 m_modifiers |= PlatformEvent::CtrlKey;
151 if (e.modifiers & WebInputEvent::AltKey)
152 m_modifiers |= PlatformEvent::AltKey;
153 if (e.modifiers & WebInputEvent::MetaKey)
154 m_modifiers |= PlatformEvent::MetaKey;
156 m_hasPreciseScrollingDeltas = e.hasPreciseScrollingDeltas;
158 m_phase = static_cast<PlatformWheelEventPhase>(e.phase);
159 m_momentumPhase = static_cast<PlatformWheelEventPhase>(e.momentumPhase);
160 m_timestamp = e.timeStampSeconds;
161 m_canRubberbandLeft = e.canRubberbandLeft;
162 m_canRubberbandRight = e.canRubberbandRight;
166 // PlatformGestureEventBuilder --------------------------------------------------
168 PlatformGestureEventBuilder::PlatformGestureEventBuilder(Widget* widget, const WebGestureEvent& e)
171 case WebInputEvent::GestureScrollBegin:
172 m_type = PlatformEvent::GestureScrollBegin;
174 case WebInputEvent::GestureScrollEnd:
175 m_type = PlatformEvent::GestureScrollEnd;
177 case WebInputEvent::GestureFlingStart:
178 m_type = PlatformEvent::GestureFlingStart;
180 case WebInputEvent::GestureScrollUpdate:
181 m_type = PlatformEvent::GestureScrollUpdate;
182 m_data.m_scrollUpdate.m_deltaX = scaleDeltaToWindow(widget, e.data.scrollUpdate.deltaX);
183 m_data.m_scrollUpdate.m_deltaY = scaleDeltaToWindow(widget, e.data.scrollUpdate.deltaY);
184 m_data.m_scrollUpdate.m_velocityX = e.data.scrollUpdate.velocityX;
185 m_data.m_scrollUpdate.m_velocityY = e.data.scrollUpdate.velocityY;
187 case WebInputEvent::GestureScrollUpdateWithoutPropagation:
188 m_type = PlatformEvent::GestureScrollUpdateWithoutPropagation;
189 m_data.m_scrollUpdate.m_deltaX = scaleDeltaToWindow(widget, e.data.scrollUpdate.deltaX);
190 m_data.m_scrollUpdate.m_deltaY = scaleDeltaToWindow(widget, e.data.scrollUpdate.deltaY);
191 m_data.m_scrollUpdate.m_velocityX = e.data.scrollUpdate.velocityX;
192 m_data.m_scrollUpdate.m_velocityY = e.data.scrollUpdate.velocityY;
194 case WebInputEvent::GestureTap:
195 m_type = PlatformEvent::GestureTap;
196 m_area = expandedIntSize(scaleSizeToWindow(widget, FloatSize(e.data.tap.width, e.data.tap.height)));
197 m_data.m_tap.m_tapCount = e.data.tap.tapCount;
199 case WebInputEvent::GestureTapUnconfirmed:
200 m_type = PlatformEvent::GestureTapUnconfirmed;
201 m_area = expandedIntSize(scaleSizeToWindow(widget, FloatSize(e.data.tap.width, e.data.tap.height)));
203 case WebInputEvent::GestureTapDown:
204 m_type = PlatformEvent::GestureTapDown;
205 m_area = expandedIntSize(scaleSizeToWindow(widget, FloatSize(e.data.tapDown.width, e.data.tapDown.height)));
207 case WebInputEvent::GestureShowPress:
208 m_type = PlatformEvent::GestureShowPress;
209 m_area = expandedIntSize(scaleSizeToWindow(widget, FloatSize(e.data.showPress.width, e.data.showPress.height)));
211 case WebInputEvent::GestureTapCancel:
212 m_type = PlatformEvent::GestureTapDownCancel;
214 case WebInputEvent::GestureDoubleTap:
215 // DoubleTap gesture is now handled as PlatformEvent::GestureTap with tap_count = 2. So no
216 // need to convert to a Platfrom DoubleTap gesture. But in WebViewImpl::handleGestureEvent
217 // all WebGestureEvent are converted to PlatformGestureEvent, for completeness and not reach
218 // the ASSERT_NOT_REACHED() at the end, convert the DoubleTap to a NoType.
219 m_type = PlatformEvent::NoType;
221 case WebInputEvent::GestureTwoFingerTap:
222 m_type = PlatformEvent::GestureTwoFingerTap;
223 m_area = expandedIntSize(scaleSizeToWindow(widget, FloatSize(e.data.twoFingerTap.firstFingerWidth, e.data.twoFingerTap.firstFingerHeight)));
225 case WebInputEvent::GestureLongPress:
226 m_type = PlatformEvent::GestureLongPress;
227 m_area = expandedIntSize(scaleSizeToWindow(widget, FloatSize(e.data.longPress.width, e.data.longPress.height)));
229 case WebInputEvent::GestureLongTap:
230 m_type = PlatformEvent::GestureLongTap;
231 m_area = expandedIntSize(scaleSizeToWindow(widget, FloatSize(e.data.longPress.width, e.data.longPress.height)));
233 case WebInputEvent::GesturePinchBegin:
234 m_type = PlatformEvent::GesturePinchBegin;
236 case WebInputEvent::GesturePinchEnd:
237 m_type = PlatformEvent::GesturePinchEnd;
239 case WebInputEvent::GesturePinchUpdate:
240 m_type = PlatformEvent::GesturePinchUpdate;
241 m_data.m_pinchUpdate.m_scale = e.data.pinchUpdate.scale;
244 ASSERT_NOT_REACHED();
246 m_position = widget->convertFromContainingWindow(flooredIntPoint(convertHitPointToWindow(widget, FloatPoint(e.x, e.y))));
247 m_globalPosition = IntPoint(e.globalX, e.globalY);
248 m_timestamp = e.timeStampSeconds;
251 if (e.modifiers & WebInputEvent::ShiftKey)
252 m_modifiers |= PlatformEvent::ShiftKey;
253 if (e.modifiers & WebInputEvent::ControlKey)
254 m_modifiers |= PlatformEvent::CtrlKey;
255 if (e.modifiers & WebInputEvent::AltKey)
256 m_modifiers |= PlatformEvent::AltKey;
257 if (e.modifiers & WebInputEvent::MetaKey)
258 m_modifiers |= PlatformEvent::MetaKey;
261 // MakePlatformKeyboardEvent --------------------------------------------------
263 inline PlatformEvent::Type toPlatformKeyboardEventType(WebInputEvent::Type type)
266 case WebInputEvent::KeyUp:
267 return PlatformEvent::KeyUp;
268 case WebInputEvent::KeyDown:
269 return PlatformEvent::KeyDown;
270 case WebInputEvent::RawKeyDown:
271 return PlatformEvent::RawKeyDown;
272 case WebInputEvent::Char:
273 return PlatformEvent::Char;
275 ASSERT_NOT_REACHED();
277 return PlatformEvent::KeyDown;
280 PlatformKeyboardEventBuilder::PlatformKeyboardEventBuilder(const WebKeyboardEvent& e)
282 m_type = toPlatformKeyboardEventType(e.type);
283 m_text = String(e.text);
284 m_unmodifiedText = String(e.unmodifiedText);
285 m_keyIdentifier = String(e.keyIdentifier);
286 m_autoRepeat = (e.modifiers & WebInputEvent::IsAutoRepeat);
287 m_nativeVirtualKeyCode = e.nativeKeyCode;
288 m_isKeypad = (e.modifiers & WebInputEvent::IsKeyPad);
289 m_isSystemKey = e.isSystemKey;
292 if (e.modifiers & WebInputEvent::ShiftKey)
293 m_modifiers |= PlatformEvent::ShiftKey;
294 if (e.modifiers & WebInputEvent::ControlKey)
295 m_modifiers |= PlatformEvent::CtrlKey;
296 if (e.modifiers & WebInputEvent::AltKey)
297 m_modifiers |= PlatformEvent::AltKey;
298 if (e.modifiers & WebInputEvent::MetaKey)
299 m_modifiers |= PlatformEvent::MetaKey;
301 // FIXME: PlatformKeyboardEvents expect a locational version of the keycode (e.g. VK_LSHIFT
302 // instead of VK_SHIFT). This should be changed so the location/keycode are stored separately,
303 // as in other places in the code.
304 m_windowsVirtualKeyCode = e.windowsKeyCode;
305 if (e.windowsKeyCode == VK_SHIFT) {
306 if (e.modifiers & WebInputEvent::IsLeft)
307 m_windowsVirtualKeyCode = VK_LSHIFT;
308 else if (e.modifiers & WebInputEvent::IsRight)
309 m_windowsVirtualKeyCode = VK_RSHIFT;
310 } else if (e.windowsKeyCode == VK_CONTROL) {
311 if (e.modifiers & WebInputEvent::IsLeft)
312 m_windowsVirtualKeyCode = VK_LCONTROL;
313 else if (e.modifiers & WebInputEvent::IsRight)
314 m_windowsVirtualKeyCode = VK_RCONTROL;
315 } else if (e.windowsKeyCode == VK_MENU) {
316 if (e.modifiers & WebInputEvent::IsLeft)
317 m_windowsVirtualKeyCode = VK_LMENU;
318 else if (e.modifiers & WebInputEvent::IsRight)
319 m_windowsVirtualKeyCode = VK_RMENU;
324 void PlatformKeyboardEventBuilder::setKeyType(Type type)
326 // According to the behavior of Webkit in Windows platform,
327 // we need to convert KeyDown to RawKeydown and Char events
328 // See WebKit/WebKit/Win/WebView.cpp
329 ASSERT(m_type == KeyDown);
330 ASSERT(type == RawKeyDown || type == Char);
333 if (type == RawKeyDown) {
335 m_unmodifiedText = String();
337 m_keyIdentifier = String();
338 m_windowsVirtualKeyCode = 0;
342 // Please refer to bug http://b/issue?id=961192, which talks about Webkit
343 // keyboard event handling changes. It also mentions the list of keys
344 // which don't have associated character events.
345 bool PlatformKeyboardEventBuilder::isCharacterKey() const
347 switch (windowsVirtualKeyCode()) {
355 inline PlatformEvent::Type toPlatformTouchEventType(const WebInputEvent::Type type)
358 case WebInputEvent::TouchStart:
359 return PlatformEvent::TouchStart;
360 case WebInputEvent::TouchMove:
361 return PlatformEvent::TouchMove;
362 case WebInputEvent::TouchEnd:
363 return PlatformEvent::TouchEnd;
364 case WebInputEvent::TouchCancel:
365 return PlatformEvent::TouchCancel;
367 ASSERT_NOT_REACHED();
369 return PlatformEvent::TouchStart;
372 inline PlatformTouchPoint::State toPlatformTouchPointState(const WebTouchPoint::State state)
375 case WebTouchPoint::StateReleased:
376 return PlatformTouchPoint::TouchReleased;
377 case WebTouchPoint::StatePressed:
378 return PlatformTouchPoint::TouchPressed;
379 case WebTouchPoint::StateMoved:
380 return PlatformTouchPoint::TouchMoved;
381 case WebTouchPoint::StateStationary:
382 return PlatformTouchPoint::TouchStationary;
383 case WebTouchPoint::StateCancelled:
384 return PlatformTouchPoint::TouchCancelled;
385 case WebTouchPoint::StateUndefined:
386 ASSERT_NOT_REACHED();
388 return PlatformTouchPoint::TouchReleased;
391 inline WebTouchPoint::State toWebTouchPointState(const AtomicString& type)
393 if (type == EventTypeNames::touchend)
394 return WebTouchPoint::StateReleased;
395 if (type == EventTypeNames::touchcancel)
396 return WebTouchPoint::StateCancelled;
397 if (type == EventTypeNames::touchstart)
398 return WebTouchPoint::StatePressed;
399 if (type == EventTypeNames::touchmove)
400 return WebTouchPoint::StateMoved;
401 return WebTouchPoint::StateUndefined;
404 PlatformTouchPointBuilder::PlatformTouchPointBuilder(Widget* widget, const WebTouchPoint& point)
407 m_state = toPlatformTouchPointState(point.state);
409 // This assumes convertFromContainingWindow does only translations, not scales.
410 FloatPoint floatPos = convertHitPointToWindow(widget, point.position);
411 IntPoint flooredPoint = flooredIntPoint(floatPos);
412 m_pos = widget->convertFromContainingWindow(flooredPoint) + (floatPos - flooredPoint);
414 m_screenPos = FloatPoint(point.screenPosition.x, point.screenPosition.y);
415 m_radius = scaleSizeToWindow(widget, FloatSize(point.radiusX, point.radiusY));
416 m_rotationAngle = point.rotationAngle;
417 m_force = point.force;
420 PlatformTouchEventBuilder::PlatformTouchEventBuilder(Widget* widget, const WebTouchEvent& event)
422 m_type = toPlatformTouchEventType(event.type);
425 if (event.modifiers & WebInputEvent::ShiftKey)
426 m_modifiers |= PlatformEvent::ShiftKey;
427 if (event.modifiers & WebInputEvent::ControlKey)
428 m_modifiers |= PlatformEvent::CtrlKey;
429 if (event.modifiers & WebInputEvent::AltKey)
430 m_modifiers |= PlatformEvent::AltKey;
431 if (event.modifiers & WebInputEvent::MetaKey)
432 m_modifiers |= PlatformEvent::MetaKey;
434 m_timestamp = event.timeStampSeconds;
436 for (unsigned i = 0; i < event.touchesLength; ++i)
437 m_touchPoints.append(PlatformTouchPointBuilder(widget, event.touches[i]));
439 m_cancelable = event.cancelable;
442 static int getWebInputModifiers(const UIEventWithKeyState& event)
446 modifiers |= WebInputEvent::ControlKey;
447 if (event.shiftKey())
448 modifiers |= WebInputEvent::ShiftKey;
450 modifiers |= WebInputEvent::AltKey;
452 modifiers |= WebInputEvent::MetaKey;
456 static FloatPoint convertAbsoluteLocationForRenderObjectFloat(const LayoutPoint& location, const RenderObject& renderObject)
458 return renderObject.absoluteToLocal(location, UseTransforms);
461 static IntPoint convertAbsoluteLocationForRenderObject(const LayoutPoint& location, const RenderObject& renderObject)
463 return roundedIntPoint(convertAbsoluteLocationForRenderObjectFloat(location, renderObject));
466 // FIXME: Change |widget| to const Widget& after RemoteFrames get
468 static void updateWebMouseEventFromCoreMouseEvent(const MouseRelatedEvent& event, const Widget* widget, const RenderObject& renderObject, WebMouseEvent& webEvent)
470 webEvent.timeStampSeconds = event.timeStamp() / millisPerSecond;
471 webEvent.modifiers = getWebInputModifiers(event);
473 FrameView* view = widget ? toFrameView(widget->parent()) : 0;
474 IntPoint windowPoint = IntPoint(event.absoluteLocation().x(), event.absoluteLocation().y());
476 windowPoint = view->contentsToWindow(windowPoint);
477 webEvent.globalX = event.screenX();
478 webEvent.globalY = event.screenY();
479 webEvent.windowX = windowPoint.x();
480 webEvent.windowY = windowPoint.y();
481 IntPoint localPoint = convertAbsoluteLocationForRenderObject(event.absoluteLocation(), renderObject);
482 webEvent.x = localPoint.x();
483 webEvent.y = localPoint.y();
486 WebMouseEventBuilder::WebMouseEventBuilder(const Widget* widget, const RenderObject* renderObject, const MouseEvent& event)
488 if (event.type() == EventTypeNames::mousemove)
489 type = WebInputEvent::MouseMove;
490 else if (event.type() == EventTypeNames::mouseout)
491 type = WebInputEvent::MouseLeave;
492 else if (event.type() == EventTypeNames::mouseover)
493 type = WebInputEvent::MouseEnter;
494 else if (event.type() == EventTypeNames::mousedown)
495 type = WebInputEvent::MouseDown;
496 else if (event.type() == EventTypeNames::mouseup)
497 type = WebInputEvent::MouseUp;
498 else if (event.type() == EventTypeNames::contextmenu)
499 type = WebInputEvent::ContextMenu;
501 return; // Skip all other mouse events.
503 updateWebMouseEventFromCoreMouseEvent(event, widget, *renderObject, *this);
505 switch (event.button()) {
507 button = WebMouseEvent::ButtonLeft;
510 button = WebMouseEvent::ButtonMiddle;
513 button = WebMouseEvent::ButtonRight;
516 if (event.buttonDown()) {
517 switch (event.button()) {
519 modifiers |= WebInputEvent::LeftButtonDown;
522 modifiers |= WebInputEvent::MiddleButtonDown;
525 modifiers |= WebInputEvent::RightButtonDown;
529 button = WebMouseEvent::ButtonNone;
530 movementX = event.movementX();
531 movementY = event.movementY();
532 clickCount = event.detail();
535 // Generate a synthetic WebMouseEvent given a TouchEvent (eg. for emulating a mouse
536 // with touch input for plugins that don't support touch input).
537 WebMouseEventBuilder::WebMouseEventBuilder(const Widget* widget, const RenderObject* renderObject, const TouchEvent& event)
539 if (!event.touches())
541 if (event.touches()->length() != 1) {
542 if (event.touches()->length() || event.type() != EventTypeNames::touchend || !event.changedTouches() || event.changedTouches()->length() != 1)
546 const Touch* touch = event.touches()->length() == 1 ? event.touches()->item(0) : event.changedTouches()->item(0);
547 if (touch->identifier())
550 if (event.type() == EventTypeNames::touchstart)
552 else if (event.type() == EventTypeNames::touchmove)
554 else if (event.type() == EventTypeNames::touchend)
559 timeStampSeconds = event.timeStamp() / millisPerSecond;
560 modifiers = getWebInputModifiers(event);
562 // The mouse event co-ordinates should be generated from the co-ordinates of the touch point.
563 FrameView* view = toFrameView(widget->parent());
564 IntPoint windowPoint = roundedIntPoint(touch->absoluteLocation());
566 windowPoint = view->contentsToWindow(windowPoint);
567 IntPoint screenPoint = roundedIntPoint(touch->screenLocation());
568 globalX = screenPoint.x();
569 globalY = screenPoint.y();
570 windowX = windowPoint.x();
571 windowY = windowPoint.y();
573 button = WebMouseEvent::ButtonLeft;
574 modifiers |= WebInputEvent::LeftButtonDown;
575 clickCount = (type == MouseDown || type == MouseUp);
577 IntPoint localPoint = convertAbsoluteLocationForRenderObject(touch->absoluteLocation(), *renderObject);
582 WebMouseEventBuilder::WebMouseEventBuilder(const Widget* widget, const PlatformMouseEvent& event)
584 switch (event.type()) {
585 case PlatformEvent::MouseMoved:
588 case PlatformEvent::MousePressed:
591 case PlatformEvent::MouseReleased:
595 ASSERT_NOT_REACHED();
601 if (event.modifiers() & PlatformEvent::ShiftKey)
602 modifiers |= ShiftKey;
603 if (event.modifiers() & PlatformEvent::CtrlKey)
604 modifiers |= ControlKey;
605 if (event.modifiers() & PlatformEvent::AltKey)
607 if (event.modifiers() & PlatformEvent::MetaKey)
608 modifiers |= MetaKey;
610 timeStampSeconds = event.timestamp();
612 // FIXME: Widget is always toplevel, unless it's a popup. We may be able
613 // to get rid of this once we abstract popups into a WebKit API.
614 IntPoint position = widget->convertToContainingWindow(event.position());
617 FrameView* rootView = toFrameView(widget->root());
619 scale = rootView->inputEventsScaleFactor();
621 position.scale(scale, scale);
624 globalX = event.globalPosition().x();
625 globalY = event.globalPosition().y();
626 movementX = event.movementDelta().x() * scale;
627 movementY = event.movementDelta().y() * scale;
629 button = static_cast<Button>(event.button());
630 clickCount = event.clickCount();
633 WebMouseWheelEventBuilder::WebMouseWheelEventBuilder(const Widget* widget, const RenderObject* renderObject, const WheelEvent& event)
635 if (event.type() != EventTypeNames::wheel && event.type() != EventTypeNames::mousewheel)
637 type = WebInputEvent::MouseWheel;
638 updateWebMouseEventFromCoreMouseEvent(event, widget, *renderObject, *this);
639 deltaX = -event.deltaX();
640 deltaY = -event.deltaY();
641 wheelTicksX = event.ticksX();
642 wheelTicksY = event.ticksY();
643 scrollByPage = event.deltaMode() == WheelEvent::DOM_DELTA_PAGE;
646 WebKeyboardEventBuilder::WebKeyboardEventBuilder(const KeyboardEvent& event)
648 if (event.type() == EventTypeNames::keydown)
650 else if (event.type() == EventTypeNames::keyup)
651 type = WebInputEvent::KeyUp;
652 else if (event.type() == EventTypeNames::keypress)
653 type = WebInputEvent::Char;
655 return; // Skip all other keyboard events.
657 modifiers = getWebInputModifiers(event);
658 if (event.location() == KeyboardEvent::DOM_KEY_LOCATION_NUMPAD)
659 modifiers |= WebInputEvent::IsKeyPad;
660 else if (event.location() == KeyboardEvent::DOM_KEY_LOCATION_LEFT)
661 modifiers |= WebInputEvent::IsLeft;
662 else if (event.location() == KeyboardEvent::DOM_KEY_LOCATION_RIGHT)
663 modifiers |= WebInputEvent::IsRight;
665 timeStampSeconds = event.timeStamp() / millisPerSecond;
666 windowsKeyCode = event.keyCode();
668 // The platform keyevent does not exist if the event was created using
669 // initKeyboardEvent.
670 if (!event.keyEvent())
672 nativeKeyCode = event.keyEvent()->nativeVirtualKeyCode();
673 unsigned numberOfCharacters = std::min(event.keyEvent()->text().length(), static_cast<unsigned>(textLengthCap));
674 for (unsigned i = 0; i < numberOfCharacters; ++i) {
675 text[i] = event.keyEvent()->text()[i];
676 unmodifiedText[i] = event.keyEvent()->unmodifiedText()[i];
678 memcpy(keyIdentifier, event.keyIdentifier().ascii().data(), event.keyIdentifier().length());
681 WebInputEvent::Type toWebKeyboardEventType(PlatformEvent::Type type)
684 case PlatformEvent::KeyUp:
685 return WebInputEvent::KeyUp;
686 case PlatformEvent::KeyDown:
687 return WebInputEvent::KeyDown;
688 case PlatformEvent::RawKeyDown:
689 return WebInputEvent::RawKeyDown;
690 case PlatformEvent::Char:
691 return WebInputEvent::Char;
693 return WebInputEvent::Undefined;
697 int toWebKeyboardEventModifiers(int modifiers)
699 int newModifiers = 0;
700 if (modifiers & PlatformEvent::ShiftKey)
701 newModifiers |= WebInputEvent::ShiftKey;
702 if (modifiers & PlatformEvent::CtrlKey)
703 newModifiers |= WebInputEvent::ControlKey;
704 if (modifiers & PlatformEvent::AltKey)
705 newModifiers |= WebInputEvent::AltKey;
706 if (modifiers & PlatformEvent::MetaKey)
707 newModifiers |= WebInputEvent::MetaKey;
711 WebKeyboardEventBuilder::WebKeyboardEventBuilder(const PlatformKeyboardEvent& event)
713 type = toWebKeyboardEventType(event.type());
714 modifiers = toWebKeyboardEventModifiers(event.modifiers());
715 if (event.isAutoRepeat())
716 modifiers |= WebInputEvent::IsAutoRepeat;
717 if (event.isKeypad())
718 modifiers |= WebInputEvent::IsKeyPad;
719 isSystemKey = event.isSystemKey();
720 nativeKeyCode = event.nativeVirtualKeyCode();
722 windowsKeyCode = windowsKeyCodeWithoutLocation(event.windowsVirtualKeyCode());
723 modifiers |= locationModifiersFromWindowsKeyCode(event.windowsVirtualKeyCode());
725 event.text().copyTo(text, 0, textLengthCap);
726 event.unmodifiedText().copyTo(unmodifiedText, 0, textLengthCap);
727 memcpy(keyIdentifier, event.keyIdentifier().ascii().data(), std::min(static_cast<unsigned>(keyIdentifierLengthCap), event.keyIdentifier().length()));
730 static WebTouchPoint toWebTouchPoint(const Touch* touch, const RenderObject* renderObject, WebTouchPoint::State state)
733 point.id = touch->identifier();
734 point.screenPosition = touch->screenLocation();
735 point.position = convertAbsoluteLocationForRenderObjectFloat(touch->absoluteLocation(), *renderObject);
736 point.radiusX = touch->radiusX();
737 point.radiusY = touch->radiusY();
738 point.rotationAngle = touch->webkitRotationAngle();
739 point.force = touch->force();
744 static bool hasTouchPointWithId(const WebTouchPoint* touchPoints, unsigned touchPointsLength, unsigned id)
746 for (unsigned i = 0; i < touchPointsLength; ++i) {
747 if (touchPoints[i].id == static_cast<int>(id))
753 static void addTouchPointsIfNotYetAdded(const Widget* widget, WebTouchPoint::State state, TouchList* touches, WebTouchPoint* touchPoints, unsigned* touchPointsLength, const RenderObject* renderObject)
755 unsigned initialTouchPointsLength = *touchPointsLength;
756 for (unsigned i = 0; i < touches->length(); ++i) {
757 const unsigned pointIndex = *touchPointsLength;
758 if (pointIndex >= static_cast<unsigned>(WebTouchEvent::touchesLengthCap))
761 const Touch* touch = touches->item(i);
762 if (hasTouchPointWithId(touchPoints, initialTouchPointsLength, touch->identifier()))
765 touchPoints[pointIndex] = toWebTouchPoint(touch, renderObject, state);
766 ++(*touchPointsLength);
770 WebTouchEventBuilder::WebTouchEventBuilder(const Widget* widget, const RenderObject* renderObject, const TouchEvent& event)
772 if (event.type() == EventTypeNames::touchstart)
774 else if (event.type() == EventTypeNames::touchmove)
776 else if (event.type() == EventTypeNames::touchend)
778 else if (event.type() == EventTypeNames::touchcancel)
781 ASSERT_NOT_REACHED();
786 modifiers = getWebInputModifiers(event);
787 timeStampSeconds = event.timeStamp() / millisPerSecond;
788 cancelable = event.cancelable();
790 addTouchPointsIfNotYetAdded(widget, toWebTouchPointState(event.type()), event.changedTouches(), touches, &touchesLength, renderObject);
791 addTouchPointsIfNotYetAdded(widget, WebTouchPoint::StateStationary, event.touches(), touches, &touchesLength, renderObject);
794 WebGestureEventBuilder::WebGestureEventBuilder(const Widget* widget, const RenderObject* renderObject, const GestureEvent& event)
796 if (event.type() == EventTypeNames::gestureshowpress)
797 type = GestureShowPress;
798 else if (event.type() == EventTypeNames::gesturetapdown)
799 type = GestureTapDown;
800 else if (event.type() == EventTypeNames::gesturescrollstart)
801 type = GestureScrollBegin;
802 else if (event.type() == EventTypeNames::gesturescrollend)
803 type = GestureScrollEnd;
804 else if (event.type() == EventTypeNames::gesturescrollupdate) {
805 type = GestureScrollUpdate;
806 data.scrollUpdate.deltaX = event.deltaX();
807 data.scrollUpdate.deltaY = event.deltaY();
808 } else if (event.type() == EventTypeNames::gesturetap) {
810 data.tap.tapCount = 1;
813 timeStampSeconds = event.timeStamp() / millisPerSecond;
814 modifiers = getWebInputModifiers(event);
816 globalX = event.screenX();
817 globalY = event.screenY();
818 IntPoint localPoint = convertAbsoluteLocationForRenderObject(event.absoluteLocation(), *renderObject);