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 "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/rendering/RenderObject.h"
42 #include "platform/KeyboardCodes.h"
43 #include "platform/Widget.h"
44 #include "platform/scroll/ScrollView.h"
46 using namespace WebCore;
50 static const double millisPerSecond = 1000.0;
52 static float widgetInputEventsScaleFactor(const Widget* widget)
57 ScrollView* rootView = toScrollView(widget->root());
61 return rootView->inputEventsScaleFactor();
64 static IntSize widgetInputEventsOffset(const Widget* widget)
68 ScrollView* rootView = toScrollView(widget->root());
72 return rootView->inputEventsOffsetForEmulation();
75 // MakePlatformMouseEvent -----------------------------------------------------
77 PlatformMouseEventBuilder::PlatformMouseEventBuilder(Widget* widget, const WebMouseEvent& e)
79 float scale = widgetInputEventsScaleFactor(widget);
80 IntSize offset = widgetInputEventsOffset(widget);
82 // FIXME: Widget is always toplevel, unless it's a popup. We may be able
83 // to get rid of this once we abstract popups into a WebKit API.
84 m_position = widget->convertFromContainingWindow(IntPoint((e.x - offset.width()) / scale, (e.y - offset.height()) / scale));
85 m_globalPosition = IntPoint(e.globalX, e.globalY);
86 m_movementDelta = IntPoint(e.movementX / scale, e.movementY / scale);
87 m_button = static_cast<MouseButton>(e.button);
90 if (e.modifiers & WebInputEvent::ShiftKey)
91 m_modifiers |= PlatformEvent::ShiftKey;
92 if (e.modifiers & WebInputEvent::ControlKey)
93 m_modifiers |= PlatformEvent::CtrlKey;
94 if (e.modifiers & WebInputEvent::AltKey)
95 m_modifiers |= PlatformEvent::AltKey;
96 if (e.modifiers & WebInputEvent::MetaKey)
97 m_modifiers |= PlatformEvent::MetaKey;
99 m_modifierFlags = e.modifiers;
100 m_timestamp = e.timeStampSeconds;
101 m_clickCount = e.clickCount;
104 case WebInputEvent::MouseMove:
105 case WebInputEvent::MouseLeave: // synthesize a move event
106 m_type = PlatformEvent::MouseMoved;
109 case WebInputEvent::MouseDown:
110 m_type = PlatformEvent::MousePressed;
113 case WebInputEvent::MouseUp:
114 m_type = PlatformEvent::MouseReleased;
118 ASSERT_NOT_REACHED();
122 // PlatformWheelEventBuilder --------------------------------------------------
124 PlatformWheelEventBuilder::PlatformWheelEventBuilder(Widget* widget, const WebMouseWheelEvent& e)
126 float scale = widgetInputEventsScaleFactor(widget);
127 IntSize offset = widgetInputEventsOffset(widget);
129 m_position = widget->convertFromContainingWindow(IntPoint((e.x - offset.width()) / scale, (e.y - offset.height()) / scale));
130 m_globalPosition = IntPoint(e.globalX, e.globalY);
133 m_wheelTicksX = e.wheelTicksX;
134 m_wheelTicksY = e.wheelTicksY;
135 m_granularity = e.scrollByPage ?
136 ScrollByPageWheelEvent : ScrollByPixelWheelEvent;
138 m_type = PlatformEvent::Wheel;
141 if (e.modifiers & WebInputEvent::ShiftKey)
142 m_modifiers |= PlatformEvent::ShiftKey;
143 if (e.modifiers & WebInputEvent::ControlKey)
144 m_modifiers |= PlatformEvent::CtrlKey;
145 if (e.modifiers & WebInputEvent::AltKey)
146 m_modifiers |= PlatformEvent::AltKey;
147 if (e.modifiers & WebInputEvent::MetaKey)
148 m_modifiers |= PlatformEvent::MetaKey;
150 m_hasPreciseScrollingDeltas = e.hasPreciseScrollingDeltas;
152 m_phase = static_cast<WebCore::PlatformWheelEventPhase>(e.phase);
153 m_momentumPhase = static_cast<WebCore::PlatformWheelEventPhase>(e.momentumPhase);
154 m_timestamp = e.timeStampSeconds;
156 m_unacceleratedScrollingDeltaX = e.deltaX;
157 m_unacceleratedScrollingDeltaY = e.deltaY;
158 m_canRubberbandLeft = e.canRubberbandLeft;
159 m_canRubberbandRight = e.canRubberbandRight;
163 // PlatformGestureEventBuilder --------------------------------------------------
165 PlatformGestureEventBuilder::PlatformGestureEventBuilder(Widget* widget, const WebGestureEvent& e)
167 float scale = widgetInputEventsScaleFactor(widget);
168 IntSize offset = widgetInputEventsOffset(widget);
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 = e.data.scrollUpdate.deltaX / scale;
183 m_data.m_scrollUpdate.m_deltaY = e.data.scrollUpdate.deltaY / scale;
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 = e.data.scrollUpdate.deltaX / scale;
190 m_data.m_scrollUpdate.m_deltaY = e.data.scrollUpdate.deltaY / scale;
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(FloatSize(e.data.tap.width / scale, e.data.tap.height / scale));
197 m_data.m_tap.m_tapCount = e.data.tap.tapCount;
199 case WebInputEvent::GestureTapUnconfirmed:
200 m_type = PlatformEvent::GestureTapUnconfirmed;
201 m_area = expandedIntSize(FloatSize(e.data.tap.width / scale, e.data.tap.height / scale));
203 case WebInputEvent::GestureTapDown:
204 m_type = PlatformEvent::GestureTapDown;
205 m_area = expandedIntSize(FloatSize(e.data.tapDown.width / scale, e.data.tapDown.height / scale));
207 case WebInputEvent::GestureShowPress:
208 m_type = PlatformEvent::GestureShowPress;
209 m_area = expandedIntSize(FloatSize(e.data.showPress.width / scale, e.data.showPress.height / scale));
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(FloatSize(e.data.twoFingerTap.firstFingerWidth / scale, e.data.twoFingerTap.firstFingerHeight / scale));
225 case WebInputEvent::GestureLongPress:
226 m_type = PlatformEvent::GestureLongPress;
227 m_area = expandedIntSize(FloatSize(e.data.longPress.width / scale, e.data.longPress.height / scale));
229 case WebInputEvent::GestureLongTap:
230 m_type = PlatformEvent::GestureLongTap;
231 m_area = expandedIntSize(FloatSize(e.data.longPress.width / scale, e.data.longPress.height / scale));
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(IntPoint((e.x - offset.width()) / scale, (e.y - offset.height()) / scale));
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)
406 float scale = widgetInputEventsScaleFactor(widget);
407 IntSize offset = widgetInputEventsOffset(widget);
409 m_state = toPlatformTouchPointState(point.state);
410 m_pos = widget->convertFromContainingWindow(IntPoint((point.position.x - offset.width()) / scale, (point.position.y - offset.height()) / scale));
411 m_screenPos = IntPoint(point.screenPosition.x, point.screenPosition.y);
412 m_radiusY = point.radiusY / scale;
413 m_radiusX = point.radiusX / scale;
414 m_rotationAngle = point.rotationAngle;
415 m_force = point.force;
418 PlatformTouchEventBuilder::PlatformTouchEventBuilder(Widget* widget, const WebTouchEvent& event)
420 m_type = toPlatformTouchEventType(event.type);
423 if (event.modifiers & WebInputEvent::ShiftKey)
424 m_modifiers |= PlatformEvent::ShiftKey;
425 if (event.modifiers & WebInputEvent::ControlKey)
426 m_modifiers |= PlatformEvent::CtrlKey;
427 if (event.modifiers & WebInputEvent::AltKey)
428 m_modifiers |= PlatformEvent::AltKey;
429 if (event.modifiers & WebInputEvent::MetaKey)
430 m_modifiers |= PlatformEvent::MetaKey;
432 m_timestamp = event.timeStampSeconds;
434 for (unsigned i = 0; i < event.touchesLength; ++i)
435 m_touchPoints.append(PlatformTouchPointBuilder(widget, event.touches[i]));
438 static int getWebInputModifiers(const UIEventWithKeyState& event)
442 modifiers |= WebInputEvent::ControlKey;
443 if (event.shiftKey())
444 modifiers |= WebInputEvent::ShiftKey;
446 modifiers |= WebInputEvent::AltKey;
448 modifiers |= WebInputEvent::MetaKey;
452 static IntPoint convertAbsoluteLocationForRenderObject(const LayoutPoint& location, const WebCore::RenderObject& renderObject)
454 return roundedIntPoint(renderObject.absoluteToLocal(location, UseTransforms));
457 static void updateWebMouseEventFromWebCoreMouseEvent(const MouseRelatedEvent& event, const Widget& widget, const WebCore::RenderObject& renderObject, WebMouseEvent& webEvent)
459 webEvent.timeStampSeconds = event.timeStamp() / millisPerSecond;
460 webEvent.modifiers = getWebInputModifiers(event);
462 ScrollView* view = toScrollView(widget.parent());
463 IntPoint windowPoint = IntPoint(event.absoluteLocation().x(), event.absoluteLocation().y());
465 windowPoint = view->contentsToWindow(windowPoint);
466 webEvent.globalX = event.screenX();
467 webEvent.globalY = event.screenY();
468 webEvent.windowX = windowPoint.x();
469 webEvent.windowY = windowPoint.y();
470 IntPoint localPoint = convertAbsoluteLocationForRenderObject(event.absoluteLocation(), renderObject);
471 webEvent.x = localPoint.x();
472 webEvent.y = localPoint.y();
475 WebMouseEventBuilder::WebMouseEventBuilder(const Widget* widget, const WebCore::RenderObject* renderObject, const MouseEvent& event)
477 if (event.type() == EventTypeNames::mousemove)
478 type = WebInputEvent::MouseMove;
479 else if (event.type() == EventTypeNames::mouseout)
480 type = WebInputEvent::MouseLeave;
481 else if (event.type() == EventTypeNames::mouseover)
482 type = WebInputEvent::MouseEnter;
483 else if (event.type() == EventTypeNames::mousedown)
484 type = WebInputEvent::MouseDown;
485 else if (event.type() == EventTypeNames::mouseup)
486 type = WebInputEvent::MouseUp;
487 else if (event.type() == EventTypeNames::contextmenu)
488 type = WebInputEvent::ContextMenu;
490 return; // Skip all other mouse events.
492 updateWebMouseEventFromWebCoreMouseEvent(event, *widget, *renderObject, *this);
494 switch (event.button()) {
496 button = WebMouseEvent::ButtonLeft;
499 button = WebMouseEvent::ButtonMiddle;
502 button = WebMouseEvent::ButtonRight;
505 if (event.buttonDown()) {
506 switch (event.button()) {
508 modifiers |= WebInputEvent::LeftButtonDown;
511 modifiers |= WebInputEvent::MiddleButtonDown;
514 modifiers |= WebInputEvent::RightButtonDown;
518 button = WebMouseEvent::ButtonNone;
519 movementX = event.webkitMovementX();
520 movementY = event.webkitMovementY();
521 clickCount = event.detail();
524 WebMouseEventBuilder::WebMouseEventBuilder(const Widget* widget, const WebCore::RenderObject* renderObject, const TouchEvent& event)
526 if (!event.touches())
528 if (event.touches()->length() != 1) {
529 if (event.touches()->length() || event.type() != EventTypeNames::touchend || !event.changedTouches() || event.changedTouches()->length() != 1)
533 const Touch* touch = event.touches()->length() == 1 ? event.touches()->item(0) : event.changedTouches()->item(0);
534 if (touch->identifier())
537 if (event.type() == EventTypeNames::touchstart)
539 else if (event.type() == EventTypeNames::touchmove)
541 else if (event.type() == EventTypeNames::touchend)
546 updateWebMouseEventFromWebCoreMouseEvent(event, *widget, *renderObject, *this);
548 button = WebMouseEvent::ButtonLeft;
549 modifiers |= WebInputEvent::LeftButtonDown;
550 clickCount = (type == MouseDown || type == MouseUp);
552 IntPoint localPoint = convertAbsoluteLocationForRenderObject(touch->absoluteLocation(), *renderObject);
557 WebMouseEventBuilder::WebMouseEventBuilder(const WebCore::Widget* widget, const WebCore::PlatformMouseEvent& event)
559 switch (event.type()) {
560 case PlatformEvent::MouseMoved:
563 case PlatformEvent::MousePressed:
566 case PlatformEvent::MouseReleased:
570 ASSERT_NOT_REACHED();
576 if (event.modifiers() & PlatformEvent::ShiftKey)
577 modifiers |= ShiftKey;
578 if (event.modifiers() & PlatformEvent::CtrlKey)
579 modifiers |= ControlKey;
580 if (event.modifiers() & PlatformEvent::AltKey)
582 if (event.modifiers() & PlatformEvent::MetaKey)
583 modifiers |= MetaKey;
585 timeStampSeconds = event.timestamp();
587 // FIXME: Widget is always toplevel, unless it's a popup. We may be able
588 // to get rid of this once we abstract popups into a WebKit API.
589 IntPoint position = widget->convertToContainingWindow(event.position());
590 float scale = widgetInputEventsScaleFactor(widget);
591 position.scale(scale, scale);
594 globalX = event.globalPosition().x();
595 globalY = event.globalPosition().y();
596 movementX = event.movementDelta().x() * scale;
597 movementY = event.movementDelta().y() * scale;
599 button = static_cast<Button>(event.button());
600 clickCount = event.clickCount();
603 WebMouseWheelEventBuilder::WebMouseWheelEventBuilder(const Widget* widget, const WebCore::RenderObject* renderObject, const WheelEvent& event)
605 if (event.type() != EventTypeNames::wheel && event.type() != EventTypeNames::mousewheel)
607 type = WebInputEvent::MouseWheel;
608 updateWebMouseEventFromWebCoreMouseEvent(event, *widget, *renderObject, *this);
609 deltaX = -event.deltaX();
610 deltaY = -event.deltaY();
611 wheelTicksX = event.ticksX();
612 wheelTicksY = event.ticksY();
613 scrollByPage = event.deltaMode() == WheelEvent::DOM_DELTA_PAGE;
616 WebKeyboardEventBuilder::WebKeyboardEventBuilder(const KeyboardEvent& event)
618 if (event.type() == EventTypeNames::keydown)
620 else if (event.type() == EventTypeNames::keyup)
621 type = WebInputEvent::KeyUp;
622 else if (event.type() == EventTypeNames::keypress)
623 type = WebInputEvent::Char;
625 return; // Skip all other keyboard events.
627 modifiers = getWebInputModifiers(event);
628 if (event.location() == KeyboardEvent::DOM_KEY_LOCATION_NUMPAD)
629 modifiers |= WebInputEvent::IsKeyPad;
630 else if (event.location() == KeyboardEvent::DOM_KEY_LOCATION_LEFT)
631 modifiers |= WebInputEvent::IsLeft;
632 else if (event.location() == KeyboardEvent::DOM_KEY_LOCATION_RIGHT)
633 modifiers |= WebInputEvent::IsRight;
635 timeStampSeconds = event.timeStamp() / millisPerSecond;
636 windowsKeyCode = event.keyCode();
638 // The platform keyevent does not exist if the event was created using
639 // initKeyboardEvent.
640 if (!event.keyEvent())
642 nativeKeyCode = event.keyEvent()->nativeVirtualKeyCode();
643 unsigned numberOfCharacters = std::min(event.keyEvent()->text().length(), static_cast<unsigned>(textLengthCap));
644 for (unsigned i = 0; i < numberOfCharacters; ++i) {
645 text[i] = event.keyEvent()->text()[i];
646 unmodifiedText[i] = event.keyEvent()->unmodifiedText()[i];
648 memcpy(keyIdentifier, event.keyIdentifier().ascii().data(), event.keyIdentifier().length());
651 WebInputEvent::Type toWebKeyboardEventType(PlatformEvent::Type type)
654 case PlatformEvent::KeyUp:
655 return WebInputEvent::KeyUp;
656 case PlatformEvent::KeyDown:
657 return WebInputEvent::KeyDown;
658 case PlatformEvent::RawKeyDown:
659 return WebInputEvent::RawKeyDown;
660 case PlatformEvent::Char:
661 return WebInputEvent::Char;
663 return WebInputEvent::Undefined;
667 int toWebKeyboardEventModifiers(int modifiers)
669 int newModifiers = 0;
670 if (modifiers & PlatformEvent::ShiftKey)
671 newModifiers |= WebInputEvent::ShiftKey;
672 if (modifiers & PlatformEvent::CtrlKey)
673 newModifiers |= WebInputEvent::ControlKey;
674 if (modifiers & PlatformEvent::AltKey)
675 newModifiers |= WebInputEvent::AltKey;
676 if (modifiers & PlatformEvent::MetaKey)
677 newModifiers |= WebInputEvent::MetaKey;
681 WebKeyboardEventBuilder::WebKeyboardEventBuilder(const WebCore::PlatformKeyboardEvent& event)
683 type = toWebKeyboardEventType(event.type());
684 modifiers = toWebKeyboardEventModifiers(event.modifiers());
685 if (event.isAutoRepeat())
686 modifiers |= WebInputEvent::IsAutoRepeat;
687 if (event.isKeypad())
688 modifiers |= WebInputEvent::IsKeyPad;
689 isSystemKey = event.isSystemKey();
690 nativeKeyCode = event.nativeVirtualKeyCode();
692 windowsKeyCode = windowsKeyCodeWithoutLocation(event.windowsVirtualKeyCode());
693 modifiers |= locationModifiersFromWindowsKeyCode(event.windowsVirtualKeyCode());
695 event.text().copyTo(text, 0, textLengthCap);
696 event.unmodifiedText().copyTo(unmodifiedText, 0, textLengthCap);
697 memcpy(keyIdentifier, event.keyIdentifier().ascii().data(), std::min(static_cast<unsigned>(keyIdentifierLengthCap), event.keyIdentifier().length()));
700 static void addTouchPoints(const Widget* widget, const AtomicString& touchType, TouchList* touches, WebTouchPoint* touchPoints, unsigned* touchPointsLength, const WebCore::RenderObject* renderObject)
702 unsigned numberOfTouches = std::min(touches->length(), static_cast<unsigned>(WebTouchEvent::touchesLengthCap));
703 for (unsigned i = 0; i < numberOfTouches; ++i) {
704 const Touch* touch = touches->item(i);
707 point.id = touch->identifier();
708 point.screenPosition = WebFloatPoint(touch->screenX(), touch->screenY());
709 point.position = convertAbsoluteLocationForRenderObject(touch->absoluteLocation(), *renderObject);
710 point.radiusX = touch->webkitRadiusX();
711 point.radiusY = touch->webkitRadiusY();
712 point.rotationAngle = touch->webkitRotationAngle();
713 point.force = touch->webkitForce();
714 point.state = toWebTouchPointState(touchType);
716 touchPoints[i] = point;
718 *touchPointsLength = numberOfTouches;
721 WebTouchEventBuilder::WebTouchEventBuilder(const Widget* widget, const WebCore::RenderObject* renderObject, const TouchEvent& event)
723 if (event.type() == EventTypeNames::touchstart)
725 else if (event.type() == EventTypeNames::touchmove)
727 else if (event.type() == EventTypeNames::touchend)
729 else if (event.type() == EventTypeNames::touchcancel)
732 ASSERT_NOT_REACHED();
737 modifiers = getWebInputModifiers(event);
738 timeStampSeconds = event.timeStamp() / millisPerSecond;
740 addTouchPoints(widget, event.type(), event.touches(), touches, &touchesLength, renderObject);
741 addTouchPoints(widget, event.type(), event.changedTouches(), changedTouches, &changedTouchesLength, renderObject);
742 addTouchPoints(widget, event.type(), event.targetTouches(), targetTouches, &targetTouchesLength, renderObject);
745 WebGestureEventBuilder::WebGestureEventBuilder(const Widget* widget, const WebCore::RenderObject* renderObject, const GestureEvent& event)
747 if (event.type() == EventTypeNames::gestureshowpress)
748 type = GestureShowPress;
749 else if (event.type() == EventTypeNames::gesturetapdown)
750 type = GestureTapDown;
751 else if (event.type() == EventTypeNames::gesturescrollstart)
752 type = GestureScrollBegin;
753 else if (event.type() == EventTypeNames::gesturescrollend)
754 type = GestureScrollEnd;
755 else if (event.type() == EventTypeNames::gesturescrollupdate) {
756 type = GestureScrollUpdate;
757 data.scrollUpdate.deltaX = event.deltaX();
758 data.scrollUpdate.deltaY = event.deltaY();
759 } else if (event.type() == EventTypeNames::gesturetap) {
761 data.tap.tapCount = 1;
764 timeStampSeconds = event.timeStamp() / millisPerSecond;
765 modifiers = getWebInputModifiers(event);
767 globalX = event.screenX();
768 globalY = event.screenY();
769 IntPoint localPoint = convertAbsoluteLocationForRenderObject(event.absoluteLocation(), *renderObject);