15821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Copyright (c) 2012 The Chromium Authors. All rights reserved.
25821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be
35821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// found in the LICENSE file.
45821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
55821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "content/browser/renderer_host/ui_events_helper.h"
65821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
77d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)#include "third_party/WebKit/public/web/WebInputEvent.h"
85821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ui/base/events/event.h"
95821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ui/base/events/event_constants.h"
105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace {
125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)int WebModifiersToUIFlags(int modifiers) {
145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int flags = ui::EF_NONE;
155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (modifiers & WebKit::WebInputEvent::ShiftKey)
175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    flags |= ui::EF_SHIFT_DOWN;
185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (modifiers & WebKit::WebInputEvent::ControlKey)
195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    flags |= ui::EF_CONTROL_DOWN;
205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (modifiers & WebKit::WebInputEvent::AltKey)
215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    flags |= ui::EF_ALT_DOWN;
225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (modifiers & WebKit::WebInputEvent::LeftButtonDown)
245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    flags |= ui::EF_LEFT_MOUSE_BUTTON;
255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (modifiers & WebKit::WebInputEvent::RightButtonDown)
265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    flags |= ui::EF_RIGHT_MOUSE_BUTTON;
275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (modifiers & WebKit::WebInputEvent::MiddleButtonDown)
285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    flags |= ui::EF_MIDDLE_MOUSE_BUTTON;
295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (modifiers & WebKit::WebInputEvent::CapsLockOn)
315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    flags |= ui::EF_CAPS_LOCK_DOWN;
325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return flags;
345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)ui::EventType WebTouchPointStateToEventType(
375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    WebKit::WebTouchPoint::State state) {
385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  switch (state) {
395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    case WebKit::WebTouchPoint::StateReleased:
405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      return ui::ET_TOUCH_RELEASED;
415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    case WebKit::WebTouchPoint::StatePressed:
435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      return ui::ET_TOUCH_PRESSED;
445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    case WebKit::WebTouchPoint::StateMoved:
465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      return ui::ET_TOUCH_MOVED;
475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    case WebKit::WebTouchPoint::StateCancelled:
495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      return ui::ET_TOUCH_CANCELLED;
505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    default:
525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      return ui::ET_UNKNOWN;
535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)WebKit::WebTouchPoint::State TouchPointStateFromEvent(
575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const ui::TouchEvent& event) {
585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  switch (event.type()) {
595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    case ui::ET_TOUCH_PRESSED:
605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      return WebKit::WebTouchPoint::StatePressed;
615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    case ui::ET_TOUCH_RELEASED:
625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      return WebKit::WebTouchPoint::StateReleased;
635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    case ui::ET_TOUCH_MOVED:
645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      return WebKit::WebTouchPoint::StateMoved;
655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    case ui::ET_TOUCH_CANCELLED:
665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      return WebKit::WebTouchPoint::StateCancelled;
675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    default:
685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      return WebKit::WebTouchPoint::StateUndefined;
695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)WebKit::WebInputEvent::Type TouchEventTypeFromEvent(
735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const ui::TouchEvent& event) {
745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  switch (event.type()) {
755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    case ui::ET_TOUCH_PRESSED:
765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      return WebKit::WebInputEvent::TouchStart;
775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    case ui::ET_TOUCH_RELEASED:
785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      return WebKit::WebInputEvent::TouchEnd;
795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    case ui::ET_TOUCH_MOVED:
805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      return WebKit::WebInputEvent::TouchMove;
815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    case ui::ET_TOUCH_CANCELLED:
825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      return WebKit::WebInputEvent::TouchCancel;
835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    default:
845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      return WebKit::WebInputEvent::Undefined;
855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}  // namespace
895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace content {
915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)bool MakeUITouchEventsFromWebTouchEvents(
937d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    const TouchEventWithLatencyInfo& touch_with_latency,
942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    ScopedVector<ui::TouchEvent>* list,
952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    TouchEventCoordinateSystem coordinate_system) {
967d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  const WebKit::WebTouchEvent& touch = touch_with_latency.event;
975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ui::EventType type = ui::ET_UNKNOWN;
985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  switch (touch.type) {
995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    case WebKit::WebInputEvent::TouchStart:
1005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      type = ui::ET_TOUCH_PRESSED;
1015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      break;
1025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    case WebKit::WebInputEvent::TouchEnd:
1035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      type = ui::ET_TOUCH_RELEASED;
1045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      break;
1055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    case WebKit::WebInputEvent::TouchMove:
1065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      type = ui::ET_TOUCH_MOVED;
1075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      break;
1085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    case WebKit::WebInputEvent::TouchCancel:
1095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      type = ui::ET_TOUCH_CANCELLED;
1105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      break;
1115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    default:
1125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      NOTREACHED();
1135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      return false;
1145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
1155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int flags = WebModifiersToUIFlags(touch.modifiers);
1175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  base::TimeDelta timestamp = base::TimeDelta::FromMicroseconds(
1185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      static_cast<int64>(touch.timeStampSeconds * 1000000));
1195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  for (unsigned i = 0; i < touch.touchesLength; ++i) {
1205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const WebKit::WebTouchPoint& point = touch.touches[i];
1215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (WebTouchPointStateToEventType(point.state) != type)
1225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      continue;
1235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // In aura, the touch-event needs to be in the screen coordinate, since the
1245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // touch-event is routed to RootWindow first. In Windows, on the other hand,
1255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // the touch-event is dispatched directly to the gesture-recognizer, so the
1265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // location needs to be in the local coordinate space.
1275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#if defined(USE_AURA)
1282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    gfx::Point location;
1292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    if (coordinate_system == LOCAL_COORDINATES)
1302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      location = gfx::Point(point.position.x, point.position.y);
1312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    else
1322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      location = gfx::Point(point.screenPosition.x, point.screenPosition.y);
1335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#else
1345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    gfx::Point location(point.position.x, point.position.y);
1355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif
1365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ui::TouchEvent* uievent = new ui::TouchEvent(type,
1375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          location,
1385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          flags,
1395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          point.id,
1405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          timestamp,
1415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          point.radiusX,
1425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          point.radiusY,
1435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          point.rotationAngle,
1445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          point.force);
1457d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    uievent->set_latency(touch_with_latency.latency);
1465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    list->push_back(uievent);
1475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
1485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return true;
1495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)WebKit::WebGestureEvent MakeWebGestureEventFromUIEvent(
1525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const ui::GestureEvent& event) {
1535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  WebKit::WebGestureEvent gesture_event;
1545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  switch (event.type()) {
1565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    case ui::ET_GESTURE_TAP:
1575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      gesture_event.type = WebKit::WebInputEvent::GestureTap;
1585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      gesture_event.data.tap.tapCount = event.details().tap_count();
1595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      gesture_event.data.tap.width = event.details().bounding_box().width();
1605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      gesture_event.data.tap.height = event.details().bounding_box().height();
1615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      break;
1625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    case ui::ET_GESTURE_TAP_DOWN:
1635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      gesture_event.type = WebKit::WebInputEvent::GestureTapDown;
1645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      gesture_event.data.tapDown.width =
1655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          event.details().bounding_box().width();
1665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      gesture_event.data.tapDown.height =
1675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          event.details().bounding_box().height();
1685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      break;
1695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    case ui::ET_GESTURE_TAP_CANCEL:
1705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      gesture_event.type = WebKit::WebInputEvent::GestureTapCancel;
1715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      break;
1725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    case ui::ET_GESTURE_SCROLL_BEGIN:
1735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      gesture_event.type = WebKit::WebInputEvent::GestureScrollBegin;
1745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      break;
1755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    case ui::ET_GESTURE_SCROLL_UPDATE:
1765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      gesture_event.type = WebKit::WebInputEvent::GestureScrollUpdate;
1775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      gesture_event.data.scrollUpdate.deltaX = event.details().scroll_x();
1785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      gesture_event.data.scrollUpdate.deltaY = event.details().scroll_y();
1795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      break;
1805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    case ui::ET_GESTURE_SCROLL_END:
1815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      gesture_event.type = WebKit::WebInputEvent::GestureScrollEnd;
1825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      break;
1835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    case ui::ET_GESTURE_PINCH_BEGIN:
1845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      gesture_event.type = WebKit::WebInputEvent::GesturePinchBegin;
1855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      break;
1865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    case ui::ET_GESTURE_PINCH_UPDATE:
1875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      gesture_event.type = WebKit::WebInputEvent::GesturePinchUpdate;
1885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      gesture_event.data.pinchUpdate.scale = event.details().scale();
1895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      break;
1905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    case ui::ET_GESTURE_PINCH_END:
1915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      gesture_event.type = WebKit::WebInputEvent::GesturePinchEnd;
1925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      break;
1935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    case ui::ET_SCROLL_FLING_START:
1945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      gesture_event.type = WebKit::WebInputEvent::GestureFlingStart;
1955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      gesture_event.data.flingStart.velocityX = event.details().velocity_x();
1965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      gesture_event.data.flingStart.velocityY = event.details().velocity_y();
1975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      break;
1985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    case ui::ET_SCROLL_FLING_CANCEL:
1995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      gesture_event.type = WebKit::WebInputEvent::GestureFlingCancel;
2005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      break;
2015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    case ui::ET_GESTURE_LONG_PRESS:
2025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      gesture_event.type = WebKit::WebInputEvent::GestureLongPress;
2035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      gesture_event.data.longPress.width =
2045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          event.details().bounding_box().width();
2055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      gesture_event.data.longPress.height =
2065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          event.details().bounding_box().height();
2075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      break;
2085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    case ui::ET_GESTURE_LONG_TAP:
2092a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      gesture_event.type = WebKit::WebInputEvent::GestureLongTap;
2105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      gesture_event.data.longPress.width =
2115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          event.details().bounding_box().width();
2125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      gesture_event.data.longPress.height =
2135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          event.details().bounding_box().height();
2145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      break;
2155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    case ui::ET_GESTURE_TWO_FINGER_TAP:
2165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      gesture_event.type = WebKit::WebInputEvent::GestureTwoFingerTap;
2175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      gesture_event.data.twoFingerTap.firstFingerWidth =
2185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          event.details().first_finger_width();
2195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      gesture_event.data.twoFingerTap.firstFingerHeight =
2205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          event.details().first_finger_height();
2215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      break;
2225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    case ui::ET_GESTURE_BEGIN:
2235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    case ui::ET_GESTURE_END:
2245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    case ui::ET_GESTURE_MULTIFINGER_SWIPE:
2255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      gesture_event.type = WebKit::WebInputEvent::Undefined;
2265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      break;
2275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    default:
2285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      NOTREACHED() << "Unknown gesture type: " << event.type();
2295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
2305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  gesture_event.sourceDevice = WebKit::WebGestureEvent::Touchscreen;
2325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  gesture_event.modifiers = EventFlagsToWebEventModifiers(event.flags());
2335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  gesture_event.timeStampSeconds = event.time_stamp().InSecondsF();
2345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return gesture_event;
2365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)int EventFlagsToWebEventModifiers(int flags) {
2395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int modifiers = 0;
240a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)
2415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (flags & ui::EF_SHIFT_DOWN)
2425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    modifiers |= WebKit::WebInputEvent::ShiftKey;
2435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (flags & ui::EF_CONTROL_DOWN)
2445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    modifiers |= WebKit::WebInputEvent::ControlKey;
2455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (flags & ui::EF_ALT_DOWN)
2465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    modifiers |= WebKit::WebInputEvent::AltKey;
2475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // TODO(beng): MetaKey/META_MASK
2485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (flags & ui::EF_LEFT_MOUSE_BUTTON)
2495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    modifiers |= WebKit::WebInputEvent::LeftButtonDown;
2505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (flags & ui::EF_MIDDLE_MOUSE_BUTTON)
2515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    modifiers |= WebKit::WebInputEvent::MiddleButtonDown;
2525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (flags & ui::EF_RIGHT_MOUSE_BUTTON)
2535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    modifiers |= WebKit::WebInputEvent::RightButtonDown;
2545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (flags & ui::EF_CAPS_LOCK_DOWN)
2555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    modifiers |= WebKit::WebInputEvent::CapsLockOn;
2565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return modifiers;
2575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)WebKit::WebTouchPoint* UpdateWebTouchEventFromUIEvent(
2605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const ui::TouchEvent& event,
2615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    WebKit::WebTouchEvent* web_event) {
2625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  WebKit::WebTouchPoint* point = NULL;
2635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  switch (event.type()) {
2645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    case ui::ET_TOUCH_PRESSED:
2655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      // Add a new touch point.
2665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      if (web_event->touchesLength < WebKit::WebTouchEvent::touchesLengthCap) {
2675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        point = &web_event->touches[web_event->touchesLength++];
2685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        point->id = event.touch_id();
2695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      }
2705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      break;
2715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    case ui::ET_TOUCH_RELEASED:
2725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    case ui::ET_TOUCH_CANCELLED:
2735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    case ui::ET_TOUCH_MOVED: {
2745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      // The touch point should have been added to the event from an earlier
2755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      // _PRESSED event. So find that.
2765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      // At the moment, only a maximum of 4 touch-points are allowed. So a
2775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      // simple loop should be sufficient.
2785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      for (unsigned i = 0; i < web_event->touchesLength; ++i) {
2795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        point = web_event->touches + i;
2805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        if (point->id == event.touch_id())
2815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          break;
2825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        point = NULL;
2835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      }
2845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      break;
2855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
2865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    default:
2875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      DLOG(WARNING) << "Unknown touch event " << event.type();
2885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      break;
2895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
2905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (!point)
2925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return NULL;
2935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // The spec requires the radii values to be positive (and 1 when unknown).
2955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  point->radiusX = std::max(1.f, event.radius_x());
2965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  point->radiusY = std::max(1.f, event.radius_y());
2975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  point->rotationAngle = event.rotation_angle();
2985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  point->force = event.force();
2995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Update the location and state of the point.
3015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  point->state = TouchPointStateFromEvent(event);
3025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (point->state == WebKit::WebTouchPoint::StateMoved) {
3035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // It is possible for badly written touch drivers to emit Move events even
3045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // when the touch location hasn't changed. In such cases, consume the event
3055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // and pretend nothing happened.
3065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (point->position.x == event.x() && point->position.y == event.y())
3075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      return NULL;
3085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
3095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  point->position.x = event.x();
3105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  point->position.y = event.y();
3115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const gfx::Point root_point = event.root_location();
3135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  point->screenPosition.x = root_point.x();
3145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  point->screenPosition.y = root_point.y();
3155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Mark the rest of the points as stationary.
3175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  for (unsigned i = 0; i < web_event->touchesLength; ++i) {
3185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    WebKit::WebTouchPoint* iter = web_event->touches + i;
3195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (iter != point)
3205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      iter->state = WebKit::WebTouchPoint::StateStationary;
3215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
3225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Update the type of the touch event.
3245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  web_event->type = TouchEventTypeFromEvent(event);
3255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  web_event->timeStampSeconds = event.time_stamp().InSecondsF();
3265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  web_event->modifiers = EventFlagsToWebEventModifiers(event.flags());
3275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return point;
3295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
3305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}  // namespace content
332