event_conversion.cc revision 58e6fbe4ee35d65e14b626c557d37565bf8ad179
15821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Copyright (c) 2012 The Chromium Authors. All rights reserved.
25821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be
35821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// found in the LICENSE file.
45821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
55821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "content/renderer/pepper/event_conversion.h"
65821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
75821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <map>
85821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
95821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/basictypes.h"
105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/i18n/char_iterator.h"
112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "base/logging.h"
125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/memory/scoped_ptr.h"
132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "base/strings/string_util.h"
145e3f23d412006dc4db4e659864679f29341e113fTorne (Richard Coles)#include "base/strings/stringprintf.h"
15868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#include "base/strings/utf_string_conversion_utils.h"
165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/strings/utf_string_conversions.h"
175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "content/renderer/pepper/common.h"
185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "content/renderer/pepper/usb_key_code_conversion.h"
195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ppapi/c/pp_input_event.h"
205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ppapi/shared_impl/ppb_input_event_shared.h"
215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ppapi/shared_impl/time_conversion.h"
225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "third_party/WebKit/public/platform/WebGamepads.h"
23a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)#include "third_party/WebKit/public/platform/WebString.h"
242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "third_party/WebKit/public/web/WebInputEvent.h"
255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)using ppapi::EventTimeToPPTimeTicks;
275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)using ppapi::InputEventData;
28a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)using ppapi::PPTimeTicksToEventTime;
295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)using WebKit::WebInputEvent;
305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)using WebKit::WebKeyboardEvent;
3168043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)using WebKit::WebMouseEvent;
325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)using WebKit::WebMouseWheelEvent;
335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)using WebKit::WebString;
345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)using WebKit::WebTouchEvent;
3568043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)using WebKit::WebTouchPoint;
3668043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)using WebKit::WebUChar;
3768043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)
385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace content {
395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace {
415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Verify the modifier flags WebKit uses match the Pepper ones. If these start
4368043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)// not matching, we'll need to write conversion code to preserve the Pepper
445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// values (since plugins will be depending on them).
455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)COMPILE_ASSERT(static_cast<int>(PP_INPUTEVENT_MODIFIER_SHIFTKEY) ==
4668043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)               static_cast<int>(WebInputEvent::ShiftKey),
475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)               ShiftKeyMatches);
485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)COMPILE_ASSERT(static_cast<int>(PP_INPUTEVENT_MODIFIER_CONTROLKEY) ==
495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)               static_cast<int>(WebInputEvent::ControlKey),
505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)               ControlKeyMatches);
515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)COMPILE_ASSERT(static_cast<int>(PP_INPUTEVENT_MODIFIER_ALTKEY) ==
525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)               static_cast<int>(WebInputEvent::AltKey),
535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)               AltKeyMatches);
545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)COMPILE_ASSERT(static_cast<int>(PP_INPUTEVENT_MODIFIER_METAKEY) ==
555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)               static_cast<int>(WebInputEvent::MetaKey),
565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)               MetaKeyMatches);
575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)COMPILE_ASSERT(static_cast<int>(PP_INPUTEVENT_MODIFIER_ISKEYPAD) ==
585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)               static_cast<int>(WebInputEvent::IsKeyPad),
595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)               KeyPadMatches);
605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)COMPILE_ASSERT(static_cast<int>(PP_INPUTEVENT_MODIFIER_ISAUTOREPEAT) ==
615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)               static_cast<int>(WebInputEvent::IsAutoRepeat),
625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)               AutoRepeatMatches);
635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)COMPILE_ASSERT(static_cast<int>(PP_INPUTEVENT_MODIFIER_LEFTBUTTONDOWN) ==
645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)               static_cast<int>(WebInputEvent::LeftButtonDown),
655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)               LeftButtonMatches);
665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)COMPILE_ASSERT(static_cast<int>(PP_INPUTEVENT_MODIFIER_MIDDLEBUTTONDOWN) ==
675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)               static_cast<int>(WebInputEvent::MiddleButtonDown),
685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)               MiddleButtonMatches);
695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)COMPILE_ASSERT(static_cast<int>(PP_INPUTEVENT_MODIFIER_RIGHTBUTTONDOWN) ==
705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)               static_cast<int>(WebInputEvent::RightButtonDown),
715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)               RightButtonMatches);
725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)COMPILE_ASSERT(static_cast<int>(PP_INPUTEVENT_MODIFIER_CAPSLOCKKEY) ==
735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)               static_cast<int>(WebInputEvent::CapsLockOn),
745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)               CapsLockMatches);
755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)COMPILE_ASSERT(static_cast<int>(PP_INPUTEVENT_MODIFIER_NUMLOCKKEY) ==
765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)               static_cast<int>(WebInputEvent::NumLockOn),
775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)               NumLockMatches);
785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)COMPILE_ASSERT(static_cast<int>(PP_INPUTEVENT_MODIFIER_ISLEFT) ==
795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)               static_cast<int>(WebInputEvent::IsLeft),
805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)               LeftMatches);
815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)COMPILE_ASSERT(static_cast<int>(PP_INPUTEVENT_MODIFIER_ISRIGHT) ==
825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)               static_cast<int>(WebInputEvent::IsRight),
835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)               RightMatches);
845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
85a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)PP_InputEvent_Type ConvertEventTypes(WebInputEvent::Type wetype) {
86a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  switch (wetype) {
875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    case WebInputEvent::MouseDown:
885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      return PP_INPUTEVENT_TYPE_MOUSEDOWN;
895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    case WebInputEvent::MouseUp:
905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      return PP_INPUTEVENT_TYPE_MOUSEUP;
915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    case WebInputEvent::MouseMove:
925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      return PP_INPUTEVENT_TYPE_MOUSEMOVE;
935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    case WebInputEvent::MouseEnter:
945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      return PP_INPUTEVENT_TYPE_MOUSEENTER;
955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    case WebInputEvent::MouseLeave:
965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      return PP_INPUTEVENT_TYPE_MOUSELEAVE;
975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    case WebInputEvent::ContextMenu:
985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      return PP_INPUTEVENT_TYPE_CONTEXTMENU;
996e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)    case WebInputEvent::MouseWheel:
1005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      return PP_INPUTEVENT_TYPE_WHEEL;
1015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    case WebInputEvent::RawKeyDown:
1025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      return PP_INPUTEVENT_TYPE_RAWKEYDOWN;
1035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    case WebInputEvent::KeyDown:
1045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      return PP_INPUTEVENT_TYPE_KEYDOWN;
1055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    case WebInputEvent::KeyUp:
1065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      return PP_INPUTEVENT_TYPE_KEYUP;
1075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    case WebInputEvent::Char:
1085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      return PP_INPUTEVENT_TYPE_CHAR;
1095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    case WebInputEvent::TouchStart:
1105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      return PP_INPUTEVENT_TYPE_TOUCHSTART;
1115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    case WebInputEvent::TouchMove:
1125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      return PP_INPUTEVENT_TYPE_TOUCHMOVE;
1135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    case WebInputEvent::TouchEnd:
1145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      return PP_INPUTEVENT_TYPE_TOUCHEND;
1155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    case WebInputEvent::TouchCancel:
1165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      return PP_INPUTEVENT_TYPE_TOUCHCANCEL;
1175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    case WebInputEvent::Undefined:
1185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    default:
1195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      return PP_INPUTEVENT_TYPE_UNDEFINED;
1205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
1215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Generates a PP_InputEvent with the fields common to all events, as well as
1245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// the event type from the given web event. Event-specific fields will be zero
1255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// initialized.
1265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)InputEventData GetEventWithCommonFieldsAndType(const WebInputEvent& web_event) {
1275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  InputEventData result;
1285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  result.event_type = ConvertEventTypes(web_event.type);
1295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  result.event_time_stamp = EventTimeToPPTimeTicks(web_event.timeStampSeconds);
1305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  result.usb_key_code = 0;
1315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return result;
1325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void AppendKeyEvent(const WebInputEvent& event,
1355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                    std::vector<InputEventData>* result_events) {
1365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const WebKeyboardEvent& key_event =
1375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      static_cast<const WebKeyboardEvent&>(event);
1385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  InputEventData result = GetEventWithCommonFieldsAndType(event);
1395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  result.event_modifiers = key_event.modifiers;
1405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  result.key_code = key_event.windowsKeyCode;
1415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  result.usb_key_code = UsbKeyCodeForKeyboardEvent(key_event);
1425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  result_events->push_back(result);
1435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void AppendCharEvent(const WebInputEvent& event,
1465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                     std::vector<InputEventData>* result_events) {
1475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const WebKeyboardEvent& key_event =
1485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      static_cast<const WebKeyboardEvent&>(event);
1495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // This is a bit complex, the input event will normally just have one 16-bit
1515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // character in it, but may be zero or more than one. The text array is
1525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // just padded with 0 values for the unused ones, but is not necessarily
1535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // null-terminated.
1545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  //
1555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Here we see how many UTF-16 characters we have.
1565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  size_t utf16_char_count = 0;
1575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  while (utf16_char_count < WebKeyboardEvent::textLengthCap &&
1585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)         key_event.text[utf16_char_count])
1595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    utf16_char_count++;
1605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Make a separate InputEventData for each Unicode character in the input.
1625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  base::i18n::UTF16CharIterator iter(key_event.text, utf16_char_count);
1635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  while (!iter.end()) {
1645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    InputEventData result = GetEventWithCommonFieldsAndType(event);
1655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    result.event_modifiers = key_event.modifiers;
1665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    base::WriteUnicodeCharacter(iter.get(), &result.character_text);
1675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    result_events->push_back(result);
1695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    iter.Advance();
1705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
1715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void AppendMouseEvent(const WebInputEvent& event,
1745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                      std::vector<InputEventData>* result_events) {
1755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  COMPILE_ASSERT(static_cast<int>(WebMouseEvent::ButtonNone) ==
1765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                 static_cast<int>(PP_INPUTEVENT_MOUSEBUTTON_NONE),
1775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                 MouseNone);
1785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  COMPILE_ASSERT(static_cast<int>(WebMouseEvent::ButtonLeft) ==
17968043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)                 static_cast<int>(PP_INPUTEVENT_MOUSEBUTTON_LEFT),
18068043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)                 MouseLeft);
18168043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  COMPILE_ASSERT(static_cast<int>(WebMouseEvent::ButtonRight) ==
18268043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)                 static_cast<int>(PP_INPUTEVENT_MOUSEBUTTON_RIGHT),
18368043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)                 MouseRight);
18468043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  COMPILE_ASSERT(static_cast<int>(WebMouseEvent::ButtonMiddle) ==
18568043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)                 static_cast<int>(PP_INPUTEVENT_MOUSEBUTTON_MIDDLE),
18668043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)                 MouseMiddle);
18768043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)
1885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const WebMouseEvent& mouse_event =
1895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      static_cast<const WebMouseEvent&>(event);
1905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  InputEventData result = GetEventWithCommonFieldsAndType(event);
1915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  result.event_modifiers = mouse_event.modifiers;
1925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (mouse_event.type == WebInputEvent::MouseDown ||
1935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      mouse_event.type == WebInputEvent::MouseMove ||
1945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      mouse_event.type == WebInputEvent::MouseUp) {
1955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    result.mouse_button =
1965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        static_cast<PP_InputEvent_MouseButton>(mouse_event.button);
1975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
1985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  result.mouse_position.x = mouse_event.x;
1995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  result.mouse_position.y = mouse_event.y;
2005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  result.mouse_click_count = mouse_event.clickCount;
2015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  result.mouse_movement.x = mouse_event.movementX;
2025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  result.mouse_movement.y = mouse_event.movementY;
2035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  result_events->push_back(result);
2045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void AppendMouseWheelEvent(const WebInputEvent& event,
2075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                           std::vector<InputEventData>* result_events) {
2085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const WebMouseWheelEvent& mouse_wheel_event =
2095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      static_cast<const WebMouseWheelEvent&>(event);
2105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  InputEventData result = GetEventWithCommonFieldsAndType(event);
2115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  result.event_modifiers = mouse_wheel_event.modifiers;
2125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  result.wheel_delta.x = mouse_wheel_event.deltaX;
2135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  result.wheel_delta.y = mouse_wheel_event.deltaY;
2145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  result.wheel_ticks.x = mouse_wheel_event.wheelTicksX;
2155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  result.wheel_ticks.y = mouse_wheel_event.wheelTicksY;
2165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  result.wheel_scroll_by_page = !!mouse_wheel_event.scrollByPage;
2175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  result_events->push_back(result);
2185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2207dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdochvoid SetPPTouchPoints(const WebTouchPoint* touches, uint32_t touches_length,
2217dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch                      std::vector<PP_TouchPoint>* result) {
2227dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  for (uint32_t i = 0; i < touches_length; i++) {
2237dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch    const WebTouchPoint& touch_point = touches[i];
2247dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch    PP_TouchPoint pp_pt;
2255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    pp_pt.id = touch_point.id;
2265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    pp_pt.position.x = touch_point.position.x;
2275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    pp_pt.position.y = touch_point.position.y;
2285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    pp_pt.radius.x = touch_point.radiusX;
2295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    pp_pt.radius.y = touch_point.radiusY;
2305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    pp_pt.rotation_angle = touch_point.rotationAngle;
2315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    pp_pt.pressure = touch_point.force;
2325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    result->push_back(pp_pt);
2335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
2345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void AppendTouchEvent(const WebInputEvent& event,
2375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                      std::vector<InputEventData>* result_events) {
2385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const WebTouchEvent& touch_event =
2395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      reinterpret_cast<const WebTouchEvent&>(event);
2405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  InputEventData result = GetEventWithCommonFieldsAndType(event);
2425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  SetPPTouchPoints(touch_event.touches, touch_event.touchesLength,
2435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                   &result.touches);
2447d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  SetPPTouchPoints(touch_event.changedTouches, touch_event.changedTouchesLength,
2455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                   &result.changed_touches);
2465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  SetPPTouchPoints(touch_event.targetTouches, touch_event.targetTouchesLength,
2475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                   &result.target_touches);
2485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  result_events->push_back(result);
2505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Structure used to map touch point id's to touch states.  Since the pepper
2535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// touch event structure does not have states for individual touch points and
2545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// instead relies on the event type in combination with the set of touch lists,
2555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// we have to set the state for the changed touches to be the same as the event
2565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// type and all others to be 'stationary.'
2575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)typedef std::map<uint32_t, WebTouchPoint::State> TouchStateMap;
2585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void SetWebTouchPoints(const std::vector<PP_TouchPoint>& pp_touches,
2605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                       const TouchStateMap& states_map,
2615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                       WebTouchPoint* web_touches,
2625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                       uint32_t* web_touches_length) {
2635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  for (uint32_t i = 0; i < pp_touches.size() &&
2655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)       i < WebTouchEvent::touchesLengthCap; i++) {
2665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    WebTouchPoint pt;
2675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const PP_TouchPoint& pp_pt = pp_touches[i];
2685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    pt.id = pp_pt.id;
2695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (states_map.find(pt.id) == states_map.end())
2715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      pt.state = WebTouchPoint::StateStationary;
2725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    else
2735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      pt.state = states_map.find(pt.id)->second;
2745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    pt.position.x = pp_pt.position.x;
2765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    pt.position.y = pp_pt.position.y;
2775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // TODO bug:http://code.google.com/p/chromium/issues/detail?id=93902
2785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    pt.screenPosition.x = 0;
2795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    pt.screenPosition.y = 0;
2805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    pt.force = pp_pt.pressure;
2815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    pt.radiusX = pp_pt.radius.x;
2825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    pt.radiusY = pp_pt.radius.y;
2835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    pt.rotationAngle = pp_pt.rotation_angle;
2845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    web_touches[i] = pt;
2855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    (*web_touches_length)++;
2865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
2875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)WebTouchEvent* BuildTouchEvent(const InputEventData& event) {
2905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  WebTouchEvent* web_event = new WebTouchEvent();
2915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  WebTouchPoint::State state = WebTouchPoint::StateUndefined;
2925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  switch (event.event_type) {
2935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    case PP_INPUTEVENT_TYPE_TOUCHSTART:
2945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      web_event->type = WebInputEvent::TouchStart;
2955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      state = WebTouchPoint::StatePressed;
2965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      break;
2975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    case PP_INPUTEVENT_TYPE_TOUCHMOVE:
2985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      web_event->type = WebInputEvent::TouchMove;
2995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      state = WebTouchPoint::StateMoved;
3005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      break;
3015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    case PP_INPUTEVENT_TYPE_TOUCHEND:
3025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      web_event->type = WebInputEvent::TouchEnd;
3035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      state = WebTouchPoint::StateReleased;
3045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      break;
3055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    case PP_INPUTEVENT_TYPE_TOUCHCANCEL:
3065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      web_event->type = WebInputEvent::TouchCancel;
3075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      state = WebTouchPoint::StateCancelled;
3085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      break;
3095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    default:
3105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      NOTREACHED();
3115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
3125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
313a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  TouchStateMap states_map;
3145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  for (uint32_t i = 0; i < event.changed_touches.size(); i++)
3155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    states_map[event.changed_touches[i].id] = state;
3165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  web_event->timeStampSeconds = PPTimeTicksToEventTime(event.event_time_stamp);
3185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  SetWebTouchPoints(event.changed_touches, states_map,
3205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                    web_event->changedTouches,
3215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                    &web_event->changedTouchesLength);
3225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  SetWebTouchPoints(event.touches, states_map, web_event->touches,
3245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                    &web_event->touchesLength);
3255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
326f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  SetWebTouchPoints(event.target_touches, states_map, web_event->targetTouches,
327f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)                    &web_event->targetTouchesLength);
3285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (web_event->type == WebInputEvent::TouchEnd ||
3305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      web_event->type == WebInputEvent::TouchCancel) {
3315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    SetWebTouchPoints(event.changed_touches, states_map,
3325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                      web_event->touches, &web_event->touchesLength);
3335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    SetWebTouchPoints(event.changed_touches, states_map,
3345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                      web_event->targetTouches,
3355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                      &web_event->targetTouchesLength);
3365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
3375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return web_event;
3395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
3405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)WebKeyboardEvent* BuildKeyEvent(const InputEventData& event) {
3425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  WebKeyboardEvent* key_event = new WebKeyboardEvent();
3435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  switch (event.event_type) {
344a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    case PP_INPUTEVENT_TYPE_RAWKEYDOWN:
3455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      key_event->type = WebInputEvent::RawKeyDown;
3465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      break;
3475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    case PP_INPUTEVENT_TYPE_KEYDOWN:
3485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      key_event->type = WebInputEvent::KeyDown;
3495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      break;
3505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    case PP_INPUTEVENT_TYPE_KEYUP:
3515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      key_event->type = WebInputEvent::KeyUp;
3525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      break;
3535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    default:
3545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      NOTREACHED();
3555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
3565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  key_event->timeStampSeconds = PPTimeTicksToEventTime(event.event_time_stamp);
3575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  key_event->modifiers = event.event_modifiers;
3585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  key_event->windowsKeyCode = event.key_code;
3595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  key_event->setKeyIdentifierFromWindowsKeyCode();
3605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return key_event;
3615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
362a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
3635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)WebKeyboardEvent* BuildCharEvent(const InputEventData& event) {
3645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  WebKeyboardEvent* key_event = new WebKeyboardEvent();
3655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  key_event->type = WebInputEvent::Char;
3665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  key_event->timeStampSeconds = PPTimeTicksToEventTime(event.event_time_stamp);
3675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  key_event->modifiers = event.event_modifiers;
3685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Make sure to not read beyond the buffer in case some bad code doesn't
3705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // NULL-terminate it (this is called from plugins).
3715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  size_t text_length_cap = WebKeyboardEvent::textLengthCap;
3725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  base::string16 text16 = UTF8ToUTF16(event.character_text);
3735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  memset(key_event->text, 0, text_length_cap);
3755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  memset(key_event->unmodifiedText, 0, text_length_cap);
3765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  for (size_t i = 0;
3775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)       i < std::min(text_length_cap, text16.size());
3785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)       ++i)
3795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    key_event->text[i] = text16[i];
3805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return key_event;
3815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
3825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)WebMouseEvent* BuildMouseEvent(const InputEventData& event) {
3845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  WebMouseEvent* mouse_event = new WebMouseEvent();
3855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  switch (event.event_type) {
3865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    case PP_INPUTEVENT_TYPE_MOUSEDOWN:
3875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      mouse_event->type = WebInputEvent::MouseDown;
3885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      break;
3895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    case PP_INPUTEVENT_TYPE_MOUSEUP:
3905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      mouse_event->type = WebInputEvent::MouseUp;
391a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)      break;
3925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    case PP_INPUTEVENT_TYPE_MOUSEMOVE:
3935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      mouse_event->type = WebInputEvent::MouseMove;
3945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      break;
3955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    case PP_INPUTEVENT_TYPE_MOUSEENTER:
3965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      mouse_event->type = WebInputEvent::MouseEnter;
3975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      break;
3985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    case PP_INPUTEVENT_TYPE_MOUSELEAVE:
3995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      mouse_event->type = WebInputEvent::MouseLeave;
4005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      break;
4015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    case PP_INPUTEVENT_TYPE_CONTEXTMENU:
4025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      mouse_event->type = WebInputEvent::ContextMenu;
4035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      break;
4045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    default:
4055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      NOTREACHED();
4065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
4075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  mouse_event->timeStampSeconds =
4085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      PPTimeTicksToEventTime(event.event_time_stamp);
4095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  mouse_event->modifiers = event.event_modifiers;
4105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  mouse_event->button =
4115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      static_cast<WebMouseEvent::Button>(event.mouse_button);
4125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (mouse_event->type == WebInputEvent::MouseMove) {
4135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (mouse_event->modifiers & WebInputEvent::LeftButtonDown)
4145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      mouse_event->button = WebMouseEvent::ButtonLeft;
4155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    else if (mouse_event->modifiers & WebInputEvent::MiddleButtonDown)
4165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      mouse_event->button = WebMouseEvent::ButtonMiddle;
4175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    else if (mouse_event->modifiers & WebInputEvent::RightButtonDown)
418a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)      mouse_event->button = WebMouseEvent::ButtonRight;
4195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
4205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  mouse_event->x = event.mouse_position.x;
4215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  mouse_event->y = event.mouse_position.y;
4225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  mouse_event->clickCount = event.mouse_click_count;
4235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  mouse_event->movementX = event.mouse_movement.x;
4245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  mouse_event->movementY = event.mouse_movement.y;
4255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return mouse_event;
4265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
4275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)WebMouseWheelEvent* BuildMouseWheelEvent(const InputEventData& event) {
4295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  WebMouseWheelEvent* mouse_wheel_event = new WebMouseWheelEvent();
4305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  mouse_wheel_event->type = WebInputEvent::MouseWheel;
4315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  mouse_wheel_event->timeStampSeconds =
4325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      PPTimeTicksToEventTime(event.event_time_stamp);
4335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  mouse_wheel_event->modifiers = event.event_modifiers;
4345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  mouse_wheel_event->deltaX = event.wheel_delta.x;
4355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  mouse_wheel_event->deltaY = event.wheel_delta.y;
436a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  mouse_wheel_event->wheelTicksX = event.wheel_ticks.x;
4375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  mouse_wheel_event->wheelTicksY = event.wheel_ticks.y;
4385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  mouse_wheel_event->scrollByPage = event.wheel_scroll_by_page;
4395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return mouse_wheel_event;
4405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
441a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
442a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)#if !defined(OS_WIN)
443#define VK_RETURN         0x0D
444
445#define VK_PRIOR          0x21
446#define VK_NEXT           0x22
447#define VK_END            0x23
448#define VK_HOME           0x24
449#define VK_LEFT           0x25
450#define VK_UP             0x26
451#define VK_RIGHT          0x27
452#define VK_DOWN           0x28
453#define VK_SNAPSHOT       0x2C
454#define VK_INSERT         0x2D
455#define VK_DELETE         0x2E
456
457#define VK_APPS           0x5D
458
459#define VK_F1             0x70
460#endif
461
462// Convert a character string to a Windows virtual key code. Adapted from
463// src/third_party/WebKit/Tools/DumpRenderTree/chromium/EventSender.cpp. This
464// is used by CreateSimulatedWebInputEvents to convert keyboard events.
465void GetKeyCode(const std::string& char_text,
466                WebUChar* code,
467                WebUChar* text,
468                bool* needs_shift_modifier,
469                bool* generate_char) {
470  WebUChar vk_code = 0;
471  WebUChar vk_text = 0;
472  *needs_shift_modifier = false;
473  *generate_char = false;
474  if ("\n" == char_text) {
475    vk_text = vk_code = VK_RETURN;
476    *generate_char = true;
477  } else if ("rightArrow" == char_text) {
478    vk_code = VK_RIGHT;
479  } else if ("downArrow" == char_text) {
480    vk_code = VK_DOWN;
481  } else if ("leftArrow" == char_text) {
482    vk_code = VK_LEFT;
483  } else if ("upArrow" == char_text) {
484    vk_code = VK_UP;
485  } else if ("insert" == char_text) {
486    vk_code = VK_INSERT;
487  } else if ("delete" == char_text) {
488    vk_code = VK_DELETE;
489  } else if ("pageUp" == char_text) {
490    vk_code = VK_PRIOR;
491  } else if ("pageDown" == char_text) {
492    vk_code = VK_NEXT;
493  } else if ("home" == char_text) {
494    vk_code = VK_HOME;
495  } else if ("end" == char_text) {
496    vk_code = VK_END;
497  } else if ("printScreen" == char_text) {
498    vk_code = VK_SNAPSHOT;
499  } else if ("menu" == char_text) {
500    vk_code = VK_APPS;
501  } else {
502    // Compare the input string with the function-key names defined by the
503    // DOM spec (i.e. "F1",...,"F24").
504    for (int i = 1; i <= 24; ++i) {
505      std::string functionKeyName = base::StringPrintf("F%d", i);
506      if (functionKeyName == char_text) {
507        vk_code = VK_F1 + (i - 1);
508        break;
509      }
510    }
511    if (!vk_code) {
512      WebString web_char_text =
513          WebString::fromUTF8(char_text.data(), char_text.size());
514      DCHECK_EQ(web_char_text.length(), 1U);
515      vk_text = vk_code = web_char_text.at(0);
516      *needs_shift_modifier =
517          (vk_code & 0xFF) >= 'A' && (vk_code & 0xFF) <= 'Z';
518      if ((vk_code & 0xFF) >= 'a' && (vk_code & 0xFF) <= 'z')
519          vk_code -= 'a' - 'A';
520      *generate_char = true;
521    }
522  }
523
524  *code = vk_code;
525  *text = vk_text;
526}
527
528}  // namespace
529
530void CreateInputEventData(const WebInputEvent& event,
531                          std::vector<InputEventData>* result) {
532  result->clear();
533
534  switch (event.type) {
535    case WebInputEvent::MouseDown:
536    case WebInputEvent::MouseUp:
537    case WebInputEvent::MouseMove:
538    case WebInputEvent::MouseEnter:
539    case WebInputEvent::MouseLeave:
540    case WebInputEvent::ContextMenu:
541      AppendMouseEvent(event, result);
542      break;
543    case WebInputEvent::MouseWheel:
544      AppendMouseWheelEvent(event, result);
545      break;
546    case WebInputEvent::RawKeyDown:
547    case WebInputEvent::KeyDown:
548    case WebInputEvent::KeyUp:
549      AppendKeyEvent(event, result);
550      break;
551    case WebInputEvent::Char:
552      AppendCharEvent(event, result);
553      break;
554    case WebInputEvent::TouchStart:
555    case WebInputEvent::TouchMove:
556    case WebInputEvent::TouchEnd:
557    case WebInputEvent::TouchCancel:
558      AppendTouchEvent(event, result);
559      break;
560    case WebInputEvent::Undefined:
561    default:
562      break;
563  }
564}
565
566WebInputEvent* CreateWebInputEvent(const InputEventData& event) {
567  scoped_ptr<WebInputEvent> web_input_event;
568  switch (event.event_type) {
569    case PP_INPUTEVENT_TYPE_UNDEFINED:
570      return NULL;
571    case PP_INPUTEVENT_TYPE_MOUSEDOWN:
572    case PP_INPUTEVENT_TYPE_MOUSEUP:
573    case PP_INPUTEVENT_TYPE_MOUSEMOVE:
574    case PP_INPUTEVENT_TYPE_MOUSEENTER:
575    case PP_INPUTEVENT_TYPE_MOUSELEAVE:
576    case PP_INPUTEVENT_TYPE_CONTEXTMENU:
577      web_input_event.reset(BuildMouseEvent(event));
578      break;
579    case PP_INPUTEVENT_TYPE_WHEEL:
580      web_input_event.reset(BuildMouseWheelEvent(event));
581      break;
582    case PP_INPUTEVENT_TYPE_RAWKEYDOWN:
583    case PP_INPUTEVENT_TYPE_KEYDOWN:
584    case PP_INPUTEVENT_TYPE_KEYUP:
585      web_input_event.reset(BuildKeyEvent(event));
586      break;
587    case PP_INPUTEVENT_TYPE_CHAR:
588      web_input_event.reset(BuildCharEvent(event));
589      break;
590    case PP_INPUTEVENT_TYPE_IME_COMPOSITION_START:
591    case PP_INPUTEVENT_TYPE_IME_COMPOSITION_UPDATE:
592    case PP_INPUTEVENT_TYPE_IME_COMPOSITION_END:
593    case PP_INPUTEVENT_TYPE_IME_TEXT:
594      // TODO(kinaba) implement in WebKit an event structure to handle
595      // composition events.
596      NOTREACHED();
597      break;
598    case PP_INPUTEVENT_TYPE_TOUCHSTART:
599    case PP_INPUTEVENT_TYPE_TOUCHMOVE:
600    case PP_INPUTEVENT_TYPE_TOUCHEND:
601    case PP_INPUTEVENT_TYPE_TOUCHCANCEL:
602      web_input_event.reset(BuildTouchEvent(event));
603      break;
604  }
605
606  return web_input_event.release();
607}
608
609// Generate a coherent sequence of input events to simulate a user event.
610// From src/third_party/WebKit/Tools/DumpRenderTree/chromium/EventSender.cpp.
611std::vector<linked_ptr<WebInputEvent> > CreateSimulatedWebInputEvents(
612    const ::ppapi::InputEventData& event,
613    int plugin_x,
614    int plugin_y) {
615  std::vector<linked_ptr<WebInputEvent> > events;
616  linked_ptr<WebInputEvent> original_event(CreateWebInputEvent(event));
617
618  switch (event.event_type) {
619    case PP_INPUTEVENT_TYPE_MOUSEDOWN:
620    case PP_INPUTEVENT_TYPE_MOUSEUP:
621    case PP_INPUTEVENT_TYPE_MOUSEMOVE:
622    case PP_INPUTEVENT_TYPE_MOUSEENTER:
623    case PP_INPUTEVENT_TYPE_MOUSELEAVE:
624    case PP_INPUTEVENT_TYPE_TOUCHSTART:
625    case PP_INPUTEVENT_TYPE_TOUCHMOVE:
626    case PP_INPUTEVENT_TYPE_TOUCHEND:
627    case PP_INPUTEVENT_TYPE_TOUCHCANCEL:
628      events.push_back(original_event);
629      break;
630
631    case PP_INPUTEVENT_TYPE_WHEEL: {
632      WebMouseWheelEvent* web_mouse_wheel_event =
633          static_cast<WebMouseWheelEvent*>(original_event.get());
634      web_mouse_wheel_event->x = plugin_x;
635      web_mouse_wheel_event->y = plugin_y;
636      events.push_back(original_event);
637      break;
638    }
639
640    case PP_INPUTEVENT_TYPE_RAWKEYDOWN:
641    case PP_INPUTEVENT_TYPE_KEYDOWN:
642    case PP_INPUTEVENT_TYPE_KEYUP: {
643      // Windows key down events should always be "raw" to avoid an ASSERT.
644#if defined(OS_WIN)
645      WebKeyboardEvent* web_keyboard_event =
646          static_cast<WebKeyboardEvent*>(original_event.get());
647      if (web_keyboard_event->type == WebInputEvent::KeyDown)
648        web_keyboard_event->type = WebInputEvent::RawKeyDown;
649#endif
650      events.push_back(original_event);
651      break;
652    }
653
654    case PP_INPUTEVENT_TYPE_CHAR: {
655      WebKeyboardEvent* web_char_event =
656          static_cast<WebKeyboardEvent*>(original_event.get());
657
658      WebUChar code = 0, text = 0;
659      bool needs_shift_modifier = false, generate_char = false;
660      GetKeyCode(event.character_text,
661                 &code,
662                 &text,
663                 &needs_shift_modifier,
664                 &generate_char);
665
666      // Synthesize key down and key up events in all cases.
667      scoped_ptr<WebKeyboardEvent> key_down_event(new WebKeyboardEvent());
668      scoped_ptr<WebKeyboardEvent> key_up_event(new WebKeyboardEvent());
669
670      key_down_event->type = WebInputEvent::RawKeyDown;
671      key_down_event->windowsKeyCode = code;
672      key_down_event->nativeKeyCode = code;
673      if (needs_shift_modifier)
674        key_down_event->modifiers |= WebInputEvent::ShiftKey;
675
676      // If a char event is needed, set the text fields.
677      if (generate_char) {
678        key_down_event->text[0] = text;
679        key_down_event->unmodifiedText[0] = text;
680      }
681      // Convert the key code to a string identifier.
682      key_down_event->setKeyIdentifierFromWindowsKeyCode();
683
684      *key_up_event = *web_char_event = *key_down_event;
685
686      events.push_back(linked_ptr<WebInputEvent>(key_down_event.release()));
687
688      if (generate_char) {
689        web_char_event->type = WebInputEvent::Char;
690        web_char_event->keyIdentifier[0] = '\0';
691        events.push_back(original_event);
692      }
693
694      key_up_event->type = WebInputEvent::KeyUp;
695      events.push_back(linked_ptr<WebInputEvent>(key_up_event.release()));
696      break;
697    }
698
699    default:
700      break;
701  }
702  return events;
703}
704
705PP_InputEvent_Class ClassifyInputEvent(WebInputEvent::Type type) {
706  switch (type) {
707    case WebInputEvent::MouseDown:
708    case WebInputEvent::MouseUp:
709    case WebInputEvent::MouseMove:
710    case WebInputEvent::MouseEnter:
711    case WebInputEvent::MouseLeave:
712    case WebInputEvent::ContextMenu:
713      return PP_INPUTEVENT_CLASS_MOUSE;
714    case WebInputEvent::MouseWheel:
715      return PP_INPUTEVENT_CLASS_WHEEL;
716    case WebInputEvent::RawKeyDown:
717    case WebInputEvent::KeyDown:
718    case WebInputEvent::KeyUp:
719    case WebInputEvent::Char:
720      return PP_INPUTEVENT_CLASS_KEYBOARD;
721    case WebInputEvent::TouchCancel:
722    case WebInputEvent::TouchEnd:
723    case WebInputEvent::TouchMove:
724    case WebInputEvent::TouchStart:
725      return PP_INPUTEVENT_CLASS_TOUCH;
726    case WebInputEvent::Undefined:
727    default:
728      NOTREACHED();
729      return PP_InputEvent_Class(0);
730  }
731}
732
733}  // namespace content
734