Chromium Code Reviews| Index: content/browser/renderer_host/render_widget_host_view_aura.cc |
| diff --git a/content/browser/renderer_host/render_widget_host_view_aura.cc b/content/browser/renderer_host/render_widget_host_view_aura.cc |
| index 8ff3036fdf34f65decc0884841fef8270d91ea1b..e25cc9caf87591c9e82f8dcc3aa4b6ae3165f335 100644 |
| --- a/content/browser/renderer_host/render_widget_host_view_aura.cc |
| +++ b/content/browser/renderer_host/render_widget_host_view_aura.cc |
| @@ -25,6 +25,8 @@ |
| #include "ui/gfx/gl/gl_bindings.h" |
| #endif |
| +using WebKit::WebTouchEvent; |
| + |
| namespace { |
| #if defined(UI_COMPOSITOR_IMAGE_TRANSPORT) |
| @@ -36,6 +38,38 @@ void AcknowledgeSwapBuffers(int32 route_id, int gpu_host_id) { |
| } |
| #endif |
| +WebKit::WebTouchPoint::State TouchPointStateFromEvent( |
| + const aura::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 aura::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 |
| //////////////////////////////////////////////////////////////////////////////// |
| @@ -359,8 +393,99 @@ bool RenderWidgetHostViewAura::OnMouseEvent(aura::MouseEvent* event) { |
| ui::TouchStatus RenderWidgetHostViewAura::OnTouchEvent( |
| aura::TouchEvent* event) { |
| - NOTIMPLEMENTED(); |
| - return ui::TOUCH_STATUS_UNKNOWN; |
| + // Update the list of touch points first. |
| + WebKit::WebTouchPoint* point = NULL; |
|
Ben Goodger (Google)
2011/10/25 15:00:30
Can we do this in a separate factory function a la
sadrul
2011/10/25 15:09:45
I was going to do this like the other functions, b
|
| + ui::TouchStatus status = ui::TOUCH_STATUS_UNKNOWN; |
| + |
| + switch (event->type()) { |
| + case ui::ET_TOUCH_PRESSED: |
| + // Add a new touch point. |
| + if (touch_event_.touchesLength < WebTouchEvent::touchesLengthCap) { |
| + point = &touch_event_.touches[touch_event_.touchesLength++]; |
| + point->id = event->touch_id(); |
| + |
| + if (touch_event_.touchesLength == 1) { |
| + // A new touch sequence has started. |
| + status = ui::TOUCH_STATUS_START; |
| + } |
| + } |
| + 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 < touch_event_.touchesLength; ++i) { |
| + point = touch_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 ui::TOUCH_STATUS_UNKNOWN; |
| + |
| + if (status != ui::TOUCH_STATUS_START) |
| + status = ui::TOUCH_STATUS_CONTINUE; |
| + |
| + point->radiusX = event->radius_x(); |
| + point->radiusY = 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 status; |
| + } |
| + point->position.x = event->x(); |
| + point->position.y = event->y(); |
| + |
| + // TODO(sad): Convert to screen coordinates. |
| + point->screenPosition.x = point->position.x; |
| + point->screenPosition.y = point->position.y; |
| + |
| + // Mark the rest of the points as stationary. |
| + for (unsigned i = 0; i < touch_event_.touchesLength; ++i) { |
| + WebKit::WebTouchPoint* iter = touch_event_.touches + i; |
| + if (iter != point) |
| + iter->state = WebKit::WebTouchPoint::StateStationary; |
| + } |
| + |
| + // Update the type of the touch event. |
| + touch_event_.type = TouchEventTypeFromEvent(event); |
| + touch_event_.timeStampSeconds = event->time_stamp().ToDoubleT(); |
| + |
| + // The event and all the touches have been updated. Dispatch. |
| + host_->ForwardTouchEvent(touch_event_); |
| + |
| + // If the touch was released, then remove it from the list of touch points. |
| + if (event->type() == ui::ET_TOUCH_RELEASED) { |
| + --touch_event_.touchesLength; |
| + for (unsigned i = point - touch_event_.touches; |
| + i < touch_event_.touchesLength; |
| + ++i) { |
| + touch_event_.touches[i] = touch_event_.touches[i + 1]; |
| + } |
| + if (touch_event_.touchesLength == 0) |
| + status = ui::TOUCH_STATUS_END; |
| + } else if (event->type() == ui::ET_TOUCH_CANCELLED) { |
| + status = ui::TOUCH_STATUS_CANCEL; |
| + } |
| + |
| + return status; |
| } |
| bool RenderWidgetHostViewAura::ShouldActivate(aura::Event* event) { |