OLD | NEW |
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "content/renderer/pepper/event_conversion.h" | 5 #include "content/renderer/pepper/event_conversion.h" |
6 | 6 |
7 #include <map> | |
8 | |
9 #include "base/basictypes.h" | 7 #include "base/basictypes.h" |
10 #include "base/i18n/char_iterator.h" | 8 #include "base/i18n/char_iterator.h" |
11 #include "base/logging.h" | 9 #include "base/logging.h" |
12 #include "base/memory/scoped_ptr.h" | 10 #include "base/memory/scoped_ptr.h" |
13 #include "base/strings/string_util.h" | 11 #include "base/strings/string_util.h" |
14 #include "base/strings/stringprintf.h" | 12 #include "base/strings/stringprintf.h" |
15 #include "base/strings/utf_string_conversion_utils.h" | 13 #include "base/strings/utf_string_conversion_utils.h" |
16 #include "base/strings/utf_string_conversions.h" | 14 #include "base/strings/utf_string_conversions.h" |
17 #include "content/common/input/web_touch_event_traits.h" | 15 #include "content/common/input/web_touch_event_traits.h" |
18 #include "content/renderer/pepper/usb_key_code_conversion.h" | 16 #include "content/renderer/pepper/usb_key_code_conversion.h" |
(...skipping 189 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
208 InputEventData result = GetEventWithCommonFieldsAndType(event); | 206 InputEventData result = GetEventWithCommonFieldsAndType(event); |
209 result.event_modifiers = mouse_wheel_event.modifiers; | 207 result.event_modifiers = mouse_wheel_event.modifiers; |
210 result.wheel_delta.x = mouse_wheel_event.deltaX; | 208 result.wheel_delta.x = mouse_wheel_event.deltaX; |
211 result.wheel_delta.y = mouse_wheel_event.deltaY; | 209 result.wheel_delta.y = mouse_wheel_event.deltaY; |
212 result.wheel_ticks.x = mouse_wheel_event.wheelTicksX; | 210 result.wheel_ticks.x = mouse_wheel_event.wheelTicksX; |
213 result.wheel_ticks.y = mouse_wheel_event.wheelTicksY; | 211 result.wheel_ticks.y = mouse_wheel_event.wheelTicksY; |
214 result.wheel_scroll_by_page = !!mouse_wheel_event.scrollByPage; | 212 result.wheel_scroll_by_page = !!mouse_wheel_event.scrollByPage; |
215 result_events->push_back(result); | 213 result_events->push_back(result); |
216 } | 214 } |
217 | 215 |
| 216 enum IncludedTouchPointTypes { |
| 217 ALL, // All pointers targetting the plugin. |
| 218 ACTIVE, // Only pointers that are currently down. |
| 219 CHANGED // Only pointers that have changed since the previous event. |
| 220 }; |
218 void SetPPTouchPoints(const WebTouchPoint* touches, | 221 void SetPPTouchPoints(const WebTouchPoint* touches, |
219 uint32_t touches_length, | 222 uint32_t touches_length, |
| 223 IncludedTouchPointTypes included_types, |
220 std::vector<PP_TouchPoint>* result) { | 224 std::vector<PP_TouchPoint>* result) { |
221 for (uint32_t i = 0; i < touches_length; i++) { | 225 for (uint32_t i = 0; i < touches_length; i++) { |
222 const WebTouchPoint& touch_point = touches[i]; | 226 const WebTouchPoint& touch_point = touches[i]; |
| 227 if (included_types == ACTIVE && |
| 228 (touch_point.state == WebTouchPoint::StateReleased || |
| 229 touch_point.state == WebTouchPoint::StateCancelled)) { |
| 230 continue; |
| 231 } |
| 232 if (included_types == CHANGED && |
| 233 (touch_point.state == WebTouchPoint::StateUndefined || |
| 234 touch_point.state == WebTouchPoint::StateStationary)) { |
| 235 continue; |
| 236 } |
223 PP_TouchPoint pp_pt; | 237 PP_TouchPoint pp_pt; |
224 pp_pt.id = touch_point.id; | 238 pp_pt.id = touch_point.id; |
225 pp_pt.position.x = touch_point.position.x; | 239 pp_pt.position.x = touch_point.position.x; |
226 pp_pt.position.y = touch_point.position.y; | 240 pp_pt.position.y = touch_point.position.y; |
227 pp_pt.radius.x = touch_point.radiusX; | 241 pp_pt.radius.x = touch_point.radiusX; |
228 pp_pt.radius.y = touch_point.radiusY; | 242 pp_pt.radius.y = touch_point.radiusY; |
229 pp_pt.rotation_angle = touch_point.rotationAngle; | 243 pp_pt.rotation_angle = touch_point.rotationAngle; |
230 pp_pt.pressure = touch_point.force; | 244 pp_pt.pressure = touch_point.force; |
231 result->push_back(pp_pt); | 245 result->push_back(pp_pt); |
232 } | 246 } |
233 } | 247 } |
234 | 248 |
235 void AppendTouchEvent(const WebInputEvent& event, | 249 void AppendTouchEvent(const WebInputEvent& event, |
236 std::vector<InputEventData>* result_events) { | 250 std::vector<InputEventData>* result_events) { |
237 const WebTouchEvent& touch_event = | 251 const WebTouchEvent& touch_event = |
238 reinterpret_cast<const WebTouchEvent&>(event); | 252 reinterpret_cast<const WebTouchEvent&>(event); |
239 | 253 |
240 InputEventData result = GetEventWithCommonFieldsAndType(event); | 254 InputEventData result = GetEventWithCommonFieldsAndType(event); |
241 SetPPTouchPoints( | 255 SetPPTouchPoints( |
242 touch_event.touches, touch_event.touchesLength, &result.touches); | 256 touch_event.touches, touch_event.touchesLength, ACTIVE, &result.touches); |
243 SetPPTouchPoints(touch_event.changedTouches, | 257 SetPPTouchPoints(touch_event.touches, |
244 touch_event.changedTouchesLength, | 258 touch_event.touchesLength, |
| 259 CHANGED, |
245 &result.changed_touches); | 260 &result.changed_touches); |
246 SetPPTouchPoints(touch_event.targetTouches, | 261 SetPPTouchPoints(touch_event.touches, |
247 touch_event.targetTouchesLength, | 262 touch_event.touchesLength, |
| 263 ALL, |
248 &result.target_touches); | 264 &result.target_touches); |
249 | 265 |
250 result_events->push_back(result); | 266 result_events->push_back(result); |
251 } | 267 } |
252 | 268 |
253 // Structure used to map touch point id's to touch states. Since the pepper | 269 WebTouchPoint CreateWebTouchPoint(const PP_TouchPoint& pp_pt, |
254 // touch event structure does not have states for individual touch points and | 270 WebTouchPoint::State state) { |
255 // instead relies on the event type in combination with the set of touch lists, | 271 WebTouchPoint pt; |
256 // we have to set the state for the changed touches to be the same as the event | 272 pt.id = pp_pt.id; |
257 // type and all others to be 'stationary.' | 273 pt.position.x = pp_pt.position.x; |
258 typedef std::map<uint32_t, WebTouchPoint::State> TouchStateMap; | 274 pt.position.y = pp_pt.position.y; |
| 275 // TODO bug:http://code.google.com/p/chromium/issues/detail?id=93902 |
| 276 pt.screenPosition.x = 0; |
| 277 pt.screenPosition.y = 0; |
| 278 pt.force = pp_pt.pressure; |
| 279 pt.radiusX = pp_pt.radius.x; |
| 280 pt.radiusY = pp_pt.radius.y; |
| 281 pt.rotationAngle = pp_pt.rotation_angle; |
| 282 pt.state = state; |
| 283 return pt; |
| 284 } |
259 | 285 |
260 void SetWebTouchPoints(const std::vector<PP_TouchPoint>& pp_touches, | 286 bool HasTouchPointWithId(const WebTouchPoint* web_touches, |
261 const TouchStateMap& states_map, | 287 uint32_t web_touches_length, |
262 WebTouchPoint* web_touches, | 288 uint32_t id) { |
263 uint32_t* web_touches_length) { | 289 // Note: A brute force search to find the (potentially) existing touch point |
| 290 // is cheap given the small bound on |WebTouchEvent::touchesLengthCap|. |
| 291 for (uint32_t i = 0; i < web_touches_length; ++i) { |
| 292 if (web_touches[i].id == static_cast<int>(id)) |
| 293 return true; |
| 294 } |
| 295 return false; |
| 296 } |
264 | 297 |
265 for (uint32_t i = 0; | 298 void SetWebTouchPointsIfNotYetSet(const std::vector<PP_TouchPoint>& pp_touches, |
266 i < pp_touches.size() && i < WebTouchEvent::touchesLengthCap; | 299 WebTouchPoint::State state, |
267 i++) { | 300 WebTouchPoint* web_touches, |
268 WebTouchPoint pt; | 301 uint32_t* web_touches_length) { |
| 302 const uint32_t initial_web_touches_length = *web_touches_length; |
| 303 const uint32_t touches_length = |
| 304 std::min(static_cast<uint32_t>(pp_touches.size()), |
| 305 static_cast<uint32_t>(WebTouchEvent::touchesLengthCap)); |
| 306 for (uint32_t i = 0; i < touches_length; ++i) { |
| 307 const uint32_t touch_index = *web_touches_length; |
| 308 if (touch_index >= static_cast<uint32_t>(WebTouchEvent::touchesLengthCap)) |
| 309 return; |
| 310 |
269 const PP_TouchPoint& pp_pt = pp_touches[i]; | 311 const PP_TouchPoint& pp_pt = pp_touches[i]; |
270 pt.id = pp_pt.id; | 312 if (HasTouchPointWithId(web_touches, initial_web_touches_length, pp_pt.id)) |
| 313 continue; |
271 | 314 |
272 if (states_map.find(pt.id) == states_map.end()) | 315 web_touches[touch_index] = CreateWebTouchPoint(pp_pt, state); |
273 pt.state = WebTouchPoint::StateStationary; | 316 ++(*web_touches_length); |
274 else | |
275 pt.state = states_map.find(pt.id)->second; | |
276 | |
277 pt.position.x = pp_pt.position.x; | |
278 pt.position.y = pp_pt.position.y; | |
279 // TODO bug:http://code.google.com/p/chromium/issues/detail?id=93902 | |
280 pt.screenPosition.x = 0; | |
281 pt.screenPosition.y = 0; | |
282 pt.force = pp_pt.pressure; | |
283 pt.radiusX = pp_pt.radius.x; | |
284 pt.radiusY = pp_pt.radius.y; | |
285 pt.rotationAngle = pp_pt.rotation_angle; | |
286 web_touches[i] = pt; | |
287 (*web_touches_length)++; | |
288 } | 317 } |
289 } | 318 } |
290 | 319 |
291 WebTouchEvent* BuildTouchEvent(const InputEventData& event) { | 320 WebTouchEvent* BuildTouchEvent(const InputEventData& event) { |
292 WebTouchEvent* web_event = new WebTouchEvent(); | 321 WebTouchEvent* web_event = new WebTouchEvent(); |
293 WebTouchPoint::State state = WebTouchPoint::StateUndefined; | 322 WebTouchPoint::State state = WebTouchPoint::StateUndefined; |
294 WebInputEvent::Type type = WebInputEvent::Undefined; | 323 WebInputEvent::Type type = WebInputEvent::Undefined; |
295 switch (event.event_type) { | 324 switch (event.event_type) { |
296 case PP_INPUTEVENT_TYPE_TOUCHSTART: | 325 case PP_INPUTEVENT_TYPE_TOUCHSTART: |
297 type = WebInputEvent::TouchStart; | 326 type = WebInputEvent::TouchStart; |
298 state = WebTouchPoint::StatePressed; | 327 state = WebTouchPoint::StatePressed; |
299 break; | 328 break; |
300 case PP_INPUTEVENT_TYPE_TOUCHMOVE: | 329 case PP_INPUTEVENT_TYPE_TOUCHMOVE: |
301 type = WebInputEvent::TouchMove; | 330 type = WebInputEvent::TouchMove; |
302 state = WebTouchPoint::StateMoved; | 331 state = WebTouchPoint::StateMoved; |
303 break; | 332 break; |
304 case PP_INPUTEVENT_TYPE_TOUCHEND: | 333 case PP_INPUTEVENT_TYPE_TOUCHEND: |
305 type = WebInputEvent::TouchEnd; | 334 type = WebInputEvent::TouchEnd; |
306 state = WebTouchPoint::StateReleased; | 335 state = WebTouchPoint::StateReleased; |
307 break; | 336 break; |
308 case PP_INPUTEVENT_TYPE_TOUCHCANCEL: | 337 case PP_INPUTEVENT_TYPE_TOUCHCANCEL: |
309 type = WebInputEvent::TouchCancel; | 338 type = WebInputEvent::TouchCancel; |
310 state = WebTouchPoint::StateCancelled; | 339 state = WebTouchPoint::StateCancelled; |
311 break; | 340 break; |
312 default: | 341 default: |
313 NOTREACHED(); | 342 NOTREACHED(); |
314 } | 343 } |
315 WebTouchEventTraits::ResetType( | 344 WebTouchEventTraits::ResetType( |
316 type, PPTimeTicksToEventTime(event.event_time_stamp), web_event); | 345 type, PPTimeTicksToEventTime(event.event_time_stamp), web_event); |
| 346 web_event->touchesLength = 0; |
317 | 347 |
318 TouchStateMap states_map; | 348 // First add all changed touches, then add only the remaining unset |
319 for (uint32_t i = 0; i < event.changed_touches.size(); i++) | 349 // (stationary) touches. |
320 states_map[event.changed_touches[i].id] = state; | 350 SetWebTouchPointsIfNotYetSet(event.changed_touches, |
321 | 351 state, |
322 SetWebTouchPoints(event.changed_touches, | 352 web_event->touches, |
323 states_map, | 353 &web_event->touchesLength); |
324 web_event->changedTouches, | 354 SetWebTouchPointsIfNotYetSet(event.touches, |
325 &web_event->changedTouchesLength); | 355 WebTouchPoint::StateStationary, |
326 | 356 web_event->touches, |
327 SetWebTouchPoints( | 357 &web_event->touchesLength); |
328 event.touches, states_map, web_event->touches, &web_event->touchesLength); | |
329 | |
330 SetWebTouchPoints(event.target_touches, | |
331 states_map, | |
332 web_event->targetTouches, | |
333 &web_event->targetTouchesLength); | |
334 | |
335 if (web_event->type == WebInputEvent::TouchEnd || | |
336 web_event->type == WebInputEvent::TouchCancel) { | |
337 SetWebTouchPoints(event.changed_touches, | |
338 states_map, | |
339 web_event->touches, | |
340 &web_event->touchesLength); | |
341 SetWebTouchPoints(event.changed_touches, | |
342 states_map, | |
343 web_event->targetTouches, | |
344 &web_event->targetTouchesLength); | |
345 } | |
346 | 358 |
347 return web_event; | 359 return web_event; |
348 } | 360 } |
349 | 361 |
350 WebKeyboardEvent* BuildKeyEvent(const InputEventData& event) { | 362 WebKeyboardEvent* BuildKeyEvent(const InputEventData& event) { |
351 WebKeyboardEvent* key_event = new WebKeyboardEvent(); | 363 WebKeyboardEvent* key_event = new WebKeyboardEvent(); |
352 switch (event.event_type) { | 364 switch (event.event_type) { |
353 case PP_INPUTEVENT_TYPE_RAWKEYDOWN: | 365 case PP_INPUTEVENT_TYPE_RAWKEYDOWN: |
354 key_event->type = WebInputEvent::RawKeyDown; | 366 key_event->type = WebInputEvent::RawKeyDown; |
355 break; | 367 break; |
(...skipping 374 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
730 case WebInputEvent::TouchStart: | 742 case WebInputEvent::TouchStart: |
731 return PP_INPUTEVENT_CLASS_TOUCH; | 743 return PP_INPUTEVENT_CLASS_TOUCH; |
732 case WebInputEvent::Undefined: | 744 case WebInputEvent::Undefined: |
733 default: | 745 default: |
734 CHECK(WebInputEvent::isGestureEventType(type)); | 746 CHECK(WebInputEvent::isGestureEventType(type)); |
735 return PP_InputEvent_Class(0); | 747 return PP_InputEvent_Class(0); |
736 } | 748 } |
737 } | 749 } |
738 | 750 |
739 } // namespace content | 751 } // namespace content |
OLD | NEW |