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 "ppapi/c/pp_input_event.h"
17 #include "ppapi/shared_impl/ppb_input_event_shared.h"
18 #include "ppapi/shared_impl/time_conversion.h"
19 #include "third_party/WebKit/public/platform/WebGamepads.h"
20 #include "third_party/WebKit/public/platform/WebString.h"
21 #include "third_party/WebKit/public/web/WebInputEvent.h"
22 #include "ui/events/keycodes/dom/keycode_converter.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 #if defined(OS_MACOSX)
139 // Workaround for |domCode| not being set on OS X. crbug.com/493833
140 result
.code
= ui::KeycodeConverter::DomCodeToCodeString(
141 ui::KeycodeConverter::NativeKeycodeToDomCode(key_event
.nativeKeyCode
));
143 result
.code
= ui::KeycodeConverter::DomCodeToCodeString(
144 static_cast<ui::DomCode
>(key_event
.domCode
));
146 result_events
->push_back(result
);
149 void AppendCharEvent(const WebInputEvent
& event
,
150 std::vector
<InputEventData
>* result_events
) {
151 const WebKeyboardEvent
& key_event
=
152 static_cast<const WebKeyboardEvent
&>(event
);
154 // This is a bit complex, the input event will normally just have one 16-bit
155 // character in it, but may be zero or more than one. The text array is
156 // just padded with 0 values for the unused ones, but is not necessarily
159 // Here we see how many UTF-16 characters we have.
160 size_t utf16_char_count
= 0;
161 while (utf16_char_count
< WebKeyboardEvent::textLengthCap
&&
162 key_event
.text
[utf16_char_count
])
165 // Make a separate InputEventData for each Unicode character in the input.
166 base::i18n::UTF16CharIterator
iter(key_event
.text
, utf16_char_count
);
167 while (!iter
.end()) {
168 InputEventData result
= GetEventWithCommonFieldsAndType(event
);
169 result
.event_modifiers
= key_event
.modifiers
;
170 base::WriteUnicodeCharacter(iter
.get(), &result
.character_text
);
172 result_events
->push_back(result
);
177 void AppendMouseEvent(const WebInputEvent
& event
,
178 std::vector
<InputEventData
>* result_events
) {
179 static_assert(static_cast<int>(WebMouseEvent::ButtonNone
) ==
180 static_cast<int>(PP_INPUTEVENT_MOUSEBUTTON_NONE
),
181 "MouseNone should match");
182 static_assert(static_cast<int>(WebMouseEvent::ButtonLeft
) ==
183 static_cast<int>(PP_INPUTEVENT_MOUSEBUTTON_LEFT
),
184 "MouseLeft should match");
185 static_assert(static_cast<int>(WebMouseEvent::ButtonRight
) ==
186 static_cast<int>(PP_INPUTEVENT_MOUSEBUTTON_RIGHT
),
187 "MouseRight should match");
188 static_assert(static_cast<int>(WebMouseEvent::ButtonMiddle
) ==
189 static_cast<int>(PP_INPUTEVENT_MOUSEBUTTON_MIDDLE
),
190 "MouseMiddle should match");
192 const WebMouseEvent
& mouse_event
= static_cast<const WebMouseEvent
&>(event
);
193 InputEventData result
= GetEventWithCommonFieldsAndType(event
);
194 result
.event_modifiers
= mouse_event
.modifiers
;
195 if (mouse_event
.type
== WebInputEvent::MouseDown
||
196 mouse_event
.type
== WebInputEvent::MouseMove
||
197 mouse_event
.type
== WebInputEvent::MouseUp
) {
198 result
.mouse_button
=
199 static_cast<PP_InputEvent_MouseButton
>(mouse_event
.button
);
201 result
.mouse_position
.x
= mouse_event
.x
;
202 result
.mouse_position
.y
= mouse_event
.y
;
203 result
.mouse_click_count
= mouse_event
.clickCount
;
204 result
.mouse_movement
.x
= mouse_event
.movementX
;
205 result
.mouse_movement
.y
= mouse_event
.movementY
;
206 result_events
->push_back(result
);
209 void AppendMouseWheelEvent(const WebInputEvent
& event
,
210 std::vector
<InputEventData
>* result_events
) {
211 const WebMouseWheelEvent
& mouse_wheel_event
=
212 static_cast<const WebMouseWheelEvent
&>(event
);
213 InputEventData result
= GetEventWithCommonFieldsAndType(event
);
214 result
.event_modifiers
= mouse_wheel_event
.modifiers
;
215 result
.wheel_delta
.x
= mouse_wheel_event
.deltaX
;
216 result
.wheel_delta
.y
= mouse_wheel_event
.deltaY
;
217 result
.wheel_ticks
.x
= mouse_wheel_event
.wheelTicksX
;
218 result
.wheel_ticks
.y
= mouse_wheel_event
.wheelTicksY
;
219 result
.wheel_scroll_by_page
= !!mouse_wheel_event
.scrollByPage
;
220 result_events
->push_back(result
);
223 enum IncludedTouchPointTypes
{
224 ALL
, // All pointers targetting the plugin.
225 ACTIVE
, // Only pointers that are currently down.
226 CHANGED
// Only pointers that have changed since the previous event.
228 void SetPPTouchPoints(const WebTouchPoint
* touches
,
229 uint32_t touches_length
,
230 IncludedTouchPointTypes included_types
,
231 std::vector
<PP_TouchPoint
>* result
) {
232 for (uint32_t i
= 0; i
< touches_length
; i
++) {
233 const WebTouchPoint
& touch_point
= touches
[i
];
234 if (included_types
== ACTIVE
&&
235 (touch_point
.state
== WebTouchPoint::StateReleased
||
236 touch_point
.state
== WebTouchPoint::StateCancelled
)) {
239 if (included_types
== CHANGED
&&
240 (touch_point
.state
== WebTouchPoint::StateUndefined
||
241 touch_point
.state
== WebTouchPoint::StateStationary
)) {
245 pp_pt
.id
= touch_point
.id
;
246 pp_pt
.position
.x
= touch_point
.position
.x
;
247 pp_pt
.position
.y
= touch_point
.position
.y
;
248 pp_pt
.radius
.x
= touch_point
.radiusX
;
249 pp_pt
.radius
.y
= touch_point
.radiusY
;
250 pp_pt
.rotation_angle
= touch_point
.rotationAngle
;
251 pp_pt
.pressure
= touch_point
.force
;
252 result
->push_back(pp_pt
);
256 void AppendTouchEvent(const WebInputEvent
& event
,
257 std::vector
<InputEventData
>* result_events
) {
258 const WebTouchEvent
& touch_event
=
259 reinterpret_cast<const WebTouchEvent
&>(event
);
261 InputEventData result
= GetEventWithCommonFieldsAndType(event
);
263 touch_event
.touches
, touch_event
.touchesLength
, ACTIVE
, &result
.touches
);
264 SetPPTouchPoints(touch_event
.touches
,
265 touch_event
.touchesLength
,
267 &result
.changed_touches
);
268 SetPPTouchPoints(touch_event
.touches
,
269 touch_event
.touchesLength
,
271 &result
.target_touches
);
273 result_events
->push_back(result
);
276 WebTouchPoint
CreateWebTouchPoint(const PP_TouchPoint
& pp_pt
,
277 WebTouchPoint::State state
) {
280 pt
.position
.x
= pp_pt
.position
.x
;
281 pt
.position
.y
= pp_pt
.position
.y
;
282 // TODO bug:http://code.google.com/p/chromium/issues/detail?id=93902
283 pt
.screenPosition
.x
= 0;
284 pt
.screenPosition
.y
= 0;
285 pt
.force
= pp_pt
.pressure
;
286 pt
.radiusX
= pp_pt
.radius
.x
;
287 pt
.radiusY
= pp_pt
.radius
.y
;
288 pt
.rotationAngle
= pp_pt
.rotation_angle
;
293 bool HasTouchPointWithId(const WebTouchPoint
* web_touches
,
294 uint32_t web_touches_length
,
296 // Note: A brute force search to find the (potentially) existing touch point
297 // is cheap given the small bound on |WebTouchEvent::touchesLengthCap|.
298 for (uint32_t i
= 0; i
< web_touches_length
; ++i
) {
299 if (web_touches
[i
].id
== static_cast<int>(id
))
305 void SetWebTouchPointsIfNotYetSet(const std::vector
<PP_TouchPoint
>& pp_touches
,
306 WebTouchPoint::State state
,
307 WebTouchPoint
* web_touches
,
308 uint32_t* web_touches_length
) {
309 const uint32_t initial_web_touches_length
= *web_touches_length
;
310 const uint32_t touches_length
=
311 std::min(static_cast<uint32_t>(pp_touches
.size()),
312 static_cast<uint32_t>(WebTouchEvent::touchesLengthCap
));
313 for (uint32_t i
= 0; i
< touches_length
; ++i
) {
314 const uint32_t touch_index
= *web_touches_length
;
315 if (touch_index
>= static_cast<uint32_t>(WebTouchEvent::touchesLengthCap
))
318 const PP_TouchPoint
& pp_pt
= pp_touches
[i
];
319 if (HasTouchPointWithId(web_touches
, initial_web_touches_length
, pp_pt
.id
))
322 web_touches
[touch_index
] = CreateWebTouchPoint(pp_pt
, state
);
323 ++(*web_touches_length
);
327 WebTouchEvent
* BuildTouchEvent(const InputEventData
& event
) {
328 WebTouchEvent
* web_event
= new WebTouchEvent();
329 WebTouchPoint::State state
= WebTouchPoint::StateUndefined
;
330 WebInputEvent::Type type
= WebInputEvent::Undefined
;
331 switch (event
.event_type
) {
332 case PP_INPUTEVENT_TYPE_TOUCHSTART
:
333 type
= WebInputEvent::TouchStart
;
334 state
= WebTouchPoint::StatePressed
;
336 case PP_INPUTEVENT_TYPE_TOUCHMOVE
:
337 type
= WebInputEvent::TouchMove
;
338 state
= WebTouchPoint::StateMoved
;
340 case PP_INPUTEVENT_TYPE_TOUCHEND
:
341 type
= WebInputEvent::TouchEnd
;
342 state
= WebTouchPoint::StateReleased
;
344 case PP_INPUTEVENT_TYPE_TOUCHCANCEL
:
345 type
= WebInputEvent::TouchCancel
;
346 state
= WebTouchPoint::StateCancelled
;
351 WebTouchEventTraits::ResetType(
352 type
, PPTimeTicksToEventTime(event
.event_time_stamp
), web_event
);
353 web_event
->touchesLength
= 0;
355 // First add all changed touches, then add only the remaining unset
356 // (stationary) touches.
357 SetWebTouchPointsIfNotYetSet(event
.changed_touches
,
360 &web_event
->touchesLength
);
361 SetWebTouchPointsIfNotYetSet(event
.touches
,
362 WebTouchPoint::StateStationary
,
364 &web_event
->touchesLength
);
369 WebKeyboardEvent
* BuildKeyEvent(const InputEventData
& event
) {
370 WebKeyboardEvent
* key_event
= new WebKeyboardEvent();
371 switch (event
.event_type
) {
372 case PP_INPUTEVENT_TYPE_RAWKEYDOWN
:
373 key_event
->type
= WebInputEvent::RawKeyDown
;
375 case PP_INPUTEVENT_TYPE_KEYDOWN
:
376 key_event
->type
= WebInputEvent::KeyDown
;
378 case PP_INPUTEVENT_TYPE_KEYUP
:
379 key_event
->type
= WebInputEvent::KeyUp
;
384 key_event
->timeStampSeconds
= PPTimeTicksToEventTime(event
.event_time_stamp
);
385 key_event
->modifiers
= event
.event_modifiers
;
386 key_event
->windowsKeyCode
= event
.key_code
;
387 key_event
->setKeyIdentifierFromWindowsKeyCode();
391 WebKeyboardEvent
* BuildCharEvent(const InputEventData
& event
) {
392 WebKeyboardEvent
* key_event
= new WebKeyboardEvent();
393 key_event
->type
= WebInputEvent::Char
;
394 key_event
->timeStampSeconds
= PPTimeTicksToEventTime(event
.event_time_stamp
);
395 key_event
->modifiers
= event
.event_modifiers
;
397 // Make sure to not read beyond the buffer in case some bad code doesn't
398 // NULL-terminate it (this is called from plugins).
399 size_t text_length_cap
= WebKeyboardEvent::textLengthCap
;
400 base::string16 text16
= base::UTF8ToUTF16(event
.character_text
);
402 memset(key_event
->text
, 0, text_length_cap
);
403 memset(key_event
->unmodifiedText
, 0, text_length_cap
);
404 for (size_t i
= 0; i
< std::min(text_length_cap
, text16
.size()); ++i
)
405 key_event
->text
[i
] = text16
[i
];
409 WebMouseEvent
* BuildMouseEvent(const InputEventData
& event
) {
410 WebMouseEvent
* mouse_event
= new WebMouseEvent();
411 switch (event
.event_type
) {
412 case PP_INPUTEVENT_TYPE_MOUSEDOWN
:
413 mouse_event
->type
= WebInputEvent::MouseDown
;
415 case PP_INPUTEVENT_TYPE_MOUSEUP
:
416 mouse_event
->type
= WebInputEvent::MouseUp
;
418 case PP_INPUTEVENT_TYPE_MOUSEMOVE
:
419 mouse_event
->type
= WebInputEvent::MouseMove
;
421 case PP_INPUTEVENT_TYPE_MOUSEENTER
:
422 mouse_event
->type
= WebInputEvent::MouseEnter
;
424 case PP_INPUTEVENT_TYPE_MOUSELEAVE
:
425 mouse_event
->type
= WebInputEvent::MouseLeave
;
427 case PP_INPUTEVENT_TYPE_CONTEXTMENU
:
428 mouse_event
->type
= WebInputEvent::ContextMenu
;
433 mouse_event
->timeStampSeconds
=
434 PPTimeTicksToEventTime(event
.event_time_stamp
);
435 mouse_event
->modifiers
= event
.event_modifiers
;
436 mouse_event
->button
= static_cast<WebMouseEvent::Button
>(event
.mouse_button
);
437 if (mouse_event
->type
== WebInputEvent::MouseMove
) {
438 if (mouse_event
->modifiers
& WebInputEvent::LeftButtonDown
)
439 mouse_event
->button
= WebMouseEvent::ButtonLeft
;
440 else if (mouse_event
->modifiers
& WebInputEvent::MiddleButtonDown
)
441 mouse_event
->button
= WebMouseEvent::ButtonMiddle
;
442 else if (mouse_event
->modifiers
& WebInputEvent::RightButtonDown
)
443 mouse_event
->button
= WebMouseEvent::ButtonRight
;
445 mouse_event
->x
= event
.mouse_position
.x
;
446 mouse_event
->y
= event
.mouse_position
.y
;
447 mouse_event
->clickCount
= event
.mouse_click_count
;
448 mouse_event
->movementX
= event
.mouse_movement
.x
;
449 mouse_event
->movementY
= event
.mouse_movement
.y
;
453 WebMouseWheelEvent
* BuildMouseWheelEvent(const InputEventData
& event
) {
454 WebMouseWheelEvent
* mouse_wheel_event
= new WebMouseWheelEvent();
455 mouse_wheel_event
->type
= WebInputEvent::MouseWheel
;
456 mouse_wheel_event
->timeStampSeconds
=
457 PPTimeTicksToEventTime(event
.event_time_stamp
);
458 mouse_wheel_event
->modifiers
= event
.event_modifiers
;
459 mouse_wheel_event
->deltaX
= event
.wheel_delta
.x
;
460 mouse_wheel_event
->deltaY
= event
.wheel_delta
.y
;
461 mouse_wheel_event
->wheelTicksX
= event
.wheel_ticks
.x
;
462 mouse_wheel_event
->wheelTicksY
= event
.wheel_ticks
.y
;
463 mouse_wheel_event
->scrollByPage
= event
.wheel_scroll_by_page
;
464 return mouse_wheel_event
;
468 #define VK_RETURN 0x0D
470 #define VK_PRIOR 0x21
476 #define VK_RIGHT 0x27
478 #define VK_SNAPSHOT 0x2C
479 #define VK_INSERT 0x2D
480 #define VK_DELETE 0x2E
487 // Convert a character string to a Windows virtual key code. Adapted from
488 // src/components/test_runner/event_sender.cc. This
489 // is used by CreateSimulatedWebInputEvents to convert keyboard events.
490 void GetKeyCode(const std::string
& char_text
,
493 bool* needs_shift_modifier
,
494 bool* generate_char
) {
495 WebUChar vk_code
= 0;
496 WebUChar vk_text
= 0;
497 *needs_shift_modifier
= false;
498 *generate_char
= false;
499 if ("\n" == char_text
) {
500 vk_text
= vk_code
= VK_RETURN
;
501 *generate_char
= true;
502 } else if ("rightArrow" == char_text
) {
504 } else if ("downArrow" == char_text
) {
506 } else if ("leftArrow" == char_text
) {
508 } else if ("upArrow" == char_text
) {
510 } else if ("insert" == char_text
) {
512 } else if ("delete" == char_text
) {
514 } else if ("pageUp" == char_text
) {
516 } else if ("pageDown" == char_text
) {
518 } else if ("home" == char_text
) {
520 } else if ("end" == char_text
) {
522 } else if ("printScreen" == char_text
) {
523 vk_code
= VK_SNAPSHOT
;
524 } else if ("menu" == char_text
) {
527 // Compare the input string with the function-key names defined by the
528 // DOM spec (i.e. "F1",...,"F24").
529 for (int i
= 1; i
<= 24; ++i
) {
530 std::string functionKeyName
= base::StringPrintf("F%d", i
);
531 if (functionKeyName
== char_text
) {
532 vk_code
= VK_F1
+ (i
- 1);
537 WebString web_char_text
=
538 WebString::fromUTF8(char_text
.data(), char_text
.size());
539 DCHECK_EQ(web_char_text
.length(), 1U);
540 vk_text
= vk_code
= web_char_text
.at(0);
541 *needs_shift_modifier
=
542 (vk_code
& 0xFF) >= 'A' && (vk_code
& 0xFF) <= 'Z';
543 if ((vk_code
& 0xFF) >= 'a' && (vk_code
& 0xFF) <= 'z')
544 vk_code
-= 'a' - 'A';
545 *generate_char
= true;
555 void CreateInputEventData(const WebInputEvent
& event
,
556 std::vector
<InputEventData
>* result
) {
559 switch (event
.type
) {
560 case WebInputEvent::MouseDown
:
561 case WebInputEvent::MouseUp
:
562 case WebInputEvent::MouseMove
:
563 case WebInputEvent::MouseEnter
:
564 case WebInputEvent::MouseLeave
:
565 case WebInputEvent::ContextMenu
:
566 AppendMouseEvent(event
, result
);
568 case WebInputEvent::MouseWheel
:
569 AppendMouseWheelEvent(event
, result
);
571 case WebInputEvent::RawKeyDown
:
572 case WebInputEvent::KeyDown
:
573 case WebInputEvent::KeyUp
:
574 AppendKeyEvent(event
, result
);
576 case WebInputEvent::Char
:
577 AppendCharEvent(event
, result
);
579 case WebInputEvent::TouchStart
:
580 case WebInputEvent::TouchMove
:
581 case WebInputEvent::TouchEnd
:
582 case WebInputEvent::TouchCancel
:
583 AppendTouchEvent(event
, result
);
585 case WebInputEvent::Undefined
:
591 WebInputEvent
* CreateWebInputEvent(const InputEventData
& event
) {
592 scoped_ptr
<WebInputEvent
> web_input_event
;
593 switch (event
.event_type
) {
594 case PP_INPUTEVENT_TYPE_UNDEFINED
:
596 case PP_INPUTEVENT_TYPE_MOUSEDOWN
:
597 case PP_INPUTEVENT_TYPE_MOUSEUP
:
598 case PP_INPUTEVENT_TYPE_MOUSEMOVE
:
599 case PP_INPUTEVENT_TYPE_MOUSEENTER
:
600 case PP_INPUTEVENT_TYPE_MOUSELEAVE
:
601 case PP_INPUTEVENT_TYPE_CONTEXTMENU
:
602 web_input_event
.reset(BuildMouseEvent(event
));
604 case PP_INPUTEVENT_TYPE_WHEEL
:
605 web_input_event
.reset(BuildMouseWheelEvent(event
));
607 case PP_INPUTEVENT_TYPE_RAWKEYDOWN
:
608 case PP_INPUTEVENT_TYPE_KEYDOWN
:
609 case PP_INPUTEVENT_TYPE_KEYUP
:
610 web_input_event
.reset(BuildKeyEvent(event
));
612 case PP_INPUTEVENT_TYPE_CHAR
:
613 web_input_event
.reset(BuildCharEvent(event
));
615 case PP_INPUTEVENT_TYPE_IME_COMPOSITION_START
:
616 case PP_INPUTEVENT_TYPE_IME_COMPOSITION_UPDATE
:
617 case PP_INPUTEVENT_TYPE_IME_COMPOSITION_END
:
618 case PP_INPUTEVENT_TYPE_IME_TEXT
:
619 // TODO(kinaba) implement in WebKit an event structure to handle
620 // composition events.
623 case PP_INPUTEVENT_TYPE_TOUCHSTART
:
624 case PP_INPUTEVENT_TYPE_TOUCHMOVE
:
625 case PP_INPUTEVENT_TYPE_TOUCHEND
:
626 case PP_INPUTEVENT_TYPE_TOUCHCANCEL
:
627 web_input_event
.reset(BuildTouchEvent(event
));
631 return web_input_event
.release();
634 // Generate a coherent sequence of input events to simulate a user event.
635 // From src/components/test_runner/event_sender.cc.
636 std::vector
<linked_ptr
<WebInputEvent
> > CreateSimulatedWebInputEvents(
637 const ppapi::InputEventData
& event
,
640 std::vector
<linked_ptr
<WebInputEvent
> > events
;
641 linked_ptr
<WebInputEvent
> original_event(CreateWebInputEvent(event
));
643 switch (event
.event_type
) {
644 case PP_INPUTEVENT_TYPE_MOUSEDOWN
:
645 case PP_INPUTEVENT_TYPE_MOUSEUP
:
646 case PP_INPUTEVENT_TYPE_MOUSEMOVE
:
647 case PP_INPUTEVENT_TYPE_MOUSEENTER
:
648 case PP_INPUTEVENT_TYPE_MOUSELEAVE
:
649 case PP_INPUTEVENT_TYPE_TOUCHSTART
:
650 case PP_INPUTEVENT_TYPE_TOUCHMOVE
:
651 case PP_INPUTEVENT_TYPE_TOUCHEND
:
652 case PP_INPUTEVENT_TYPE_TOUCHCANCEL
:
653 events
.push_back(original_event
);
656 case PP_INPUTEVENT_TYPE_WHEEL
: {
657 WebMouseWheelEvent
* web_mouse_wheel_event
=
658 static_cast<WebMouseWheelEvent
*>(original_event
.get());
659 web_mouse_wheel_event
->x
= plugin_x
;
660 web_mouse_wheel_event
->y
= plugin_y
;
661 events
.push_back(original_event
);
665 case PP_INPUTEVENT_TYPE_RAWKEYDOWN
:
666 case PP_INPUTEVENT_TYPE_KEYDOWN
:
667 case PP_INPUTEVENT_TYPE_KEYUP
: {
668 // Windows key down events should always be "raw" to avoid an ASSERT.
670 WebKeyboardEvent
* web_keyboard_event
=
671 static_cast<WebKeyboardEvent
*>(original_event
.get());
672 if (web_keyboard_event
->type
== WebInputEvent::KeyDown
)
673 web_keyboard_event
->type
= WebInputEvent::RawKeyDown
;
675 events
.push_back(original_event
);
679 case PP_INPUTEVENT_TYPE_CHAR
: {
680 WebKeyboardEvent
* web_char_event
=
681 static_cast<WebKeyboardEvent
*>(original_event
.get());
683 WebUChar code
= 0, text
= 0;
684 bool needs_shift_modifier
= false, generate_char
= false;
685 GetKeyCode(event
.character_text
,
688 &needs_shift_modifier
,
691 // Synthesize key down and key up events in all cases.
692 scoped_ptr
<WebKeyboardEvent
> key_down_event(new WebKeyboardEvent());
693 scoped_ptr
<WebKeyboardEvent
> key_up_event(new WebKeyboardEvent());
695 key_down_event
->type
= WebInputEvent::RawKeyDown
;
696 key_down_event
->windowsKeyCode
= code
;
697 key_down_event
->nativeKeyCode
= code
;
698 if (needs_shift_modifier
)
699 key_down_event
->modifiers
|= WebInputEvent::ShiftKey
;
701 // If a char event is needed, set the text fields.
703 key_down_event
->text
[0] = text
;
704 key_down_event
->unmodifiedText
[0] = text
;
706 // Convert the key code to a string identifier.
707 key_down_event
->setKeyIdentifierFromWindowsKeyCode();
709 *key_up_event
= *web_char_event
= *key_down_event
;
711 events
.push_back(linked_ptr
<WebInputEvent
>(key_down_event
.release()));
714 web_char_event
->type
= WebInputEvent::Char
;
715 web_char_event
->keyIdentifier
[0] = '\0';
716 events
.push_back(original_event
);
719 key_up_event
->type
= WebInputEvent::KeyUp
;
720 events
.push_back(linked_ptr
<WebInputEvent
>(key_up_event
.release()));
730 PP_InputEvent_Class
ClassifyInputEvent(WebInputEvent::Type type
) {
732 case WebInputEvent::MouseDown
:
733 case WebInputEvent::MouseUp
:
734 case WebInputEvent::MouseMove
:
735 case WebInputEvent::MouseEnter
:
736 case WebInputEvent::MouseLeave
:
737 case WebInputEvent::ContextMenu
:
738 return PP_INPUTEVENT_CLASS_MOUSE
;
739 case WebInputEvent::MouseWheel
:
740 return PP_INPUTEVENT_CLASS_WHEEL
;
741 case WebInputEvent::RawKeyDown
:
742 case WebInputEvent::KeyDown
:
743 case WebInputEvent::KeyUp
:
744 case WebInputEvent::Char
:
745 return PP_INPUTEVENT_CLASS_KEYBOARD
;
746 case WebInputEvent::TouchCancel
:
747 case WebInputEvent::TouchEnd
:
748 case WebInputEvent::TouchMove
:
749 case WebInputEvent::TouchStart
:
750 return PP_INPUTEVENT_CLASS_TOUCH
;
751 case WebInputEvent::Undefined
:
753 CHECK(WebInputEvent::isGestureEventType(type
));
754 return PP_InputEvent_Class(0);
758 } // namespace content