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
3 // found in the LICENSE file.
5 #include "content/renderer/pepper/event_conversion.h"
9 #include "base/basictypes.h"
10 #include "base/i18n/char_iterator.h"
11 #include "base/logging.h"
12 #include "base/memory/scoped_ptr.h"
13 #include "base/strings/string_util.h"
14 #include "base/strings/stringprintf.h"
15 #include "base/strings/utf_string_conversion_utils.h"
16 #include "base/strings/utf_string_conversions.h"
17 #include "content/common/input/web_touch_event_traits.h"
18 #include "content/renderer/pepper/usb_key_code_conversion.h"
19 #include "ppapi/c/pp_input_event.h"
20 #include "ppapi/shared_impl/ppb_input_event_shared.h"
21 #include "ppapi/shared_impl/time_conversion.h"
22 #include "third_party/WebKit/public/platform/WebGamepads.h"
23 #include "third_party/WebKit/public/platform/WebString.h"
24 #include "third_party/WebKit/public/web/WebInputEvent.h"
26 using ppapi::EventTimeToPPTimeTicks
;
27 using ppapi::InputEventData
;
28 using ppapi::PPTimeTicksToEventTime
;
29 using blink::WebInputEvent
;
30 using blink::WebKeyboardEvent
;
31 using blink::WebMouseEvent
;
32 using blink::WebMouseWheelEvent
;
33 using blink::WebString
;
34 using blink::WebTouchEvent
;
35 using blink::WebTouchPoint
;
36 using blink::WebUChar
;
42 // Verify the modifier flags WebKit uses match the Pepper ones. If these start
43 // not matching, we'll need to write conversion code to preserve the Pepper
44 // values (since plugins will be depending on them).
45 COMPILE_ASSERT(static_cast<int>(PP_INPUTEVENT_MODIFIER_SHIFTKEY
) ==
46 static_cast<int>(WebInputEvent::ShiftKey
),
48 COMPILE_ASSERT(static_cast<int>(PP_INPUTEVENT_MODIFIER_CONTROLKEY
) ==
49 static_cast<int>(WebInputEvent::ControlKey
),
51 COMPILE_ASSERT(static_cast<int>(PP_INPUTEVENT_MODIFIER_ALTKEY
) ==
52 static_cast<int>(WebInputEvent::AltKey
),
54 COMPILE_ASSERT(static_cast<int>(PP_INPUTEVENT_MODIFIER_METAKEY
) ==
55 static_cast<int>(WebInputEvent::MetaKey
),
57 COMPILE_ASSERT(static_cast<int>(PP_INPUTEVENT_MODIFIER_ISKEYPAD
) ==
58 static_cast<int>(WebInputEvent::IsKeyPad
),
60 COMPILE_ASSERT(static_cast<int>(PP_INPUTEVENT_MODIFIER_ISAUTOREPEAT
) ==
61 static_cast<int>(WebInputEvent::IsAutoRepeat
),
63 COMPILE_ASSERT(static_cast<int>(PP_INPUTEVENT_MODIFIER_LEFTBUTTONDOWN
) ==
64 static_cast<int>(WebInputEvent::LeftButtonDown
),
66 COMPILE_ASSERT(static_cast<int>(PP_INPUTEVENT_MODIFIER_MIDDLEBUTTONDOWN
) ==
67 static_cast<int>(WebInputEvent::MiddleButtonDown
),
69 COMPILE_ASSERT(static_cast<int>(PP_INPUTEVENT_MODIFIER_RIGHTBUTTONDOWN
) ==
70 static_cast<int>(WebInputEvent::RightButtonDown
),
72 COMPILE_ASSERT(static_cast<int>(PP_INPUTEVENT_MODIFIER_CAPSLOCKKEY
) ==
73 static_cast<int>(WebInputEvent::CapsLockOn
),
75 COMPILE_ASSERT(static_cast<int>(PP_INPUTEVENT_MODIFIER_NUMLOCKKEY
) ==
76 static_cast<int>(WebInputEvent::NumLockOn
),
78 COMPILE_ASSERT(static_cast<int>(PP_INPUTEVENT_MODIFIER_ISLEFT
) ==
79 static_cast<int>(WebInputEvent::IsLeft
),
81 COMPILE_ASSERT(static_cast<int>(PP_INPUTEVENT_MODIFIER_ISRIGHT
) ==
82 static_cast<int>(WebInputEvent::IsRight
),
85 PP_InputEvent_Type
ConvertEventTypes(WebInputEvent::Type wetype
) {
87 case WebInputEvent::MouseDown
:
88 return PP_INPUTEVENT_TYPE_MOUSEDOWN
;
89 case WebInputEvent::MouseUp
:
90 return PP_INPUTEVENT_TYPE_MOUSEUP
;
91 case WebInputEvent::MouseMove
:
92 return PP_INPUTEVENT_TYPE_MOUSEMOVE
;
93 case WebInputEvent::MouseEnter
:
94 return PP_INPUTEVENT_TYPE_MOUSEENTER
;
95 case WebInputEvent::MouseLeave
:
96 return PP_INPUTEVENT_TYPE_MOUSELEAVE
;
97 case WebInputEvent::ContextMenu
:
98 return PP_INPUTEVENT_TYPE_CONTEXTMENU
;
99 case WebInputEvent::MouseWheel
:
100 return PP_INPUTEVENT_TYPE_WHEEL
;
101 case WebInputEvent::RawKeyDown
:
102 return PP_INPUTEVENT_TYPE_RAWKEYDOWN
;
103 case WebInputEvent::KeyDown
:
104 return PP_INPUTEVENT_TYPE_KEYDOWN
;
105 case WebInputEvent::KeyUp
:
106 return PP_INPUTEVENT_TYPE_KEYUP
;
107 case WebInputEvent::Char
:
108 return PP_INPUTEVENT_TYPE_CHAR
;
109 case WebInputEvent::TouchStart
:
110 return PP_INPUTEVENT_TYPE_TOUCHSTART
;
111 case WebInputEvent::TouchMove
:
112 return PP_INPUTEVENT_TYPE_TOUCHMOVE
;
113 case WebInputEvent::TouchEnd
:
114 return PP_INPUTEVENT_TYPE_TOUCHEND
;
115 case WebInputEvent::TouchCancel
:
116 return PP_INPUTEVENT_TYPE_TOUCHCANCEL
;
117 case WebInputEvent::Undefined
:
119 return PP_INPUTEVENT_TYPE_UNDEFINED
;
123 // Generates a PP_InputEvent with the fields common to all events, as well as
124 // the event type from the given web event. Event-specific fields will be zero
126 InputEventData
GetEventWithCommonFieldsAndType(const WebInputEvent
& web_event
) {
127 InputEventData result
;
128 result
.event_type
= ConvertEventTypes(web_event
.type
);
129 result
.event_time_stamp
= EventTimeToPPTimeTicks(web_event
.timeStampSeconds
);
133 void AppendKeyEvent(const WebInputEvent
& event
,
134 std::vector
<InputEventData
>* result_events
) {
135 const WebKeyboardEvent
& key_event
=
136 static_cast<const WebKeyboardEvent
&>(event
);
137 InputEventData result
= GetEventWithCommonFieldsAndType(event
);
138 result
.event_modifiers
= key_event
.modifiers
;
139 result
.key_code
= key_event
.windowsKeyCode
;
140 result
.code
= CodeForKeyboardEvent(key_event
);
141 result_events
->push_back(result
);
144 void AppendCharEvent(const WebInputEvent
& event
,
145 std::vector
<InputEventData
>* result_events
) {
146 const WebKeyboardEvent
& key_event
=
147 static_cast<const WebKeyboardEvent
&>(event
);
149 // This is a bit complex, the input event will normally just have one 16-bit
150 // character in it, but may be zero or more than one. The text array is
151 // just padded with 0 values for the unused ones, but is not necessarily
154 // Here we see how many UTF-16 characters we have.
155 size_t utf16_char_count
= 0;
156 while (utf16_char_count
< WebKeyboardEvent::textLengthCap
&&
157 key_event
.text
[utf16_char_count
])
160 // Make a separate InputEventData for each Unicode character in the input.
161 base::i18n::UTF16CharIterator
iter(key_event
.text
, utf16_char_count
);
162 while (!iter
.end()) {
163 InputEventData result
= GetEventWithCommonFieldsAndType(event
);
164 result
.event_modifiers
= key_event
.modifiers
;
165 base::WriteUnicodeCharacter(iter
.get(), &result
.character_text
);
167 result_events
->push_back(result
);
172 void AppendMouseEvent(const WebInputEvent
& event
,
173 std::vector
<InputEventData
>* result_events
) {
174 COMPILE_ASSERT(static_cast<int>(WebMouseEvent::ButtonNone
) ==
175 static_cast<int>(PP_INPUTEVENT_MOUSEBUTTON_NONE
),
177 COMPILE_ASSERT(static_cast<int>(WebMouseEvent::ButtonLeft
) ==
178 static_cast<int>(PP_INPUTEVENT_MOUSEBUTTON_LEFT
),
180 COMPILE_ASSERT(static_cast<int>(WebMouseEvent::ButtonRight
) ==
181 static_cast<int>(PP_INPUTEVENT_MOUSEBUTTON_RIGHT
),
183 COMPILE_ASSERT(static_cast<int>(WebMouseEvent::ButtonMiddle
) ==
184 static_cast<int>(PP_INPUTEVENT_MOUSEBUTTON_MIDDLE
),
187 const WebMouseEvent
& mouse_event
= static_cast<const WebMouseEvent
&>(event
);
188 InputEventData result
= GetEventWithCommonFieldsAndType(event
);
189 result
.event_modifiers
= mouse_event
.modifiers
;
190 if (mouse_event
.type
== WebInputEvent::MouseDown
||
191 mouse_event
.type
== WebInputEvent::MouseMove
||
192 mouse_event
.type
== WebInputEvent::MouseUp
) {
193 result
.mouse_button
=
194 static_cast<PP_InputEvent_MouseButton
>(mouse_event
.button
);
196 result
.mouse_position
.x
= mouse_event
.x
;
197 result
.mouse_position
.y
= mouse_event
.y
;
198 result
.mouse_click_count
= mouse_event
.clickCount
;
199 result
.mouse_movement
.x
= mouse_event
.movementX
;
200 result
.mouse_movement
.y
= mouse_event
.movementY
;
201 result_events
->push_back(result
);
204 void AppendMouseWheelEvent(const WebInputEvent
& event
,
205 std::vector
<InputEventData
>* result_events
) {
206 const WebMouseWheelEvent
& mouse_wheel_event
=
207 static_cast<const WebMouseWheelEvent
&>(event
);
208 InputEventData result
= GetEventWithCommonFieldsAndType(event
);
209 result
.event_modifiers
= mouse_wheel_event
.modifiers
;
210 result
.wheel_delta
.x
= mouse_wheel_event
.deltaX
;
211 result
.wheel_delta
.y
= mouse_wheel_event
.deltaY
;
212 result
.wheel_ticks
.x
= mouse_wheel_event
.wheelTicksX
;
213 result
.wheel_ticks
.y
= mouse_wheel_event
.wheelTicksY
;
214 result
.wheel_scroll_by_page
= !!mouse_wheel_event
.scrollByPage
;
215 result_events
->push_back(result
);
218 void SetPPTouchPoints(const WebTouchPoint
* touches
,
219 uint32_t touches_length
,
220 std::vector
<PP_TouchPoint
>* result
) {
221 for (uint32_t i
= 0; i
< touches_length
; i
++) {
222 const WebTouchPoint
& touch_point
= touches
[i
];
224 pp_pt
.id
= touch_point
.id
;
225 pp_pt
.position
.x
= touch_point
.position
.x
;
226 pp_pt
.position
.y
= touch_point
.position
.y
;
227 pp_pt
.radius
.x
= touch_point
.radiusX
;
228 pp_pt
.radius
.y
= touch_point
.radiusY
;
229 pp_pt
.rotation_angle
= touch_point
.rotationAngle
;
230 pp_pt
.pressure
= touch_point
.force
;
231 result
->push_back(pp_pt
);
235 void AppendTouchEvent(const WebInputEvent
& event
,
236 std::vector
<InputEventData
>* result_events
) {
237 const WebTouchEvent
& touch_event
=
238 reinterpret_cast<const WebTouchEvent
&>(event
);
240 InputEventData result
= GetEventWithCommonFieldsAndType(event
);
242 touch_event
.touches
, touch_event
.touchesLength
, &result
.touches
);
243 SetPPTouchPoints(touch_event
.changedTouches
,
244 touch_event
.changedTouchesLength
,
245 &result
.changed_touches
);
246 SetPPTouchPoints(touch_event
.targetTouches
,
247 touch_event
.targetTouchesLength
,
248 &result
.target_touches
);
250 result_events
->push_back(result
);
253 // Structure used to map touch point id's to touch states. Since the pepper
254 // touch event structure does not have states for individual touch points and
255 // instead relies on the event type in combination with the set of touch lists,
256 // we have to set the state for the changed touches to be the same as the event
257 // type and all others to be 'stationary.'
258 typedef std::map
<uint32_t, WebTouchPoint::State
> TouchStateMap
;
260 void SetWebTouchPoints(const std::vector
<PP_TouchPoint
>& pp_touches
,
261 const TouchStateMap
& states_map
,
262 WebTouchPoint
* web_touches
,
263 uint32_t* web_touches_length
) {
266 i
< pp_touches
.size() && i
< WebTouchEvent::touchesLengthCap
;
269 const PP_TouchPoint
& pp_pt
= pp_touches
[i
];
272 if (states_map
.find(pt
.id
) == states_map
.end())
273 pt
.state
= WebTouchPoint::StateStationary
;
275 pt
.state
= states_map
.find(pt
.id
)->second
;
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
;
287 (*web_touches_length
)++;
291 WebTouchEvent
* BuildTouchEvent(const InputEventData
& event
) {
292 WebTouchEvent
* web_event
= new WebTouchEvent();
293 WebTouchPoint::State state
= WebTouchPoint::StateUndefined
;
294 WebInputEvent::Type type
= WebInputEvent::Undefined
;
295 switch (event
.event_type
) {
296 case PP_INPUTEVENT_TYPE_TOUCHSTART
:
297 type
= WebInputEvent::TouchStart
;
298 state
= WebTouchPoint::StatePressed
;
300 case PP_INPUTEVENT_TYPE_TOUCHMOVE
:
301 type
= WebInputEvent::TouchMove
;
302 state
= WebTouchPoint::StateMoved
;
304 case PP_INPUTEVENT_TYPE_TOUCHEND
:
305 type
= WebInputEvent::TouchEnd
;
306 state
= WebTouchPoint::StateReleased
;
308 case PP_INPUTEVENT_TYPE_TOUCHCANCEL
:
309 type
= WebInputEvent::TouchCancel
;
310 state
= WebTouchPoint::StateCancelled
;
315 WebTouchEventTraits::ResetType(
316 type
, PPTimeTicksToEventTime(event
.event_time_stamp
), web_event
);
318 TouchStateMap states_map
;
319 for (uint32_t i
= 0; i
< event
.changed_touches
.size(); i
++)
320 states_map
[event
.changed_touches
[i
].id
] = state
;
322 SetWebTouchPoints(event
.changed_touches
,
324 web_event
->changedTouches
,
325 &web_event
->changedTouchesLength
);
328 event
.touches
, states_map
, web_event
->touches
, &web_event
->touchesLength
);
330 SetWebTouchPoints(event
.target_touches
,
332 web_event
->targetTouches
,
333 &web_event
->targetTouchesLength
);
335 if (web_event
->type
== WebInputEvent::TouchEnd
||
336 web_event
->type
== WebInputEvent::TouchCancel
) {
337 SetWebTouchPoints(event
.changed_touches
,
340 &web_event
->touchesLength
);
341 SetWebTouchPoints(event
.changed_touches
,
343 web_event
->targetTouches
,
344 &web_event
->targetTouchesLength
);
350 WebKeyboardEvent
* BuildKeyEvent(const InputEventData
& event
) {
351 WebKeyboardEvent
* key_event
= new WebKeyboardEvent();
352 switch (event
.event_type
) {
353 case PP_INPUTEVENT_TYPE_RAWKEYDOWN
:
354 key_event
->type
= WebInputEvent::RawKeyDown
;
356 case PP_INPUTEVENT_TYPE_KEYDOWN
:
357 key_event
->type
= WebInputEvent::KeyDown
;
359 case PP_INPUTEVENT_TYPE_KEYUP
:
360 key_event
->type
= WebInputEvent::KeyUp
;
365 key_event
->timeStampSeconds
= PPTimeTicksToEventTime(event
.event_time_stamp
);
366 key_event
->modifiers
= event
.event_modifiers
;
367 key_event
->windowsKeyCode
= event
.key_code
;
368 key_event
->setKeyIdentifierFromWindowsKeyCode();
372 WebKeyboardEvent
* BuildCharEvent(const InputEventData
& event
) {
373 WebKeyboardEvent
* key_event
= new WebKeyboardEvent();
374 key_event
->type
= WebInputEvent::Char
;
375 key_event
->timeStampSeconds
= PPTimeTicksToEventTime(event
.event_time_stamp
);
376 key_event
->modifiers
= event
.event_modifiers
;
378 // Make sure to not read beyond the buffer in case some bad code doesn't
379 // NULL-terminate it (this is called from plugins).
380 size_t text_length_cap
= WebKeyboardEvent::textLengthCap
;
381 base::string16 text16
= base::UTF8ToUTF16(event
.character_text
);
383 memset(key_event
->text
, 0, text_length_cap
);
384 memset(key_event
->unmodifiedText
, 0, text_length_cap
);
385 for (size_t i
= 0; i
< std::min(text_length_cap
, text16
.size()); ++i
)
386 key_event
->text
[i
] = text16
[i
];
390 WebMouseEvent
* BuildMouseEvent(const InputEventData
& event
) {
391 WebMouseEvent
* mouse_event
= new WebMouseEvent();
392 switch (event
.event_type
) {
393 case PP_INPUTEVENT_TYPE_MOUSEDOWN
:
394 mouse_event
->type
= WebInputEvent::MouseDown
;
396 case PP_INPUTEVENT_TYPE_MOUSEUP
:
397 mouse_event
->type
= WebInputEvent::MouseUp
;
399 case PP_INPUTEVENT_TYPE_MOUSEMOVE
:
400 mouse_event
->type
= WebInputEvent::MouseMove
;
402 case PP_INPUTEVENT_TYPE_MOUSEENTER
:
403 mouse_event
->type
= WebInputEvent::MouseEnter
;
405 case PP_INPUTEVENT_TYPE_MOUSELEAVE
:
406 mouse_event
->type
= WebInputEvent::MouseLeave
;
408 case PP_INPUTEVENT_TYPE_CONTEXTMENU
:
409 mouse_event
->type
= WebInputEvent::ContextMenu
;
414 mouse_event
->timeStampSeconds
=
415 PPTimeTicksToEventTime(event
.event_time_stamp
);
416 mouse_event
->modifiers
= event
.event_modifiers
;
417 mouse_event
->button
= static_cast<WebMouseEvent::Button
>(event
.mouse_button
);
418 if (mouse_event
->type
== WebInputEvent::MouseMove
) {
419 if (mouse_event
->modifiers
& WebInputEvent::LeftButtonDown
)
420 mouse_event
->button
= WebMouseEvent::ButtonLeft
;
421 else if (mouse_event
->modifiers
& WebInputEvent::MiddleButtonDown
)
422 mouse_event
->button
= WebMouseEvent::ButtonMiddle
;
423 else if (mouse_event
->modifiers
& WebInputEvent::RightButtonDown
)
424 mouse_event
->button
= WebMouseEvent::ButtonRight
;
426 mouse_event
->x
= event
.mouse_position
.x
;
427 mouse_event
->y
= event
.mouse_position
.y
;
428 mouse_event
->clickCount
= event
.mouse_click_count
;
429 mouse_event
->movementX
= event
.mouse_movement
.x
;
430 mouse_event
->movementY
= event
.mouse_movement
.y
;
434 WebMouseWheelEvent
* BuildMouseWheelEvent(const InputEventData
& event
) {
435 WebMouseWheelEvent
* mouse_wheel_event
= new WebMouseWheelEvent();
436 mouse_wheel_event
->type
= WebInputEvent::MouseWheel
;
437 mouse_wheel_event
->timeStampSeconds
=
438 PPTimeTicksToEventTime(event
.event_time_stamp
);
439 mouse_wheel_event
->modifiers
= event
.event_modifiers
;
440 mouse_wheel_event
->deltaX
= event
.wheel_delta
.x
;
441 mouse_wheel_event
->deltaY
= event
.wheel_delta
.y
;
442 mouse_wheel_event
->wheelTicksX
= event
.wheel_ticks
.x
;
443 mouse_wheel_event
->wheelTicksY
= event
.wheel_ticks
.y
;
444 mouse_wheel_event
->scrollByPage
= event
.wheel_scroll_by_page
;
445 return mouse_wheel_event
;
449 #define VK_RETURN 0x0D
451 #define VK_PRIOR 0x21
457 #define VK_RIGHT 0x27
459 #define VK_SNAPSHOT 0x2C
460 #define VK_INSERT 0x2D
461 #define VK_DELETE 0x2E
468 // Convert a character string to a Windows virtual key code. Adapted from
469 // src/content/shell/renderer/test_runner/event_sender.cc. This
470 // is used by CreateSimulatedWebInputEvents to convert keyboard events.
471 void GetKeyCode(const std::string
& char_text
,
474 bool* needs_shift_modifier
,
475 bool* generate_char
) {
476 WebUChar vk_code
= 0;
477 WebUChar vk_text
= 0;
478 *needs_shift_modifier
= false;
479 *generate_char
= false;
480 if ("\n" == char_text
) {
481 vk_text
= vk_code
= VK_RETURN
;
482 *generate_char
= true;
483 } else if ("rightArrow" == char_text
) {
485 } else if ("downArrow" == char_text
) {
487 } else if ("leftArrow" == char_text
) {
489 } else if ("upArrow" == char_text
) {
491 } else if ("insert" == char_text
) {
493 } else if ("delete" == char_text
) {
495 } else if ("pageUp" == char_text
) {
497 } else if ("pageDown" == char_text
) {
499 } else if ("home" == char_text
) {
501 } else if ("end" == char_text
) {
503 } else if ("printScreen" == char_text
) {
504 vk_code
= VK_SNAPSHOT
;
505 } else if ("menu" == char_text
) {
508 // Compare the input string with the function-key names defined by the
509 // DOM spec (i.e. "F1",...,"F24").
510 for (int i
= 1; i
<= 24; ++i
) {
511 std::string functionKeyName
= base::StringPrintf("F%d", i
);
512 if (functionKeyName
== char_text
) {
513 vk_code
= VK_F1
+ (i
- 1);
518 WebString web_char_text
=
519 WebString::fromUTF8(char_text
.data(), char_text
.size());
520 DCHECK_EQ(web_char_text
.length(), 1U);
521 vk_text
= vk_code
= web_char_text
.at(0);
522 *needs_shift_modifier
=
523 (vk_code
& 0xFF) >= 'A' && (vk_code
& 0xFF) <= 'Z';
524 if ((vk_code
& 0xFF) >= 'a' && (vk_code
& 0xFF) <= 'z')
525 vk_code
-= 'a' - 'A';
526 *generate_char
= true;
536 void CreateInputEventData(const WebInputEvent
& event
,
537 std::vector
<InputEventData
>* result
) {
540 switch (event
.type
) {
541 case WebInputEvent::MouseDown
:
542 case WebInputEvent::MouseUp
:
543 case WebInputEvent::MouseMove
:
544 case WebInputEvent::MouseEnter
:
545 case WebInputEvent::MouseLeave
:
546 case WebInputEvent::ContextMenu
:
547 AppendMouseEvent(event
, result
);
549 case WebInputEvent::MouseWheel
:
550 AppendMouseWheelEvent(event
, result
);
552 case WebInputEvent::RawKeyDown
:
553 case WebInputEvent::KeyDown
:
554 case WebInputEvent::KeyUp
:
555 AppendKeyEvent(event
, result
);
557 case WebInputEvent::Char
:
558 AppendCharEvent(event
, result
);
560 case WebInputEvent::TouchStart
:
561 case WebInputEvent::TouchMove
:
562 case WebInputEvent::TouchEnd
:
563 case WebInputEvent::TouchCancel
:
564 AppendTouchEvent(event
, result
);
566 case WebInputEvent::Undefined
:
572 WebInputEvent
* CreateWebInputEvent(const InputEventData
& event
) {
573 scoped_ptr
<WebInputEvent
> web_input_event
;
574 switch (event
.event_type
) {
575 case PP_INPUTEVENT_TYPE_UNDEFINED
:
577 case PP_INPUTEVENT_TYPE_MOUSEDOWN
:
578 case PP_INPUTEVENT_TYPE_MOUSEUP
:
579 case PP_INPUTEVENT_TYPE_MOUSEMOVE
:
580 case PP_INPUTEVENT_TYPE_MOUSEENTER
:
581 case PP_INPUTEVENT_TYPE_MOUSELEAVE
:
582 case PP_INPUTEVENT_TYPE_CONTEXTMENU
:
583 web_input_event
.reset(BuildMouseEvent(event
));
585 case PP_INPUTEVENT_TYPE_WHEEL
:
586 web_input_event
.reset(BuildMouseWheelEvent(event
));
588 case PP_INPUTEVENT_TYPE_RAWKEYDOWN
:
589 case PP_INPUTEVENT_TYPE_KEYDOWN
:
590 case PP_INPUTEVENT_TYPE_KEYUP
:
591 web_input_event
.reset(BuildKeyEvent(event
));
593 case PP_INPUTEVENT_TYPE_CHAR
:
594 web_input_event
.reset(BuildCharEvent(event
));
596 case PP_INPUTEVENT_TYPE_IME_COMPOSITION_START
:
597 case PP_INPUTEVENT_TYPE_IME_COMPOSITION_UPDATE
:
598 case PP_INPUTEVENT_TYPE_IME_COMPOSITION_END
:
599 case PP_INPUTEVENT_TYPE_IME_TEXT
:
600 // TODO(kinaba) implement in WebKit an event structure to handle
601 // composition events.
604 case PP_INPUTEVENT_TYPE_TOUCHSTART
:
605 case PP_INPUTEVENT_TYPE_TOUCHMOVE
:
606 case PP_INPUTEVENT_TYPE_TOUCHEND
:
607 case PP_INPUTEVENT_TYPE_TOUCHCANCEL
:
608 web_input_event
.reset(BuildTouchEvent(event
));
612 return web_input_event
.release();
615 // Generate a coherent sequence of input events to simulate a user event.
616 // From src/content/shell/renderer/test_runner/event_sender.cc.
617 std::vector
<linked_ptr
<WebInputEvent
> > CreateSimulatedWebInputEvents(
618 const ppapi::InputEventData
& event
,
621 std::vector
<linked_ptr
<WebInputEvent
> > events
;
622 linked_ptr
<WebInputEvent
> original_event(CreateWebInputEvent(event
));
624 switch (event
.event_type
) {
625 case PP_INPUTEVENT_TYPE_MOUSEDOWN
:
626 case PP_INPUTEVENT_TYPE_MOUSEUP
:
627 case PP_INPUTEVENT_TYPE_MOUSEMOVE
:
628 case PP_INPUTEVENT_TYPE_MOUSEENTER
:
629 case PP_INPUTEVENT_TYPE_MOUSELEAVE
:
630 case PP_INPUTEVENT_TYPE_TOUCHSTART
:
631 case PP_INPUTEVENT_TYPE_TOUCHMOVE
:
632 case PP_INPUTEVENT_TYPE_TOUCHEND
:
633 case PP_INPUTEVENT_TYPE_TOUCHCANCEL
:
634 events
.push_back(original_event
);
637 case PP_INPUTEVENT_TYPE_WHEEL
: {
638 WebMouseWheelEvent
* web_mouse_wheel_event
=
639 static_cast<WebMouseWheelEvent
*>(original_event
.get());
640 web_mouse_wheel_event
->x
= plugin_x
;
641 web_mouse_wheel_event
->y
= plugin_y
;
642 events
.push_back(original_event
);
646 case PP_INPUTEVENT_TYPE_RAWKEYDOWN
:
647 case PP_INPUTEVENT_TYPE_KEYDOWN
:
648 case PP_INPUTEVENT_TYPE_KEYUP
: {
649 // Windows key down events should always be "raw" to avoid an ASSERT.
651 WebKeyboardEvent
* web_keyboard_event
=
652 static_cast<WebKeyboardEvent
*>(original_event
.get());
653 if (web_keyboard_event
->type
== WebInputEvent::KeyDown
)
654 web_keyboard_event
->type
= WebInputEvent::RawKeyDown
;
656 events
.push_back(original_event
);
660 case PP_INPUTEVENT_TYPE_CHAR
: {
661 WebKeyboardEvent
* web_char_event
=
662 static_cast<WebKeyboardEvent
*>(original_event
.get());
664 WebUChar code
= 0, text
= 0;
665 bool needs_shift_modifier
= false, generate_char
= false;
666 GetKeyCode(event
.character_text
,
669 &needs_shift_modifier
,
672 // Synthesize key down and key up events in all cases.
673 scoped_ptr
<WebKeyboardEvent
> key_down_event(new WebKeyboardEvent());
674 scoped_ptr
<WebKeyboardEvent
> key_up_event(new WebKeyboardEvent());
676 key_down_event
->type
= WebInputEvent::RawKeyDown
;
677 key_down_event
->windowsKeyCode
= code
;
678 key_down_event
->nativeKeyCode
= code
;
679 if (needs_shift_modifier
)
680 key_down_event
->modifiers
|= WebInputEvent::ShiftKey
;
682 // If a char event is needed, set the text fields.
684 key_down_event
->text
[0] = text
;
685 key_down_event
->unmodifiedText
[0] = text
;
687 // Convert the key code to a string identifier.
688 key_down_event
->setKeyIdentifierFromWindowsKeyCode();
690 *key_up_event
= *web_char_event
= *key_down_event
;
692 events
.push_back(linked_ptr
<WebInputEvent
>(key_down_event
.release()));
695 web_char_event
->type
= WebInputEvent::Char
;
696 web_char_event
->keyIdentifier
[0] = '\0';
697 events
.push_back(original_event
);
700 key_up_event
->type
= WebInputEvent::KeyUp
;
701 events
.push_back(linked_ptr
<WebInputEvent
>(key_up_event
.release()));
711 PP_InputEvent_Class
ClassifyInputEvent(WebInputEvent::Type type
) {
713 case WebInputEvent::MouseDown
:
714 case WebInputEvent::MouseUp
:
715 case WebInputEvent::MouseMove
:
716 case WebInputEvent::MouseEnter
:
717 case WebInputEvent::MouseLeave
:
718 case WebInputEvent::ContextMenu
:
719 return PP_INPUTEVENT_CLASS_MOUSE
;
720 case WebInputEvent::MouseWheel
:
721 return PP_INPUTEVENT_CLASS_WHEEL
;
722 case WebInputEvent::RawKeyDown
:
723 case WebInputEvent::KeyDown
:
724 case WebInputEvent::KeyUp
:
725 case WebInputEvent::Char
:
726 return PP_INPUTEVENT_CLASS_KEYBOARD
;
727 case WebInputEvent::TouchCancel
:
728 case WebInputEvent::TouchEnd
:
729 case WebInputEvent::TouchMove
:
730 case WebInputEvent::TouchStart
:
731 return PP_INPUTEVENT_CLASS_TOUCH
;
732 case WebInputEvent::Undefined
:
734 CHECK(WebInputEvent::isGestureEventType(type
));
735 return PP_InputEvent_Class(0);
739 } // namespace content