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/common.h"
19 #include "content/renderer/pepper/usb_key_code_conversion.h"
20 #include "ppapi/c/pp_input_event.h"
21 #include "ppapi/shared_impl/ppb_input_event_shared.h"
22 #include "ppapi/shared_impl/time_conversion.h"
23 #include "third_party/WebKit/public/platform/WebGamepads.h"
24 #include "third_party/WebKit/public/platform/WebString.h"
25 #include "third_party/WebKit/public/web/WebInputEvent.h"
27 using ppapi::EventTimeToPPTimeTicks;
28 using ppapi::InputEventData;
29 using ppapi::PPTimeTicksToEventTime;
30 using blink::WebInputEvent;
31 using blink::WebKeyboardEvent;
32 using blink::WebMouseEvent;
33 using blink::WebMouseWheelEvent;
34 using blink::WebString;
35 using blink::WebTouchEvent;
36 using blink::WebTouchPoint;
37 using blink::WebUChar;
43 // Verify the modifier flags WebKit uses match the Pepper ones. If these start
44 // not matching, we'll need to write conversion code to preserve the Pepper
45 // values (since plugins will be depending on them).
46 COMPILE_ASSERT(static_cast<int>(PP_INPUTEVENT_MODIFIER_SHIFTKEY) ==
47 static_cast<int>(WebInputEvent::ShiftKey),
49 COMPILE_ASSERT(static_cast<int>(PP_INPUTEVENT_MODIFIER_CONTROLKEY) ==
50 static_cast<int>(WebInputEvent::ControlKey),
52 COMPILE_ASSERT(static_cast<int>(PP_INPUTEVENT_MODIFIER_ALTKEY) ==
53 static_cast<int>(WebInputEvent::AltKey),
55 COMPILE_ASSERT(static_cast<int>(PP_INPUTEVENT_MODIFIER_METAKEY) ==
56 static_cast<int>(WebInputEvent::MetaKey),
58 COMPILE_ASSERT(static_cast<int>(PP_INPUTEVENT_MODIFIER_ISKEYPAD) ==
59 static_cast<int>(WebInputEvent::IsKeyPad),
61 COMPILE_ASSERT(static_cast<int>(PP_INPUTEVENT_MODIFIER_ISAUTOREPEAT) ==
62 static_cast<int>(WebInputEvent::IsAutoRepeat),
64 COMPILE_ASSERT(static_cast<int>(PP_INPUTEVENT_MODIFIER_LEFTBUTTONDOWN) ==
65 static_cast<int>(WebInputEvent::LeftButtonDown),
67 COMPILE_ASSERT(static_cast<int>(PP_INPUTEVENT_MODIFIER_MIDDLEBUTTONDOWN) ==
68 static_cast<int>(WebInputEvent::MiddleButtonDown),
70 COMPILE_ASSERT(static_cast<int>(PP_INPUTEVENT_MODIFIER_RIGHTBUTTONDOWN) ==
71 static_cast<int>(WebInputEvent::RightButtonDown),
73 COMPILE_ASSERT(static_cast<int>(PP_INPUTEVENT_MODIFIER_CAPSLOCKKEY) ==
74 static_cast<int>(WebInputEvent::CapsLockOn),
76 COMPILE_ASSERT(static_cast<int>(PP_INPUTEVENT_MODIFIER_NUMLOCKKEY) ==
77 static_cast<int>(WebInputEvent::NumLockOn),
79 COMPILE_ASSERT(static_cast<int>(PP_INPUTEVENT_MODIFIER_ISLEFT) ==
80 static_cast<int>(WebInputEvent::IsLeft),
82 COMPILE_ASSERT(static_cast<int>(PP_INPUTEVENT_MODIFIER_ISRIGHT) ==
83 static_cast<int>(WebInputEvent::IsRight),
86 PP_InputEvent_Type ConvertEventTypes(WebInputEvent::Type wetype) {
88 case WebInputEvent::MouseDown:
89 return PP_INPUTEVENT_TYPE_MOUSEDOWN;
90 case WebInputEvent::MouseUp:
91 return PP_INPUTEVENT_TYPE_MOUSEUP;
92 case WebInputEvent::MouseMove:
93 return PP_INPUTEVENT_TYPE_MOUSEMOVE;
94 case WebInputEvent::MouseEnter:
95 return PP_INPUTEVENT_TYPE_MOUSEENTER;
96 case WebInputEvent::MouseLeave:
97 return PP_INPUTEVENT_TYPE_MOUSELEAVE;
98 case WebInputEvent::ContextMenu:
99 return PP_INPUTEVENT_TYPE_CONTEXTMENU;
100 case WebInputEvent::MouseWheel:
101 return PP_INPUTEVENT_TYPE_WHEEL;
102 case WebInputEvent::RawKeyDown:
103 return PP_INPUTEVENT_TYPE_RAWKEYDOWN;
104 case WebInputEvent::KeyDown:
105 return PP_INPUTEVENT_TYPE_KEYDOWN;
106 case WebInputEvent::KeyUp:
107 return PP_INPUTEVENT_TYPE_KEYUP;
108 case WebInputEvent::Char:
109 return PP_INPUTEVENT_TYPE_CHAR;
110 case WebInputEvent::TouchStart:
111 return PP_INPUTEVENT_TYPE_TOUCHSTART;
112 case WebInputEvent::TouchMove:
113 return PP_INPUTEVENT_TYPE_TOUCHMOVE;
114 case WebInputEvent::TouchEnd:
115 return PP_INPUTEVENT_TYPE_TOUCHEND;
116 case WebInputEvent::TouchCancel:
117 return PP_INPUTEVENT_TYPE_TOUCHCANCEL;
118 case WebInputEvent::Undefined:
120 return PP_INPUTEVENT_TYPE_UNDEFINED;
124 // Generates a PP_InputEvent with the fields common to all events, as well as
125 // the event type from the given web event. Event-specific fields will be zero
127 InputEventData GetEventWithCommonFieldsAndType(const WebInputEvent& web_event) {
128 InputEventData result;
129 result.event_type = ConvertEventTypes(web_event.type);
130 result.event_time_stamp = EventTimeToPPTimeTicks(web_event.timeStampSeconds);
134 void AppendKeyEvent(const WebInputEvent& event,
135 std::vector<InputEventData>* result_events) {
136 const WebKeyboardEvent& key_event =
137 static_cast<const WebKeyboardEvent&>(event);
138 InputEventData result = GetEventWithCommonFieldsAndType(event);
139 result.event_modifiers = key_event.modifiers;
140 result.key_code = key_event.windowsKeyCode;
141 result.code = CodeForKeyboardEvent(key_event);
142 result_events->push_back(result);
145 void AppendCharEvent(const WebInputEvent& event,
146 std::vector<InputEventData>* result_events) {
147 const WebKeyboardEvent& key_event =
148 static_cast<const WebKeyboardEvent&>(event);
150 // This is a bit complex, the input event will normally just have one 16-bit
151 // character in it, but may be zero or more than one. The text array is
152 // just padded with 0 values for the unused ones, but is not necessarily
155 // Here we see how many UTF-16 characters we have.
156 size_t utf16_char_count = 0;
157 while (utf16_char_count < WebKeyboardEvent::textLengthCap &&
158 key_event.text[utf16_char_count])
161 // Make a separate InputEventData for each Unicode character in the input.
162 base::i18n::UTF16CharIterator iter(key_event.text, utf16_char_count);
163 while (!iter.end()) {
164 InputEventData result = GetEventWithCommonFieldsAndType(event);
165 result.event_modifiers = key_event.modifiers;
166 base::WriteUnicodeCharacter(iter.get(), &result.character_text);
168 result_events->push_back(result);
173 void AppendMouseEvent(const WebInputEvent& event,
174 std::vector<InputEventData>* result_events) {
175 COMPILE_ASSERT(static_cast<int>(WebMouseEvent::ButtonNone) ==
176 static_cast<int>(PP_INPUTEVENT_MOUSEBUTTON_NONE),
178 COMPILE_ASSERT(static_cast<int>(WebMouseEvent::ButtonLeft) ==
179 static_cast<int>(PP_INPUTEVENT_MOUSEBUTTON_LEFT),
181 COMPILE_ASSERT(static_cast<int>(WebMouseEvent::ButtonRight) ==
182 static_cast<int>(PP_INPUTEVENT_MOUSEBUTTON_RIGHT),
184 COMPILE_ASSERT(static_cast<int>(WebMouseEvent::ButtonMiddle) ==
185 static_cast<int>(PP_INPUTEVENT_MOUSEBUTTON_MIDDLE),
188 const WebMouseEvent& mouse_event = static_cast<const WebMouseEvent&>(event);
189 InputEventData result = GetEventWithCommonFieldsAndType(event);
190 result.event_modifiers = mouse_event.modifiers;
191 if (mouse_event.type == WebInputEvent::MouseDown ||
192 mouse_event.type == WebInputEvent::MouseMove ||
193 mouse_event.type == WebInputEvent::MouseUp) {
194 result.mouse_button =
195 static_cast<PP_InputEvent_MouseButton>(mouse_event.button);
197 result.mouse_position.x = mouse_event.x;
198 result.mouse_position.y = mouse_event.y;
199 result.mouse_click_count = mouse_event.clickCount;
200 result.mouse_movement.x = mouse_event.movementX;
201 result.mouse_movement.y = mouse_event.movementY;
202 result_events->push_back(result);
205 void AppendMouseWheelEvent(const WebInputEvent& event,
206 std::vector<InputEventData>* result_events) {
207 const WebMouseWheelEvent& mouse_wheel_event =
208 static_cast<const WebMouseWheelEvent&>(event);
209 InputEventData result = GetEventWithCommonFieldsAndType(event);
210 result.event_modifiers = mouse_wheel_event.modifiers;
211 result.wheel_delta.x = mouse_wheel_event.deltaX;
212 result.wheel_delta.y = mouse_wheel_event.deltaY;
213 result.wheel_ticks.x = mouse_wheel_event.wheelTicksX;
214 result.wheel_ticks.y = mouse_wheel_event.wheelTicksY;
215 result.wheel_scroll_by_page = !!mouse_wheel_event.scrollByPage;
216 result_events->push_back(result);
219 void SetPPTouchPoints(const WebTouchPoint* touches,
220 uint32_t touches_length,
221 std::vector<PP_TouchPoint>* result) {
222 for (uint32_t i = 0; i < touches_length; i++) {
223 const WebTouchPoint& touch_point = touches[i];
225 pp_pt.id = touch_point.id;
226 pp_pt.position.x = touch_point.position.x;
227 pp_pt.position.y = touch_point.position.y;
228 pp_pt.radius.x = touch_point.radiusX;
229 pp_pt.radius.y = touch_point.radiusY;
230 pp_pt.rotation_angle = touch_point.rotationAngle;
231 pp_pt.pressure = touch_point.force;
232 result->push_back(pp_pt);
236 void AppendTouchEvent(const WebInputEvent& event,
237 std::vector<InputEventData>* result_events) {
238 const WebTouchEvent& touch_event =
239 reinterpret_cast<const WebTouchEvent&>(event);
241 InputEventData result = GetEventWithCommonFieldsAndType(event);
243 touch_event.touches, touch_event.touchesLength, &result.touches);
244 SetPPTouchPoints(touch_event.changedTouches,
245 touch_event.changedTouchesLength,
246 &result.changed_touches);
247 SetPPTouchPoints(touch_event.targetTouches,
248 touch_event.targetTouchesLength,
249 &result.target_touches);
251 result_events->push_back(result);
254 // Structure used to map touch point id's to touch states. Since the pepper
255 // touch event structure does not have states for individual touch points and
256 // instead relies on the event type in combination with the set of touch lists,
257 // we have to set the state for the changed touches to be the same as the event
258 // type and all others to be 'stationary.'
259 typedef std::map<uint32_t, WebTouchPoint::State> TouchStateMap;
261 void SetWebTouchPoints(const std::vector<PP_TouchPoint>& pp_touches,
262 const TouchStateMap& states_map,
263 WebTouchPoint* web_touches,
264 uint32_t* web_touches_length) {
267 i < pp_touches.size() && i < WebTouchEvent::touchesLengthCap;
270 const PP_TouchPoint& pp_pt = pp_touches[i];
273 if (states_map.find(pt.id) == states_map.end())
274 pt.state = WebTouchPoint::StateStationary;
276 pt.state = states_map.find(pt.id)->second;
278 pt.position.x = pp_pt.position.x;
279 pt.position.y = pp_pt.position.y;
280 // TODO bug:http://code.google.com/p/chromium/issues/detail?id=93902
281 pt.screenPosition.x = 0;
282 pt.screenPosition.y = 0;
283 pt.force = pp_pt.pressure;
284 pt.radiusX = pp_pt.radius.x;
285 pt.radiusY = pp_pt.radius.y;
286 pt.rotationAngle = pp_pt.rotation_angle;
288 (*web_touches_length)++;
292 WebTouchEvent* BuildTouchEvent(const InputEventData& event) {
293 WebTouchEvent* web_event = new WebTouchEvent();
294 WebTouchPoint::State state = WebTouchPoint::StateUndefined;
295 WebInputEvent::Type type = WebInputEvent::Undefined;
296 switch (event.event_type) {
297 case PP_INPUTEVENT_TYPE_TOUCHSTART:
298 type = WebInputEvent::TouchStart;
299 state = WebTouchPoint::StatePressed;
301 case PP_INPUTEVENT_TYPE_TOUCHMOVE:
302 type = WebInputEvent::TouchMove;
303 state = WebTouchPoint::StateMoved;
305 case PP_INPUTEVENT_TYPE_TOUCHEND:
306 type = WebInputEvent::TouchEnd;
307 state = WebTouchPoint::StateReleased;
309 case PP_INPUTEVENT_TYPE_TOUCHCANCEL:
310 type = WebInputEvent::TouchCancel;
311 state = WebTouchPoint::StateCancelled;
316 WebTouchEventTraits::ResetType(
317 type, PPTimeTicksToEventTime(event.event_time_stamp), web_event);
319 TouchStateMap states_map;
320 for (uint32_t i = 0; i < event.changed_touches.size(); i++)
321 states_map[event.changed_touches[i].id] = state;
323 SetWebTouchPoints(event.changed_touches,
325 web_event->changedTouches,
326 &web_event->changedTouchesLength);
329 event.touches, states_map, web_event->touches, &web_event->touchesLength);
331 SetWebTouchPoints(event.target_touches,
333 web_event->targetTouches,
334 &web_event->targetTouchesLength);
336 if (web_event->type == WebInputEvent::TouchEnd ||
337 web_event->type == WebInputEvent::TouchCancel) {
338 SetWebTouchPoints(event.changed_touches,
341 &web_event->touchesLength);
342 SetWebTouchPoints(event.changed_touches,
344 web_event->targetTouches,
345 &web_event->targetTouchesLength);
351 WebKeyboardEvent* BuildKeyEvent(const InputEventData& event) {
352 WebKeyboardEvent* key_event = new WebKeyboardEvent();
353 switch (event.event_type) {
354 case PP_INPUTEVENT_TYPE_RAWKEYDOWN:
355 key_event->type = WebInputEvent::RawKeyDown;
357 case PP_INPUTEVENT_TYPE_KEYDOWN:
358 key_event->type = WebInputEvent::KeyDown;
360 case PP_INPUTEVENT_TYPE_KEYUP:
361 key_event->type = WebInputEvent::KeyUp;
366 key_event->timeStampSeconds = PPTimeTicksToEventTime(event.event_time_stamp);
367 key_event->modifiers = event.event_modifiers;
368 key_event->windowsKeyCode = event.key_code;
369 key_event->setKeyIdentifierFromWindowsKeyCode();
373 WebKeyboardEvent* BuildCharEvent(const InputEventData& event) {
374 WebKeyboardEvent* key_event = new WebKeyboardEvent();
375 key_event->type = WebInputEvent::Char;
376 key_event->timeStampSeconds = PPTimeTicksToEventTime(event.event_time_stamp);
377 key_event->modifiers = event.event_modifiers;
379 // Make sure to not read beyond the buffer in case some bad code doesn't
380 // NULL-terminate it (this is called from plugins).
381 size_t text_length_cap = WebKeyboardEvent::textLengthCap;
382 base::string16 text16 = base::UTF8ToUTF16(event.character_text);
384 memset(key_event->text, 0, text_length_cap);
385 memset(key_event->unmodifiedText, 0, text_length_cap);
386 for (size_t i = 0; i < std::min(text_length_cap, text16.size()); ++i)
387 key_event->text[i] = text16[i];
391 WebMouseEvent* BuildMouseEvent(const InputEventData& event) {
392 WebMouseEvent* mouse_event = new WebMouseEvent();
393 switch (event.event_type) {
394 case PP_INPUTEVENT_TYPE_MOUSEDOWN:
395 mouse_event->type = WebInputEvent::MouseDown;
397 case PP_INPUTEVENT_TYPE_MOUSEUP:
398 mouse_event->type = WebInputEvent::MouseUp;
400 case PP_INPUTEVENT_TYPE_MOUSEMOVE:
401 mouse_event->type = WebInputEvent::MouseMove;
403 case PP_INPUTEVENT_TYPE_MOUSEENTER:
404 mouse_event->type = WebInputEvent::MouseEnter;
406 case PP_INPUTEVENT_TYPE_MOUSELEAVE:
407 mouse_event->type = WebInputEvent::MouseLeave;
409 case PP_INPUTEVENT_TYPE_CONTEXTMENU:
410 mouse_event->type = WebInputEvent::ContextMenu;
415 mouse_event->timeStampSeconds =
416 PPTimeTicksToEventTime(event.event_time_stamp);
417 mouse_event->modifiers = event.event_modifiers;
418 mouse_event->button = static_cast<WebMouseEvent::Button>(event.mouse_button);
419 if (mouse_event->type == WebInputEvent::MouseMove) {
420 if (mouse_event->modifiers & WebInputEvent::LeftButtonDown)
421 mouse_event->button = WebMouseEvent::ButtonLeft;
422 else if (mouse_event->modifiers & WebInputEvent::MiddleButtonDown)
423 mouse_event->button = WebMouseEvent::ButtonMiddle;
424 else if (mouse_event->modifiers & WebInputEvent::RightButtonDown)
425 mouse_event->button = WebMouseEvent::ButtonRight;
427 mouse_event->x = event.mouse_position.x;
428 mouse_event->y = event.mouse_position.y;
429 mouse_event->clickCount = event.mouse_click_count;
430 mouse_event->movementX = event.mouse_movement.x;
431 mouse_event->movementY = event.mouse_movement.y;
435 WebMouseWheelEvent* BuildMouseWheelEvent(const InputEventData& event) {
436 WebMouseWheelEvent* mouse_wheel_event = new WebMouseWheelEvent();
437 mouse_wheel_event->type = WebInputEvent::MouseWheel;
438 mouse_wheel_event->timeStampSeconds =
439 PPTimeTicksToEventTime(event.event_time_stamp);
440 mouse_wheel_event->modifiers = event.event_modifiers;
441 mouse_wheel_event->deltaX = event.wheel_delta.x;
442 mouse_wheel_event->deltaY = event.wheel_delta.y;
443 mouse_wheel_event->wheelTicksX = event.wheel_ticks.x;
444 mouse_wheel_event->wheelTicksY = event.wheel_ticks.y;
445 mouse_wheel_event->scrollByPage = event.wheel_scroll_by_page;
446 return mouse_wheel_event;
450 #define VK_RETURN 0x0D
452 #define VK_PRIOR 0x21
458 #define VK_RIGHT 0x27
460 #define VK_SNAPSHOT 0x2C
461 #define VK_INSERT 0x2D
462 #define VK_DELETE 0x2E
469 // Convert a character string to a Windows virtual key code. Adapted from
470 // src/content/shell/renderer/test_runner/event_sender.cc. This
471 // is used by CreateSimulatedWebInputEvents to convert keyboard events.
472 void GetKeyCode(const std::string& char_text,
475 bool* needs_shift_modifier,
476 bool* generate_char) {
477 WebUChar vk_code = 0;
478 WebUChar vk_text = 0;
479 *needs_shift_modifier = false;
480 *generate_char = false;
481 if ("\n" == char_text) {
482 vk_text = vk_code = VK_RETURN;
483 *generate_char = true;
484 } else if ("rightArrow" == char_text) {
486 } else if ("downArrow" == char_text) {
488 } else if ("leftArrow" == char_text) {
490 } else if ("upArrow" == char_text) {
492 } else if ("insert" == char_text) {
494 } else if ("delete" == char_text) {
496 } else if ("pageUp" == char_text) {
498 } else if ("pageDown" == char_text) {
500 } else if ("home" == char_text) {
502 } else if ("end" == char_text) {
504 } else if ("printScreen" == char_text) {
505 vk_code = VK_SNAPSHOT;
506 } else if ("menu" == char_text) {
509 // Compare the input string with the function-key names defined by the
510 // DOM spec (i.e. "F1",...,"F24").
511 for (int i = 1; i <= 24; ++i) {
512 std::string functionKeyName = base::StringPrintf("F%d", i);
513 if (functionKeyName == char_text) {
514 vk_code = VK_F1 + (i - 1);
519 WebString web_char_text =
520 WebString::fromUTF8(char_text.data(), char_text.size());
521 DCHECK_EQ(web_char_text.length(), 1U);
522 vk_text = vk_code = web_char_text.at(0);
523 *needs_shift_modifier =
524 (vk_code & 0xFF) >= 'A' && (vk_code & 0xFF) <= 'Z';
525 if ((vk_code & 0xFF) >= 'a' && (vk_code & 0xFF) <= 'z')
526 vk_code -= 'a' - 'A';
527 *generate_char = true;
537 void CreateInputEventData(const WebInputEvent& event,
538 std::vector<InputEventData>* result) {
541 switch (event.type) {
542 case WebInputEvent::MouseDown:
543 case WebInputEvent::MouseUp:
544 case WebInputEvent::MouseMove:
545 case WebInputEvent::MouseEnter:
546 case WebInputEvent::MouseLeave:
547 case WebInputEvent::ContextMenu:
548 AppendMouseEvent(event, result);
550 case WebInputEvent::MouseWheel:
551 AppendMouseWheelEvent(event, result);
553 case WebInputEvent::RawKeyDown:
554 case WebInputEvent::KeyDown:
555 case WebInputEvent::KeyUp:
556 AppendKeyEvent(event, result);
558 case WebInputEvent::Char:
559 AppendCharEvent(event, result);
561 case WebInputEvent::TouchStart:
562 case WebInputEvent::TouchMove:
563 case WebInputEvent::TouchEnd:
564 case WebInputEvent::TouchCancel:
565 AppendTouchEvent(event, result);
567 case WebInputEvent::Undefined:
573 WebInputEvent* CreateWebInputEvent(const InputEventData& event) {
574 scoped_ptr<WebInputEvent> web_input_event;
575 switch (event.event_type) {
576 case PP_INPUTEVENT_TYPE_UNDEFINED:
578 case PP_INPUTEVENT_TYPE_MOUSEDOWN:
579 case PP_INPUTEVENT_TYPE_MOUSEUP:
580 case PP_INPUTEVENT_TYPE_MOUSEMOVE:
581 case PP_INPUTEVENT_TYPE_MOUSEENTER:
582 case PP_INPUTEVENT_TYPE_MOUSELEAVE:
583 case PP_INPUTEVENT_TYPE_CONTEXTMENU:
584 web_input_event.reset(BuildMouseEvent(event));
586 case PP_INPUTEVENT_TYPE_WHEEL:
587 web_input_event.reset(BuildMouseWheelEvent(event));
589 case PP_INPUTEVENT_TYPE_RAWKEYDOWN:
590 case PP_INPUTEVENT_TYPE_KEYDOWN:
591 case PP_INPUTEVENT_TYPE_KEYUP:
592 web_input_event.reset(BuildKeyEvent(event));
594 case PP_INPUTEVENT_TYPE_CHAR:
595 web_input_event.reset(BuildCharEvent(event));
597 case PP_INPUTEVENT_TYPE_IME_COMPOSITION_START:
598 case PP_INPUTEVENT_TYPE_IME_COMPOSITION_UPDATE:
599 case PP_INPUTEVENT_TYPE_IME_COMPOSITION_END:
600 case PP_INPUTEVENT_TYPE_IME_TEXT:
601 // TODO(kinaba) implement in WebKit an event structure to handle
602 // composition events.
605 case PP_INPUTEVENT_TYPE_TOUCHSTART:
606 case PP_INPUTEVENT_TYPE_TOUCHMOVE:
607 case PP_INPUTEVENT_TYPE_TOUCHEND:
608 case PP_INPUTEVENT_TYPE_TOUCHCANCEL:
609 web_input_event.reset(BuildTouchEvent(event));
613 return web_input_event.release();
616 // Generate a coherent sequence of input events to simulate a user event.
617 // From src/content/shell/renderer/test_runner/event_sender.cc.
618 std::vector<linked_ptr<WebInputEvent> > CreateSimulatedWebInputEvents(
619 const ppapi::InputEventData& event,
622 std::vector<linked_ptr<WebInputEvent> > events;
623 linked_ptr<WebInputEvent> original_event(CreateWebInputEvent(event));
625 switch (event.event_type) {
626 case PP_INPUTEVENT_TYPE_MOUSEDOWN:
627 case PP_INPUTEVENT_TYPE_MOUSEUP:
628 case PP_INPUTEVENT_TYPE_MOUSEMOVE:
629 case PP_INPUTEVENT_TYPE_MOUSEENTER:
630 case PP_INPUTEVENT_TYPE_MOUSELEAVE:
631 case PP_INPUTEVENT_TYPE_TOUCHSTART:
632 case PP_INPUTEVENT_TYPE_TOUCHMOVE:
633 case PP_INPUTEVENT_TYPE_TOUCHEND:
634 case PP_INPUTEVENT_TYPE_TOUCHCANCEL:
635 events.push_back(original_event);
638 case PP_INPUTEVENT_TYPE_WHEEL: {
639 WebMouseWheelEvent* web_mouse_wheel_event =
640 static_cast<WebMouseWheelEvent*>(original_event.get());
641 web_mouse_wheel_event->x = plugin_x;
642 web_mouse_wheel_event->y = plugin_y;
643 events.push_back(original_event);
647 case PP_INPUTEVENT_TYPE_RAWKEYDOWN:
648 case PP_INPUTEVENT_TYPE_KEYDOWN:
649 case PP_INPUTEVENT_TYPE_KEYUP: {
650 // Windows key down events should always be "raw" to avoid an ASSERT.
652 WebKeyboardEvent* web_keyboard_event =
653 static_cast<WebKeyboardEvent*>(original_event.get());
654 if (web_keyboard_event->type == WebInputEvent::KeyDown)
655 web_keyboard_event->type = WebInputEvent::RawKeyDown;
657 events.push_back(original_event);
661 case PP_INPUTEVENT_TYPE_CHAR: {
662 WebKeyboardEvent* web_char_event =
663 static_cast<WebKeyboardEvent*>(original_event.get());
665 WebUChar code = 0, text = 0;
666 bool needs_shift_modifier = false, generate_char = false;
667 GetKeyCode(event.character_text,
670 &needs_shift_modifier,
673 // Synthesize key down and key up events in all cases.
674 scoped_ptr<WebKeyboardEvent> key_down_event(new WebKeyboardEvent());
675 scoped_ptr<WebKeyboardEvent> key_up_event(new WebKeyboardEvent());
677 key_down_event->type = WebInputEvent::RawKeyDown;
678 key_down_event->windowsKeyCode = code;
679 key_down_event->nativeKeyCode = code;
680 if (needs_shift_modifier)
681 key_down_event->modifiers |= WebInputEvent::ShiftKey;
683 // If a char event is needed, set the text fields.
685 key_down_event->text[0] = text;
686 key_down_event->unmodifiedText[0] = text;
688 // Convert the key code to a string identifier.
689 key_down_event->setKeyIdentifierFromWindowsKeyCode();
691 *key_up_event = *web_char_event = *key_down_event;
693 events.push_back(linked_ptr<WebInputEvent>(key_down_event.release()));
696 web_char_event->type = WebInputEvent::Char;
697 web_char_event->keyIdentifier[0] = '\0';
698 events.push_back(original_event);
701 key_up_event->type = WebInputEvent::KeyUp;
702 events.push_back(linked_ptr<WebInputEvent>(key_up_event.release()));
712 PP_InputEvent_Class ClassifyInputEvent(WebInputEvent::Type type) {
714 case WebInputEvent::MouseDown:
715 case WebInputEvent::MouseUp:
716 case WebInputEvent::MouseMove:
717 case WebInputEvent::MouseEnter:
718 case WebInputEvent::MouseLeave:
719 case WebInputEvent::ContextMenu:
720 return PP_INPUTEVENT_CLASS_MOUSE;
721 case WebInputEvent::MouseWheel:
722 return PP_INPUTEVENT_CLASS_WHEEL;
723 case WebInputEvent::RawKeyDown:
724 case WebInputEvent::KeyDown:
725 case WebInputEvent::KeyUp:
726 case WebInputEvent::Char:
727 return PP_INPUTEVENT_CLASS_KEYBOARD;
728 case WebInputEvent::TouchCancel:
729 case WebInputEvent::TouchEnd:
730 case WebInputEvent::TouchMove:
731 case WebInputEvent::TouchStart:
732 return PP_INPUTEVENT_CLASS_TOUCH;
733 case WebInputEvent::Undefined:
736 return PP_InputEvent_Class(0);
740 } // namespace content