summaryrefslogtreecommitdiffstats
path: root/webkit/plugins/ppapi/event_conversion.cc
diff options
context:
space:
mode:
Diffstat (limited to 'webkit/plugins/ppapi/event_conversion.cc')
-rw-r--r--webkit/plugins/ppapi/event_conversion.cc302
1 files changed, 302 insertions, 0 deletions
diff --git a/webkit/plugins/ppapi/event_conversion.cc b/webkit/plugins/ppapi/event_conversion.cc
new file mode 100644
index 0000000..c5e8fac
--- /dev/null
+++ b/webkit/plugins/ppapi/event_conversion.cc
@@ -0,0 +1,302 @@
+// Copyright (c) 2010 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "webkit/plugins/ppapi/event_conversion.h"
+
+#include "base/i18n/char_iterator.h"
+#include "base/logging.h"
+#include "base/scoped_ptr.h"
+#include "base/string_util.h"
+#include "base/utf_string_conversions.h"
+#include "base/utf_string_conversion_utils.h"
+#include "ppapi/c/pp_input_event.h"
+#include "third_party/WebKit/WebKit/chromium/public/WebInputEvent.h"
+#include "webkit/plugins/ppapi/common.h"
+
+using WebKit::WebInputEvent;
+using WebKit::WebKeyboardEvent;
+using WebKit::WebMouseEvent;
+using WebKit::WebMouseWheelEvent;
+
+namespace webkit {
+namespace ppapi {
+
+namespace {
+
+PP_InputEvent_Type ConvertEventTypes(WebInputEvent::Type wetype) {
+ switch (wetype) {
+ case WebInputEvent::MouseDown:
+ return PP_INPUTEVENT_TYPE_MOUSEDOWN;
+ case WebInputEvent::MouseUp:
+ return PP_INPUTEVENT_TYPE_MOUSEUP;
+ case WebInputEvent::MouseMove:
+ return PP_INPUTEVENT_TYPE_MOUSEMOVE;
+ case WebInputEvent::MouseEnter:
+ return PP_INPUTEVENT_TYPE_MOUSEENTER;
+ case WebInputEvent::MouseLeave:
+ return PP_INPUTEVENT_TYPE_MOUSELEAVE;
+ case WebInputEvent::MouseWheel:
+ return PP_INPUTEVENT_TYPE_MOUSEWHEEL;
+ case WebInputEvent::RawKeyDown:
+ return PP_INPUTEVENT_TYPE_RAWKEYDOWN;
+ case WebInputEvent::KeyDown:
+ return PP_INPUTEVENT_TYPE_KEYDOWN;
+ case WebInputEvent::KeyUp:
+ return PP_INPUTEVENT_TYPE_KEYUP;
+ case WebInputEvent::Char:
+ return PP_INPUTEVENT_TYPE_CHAR;
+ case WebInputEvent::Undefined:
+ default:
+ return PP_INPUTEVENT_TYPE_UNDEFINED;
+ }
+}
+
+// Generates a PP_InputEvent with the fields common to all events, as well as
+// the event type from the given web event. Event-specific fields will be zero
+// initialized.
+PP_InputEvent GetPPEventWithCommonFieldsAndType(
+ const WebInputEvent& web_event) {
+ PP_InputEvent result;
+ memset(&result, 0, sizeof(PP_InputEvent));
+ result.type = ConvertEventTypes(web_event.type);
+ // TODO(brettw) http://code.google.com/p/chromium/issues/detail?id=57448
+ // This should use a tick count rather than the wall clock time that WebKit
+ // uses.
+ result.time_stamp = web_event.timeStampSeconds;
+ return result;
+}
+
+void AppendKeyEvent(const WebInputEvent& event,
+ std::vector<PP_InputEvent>* pp_events) {
+ const WebKeyboardEvent& key_event =
+ reinterpret_cast<const WebKeyboardEvent&>(event);
+ PP_InputEvent result = GetPPEventWithCommonFieldsAndType(event);
+ result.u.key.modifier = key_event.modifiers;
+ result.u.key.key_code = key_event.windowsKeyCode;
+ pp_events->push_back(result);
+}
+
+void AppendCharEvent(const WebInputEvent& event,
+ std::vector<PP_InputEvent>* pp_events) {
+ const WebKeyboardEvent& key_event =
+ reinterpret_cast<const WebKeyboardEvent&>(event);
+
+ // This is a bit complex, the input event will normally just have one 16-bit
+ // character in it, but may be zero or more than one. The text array is
+ // just padded with 0 values for the unused ones, but is not necessarily
+ // null-terminated.
+ //
+ // Here we see how many UTF-16 characters we have.
+ size_t utf16_char_count = 0;
+ while (utf16_char_count < WebKeyboardEvent::textLengthCap &&
+ key_event.text[utf16_char_count])
+ utf16_char_count++;
+
+ // Make a separate PP_InputEvent for each Unicode character in the input.
+ base::UTF16CharIterator iter(key_event.text, utf16_char_count);
+ while (!iter.end()) {
+ PP_InputEvent result = GetPPEventWithCommonFieldsAndType(event);
+ result.u.character.modifier = key_event.modifiers;
+
+ std::string utf8_char;
+ base::WriteUnicodeCharacter(iter.get(), &utf8_char);
+ base::strlcpy(result.u.character.text, utf8_char.c_str(),
+ sizeof(result.u.character.text));
+
+ pp_events->push_back(result);
+ iter.Advance();
+ }
+}
+
+void AppendMouseEvent(const WebInputEvent& event,
+ std::vector<PP_InputEvent>* pp_events) {
+ COMPILE_ASSERT(static_cast<int>(WebMouseEvent::ButtonNone) ==
+ static_cast<int>(PP_INPUTEVENT_MOUSEBUTTON_NONE),
+ MouseNone);
+ COMPILE_ASSERT(static_cast<int>(WebMouseEvent::ButtonLeft) ==
+ static_cast<int>(PP_INPUTEVENT_MOUSEBUTTON_LEFT),
+ MouseLeft);
+ COMPILE_ASSERT(static_cast<int>(WebMouseEvent::ButtonRight) ==
+ static_cast<int>(PP_INPUTEVENT_MOUSEBUTTON_RIGHT),
+ MouseRight);
+ COMPILE_ASSERT(static_cast<int>(WebMouseEvent::ButtonMiddle) ==
+ static_cast<int>(PP_INPUTEVENT_MOUSEBUTTON_MIDDLE),
+ MouseMiddle);
+
+ const WebMouseEvent& mouse_event =
+ reinterpret_cast<const WebMouseEvent&>(event);
+ PP_InputEvent result = GetPPEventWithCommonFieldsAndType(event);
+ result.u.mouse.modifier = mouse_event.modifiers;
+ result.u.mouse.button =
+ static_cast<PP_InputEvent_MouseButton>(mouse_event.button);
+ result.u.mouse.x = static_cast<float>(mouse_event.x);
+ result.u.mouse.y = static_cast<float>(mouse_event.y);
+ result.u.mouse.click_count = mouse_event.clickCount;
+ pp_events->push_back(result);
+}
+
+void AppendMouseWheelEvent(const WebInputEvent& event,
+ std::vector<PP_InputEvent>* pp_events) {
+ const WebMouseWheelEvent& mouse_wheel_event =
+ reinterpret_cast<const WebMouseWheelEvent&>(event);
+ PP_InputEvent result = GetPPEventWithCommonFieldsAndType(event);
+ result.u.wheel.modifier = mouse_wheel_event.modifiers;
+ result.u.wheel.delta_x = mouse_wheel_event.deltaX;
+ result.u.wheel.delta_y = mouse_wheel_event.deltaY;
+ result.u.wheel.wheel_ticks_x = mouse_wheel_event.wheelTicksX;
+ result.u.wheel.wheel_ticks_y = mouse_wheel_event.wheelTicksY;
+ result.u.wheel.scroll_by_page =
+ BoolToPPBool(!!mouse_wheel_event.scrollByPage);
+ pp_events->push_back(result);
+}
+
+WebKeyboardEvent* BuildKeyEvent(const PP_InputEvent& event) {
+ WebKeyboardEvent* key_event = new WebKeyboardEvent();
+ switch (event.type) {
+ case PP_INPUTEVENT_TYPE_RAWKEYDOWN:
+ key_event->type = WebInputEvent::RawKeyDown;
+ break;
+ case PP_INPUTEVENT_TYPE_KEYDOWN:
+ key_event->type = WebInputEvent::KeyDown;
+ break;
+ case PP_INPUTEVENT_TYPE_KEYUP:
+ key_event->type = WebInputEvent::KeyUp;
+ break;
+ default:
+ NOTREACHED();
+ }
+ key_event->timeStampSeconds = event.time_stamp;
+ key_event->modifiers = event.u.key.modifier;
+ key_event->windowsKeyCode = event.u.key.key_code;
+ return key_event;
+}
+
+WebKeyboardEvent* BuildCharEvent(const PP_InputEvent& event) {
+ WebKeyboardEvent* key_event = new WebKeyboardEvent();
+ key_event->type = WebInputEvent::Char;
+ key_event->timeStampSeconds = event.time_stamp;
+ key_event->modifiers = event.u.character.modifier;
+
+ // Make sure to not read beyond the buffer in case some bad code doesn't
+ // NULL-terminate it (this is called from plugins).
+ size_t text_length_cap = WebKeyboardEvent::textLengthCap;
+ size_t text_len = 0;
+ while (text_len < text_length_cap && event.u.character.text[text_len])
+ text_len++;
+ string16 text16 = UTF8ToUTF16(std::string(event.u.character.text, text_len));
+
+ memset(key_event->text, 0, text_length_cap);
+ memset(key_event->unmodifiedText, 0, text_length_cap);
+ for (size_t i = 0;
+ i < std::min(text_length_cap, text16.size());
+ ++i)
+ key_event->text[i] = text16[i];
+ return key_event;
+}
+
+WebMouseEvent* BuildMouseEvent(const PP_InputEvent& event) {
+ WebMouseEvent* mouse_event = new WebMouseEvent();
+ switch (event.type) {
+ case PP_INPUTEVENT_TYPE_MOUSEDOWN:
+ mouse_event->type = WebInputEvent::MouseDown;
+ break;
+ case PP_INPUTEVENT_TYPE_MOUSEUP:
+ mouse_event->type = WebInputEvent::MouseUp;
+ break;
+ case PP_INPUTEVENT_TYPE_MOUSEMOVE:
+ mouse_event->type = WebInputEvent::MouseMove;
+ break;
+ case PP_INPUTEVENT_TYPE_MOUSEENTER:
+ mouse_event->type = WebInputEvent::MouseEnter;
+ break;
+ case PP_INPUTEVENT_TYPE_MOUSELEAVE:
+ mouse_event->type = WebInputEvent::MouseLeave;
+ break;
+ default:
+ NOTREACHED();
+ }
+ mouse_event->timeStampSeconds = event.time_stamp;
+ mouse_event->modifiers = event.u.mouse.modifier;
+ mouse_event->button =
+ static_cast<WebMouseEvent::Button>(event.u.mouse.button);
+ mouse_event->x = static_cast<int>(event.u.mouse.x);
+ mouse_event->y = static_cast<int>(event.u.mouse.y);
+ mouse_event->clickCount = event.u.mouse.click_count;
+ return mouse_event;
+}
+
+WebMouseWheelEvent* BuildMouseWheelEvent(const PP_InputEvent& event) {
+ WebMouseWheelEvent* mouse_wheel_event = new WebMouseWheelEvent();
+ mouse_wheel_event->type = WebInputEvent::MouseWheel;
+ mouse_wheel_event->timeStampSeconds = event.time_stamp;
+ mouse_wheel_event->modifiers = event.u.wheel.modifier;
+ mouse_wheel_event->deltaX = event.u.wheel.delta_x;
+ mouse_wheel_event->deltaY = event.u.wheel.delta_y;
+ mouse_wheel_event->wheelTicksX = event.u.wheel.wheel_ticks_x;
+ mouse_wheel_event->wheelTicksY = event.u.wheel.wheel_ticks_y;
+ mouse_wheel_event->scrollByPage = event.u.wheel.scroll_by_page;
+ return mouse_wheel_event;
+}
+
+} // namespace
+
+void CreatePPEvent(const WebInputEvent& event,
+ std::vector<PP_InputEvent>* pp_events) {
+ pp_events->clear();
+
+ switch (event.type) {
+ case WebInputEvent::MouseDown:
+ case WebInputEvent::MouseUp:
+ case WebInputEvent::MouseMove:
+ case WebInputEvent::MouseEnter:
+ case WebInputEvent::MouseLeave:
+ AppendMouseEvent(event, pp_events);
+ break;
+ case WebInputEvent::MouseWheel:
+ AppendMouseWheelEvent(event, pp_events);
+ break;
+ case WebInputEvent::RawKeyDown:
+ case WebInputEvent::KeyDown:
+ case WebInputEvent::KeyUp:
+ AppendKeyEvent(event, pp_events);
+ break;
+ case WebInputEvent::Char:
+ AppendCharEvent(event, pp_events);
+ break;
+ case WebInputEvent::Undefined:
+ default:
+ break;
+ }
+}
+
+WebInputEvent* CreateWebInputEvent(const PP_InputEvent& event) {
+ scoped_ptr<WebInputEvent> web_input_event;
+ switch (event.type) {
+ case PP_INPUTEVENT_TYPE_UNDEFINED:
+ return NULL;
+ case PP_INPUTEVENT_TYPE_MOUSEDOWN:
+ case PP_INPUTEVENT_TYPE_MOUSEUP:
+ case PP_INPUTEVENT_TYPE_MOUSEMOVE:
+ case PP_INPUTEVENT_TYPE_MOUSEENTER:
+ case PP_INPUTEVENT_TYPE_MOUSELEAVE:
+ web_input_event.reset(BuildMouseEvent(event));
+ break;
+ case PP_INPUTEVENT_TYPE_MOUSEWHEEL:
+ web_input_event.reset(BuildMouseWheelEvent(event));
+ break;
+ case PP_INPUTEVENT_TYPE_RAWKEYDOWN:
+ case PP_INPUTEVENT_TYPE_KEYDOWN:
+ case PP_INPUTEVENT_TYPE_KEYUP:
+ web_input_event.reset(BuildKeyEvent(event));
+ break;
+ case PP_INPUTEVENT_TYPE_CHAR:
+ web_input_event.reset(BuildCharEvent(event));
+ break;
+ }
+
+ return web_input_event.release();
+}
+} // namespace ppapi
+} // namespace webkit
+