| // Copyright 2020 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 "pdf/ppapi_migration/input_event_conversions.h" |
| |
| #include <stdint.h> |
| |
| #include <algorithm> |
| #include <memory> |
| |
| #include "base/check_op.h" |
| #include "base/notreached.h" |
| #include "base/strings/utf_string_conversions.h" |
| #include "base/time/time.h" |
| #include "pdf/ppapi_migration/geometry_conversions.h" |
| #include "ppapi/c/dev/pp_cursor_type_dev.h" |
| #include "ppapi/cpp/input_event.h" |
| #include "ppapi/cpp/var.h" |
| #include "third_party/blink/public/common/input/web_input_event.h" |
| #include "third_party/blink/public/common/input/web_keyboard_event.h" |
| #include "third_party/blink/public/common/input/web_mouse_event.h" |
| #include "third_party/blink/public/common/input/web_pointer_properties.h" |
| #include "third_party/blink/public/common/input/web_touch_event.h" |
| #include "ui/base/cursor/mojom/cursor_type.mojom-shared.h" |
| |
| namespace chrome_pdf { |
| |
| namespace { |
| |
| blink::WebInputEvent::Type GetWebInputEventType(PP_InputEvent_Type event_type) { |
| switch (event_type) { |
| case PP_INPUTEVENT_TYPE_MOUSEDOWN: |
| return blink::WebInputEvent::Type::kMouseDown; |
| case PP_INPUTEVENT_TYPE_MOUSEUP: |
| return blink::WebInputEvent::Type::kMouseUp; |
| case PP_INPUTEVENT_TYPE_MOUSEMOVE: |
| return blink::WebInputEvent::Type::kMouseMove; |
| case PP_INPUTEVENT_TYPE_MOUSEENTER: |
| return blink::WebInputEvent::Type::kMouseEnter; |
| case PP_INPUTEVENT_TYPE_MOUSELEAVE: |
| return blink::WebInputEvent::Type::kMouseLeave; |
| case PP_INPUTEVENT_TYPE_WHEEL: |
| return blink::WebInputEvent::Type::kMouseWheel; |
| case PP_INPUTEVENT_TYPE_RAWKEYDOWN: |
| case PP_INPUTEVENT_TYPE_KEYDOWN: |
| // Blink no longer passes `kKeyDown` events into plugins, and instead |
| // passes `kRawKeyDown` events. However, `kRawKeyDown` gets mapped to |
| // `PP_INPUTEVENT_TYPE_KEYDOWN` for backwards compatibility. Map both |
| // Pepper enums to `kRawKeyDown` to allow for a common implementation |
| // between the Pepper and Pepper-free plugins. |
| // See the comments inside the definition of `ConvertEventTypes()` in |
| // content/renderer/pepper/event_conversion.cc. |
| return blink::WebInputEvent::Type::kRawKeyDown; |
| case PP_INPUTEVENT_TYPE_KEYUP: |
| return blink::WebInputEvent::Type::kKeyUp; |
| case PP_INPUTEVENT_TYPE_CHAR: |
| return blink::WebInputEvent::Type::kChar; |
| case PP_INPUTEVENT_TYPE_CONTEXTMENU: |
| return blink::WebInputEvent::Type::kContextMenu; |
| case PP_INPUTEVENT_TYPE_TOUCHSTART: |
| return blink::WebInputEvent::Type::kTouchStart; |
| case PP_INPUTEVENT_TYPE_TOUCHMOVE: |
| return blink::WebInputEvent::Type::kTouchMove; |
| case PP_INPUTEVENT_TYPE_TOUCHEND: |
| return blink::WebInputEvent::Type::kTouchEnd; |
| case PP_INPUTEVENT_TYPE_TOUCHCANCEL: |
| return blink::WebInputEvent::Type::kTouchCancel; |
| default: |
| NOTREACHED(); |
| return blink::WebInputEvent::Type::kUndefined; |
| } |
| } |
| |
| blink::WebPointerProperties::Button GetWebPointerPropertiesButton( |
| const PP_InputEvent_MouseButton& button_type) { |
| switch (button_type) { |
| case PP_INPUTEVENT_MOUSEBUTTON_LEFT: |
| return blink::WebPointerProperties::Button::kLeft; |
| case PP_INPUTEVENT_MOUSEBUTTON_MIDDLE: |
| return blink::WebPointerProperties::Button::kMiddle; |
| case PP_INPUTEVENT_MOUSEBUTTON_RIGHT: |
| return blink::WebPointerProperties::Button::kRight; |
| default: |
| // No other mouse button type is handled by the PDF plugin. |
| return blink::WebPointerProperties::Button::kNoButton; |
| } |
| } |
| |
| std::unique_ptr<blink::WebMouseEvent> GetWebMouseEvent( |
| const pp::MouseInputEvent& event) { |
| const blink::WebInputEvent::Type type = GetWebInputEventType(event.GetType()); |
| DCHECK(blink::WebInputEvent::IsMouseEventType(type)); |
| DCHECK_NE(type, blink::WebInputEvent::Type::kContextMenu); |
| |
| auto mouse_event = std::make_unique<blink::WebMouseEvent>( |
| type, event.GetModifiers(), |
| base::TimeTicks() + base::TimeDelta::FromSecondsD(event.GetTimeStamp())); |
| |
| mouse_event->button = GetWebPointerPropertiesButton(event.GetButton()); |
| mouse_event->click_count = event.GetClickCount(); |
| |
| const pp::Point& position = event.GetPosition(); |
| mouse_event->SetPositionInWidget(position.x(), position.y()); |
| |
| return mouse_event; |
| } |
| |
| std::unique_ptr<blink::WebKeyboardEvent> GetWebKeyboardEvent( |
| const pp::KeyboardInputEvent& event) { |
| const blink::WebInputEvent::Type type = GetWebInputEventType(event.GetType()); |
| DCHECK(blink::WebInputEvent::IsKeyboardEventType(type)); |
| |
| auto keyboard_event = std::make_unique<blink::WebKeyboardEvent>( |
| type, event.GetModifiers(), |
| base::TimeTicks() + base::TimeDelta::FromSecondsD(event.GetTimeStamp())); |
| |
| keyboard_event->windows_key_code = event.GetKeyCode(); |
| |
| const std::u16string text16 = |
| base::UTF8ToUTF16(event.GetCharacterText().AsString()); |
| const size_t text_len = |
| std::min(blink::WebKeyboardEvent::kTextLengthCap, text16.size()); |
| std::copy_n(text16.begin(), text_len, keyboard_event->text); |
| std::fill_n(keyboard_event->text + text_len, |
| blink::WebKeyboardEvent::kTextLengthCap - text_len, L'\0'); |
| |
| return keyboard_event; |
| } |
| |
| std::unique_ptr<blink::WebTouchEvent> GetWebTouchEvent( |
| const pp::TouchInputEvent& event) { |
| const blink::WebInputEvent::Type type = GetWebInputEventType(event.GetType()); |
| DCHECK(blink::WebInputEvent::IsTouchEventType(type)); |
| DCHECK_NE(type, blink::WebInputEvent::Type::kTouchScrollStarted); |
| |
| auto touch_event = std::make_unique<blink::WebTouchEvent>( |
| type, event.GetModifiers(), |
| base::TimeTicks() + base::TimeDelta::FromSecondsD(event.GetTimeStamp())); |
| |
| // The PDF plugin only cares about the first touch and the number of touches, |
| // but copy over all the touches so that `touch_event->touches_length` |
| // accurately stores the length of `touches`. |
| touch_event->touches_length = |
| std::min<uint32_t>(blink::WebTouchEvent::kTouchesLengthCap, |
| event.GetTouchCount(PP_TOUCHLIST_TYPE_TARGETTOUCHES)); |
| for (size_t i = 0; i < touch_event->touches_length; ++i) { |
| touch_event->touches[i].SetPositionInWidget(PointFFromPPFloatPoint( |
| event.GetTouchByIndex(PP_TOUCHLIST_TYPE_TARGETTOUCHES, i).position())); |
| } |
| |
| return touch_event; |
| } |
| |
| } // namespace |
| |
| std::unique_ptr<blink::WebInputEvent> GetWebInputEvent( |
| const pp::InputEvent& event) { |
| switch (GetWebInputEventType(event.GetType())) { |
| case blink::WebInputEvent::Type::kMouseDown: |
| case blink::WebInputEvent::Type::kMouseUp: |
| case blink::WebInputEvent::Type::kMouseMove: |
| case blink::WebInputEvent::Type::kMouseEnter: |
| case blink::WebInputEvent::Type::kMouseLeave: |
| return GetWebMouseEvent(pp::MouseInputEvent(event)); |
| case blink::WebInputEvent::Type::kRawKeyDown: |
| case blink::WebInputEvent::Type::kKeyUp: |
| case blink::WebInputEvent::Type::kChar: |
| return GetWebKeyboardEvent(pp::KeyboardInputEvent(event)); |
| case blink::WebInputEvent::Type::kTouchStart: |
| case blink::WebInputEvent::Type::kTouchMove: |
| case blink::WebInputEvent::Type::kTouchEnd: |
| case blink::WebInputEvent::Type::kTouchCancel: |
| return GetWebTouchEvent(pp::TouchInputEvent(event)); |
| default: |
| // Don't bother converting event types not handled by the PDF plugin. |
| return nullptr; |
| } |
| } |
| |
| PP_CursorType_Dev PPCursorTypeFromCursorType( |
| ui::mojom::CursorType cursor_type) { |
| switch (cursor_type) { |
| case ui::mojom::CursorType::kPointer: |
| return PP_CURSORTYPE_POINTER; |
| case ui::mojom::CursorType::kHand: |
| return PP_CURSORTYPE_HAND; |
| case ui::mojom::CursorType::kIBeam: |
| return PP_CURSORTYPE_IBEAM; |
| default: |
| NOTREACHED(); |
| return PP_CURSORTYPE_POINTER; |
| } |
| } |
| |
| } // namespace chrome_pdf |