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"
7 #include "base/basictypes.h"
8 #include "base/i18n/char_iterator.h"
9 #include "base/logging.h"
10 #include "base/memory/scoped_ptr.h"
11 #include "base/strings/string_util.h"
12 #include "base/strings/stringprintf.h"
13 #include "base/strings/utf_string_conversion_utils.h"
14 #include "base/strings/utf_string_conversions.h"
15 #include "content/common/input/web_touch_event_traits.h"
16 #include "content/renderer/pepper/usb_key_code_conversion.h"
17 #include "ppapi/c/pp_input_event.h"
18 #include "ppapi/shared_impl/ppb_input_event_shared.h"
19 #include "ppapi/shared_impl/time_conversion.h"
20 #include "third_party/WebKit/public/platform/WebGamepads.h"
21 #include "third_party/WebKit/public/platform/WebString.h"
22 #include "third_party/WebKit/public/web/WebInputEvent.h"
24 using ppapi::EventTimeToPPTimeTicks
;
25 using ppapi::InputEventData
;
26 using ppapi::PPTimeTicksToEventTime
;
27 using blink::WebInputEvent
;
28 using blink::WebKeyboardEvent
;
29 using blink::WebMouseEvent
;
30 using blink::WebMouseWheelEvent
;
31 using blink::WebString
;
32 using blink::WebTouchEvent
;
33 using blink::WebTouchPoint
;
34 using blink::WebUChar
;
40 // Verify the modifier flags WebKit uses match the Pepper ones. If these start
41 // not matching, we'll need to write conversion code to preserve the Pepper
42 // values (since plugins will be depending on them).
43 static_assert(static_cast<int>(PP_INPUTEVENT_MODIFIER_SHIFTKEY
) ==
44 static_cast<int>(WebInputEvent::ShiftKey
),
45 "ShiftKey should match");
46 static_assert(static_cast<int>(PP_INPUTEVENT_MODIFIER_CONTROLKEY
) ==
47 static_cast<int>(WebInputEvent::ControlKey
),
48 "ControlKey should match");
49 static_assert(static_cast<int>(PP_INPUTEVENT_MODIFIER_ALTKEY
) ==
50 static_cast<int>(WebInputEvent::AltKey
),
51 "AltKey should match");
52 static_assert(static_cast<int>(PP_INPUTEVENT_MODIFIER_METAKEY
) ==
53 static_cast<int>(WebInputEvent::MetaKey
),
54 "MetaKey should match");
55 static_assert(static_cast<int>(PP_INPUTEVENT_MODIFIER_ISKEYPAD
) ==
56 static_cast<int>(WebInputEvent::IsKeyPad
),
57 "KeyPad should match");
58 static_assert(static_cast<int>(PP_INPUTEVENT_MODIFIER_ISAUTOREPEAT
) ==
59 static_cast<int>(WebInputEvent::IsAutoRepeat
),
60 "AutoRepeat should match");
61 static_assert(static_cast<int>(PP_INPUTEVENT_MODIFIER_LEFTBUTTONDOWN
) ==
62 static_cast<int>(WebInputEvent::LeftButtonDown
),
63 "LeftButton should match");
64 static_assert(static_cast<int>(PP_INPUTEVENT_MODIFIER_MIDDLEBUTTONDOWN
) ==
65 static_cast<int>(WebInputEvent::MiddleButtonDown
),
66 "MiddleButton should match");
67 static_assert(static_cast<int>(PP_INPUTEVENT_MODIFIER_RIGHTBUTTONDOWN
) ==
68 static_cast<int>(WebInputEvent::RightButtonDown
),
69 "RightButton should match");
70 static_assert(static_cast<int>(PP_INPUTEVENT_MODIFIER_CAPSLOCKKEY
) ==
71 static_cast<int>(WebInputEvent::CapsLockOn
),
72 "CapsLock should match");
73 static_assert(static_cast<int>(PP_INPUTEVENT_MODIFIER_NUMLOCKKEY
) ==
74 static_cast<int>(WebInputEvent::NumLockOn
),
75 "NumLock should match");
76 static_assert(static_cast<int>(PP_INPUTEVENT_MODIFIER_ISLEFT
) ==
77 static_cast<int>(WebInputEvent::IsLeft
),
78 "IsLeft should match");
79 static_assert(static_cast<int>(PP_INPUTEVENT_MODIFIER_ISRIGHT
) ==
80 static_cast<int>(WebInputEvent::IsRight
),
81 "IsRight should match");
83 PP_InputEvent_Type
ConvertEventTypes(WebInputEvent::Type wetype
) {
85 case WebInputEvent::MouseDown
:
86 return PP_INPUTEVENT_TYPE_MOUSEDOWN
;
87 case WebInputEvent::MouseUp
:
88 return PP_INPUTEVENT_TYPE_MOUSEUP
;
89 case WebInputEvent::MouseMove
:
90 return PP_INPUTEVENT_TYPE_MOUSEMOVE
;
91 case WebInputEvent::MouseEnter
:
92 return PP_INPUTEVENT_TYPE_MOUSEENTER
;
93 case WebInputEvent::MouseLeave
:
94 return PP_INPUTEVENT_TYPE_MOUSELEAVE
;
95 case WebInputEvent::ContextMenu
:
96 return PP_INPUTEVENT_TYPE_CONTEXTMENU
;
97 case WebInputEvent::MouseWheel
:
98 return PP_INPUTEVENT_TYPE_WHEEL
;
99 case WebInputEvent::RawKeyDown
:
100 return PP_INPUTEVENT_TYPE_RAWKEYDOWN
;
101 case WebInputEvent::KeyDown
:
102 return PP_INPUTEVENT_TYPE_KEYDOWN
;
103 case WebInputEvent::KeyUp
:
104 return PP_INPUTEVENT_TYPE_KEYUP
;
105 case WebInputEvent::Char
:
106 return PP_INPUTEVENT_TYPE_CHAR
;
107 case WebInputEvent::TouchStart
:
108 return PP_INPUTEVENT_TYPE_TOUCHSTART
;
109 case WebInputEvent::TouchMove
:
110 return PP_INPUTEVENT_TYPE_TOUCHMOVE
;
111 case WebInputEvent::TouchEnd
:
112 return PP_INPUTEVENT_TYPE_TOUCHEND
;
113 case WebInputEvent::TouchCancel
:
114 return PP_INPUTEVENT_TYPE_TOUCHCANCEL
;
115 case WebInputEvent::Undefined
:
117 return PP_INPUTEVENT_TYPE_UNDEFINED
;
121 // Generates a PP_InputEvent with the fields common to all events, as well as
122 // the event type from the given web event. Event-specific fields will be zero
124 InputEventData
GetEventWithCommonFieldsAndType(const WebInputEvent
& web_event
) {
125 InputEventData result
;
126 result
.event_type
= ConvertEventTypes(web_event
.type
);
127 result
.event_time_stamp
= EventTimeToPPTimeTicks(web_event
.timeStampSeconds
);
131 void AppendKeyEvent(const WebInputEvent
& event
,
132 std::vector
<InputEventData
>* result_events
) {
133 const WebKeyboardEvent
& key_event
=
134 static_cast<const WebKeyboardEvent
&>(event
);
135 InputEventData result
= GetEventWithCommonFieldsAndType(event
);
136 result
.event_modifiers
= key_event
.modifiers
;
137 result
.key_code
= key_event
.windowsKeyCode
;
138 result
.code
= CodeForKeyboardEvent(key_event
);
139 result_events
->push_back(result
);
142 void AppendCharEvent(const WebInputEvent
& event
,
143 std::vector
<InputEventData
>* result_events
) {
144 const WebKeyboardEvent
& key_event
=
145 static_cast<const WebKeyboardEvent
&>(event
);
147 // This is a bit complex, the input event will normally just have one 16-bit
148 // character in it, but may be zero or more than one. The text array is
149 // just padded with 0 values for the unused ones, but is not necessarily
152 // Here we see how many UTF-16 characters we have.
153 size_t utf16_char_count
= 0;
154 while (utf16_char_count
< WebKeyboardEvent::textLengthCap
&&
155 key_event
.text
[utf16_char_count
])
158 // Make a separate InputEventData for each Unicode character in the input.
159 base::i18n::UTF16CharIterator
iter(key_event
.text
, utf16_char_count
);
160 while (!iter
.end()) {
161 InputEventData result
= GetEventWithCommonFieldsAndType(event
);
162 result
.event_modifiers
= key_event
.modifiers
;
163 base::WriteUnicodeCharacter(iter
.get(), &result
.character_text
);
165 result_events
->push_back(result
);
170 void AppendMouseEvent(const WebInputEvent
& event
,
171 std::vector
<InputEventData
>* result_events
) {
172 static_assert(static_cast<int>(WebMouseEvent::ButtonNone
) ==
173 static_cast<int>(PP_INPUTEVENT_MOUSEBUTTON_NONE
),
174 "MouseNone should match");
175 static_assert(static_cast<int>(WebMouseEvent::ButtonLeft
) ==
176 static_cast<int>(PP_INPUTEVENT_MOUSEBUTTON_LEFT
),
177 "MouseLeft should match");
178 static_assert(static_cast<int>(WebMouseEvent::ButtonRight
) ==
179 static_cast<int>(PP_INPUTEVENT_MOUSEBUTTON_RIGHT
),
180 "MouseRight should match");
181 static_assert(static_cast<int>(WebMouseEvent::ButtonMiddle
) ==
182 static_cast<int>(PP_INPUTEVENT_MOUSEBUTTON_MIDDLE
),
183 "MouseMiddle should match");
185 const WebMouseEvent
& mouse_event
= static_cast<const WebMouseEvent
&>(event
);
186 InputEventData result
= GetEventWithCommonFieldsAndType(event
);
187 result
.event_modifiers
= mouse_event
.modifiers
;
188 if (mouse_event
.type
== WebInputEvent::MouseDown
||
189 mouse_event
.type
== WebInputEvent::MouseMove
||
190 mouse_event
.type
== WebInputEvent::MouseUp
) {
191 result
.mouse_button
=
192 static_cast<PP_InputEvent_MouseButton
>(mouse_event
.button
);
194 result
.mouse_position
.x
= mouse_event
.x
;
195 result
.mouse_position
.y
= mouse_event
.y
;
196 result
.mouse_click_count
= mouse_event
.clickCount
;
197 result
.mouse_movement
.x
= mouse_event
.movementX
;
198 result
.mouse_movement
.y
= mouse_event
.movementY
;
199 result_events
->push_back(result
);
202 void AppendMouseWheelEvent(const WebInputEvent
& event
,
203 std::vector
<InputEventData
>* result_events
) {
204 const WebMouseWheelEvent
& mouse_wheel_event
=
205 static_cast<const WebMouseWheelEvent
&>(event
);
206 InputEventData result
= GetEventWithCommonFieldsAndType(event
);
207 result
.event_modifiers
= mouse_wheel_event
.modifiers
;
208 result
.wheel_delta
.x
= mouse_wheel_event
.deltaX
;
209 result
.wheel_delta
.y
= mouse_wheel_event
.deltaY
;
210 result
.wheel_ticks
.x
= mouse_wheel_event
.wheelTicksX
;
211 result
.wheel_ticks
.y
= mouse_wheel_event
.wheelTicksY
;
212 result
.wheel_scroll_by_page
= !!mouse_wheel_event
.scrollByPage
;
213 result_events
->push_back(result
);
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.
221 void SetPPTouchPoints(const WebTouchPoint
* touches
,
222 uint32_t touches_length
,
223 IncludedTouchPointTypes included_types
,
224 std::vector
<PP_TouchPoint
>* result
) {
225 for (uint32_t i
= 0; i
< touches_length
; 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
)) {
232 if (included_types
== CHANGED
&&
233 (touch_point
.state
== WebTouchPoint::StateUndefined
||
234 touch_point
.state
== WebTouchPoint::StateStationary
)) {
238 pp_pt
.id
= touch_point
.id
;
239 pp_pt
.position
.x
= touch_point
.position
.x
;
240 pp_pt
.position
.y
= touch_point
.position
.y
;
241 pp_pt
.radius
.x
= touch_point
.radiusX
;
242 pp_pt
.radius
.y
= touch_point
.radiusY
;
243 pp_pt
.rotation_angle
= touch_point
.rotationAngle
;
244 pp_pt
.pressure
= touch_point
.force
;
245 result
->push_back(pp_pt
);
249 void AppendTouchEvent(const WebInputEvent
& event
,
250 std::vector
<InputEventData
>* result_events
) {
251 const WebTouchEvent
& touch_event
=
252 reinterpret_cast<const WebTouchEvent
&>(event
);
254 InputEventData result
= GetEventWithCommonFieldsAndType(event
);
256 touch_event
.touches
, touch_event
.touchesLength
, ACTIVE
, &result
.touches
);
257 SetPPTouchPoints(touch_event
.touches
,
258 touch_event
.touchesLength
,
260 &result
.changed_touches
);
261 SetPPTouchPoints(touch_event
.touches
,
262 touch_event
.touchesLength
,
264 &result
.target_touches
);
266 result_events
->push_back(result
);
269 WebTouchPoint
CreateWebTouchPoint(const PP_TouchPoint
& pp_pt
,
270 WebTouchPoint::State state
) {
273 pt
.position
.x
= pp_pt
.position
.x
;
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
;
286 bool HasTouchPointWithId(const WebTouchPoint
* web_touches
,
287 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
))
298 void SetWebTouchPointsIfNotYetSet(const std::vector
<PP_TouchPoint
>& pp_touches
,
299 WebTouchPoint::State state
,
300 WebTouchPoint
* web_touches
,
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
))
311 const PP_TouchPoint
& pp_pt
= pp_touches
[i
];
312 if (HasTouchPointWithId(web_touches
, initial_web_touches_length
, pp_pt
.id
))
315 web_touches
[touch_index
] = CreateWebTouchPoint(pp_pt
, state
);
316 ++(*web_touches_length
);
320 WebTouchEvent
* BuildTouchEvent(const InputEventData
& event
) {
321 WebTouchEvent
* web_event
= new WebTouchEvent();
322 WebTouchPoint::State state
= WebTouchPoint::StateUndefined
;
323 WebInputEvent::Type type
= WebInputEvent::Undefined
;
324 switch (event
.event_type
) {
325 case PP_INPUTEVENT_TYPE_TOUCHSTART
:
326 type
= WebInputEvent::TouchStart
;
327 state
= WebTouchPoint::StatePressed
;
329 case PP_INPUTEVENT_TYPE_TOUCHMOVE
:
330 type
= WebInputEvent::TouchMove
;
331 state
= WebTouchPoint::StateMoved
;
333 case PP_INPUTEVENT_TYPE_TOUCHEND
:
334 type
= WebInputEvent::TouchEnd
;
335 state
= WebTouchPoint::StateReleased
;
337 case PP_INPUTEVENT_TYPE_TOUCHCANCEL
:
338 type
= WebInputEvent::TouchCancel
;
339 state
= WebTouchPoint::StateCancelled
;
344 WebTouchEventTraits::ResetType(
345 type
, PPTimeTicksToEventTime(event
.event_time_stamp
), web_event
);
346 web_event
->touchesLength
= 0;
348 // First add all changed touches, then add only the remaining unset
349 // (stationary) touches.
350 SetWebTouchPointsIfNotYetSet(event
.changed_touches
,
353 &web_event
->touchesLength
);
354 SetWebTouchPointsIfNotYetSet(event
.touches
,
355 WebTouchPoint::StateStationary
,
357 &web_event
->touchesLength
);
362 WebKeyboardEvent
* BuildKeyEvent(const InputEventData
& event
) {
363 WebKeyboardEvent
* key_event
= new WebKeyboardEvent();
364 switch (event
.event_type
) {
365 case PP_INPUTEVENT_TYPE_RAWKEYDOWN
:
366 key_event
->type
= WebInputEvent::RawKeyDown
;
368 case PP_INPUTEVENT_TYPE_KEYDOWN
:
369 key_event
->type
= WebInputEvent::KeyDown
;
371 case PP_INPUTEVENT_TYPE_KEYUP
:
372 key_event
->type
= WebInputEvent::KeyUp
;
377 key_event
->timeStampSeconds
= PPTimeTicksToEventTime(event
.event_time_stamp
);
378 key_event
->modifiers
= event
.event_modifiers
;
379 key_event
->windowsKeyCode
= event
.key_code
;
380 key_event
->setKeyIdentifierFromWindowsKeyCode();
384 WebKeyboardEvent
* BuildCharEvent(const InputEventData
& event
) {
385 WebKeyboardEvent
* key_event
= new WebKeyboardEvent();
386 key_event
->type
= WebInputEvent::Char
;
387 key_event
->timeStampSeconds
= PPTimeTicksToEventTime(event
.event_time_stamp
);
388 key_event
->modifiers
= event
.event_modifiers
;
390 // Make sure to not read beyond the buffer in case some bad code doesn't
391 // NULL-terminate it (this is called from plugins).
392 size_t text_length_cap
= WebKeyboardEvent::textLengthCap
;
393 base::string16 text16
= base::UTF8ToUTF16(event
.character_text
);
395 memset(key_event
->text
, 0, text_length_cap
);
396 memset(key_event
->unmodifiedText
, 0, text_length_cap
);
397 for (size_t i
= 0; i
< std::min(text_length_cap
, text16
.size()); ++i
)
398 key_event
->text
[i
] = text16
[i
];
402 WebMouseEvent
* BuildMouseEvent(const InputEventData
& event
) {
403 WebMouseEvent
* mouse_event
= new WebMouseEvent();
404 switch (event
.event_type
) {
405 case PP_INPUTEVENT_TYPE_MOUSEDOWN
:
406 mouse_event
->type
= WebInputEvent::MouseDown
;
408 case PP_INPUTEVENT_TYPE_MOUSEUP
:
409 mouse_event
->type
= WebInputEvent::MouseUp
;
411 case PP_INPUTEVENT_TYPE_MOUSEMOVE
:
412 mouse_event
->type
= WebInputEvent::MouseMove
;
414 case PP_INPUTEVENT_TYPE_MOUSEENTER
:
415 mouse_event
->type
= WebInputEvent::MouseEnter
;
417 case PP_INPUTEVENT_TYPE_MOUSELEAVE
:
418 mouse_event
->type
= WebInputEvent::MouseLeave
;
420 case PP_INPUTEVENT_TYPE_CONTEXTMENU
:
421 mouse_event
->type
= WebInputEvent::ContextMenu
;
426 mouse_event
->timeStampSeconds
=
427 PPTimeTicksToEventTime(event
.event_time_stamp
);
428 mouse_event
->modifiers
= event
.event_modifiers
;
429 mouse_event
->button
= static_cast<WebMouseEvent::Button
>(event
.mouse_button
);
430 if (mouse_event
->type
== WebInputEvent::MouseMove
) {
431 if (mouse_event
->modifiers
& WebInputEvent::LeftButtonDown
)
432 mouse_event
->button
= WebMouseEvent::ButtonLeft
;
433 else if (mouse_event
->modifiers
& WebInputEvent::MiddleButtonDown
)
434 mouse_event
->button
= WebMouseEvent::ButtonMiddle
;
435 else if (mouse_event
->modifiers
& WebInputEvent::RightButtonDown
)
436 mouse_event
->button
= WebMouseEvent::ButtonRight
;
438 mouse_event
->x
= event
.mouse_position
.x
;
439 mouse_event
->y
= event
.mouse_position
.y
;
440 mouse_event
->clickCount
= event
.mouse_click_count
;
441 mouse_event
->movementX
= event
.mouse_movement
.x
;
442 mouse_event
->movementY
= event
.mouse_movement
.y
;
446 WebMouseWheelEvent
* BuildMouseWheelEvent(const InputEventData
& event
) {
447 WebMouseWheelEvent
* mouse_wheel_event
= new WebMouseWheelEvent();
448 mouse_wheel_event
->type
= WebInputEvent::MouseWheel
;
449 mouse_wheel_event
->timeStampSeconds
=
450 PPTimeTicksToEventTime(event
.event_time_stamp
);
451 mouse_wheel_event
->modifiers
= event
.event_modifiers
;
452 mouse_wheel_event
->deltaX
= event
.wheel_delta
.x
;
453 mouse_wheel_event
->deltaY
= event
.wheel_delta
.y
;
454 mouse_wheel_event
->wheelTicksX
= event
.wheel_ticks
.x
;
455 mouse_wheel_event
->wheelTicksY
= event
.wheel_ticks
.y
;
456 mouse_wheel_event
->scrollByPage
= event
.wheel_scroll_by_page
;
457 return mouse_wheel_event
;
461 #define VK_RETURN 0x0D
463 #define VK_PRIOR 0x21
469 #define VK_RIGHT 0x27
471 #define VK_SNAPSHOT 0x2C
472 #define VK_INSERT 0x2D
473 #define VK_DELETE 0x2E
480 // Convert a character string to a Windows virtual key code. Adapted from
481 // src/content/shell/renderer/test_runner/event_sender.cc. This
482 // is used by CreateSimulatedWebInputEvents to convert keyboard events.
483 void GetKeyCode(const std::string
& char_text
,
486 bool* needs_shift_modifier
,
487 bool* generate_char
) {
488 WebUChar vk_code
= 0;
489 WebUChar vk_text
= 0;
490 *needs_shift_modifier
= false;
491 *generate_char
= false;
492 if ("\n" == char_text
) {
493 vk_text
= vk_code
= VK_RETURN
;
494 *generate_char
= true;
495 } else if ("rightArrow" == char_text
) {
497 } else if ("downArrow" == char_text
) {
499 } else if ("leftArrow" == char_text
) {
501 } else if ("upArrow" == char_text
) {
503 } else if ("insert" == char_text
) {
505 } else if ("delete" == char_text
) {
507 } else if ("pageUp" == char_text
) {
509 } else if ("pageDown" == char_text
) {
511 } else if ("home" == char_text
) {
513 } else if ("end" == char_text
) {
515 } else if ("printScreen" == char_text
) {
516 vk_code
= VK_SNAPSHOT
;
517 } else if ("menu" == char_text
) {
520 // Compare the input string with the function-key names defined by the
521 // DOM spec (i.e. "F1",...,"F24").
522 for (int i
= 1; i
<= 24; ++i
) {
523 std::string functionKeyName
= base::StringPrintf("F%d", i
);
524 if (functionKeyName
== char_text
) {
525 vk_code
= VK_F1
+ (i
- 1);
530 WebString web_char_text
=
531 WebString::fromUTF8(char_text
.data(), char_text
.size());
532 DCHECK_EQ(web_char_text
.length(), 1U);
533 vk_text
= vk_code
= web_char_text
.at(0);
534 *needs_shift_modifier
=
535 (vk_code
& 0xFF) >= 'A' && (vk_code
& 0xFF) <= 'Z';
536 if ((vk_code
& 0xFF) >= 'a' && (vk_code
& 0xFF) <= 'z')
537 vk_code
-= 'a' - 'A';
538 *generate_char
= true;
548 void CreateInputEventData(const WebInputEvent
& event
,
549 std::vector
<InputEventData
>* result
) {
552 switch (event
.type
) {
553 case WebInputEvent::MouseDown
:
554 case WebInputEvent::MouseUp
:
555 case WebInputEvent::MouseMove
:
556 case WebInputEvent::MouseEnter
:
557 case WebInputEvent::MouseLeave
:
558 case WebInputEvent::ContextMenu
:
559 AppendMouseEvent(event
, result
);
561 case WebInputEvent::MouseWheel
:
562 AppendMouseWheelEvent(event
, result
);
564 case WebInputEvent::RawKeyDown
:
565 case WebInputEvent::KeyDown
:
566 case WebInputEvent::KeyUp
:
567 AppendKeyEvent(event
, result
);
569 case WebInputEvent::Char
:
570 AppendCharEvent(event
, result
);
572 case WebInputEvent::TouchStart
:
573 case WebInputEvent::TouchMove
:
574 case WebInputEvent::TouchEnd
:
575 case WebInputEvent::TouchCancel
:
576 AppendTouchEvent(event
, result
);
578 case WebInputEvent::Undefined
:
584 WebInputEvent
* CreateWebInputEvent(const InputEventData
& event
) {
585 scoped_ptr
<WebInputEvent
> web_input_event
;
586 switch (event
.event_type
) {
587 case PP_INPUTEVENT_TYPE_UNDEFINED
:
589 case PP_INPUTEVENT_TYPE_MOUSEDOWN
:
590 case PP_INPUTEVENT_TYPE_MOUSEUP
:
591 case PP_INPUTEVENT_TYPE_MOUSEMOVE
:
592 case PP_INPUTEVENT_TYPE_MOUSEENTER
:
593 case PP_INPUTEVENT_TYPE_MOUSELEAVE
:
594 case PP_INPUTEVENT_TYPE_CONTEXTMENU
:
595 web_input_event
.reset(BuildMouseEvent(event
));
597 case PP_INPUTEVENT_TYPE_WHEEL
:
598 web_input_event
.reset(BuildMouseWheelEvent(event
));
600 case PP_INPUTEVENT_TYPE_RAWKEYDOWN
:
601 case PP_INPUTEVENT_TYPE_KEYDOWN
:
602 case PP_INPUTEVENT_TYPE_KEYUP
:
603 web_input_event
.reset(BuildKeyEvent(event
));
605 case PP_INPUTEVENT_TYPE_CHAR
:
606 web_input_event
.reset(BuildCharEvent(event
));
608 case PP_INPUTEVENT_TYPE_IME_COMPOSITION_START
:
609 case PP_INPUTEVENT_TYPE_IME_COMPOSITION_UPDATE
:
610 case PP_INPUTEVENT_TYPE_IME_COMPOSITION_END
:
611 case PP_INPUTEVENT_TYPE_IME_TEXT
:
612 // TODO(kinaba) implement in WebKit an event structure to handle
613 // composition events.
616 case PP_INPUTEVENT_TYPE_TOUCHSTART
:
617 case PP_INPUTEVENT_TYPE_TOUCHMOVE
:
618 case PP_INPUTEVENT_TYPE_TOUCHEND
:
619 case PP_INPUTEVENT_TYPE_TOUCHCANCEL
:
620 web_input_event
.reset(BuildTouchEvent(event
));
624 return web_input_event
.release();
627 // Generate a coherent sequence of input events to simulate a user event.
628 // From src/content/shell/renderer/test_runner/event_sender.cc.
629 std::vector
<linked_ptr
<WebInputEvent
> > CreateSimulatedWebInputEvents(
630 const ppapi::InputEventData
& event
,
633 std::vector
<linked_ptr
<WebInputEvent
> > events
;
634 linked_ptr
<WebInputEvent
> original_event(CreateWebInputEvent(event
));
636 switch (event
.event_type
) {
637 case PP_INPUTEVENT_TYPE_MOUSEDOWN
:
638 case PP_INPUTEVENT_TYPE_MOUSEUP
:
639 case PP_INPUTEVENT_TYPE_MOUSEMOVE
:
640 case PP_INPUTEVENT_TYPE_MOUSEENTER
:
641 case PP_INPUTEVENT_TYPE_MOUSELEAVE
:
642 case PP_INPUTEVENT_TYPE_TOUCHSTART
:
643 case PP_INPUTEVENT_TYPE_TOUCHMOVE
:
644 case PP_INPUTEVENT_TYPE_TOUCHEND
:
645 case PP_INPUTEVENT_TYPE_TOUCHCANCEL
:
646 events
.push_back(original_event
);
649 case PP_INPUTEVENT_TYPE_WHEEL
: {
650 WebMouseWheelEvent
* web_mouse_wheel_event
=
651 static_cast<WebMouseWheelEvent
*>(original_event
.get());
652 web_mouse_wheel_event
->x
= plugin_x
;
653 web_mouse_wheel_event
->y
= plugin_y
;
654 events
.push_back(original_event
);
658 case PP_INPUTEVENT_TYPE_RAWKEYDOWN
:
659 case PP_INPUTEVENT_TYPE_KEYDOWN
:
660 case PP_INPUTEVENT_TYPE_KEYUP
: {
661 // Windows key down events should always be "raw" to avoid an ASSERT.
663 WebKeyboardEvent
* web_keyboard_event
=
664 static_cast<WebKeyboardEvent
*>(original_event
.get());
665 if (web_keyboard_event
->type
== WebInputEvent::KeyDown
)
666 web_keyboard_event
->type
= WebInputEvent::RawKeyDown
;
668 events
.push_back(original_event
);
672 case PP_INPUTEVENT_TYPE_CHAR
: {
673 WebKeyboardEvent
* web_char_event
=
674 static_cast<WebKeyboardEvent
*>(original_event
.get());
676 WebUChar code
= 0, text
= 0;
677 bool needs_shift_modifier
= false, generate_char
= false;
678 GetKeyCode(event
.character_text
,
681 &needs_shift_modifier
,
684 // Synthesize key down and key up events in all cases.
685 scoped_ptr
<WebKeyboardEvent
> key_down_event(new WebKeyboardEvent());
686 scoped_ptr
<WebKeyboardEvent
> key_up_event(new WebKeyboardEvent());
688 key_down_event
->type
= WebInputEvent::RawKeyDown
;
689 key_down_event
->windowsKeyCode
= code
;
690 key_down_event
->nativeKeyCode
= code
;
691 if (needs_shift_modifier
)
692 key_down_event
->modifiers
|= WebInputEvent::ShiftKey
;
694 // If a char event is needed, set the text fields.
696 key_down_event
->text
[0] = text
;
697 key_down_event
->unmodifiedText
[0] = text
;
699 // Convert the key code to a string identifier.
700 key_down_event
->setKeyIdentifierFromWindowsKeyCode();
702 *key_up_event
= *web_char_event
= *key_down_event
;
704 events
.push_back(linked_ptr
<WebInputEvent
>(key_down_event
.release()));
707 web_char_event
->type
= WebInputEvent::Char
;
708 web_char_event
->keyIdentifier
[0] = '\0';
709 events
.push_back(original_event
);
712 key_up_event
->type
= WebInputEvent::KeyUp
;
713 events
.push_back(linked_ptr
<WebInputEvent
>(key_up_event
.release()));
723 PP_InputEvent_Class
ClassifyInputEvent(WebInputEvent::Type type
) {
725 case WebInputEvent::MouseDown
:
726 case WebInputEvent::MouseUp
:
727 case WebInputEvent::MouseMove
:
728 case WebInputEvent::MouseEnter
:
729 case WebInputEvent::MouseLeave
:
730 case WebInputEvent::ContextMenu
:
731 return PP_INPUTEVENT_CLASS_MOUSE
;
732 case WebInputEvent::MouseWheel
:
733 return PP_INPUTEVENT_CLASS_WHEEL
;
734 case WebInputEvent::RawKeyDown
:
735 case WebInputEvent::KeyDown
:
736 case WebInputEvent::KeyUp
:
737 case WebInputEvent::Char
:
738 return PP_INPUTEVENT_CLASS_KEYBOARD
;
739 case WebInputEvent::TouchCancel
:
740 case WebInputEvent::TouchEnd
:
741 case WebInputEvent::TouchMove
:
742 case WebInputEvent::TouchStart
:
743 return PP_INPUTEVENT_CLASS_TOUCH
;
744 case WebInputEvent::Undefined
:
746 CHECK(WebInputEvent::isGestureEventType(type
));
747 return PP_InputEvent_Class(0);
751 } // namespace content