| Index: content/renderer/pepper/event_conversion.cc
|
| diff --git a/content/renderer/pepper/event_conversion.cc b/content/renderer/pepper/event_conversion.cc
|
| index 1a8344ef40a2607b9bba7ec213f3f37069c2e217..4de55559fff5dedd8d70789f20f38cc8992040cb 100644
|
| --- a/content/renderer/pepper/event_conversion.cc
|
| +++ b/content/renderer/pepper/event_conversion.cc
|
| @@ -4,8 +4,6 @@
|
|
|
| #include "content/renderer/pepper/event_conversion.h"
|
|
|
| -#include <map>
|
| -
|
| #include "base/basictypes.h"
|
| #include "base/i18n/char_iterator.h"
|
| #include "base/logging.h"
|
| @@ -215,11 +213,27 @@ void AppendMouseWheelEvent(const WebInputEvent& event,
|
| result_events->push_back(result);
|
| }
|
|
|
| +enum IncludedTouchPointTypes {
|
| + ALL, // All pointers targetting the plugin.
|
| + ACTIVE, // Only pointers that are currently down.
|
| + CHANGED // Only pointers that have changed since the previous event.
|
| +};
|
| void SetPPTouchPoints(const WebTouchPoint* touches,
|
| uint32_t touches_length,
|
| + IncludedTouchPointTypes included_types,
|
| std::vector<PP_TouchPoint>* result) {
|
| for (uint32_t i = 0; i < touches_length; i++) {
|
| const WebTouchPoint& touch_point = touches[i];
|
| + if (included_types == ACTIVE &&
|
| + (touch_point.state == WebTouchPoint::StateReleased ||
|
| + touch_point.state == WebTouchPoint::StateCancelled)) {
|
| + continue;
|
| + }
|
| + if (included_types == CHANGED &&
|
| + (touch_point.state == WebTouchPoint::StateUndefined ||
|
| + touch_point.state == WebTouchPoint::StateStationary)) {
|
| + continue;
|
| + }
|
| PP_TouchPoint pp_pt;
|
| pp_pt.id = touch_point.id;
|
| pp_pt.position.x = touch_point.position.x;
|
| @@ -239,52 +253,67 @@ void AppendTouchEvent(const WebInputEvent& event,
|
|
|
| InputEventData result = GetEventWithCommonFieldsAndType(event);
|
| SetPPTouchPoints(
|
| - touch_event.touches, touch_event.touchesLength, &result.touches);
|
| - SetPPTouchPoints(touch_event.changedTouches,
|
| - touch_event.changedTouchesLength,
|
| + touch_event.touches, touch_event.touchesLength, ACTIVE, &result.touches);
|
| + SetPPTouchPoints(touch_event.touches,
|
| + touch_event.touchesLength,
|
| + CHANGED,
|
| &result.changed_touches);
|
| - SetPPTouchPoints(touch_event.targetTouches,
|
| - touch_event.targetTouchesLength,
|
| + SetPPTouchPoints(touch_event.touches,
|
| + touch_event.touchesLength,
|
| + ALL,
|
| &result.target_touches);
|
|
|
| result_events->push_back(result);
|
| }
|
|
|
| -// Structure used to map touch point id's to touch states. Since the pepper
|
| -// touch event structure does not have states for individual touch points and
|
| -// instead relies on the event type in combination with the set of touch lists,
|
| -// we have to set the state for the changed touches to be the same as the event
|
| -// type and all others to be 'stationary.'
|
| -typedef std::map<uint32_t, WebTouchPoint::State> TouchStateMap;
|
| -
|
| -void SetWebTouchPoints(const std::vector<PP_TouchPoint>& pp_touches,
|
| - const TouchStateMap& states_map,
|
| - WebTouchPoint* web_touches,
|
| - uint32_t* web_touches_length) {
|
| -
|
| - for (uint32_t i = 0;
|
| - i < pp_touches.size() && i < WebTouchEvent::touchesLengthCap;
|
| - i++) {
|
| - WebTouchPoint pt;
|
| +WebTouchPoint CreateWebTouchPoint(const PP_TouchPoint& pp_pt,
|
| + WebTouchPoint::State state) {
|
| + WebTouchPoint pt;
|
| + pt.id = pp_pt.id;
|
| + pt.position.x = pp_pt.position.x;
|
| + pt.position.y = pp_pt.position.y;
|
| + // TODO bug:http://code.google.com/p/chromium/issues/detail?id=93902
|
| + pt.screenPosition.x = 0;
|
| + pt.screenPosition.y = 0;
|
| + pt.force = pp_pt.pressure;
|
| + pt.radiusX = pp_pt.radius.x;
|
| + pt.radiusY = pp_pt.radius.y;
|
| + pt.rotationAngle = pp_pt.rotation_angle;
|
| + pt.state = state;
|
| + return pt;
|
| +}
|
| +
|
| +bool HasTouchPointWithId(const WebTouchPoint* web_touches,
|
| + uint32_t web_touches_length,
|
| + uint32_t id) {
|
| + // Note: A brute force search to find the (potentially) existing touch point
|
| + // is cheap given the small bound on |WebTouchEvent::touchesLengthCap|.
|
| + for (uint32_t i = 0; i < web_touches_length; ++i) {
|
| + if (web_touches[i].id == static_cast<int>(id))
|
| + return true;
|
| + }
|
| + return false;
|
| +}
|
| +
|
| +void SetWebTouchPointsIfNotYetSet(const std::vector<PP_TouchPoint>& pp_touches,
|
| + WebTouchPoint::State state,
|
| + WebTouchPoint* web_touches,
|
| + uint32_t* web_touches_length) {
|
| + const uint32_t initial_web_touches_length = *web_touches_length;
|
| + const uint32_t touches_length =
|
| + std::min(static_cast<uint32_t>(pp_touches.size()),
|
| + static_cast<uint32_t>(WebTouchEvent::touchesLengthCap));
|
| + for (uint32_t i = 0; i < touches_length; ++i) {
|
| + const uint32_t touch_index = *web_touches_length;
|
| + if (touch_index >= static_cast<uint32_t>(WebTouchEvent::touchesLengthCap))
|
| + return;
|
| +
|
| const PP_TouchPoint& pp_pt = pp_touches[i];
|
| - pt.id = pp_pt.id;
|
| -
|
| - if (states_map.find(pt.id) == states_map.end())
|
| - pt.state = WebTouchPoint::StateStationary;
|
| - else
|
| - pt.state = states_map.find(pt.id)->second;
|
| -
|
| - pt.position.x = pp_pt.position.x;
|
| - pt.position.y = pp_pt.position.y;
|
| - // TODO bug:http://code.google.com/p/chromium/issues/detail?id=93902
|
| - pt.screenPosition.x = 0;
|
| - pt.screenPosition.y = 0;
|
| - pt.force = pp_pt.pressure;
|
| - pt.radiusX = pp_pt.radius.x;
|
| - pt.radiusY = pp_pt.radius.y;
|
| - pt.rotationAngle = pp_pt.rotation_angle;
|
| - web_touches[i] = pt;
|
| - (*web_touches_length)++;
|
| + if (HasTouchPointWithId(web_touches, initial_web_touches_length, pp_pt.id))
|
| + continue;
|
| +
|
| + web_touches[touch_index] = CreateWebTouchPoint(pp_pt, state);
|
| + ++(*web_touches_length);
|
| }
|
| }
|
|
|
| @@ -314,35 +343,18 @@ WebTouchEvent* BuildTouchEvent(const InputEventData& event) {
|
| }
|
| WebTouchEventTraits::ResetType(
|
| type, PPTimeTicksToEventTime(event.event_time_stamp), web_event);
|
| -
|
| - TouchStateMap states_map;
|
| - for (uint32_t i = 0; i < event.changed_touches.size(); i++)
|
| - states_map[event.changed_touches[i].id] = state;
|
| -
|
| - SetWebTouchPoints(event.changed_touches,
|
| - states_map,
|
| - web_event->changedTouches,
|
| - &web_event->changedTouchesLength);
|
| -
|
| - SetWebTouchPoints(
|
| - event.touches, states_map, web_event->touches, &web_event->touchesLength);
|
| -
|
| - SetWebTouchPoints(event.target_touches,
|
| - states_map,
|
| - web_event->targetTouches,
|
| - &web_event->targetTouchesLength);
|
| -
|
| - if (web_event->type == WebInputEvent::TouchEnd ||
|
| - web_event->type == WebInputEvent::TouchCancel) {
|
| - SetWebTouchPoints(event.changed_touches,
|
| - states_map,
|
| - web_event->touches,
|
| - &web_event->touchesLength);
|
| - SetWebTouchPoints(event.changed_touches,
|
| - states_map,
|
| - web_event->targetTouches,
|
| - &web_event->targetTouchesLength);
|
| - }
|
| + web_event->touchesLength = 0;
|
| +
|
| + // First add all changed touches, then add only the remaining unset
|
| + // (stationary) touches.
|
| + SetWebTouchPointsIfNotYetSet(event.changed_touches,
|
| + state,
|
| + web_event->touches,
|
| + &web_event->touchesLength);
|
| + SetWebTouchPointsIfNotYetSet(event.touches,
|
| + WebTouchPoint::StateStationary,
|
| + web_event->touches,
|
| + &web_event->touchesLength);
|
|
|
| return web_event;
|
| }
|
|
|