Index: content/browser/renderer_host/ui_events_helper.cc |
diff --git a/content/browser/renderer_host/ui_events_helper.cc b/content/browser/renderer_host/ui_events_helper.cc |
index 4412b4900dbd2d46590f21efbb671099644ac844..e3201af012669ca15b538ee955f4e449ac59eb06 100644 |
--- a/content/browser/renderer_host/ui_events_helper.cc |
+++ b/content/browser/renderer_host/ui_events_helper.cc |
@@ -53,6 +53,38 @@ ui::EventType WebTouchPointStateToEventType( |
} |
} |
+WebKit::WebTouchPoint::State TouchPointStateFromEvent( |
+ const ui::TouchEvent* event) { |
+ switch (event->type()) { |
+ case ui::ET_TOUCH_PRESSED: |
+ return WebKit::WebTouchPoint::StatePressed; |
+ case ui::ET_TOUCH_RELEASED: |
+ return WebKit::WebTouchPoint::StateReleased; |
+ case ui::ET_TOUCH_MOVED: |
+ return WebKit::WebTouchPoint::StateMoved; |
+ case ui::ET_TOUCH_CANCELLED: |
+ return WebKit::WebTouchPoint::StateCancelled; |
+ default: |
+ return WebKit::WebTouchPoint::StateUndefined; |
+ } |
+} |
+ |
+WebKit::WebInputEvent::Type TouchEventTypeFromEvent( |
+ const ui::TouchEvent* event) { |
+ switch (event->type()) { |
+ case ui::ET_TOUCH_PRESSED: |
+ return WebKit::WebInputEvent::TouchStart; |
+ case ui::ET_TOUCH_RELEASED: |
+ return WebKit::WebInputEvent::TouchEnd; |
+ case ui::ET_TOUCH_MOVED: |
+ return WebKit::WebInputEvent::TouchMove; |
+ case ui::ET_TOUCH_CANCELLED: |
+ return WebKit::WebInputEvent::TouchCancel; |
+ default: |
+ return WebKit::WebInputEvent::Undefined; |
+ } |
+} |
+ |
} // namespace |
namespace content { |
@@ -108,4 +140,96 @@ bool MakeUITouchEventsFromWebTouchEvents(const WebKit::WebTouchEvent& touch, |
return true; |
} |
+int EventFlagsToWebEventModifiers(int flags) { |
+ int modifiers = 0; |
+ if (flags & ui::EF_SHIFT_DOWN) |
+ modifiers |= WebKit::WebInputEvent::ShiftKey; |
+ if (flags & ui::EF_CONTROL_DOWN) |
+ modifiers |= WebKit::WebInputEvent::ControlKey; |
+ if (flags & ui::EF_ALT_DOWN) |
+ modifiers |= WebKit::WebInputEvent::AltKey; |
+ // TODO(beng): MetaKey/META_MASK |
+ if (flags & ui::EF_LEFT_MOUSE_BUTTON) |
+ modifiers |= WebKit::WebInputEvent::LeftButtonDown; |
+ if (flags & ui::EF_MIDDLE_MOUSE_BUTTON) |
+ modifiers |= WebKit::WebInputEvent::MiddleButtonDown; |
+ if (flags & ui::EF_RIGHT_MOUSE_BUTTON) |
+ modifiers |= WebKit::WebInputEvent::RightButtonDown; |
+ if (flags & ui::EF_CAPS_LOCK_DOWN) |
+ modifiers |= WebKit::WebInputEvent::CapsLockOn; |
+ return modifiers; |
+} |
+ |
+WebKit::WebTouchPoint* UpdateWebTouchEventFromUIEvent( |
+ ui::TouchEvent* event, |
+ WebKit::WebTouchEvent* web_event) { |
+ WebKit::WebTouchPoint* point = NULL; |
+ switch (event->type()) { |
+ case ui::ET_TOUCH_PRESSED: |
+ // Add a new touch point. |
+ if (web_event->touchesLength < WebKit::WebTouchEvent::touchesLengthCap) { |
+ point = &web_event->touches[web_event->touchesLength++]; |
+ point->id = event->touch_id(); |
+ } |
+ break; |
+ case ui::ET_TOUCH_RELEASED: |
+ case ui::ET_TOUCH_CANCELLED: |
+ case ui::ET_TOUCH_MOVED: { |
+ // The touch point should have been added to the event from an earlier |
+ // _PRESSED event. So find that. |
+ // At the moment, only a maximum of 4 touch-points are allowed. So a |
+ // simple loop should be sufficient. |
+ for (unsigned i = 0; i < web_event->touchesLength; ++i) { |
+ point = web_event->touches + i; |
+ if (point->id == event->touch_id()) |
+ break; |
+ point = NULL; |
+ } |
+ break; |
+ } |
+ default: |
+ DLOG(WARNING) << "Unknown touch event " << event->type(); |
+ break; |
+ } |
+ |
+ if (!point) |
+ return NULL; |
+ |
+ // The spec requires the radii values to be positive (and 1 when unknown). |
+ point->radiusX = std::max(1.f, event->radius_x()); |
+ point->radiusY = std::max(1.f, event->radius_y()); |
+ point->rotationAngle = event->rotation_angle(); |
+ point->force = event->force(); |
+ |
+ // Update the location and state of the point. |
+ point->state = TouchPointStateFromEvent(event); |
+ if (point->state == WebKit::WebTouchPoint::StateMoved) { |
+ // It is possible for badly written touch drivers to emit Move events even |
+ // when the touch location hasn't changed. In such cases, consume the event |
+ // and pretend nothing happened. |
+ if (point->position.x == event->x() && point->position.y == event->y()) |
+ return NULL; |
+ } |
+ point->position.x = event->x(); |
+ point->position.y = event->y(); |
+ |
+ const gfx::Point root_point = event->root_location(); |
+ point->screenPosition.x = root_point.x(); |
+ point->screenPosition.y = root_point.y(); |
+ |
+ // Mark the rest of the points as stationary. |
+ for (unsigned i = 0; i < web_event->touchesLength; ++i) { |
+ WebKit::WebTouchPoint* iter = web_event->touches + i; |
+ if (iter != point) |
+ iter->state = WebKit::WebTouchPoint::StateStationary; |
+ } |
+ |
+ // Update the type of the touch event. |
+ web_event->type = TouchEventTypeFromEvent(event); |
+ web_event->timeStampSeconds = event->time_stamp().InSecondsF(); |
+ web_event->modifiers = EventFlagsToWebEventModifiers(event->flags()); |
+ |
+ return point; |
+} |
+ |
} // namespace content |