| // Copyright 2016 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 "ui/events/mojo/event_struct_traits.h" |
| |
| #include "ui/events/event.h" |
| #include "ui/events/event_utils.h" |
| #include "ui/events/keycodes/dom/keycode_converter.h" |
| #include "ui/events/mojo/event_constants.mojom.h" |
| |
| namespace mojo { |
| namespace { |
| |
| ui::mojom::EventType UIEventTypeToMojo(ui::EventType type) { |
| switch (type) { |
| case ui::ET_POINTER_DOWN: |
| return ui::mojom::EventType::POINTER_DOWN; |
| |
| case ui::ET_POINTER_MOVED: |
| return ui::mojom::EventType::POINTER_MOVE; |
| |
| case ui::ET_POINTER_EXITED: |
| return ui::mojom::EventType::MOUSE_EXIT; |
| |
| case ui::ET_POINTER_UP: |
| return ui::mojom::EventType::POINTER_UP; |
| |
| case ui::ET_POINTER_CANCELLED: |
| return ui::mojom::EventType::POINTER_CANCEL; |
| |
| case ui::ET_POINTER_WHEEL_CHANGED: |
| return ui::mojom::EventType::POINTER_WHEEL_CHANGED; |
| |
| case ui::ET_KEY_PRESSED: |
| return ui::mojom::EventType::KEY_PRESSED; |
| |
| case ui::ET_KEY_RELEASED: |
| return ui::mojom::EventType::KEY_RELEASED; |
| |
| default: |
| break; |
| } |
| return ui::mojom::EventType::UNKNOWN; |
| } |
| |
| ui::EventType MojoPointerEventTypeToUIEvent(ui::mojom::EventType action) { |
| switch (action) { |
| case ui::mojom::EventType::POINTER_DOWN: |
| return ui::ET_POINTER_DOWN; |
| |
| case ui::mojom::EventType::POINTER_UP: |
| return ui::ET_POINTER_UP; |
| |
| case ui::mojom::EventType::POINTER_MOVE: |
| return ui::ET_POINTER_MOVED; |
| |
| case ui::mojom::EventType::POINTER_CANCEL: |
| return ui::ET_POINTER_CANCELLED; |
| |
| case ui::mojom::EventType::MOUSE_EXIT: |
| return ui::ET_POINTER_EXITED; |
| |
| case ui::mojom::EventType::POINTER_WHEEL_CHANGED: |
| return ui::ET_POINTER_WHEEL_CHANGED; |
| |
| default: |
| NOTREACHED(); |
| } |
| |
| return ui::ET_UNKNOWN; |
| } |
| |
| } // namespace |
| |
| static_assert(ui::mojom::kEventFlagNone == static_cast<int32_t>(ui::EF_NONE), |
| "EVENT_FLAGS must match"); |
| static_assert(ui::mojom::kEventFlagIsSynthesized == |
| static_cast<int32_t>(ui::EF_IS_SYNTHESIZED), |
| "EVENT_FLAGS must match"); |
| static_assert(ui::mojom::kEventFlagShiftDown == |
| static_cast<int32_t>(ui::EF_SHIFT_DOWN), |
| "EVENT_FLAGS must match"); |
| static_assert(ui::mojom::kEventFlagControlDown == |
| static_cast<int32_t>(ui::EF_CONTROL_DOWN), |
| "EVENT_FLAGS must match"); |
| static_assert(ui::mojom::kEventFlagAltDown == |
| static_cast<int32_t>(ui::EF_ALT_DOWN), |
| "EVENT_FLAGS must match"); |
| static_assert(ui::mojom::kEventFlagCommandDown == |
| static_cast<int32_t>(ui::EF_COMMAND_DOWN), |
| "EVENT_FLAGS must match"); |
| static_assert(ui::mojom::kEventFlagAltgrDown == |
| static_cast<int32_t>(ui::EF_ALTGR_DOWN), |
| "EVENT_FLAGS must match"); |
| static_assert(ui::mojom::kEventFlagMod3Down == |
| static_cast<int32_t>(ui::EF_MOD3_DOWN), |
| "EVENT_FLAGS must match"); |
| static_assert(ui::mojom::kEventFlagNumLockOn == |
| static_cast<int32_t>(ui::EF_NUM_LOCK_ON), |
| "EVENT_FLAGS must match"); |
| static_assert(ui::mojom::kEventFlagCapsLockOn == |
| static_cast<int32_t>(ui::EF_CAPS_LOCK_ON), |
| "EVENT_FLAGS must match"); |
| static_assert(ui::mojom::kEventFlagScrollLockOn == |
| static_cast<int32_t>(ui::EF_SCROLL_LOCK_ON), |
| "EVENT_FLAGS must match"); |
| static_assert(ui::mojom::kEventFlagLeftMouseButton == |
| static_cast<int32_t>(ui::EF_LEFT_MOUSE_BUTTON), |
| "EVENT_FLAGS must match"); |
| static_assert(ui::mojom::kEventFlagMiddleMouseButton == |
| static_cast<int32_t>(ui::EF_MIDDLE_MOUSE_BUTTON), |
| "EVENT_FLAGS must match"); |
| static_assert(ui::mojom::kEventFlagRightMouseButton == |
| static_cast<int32_t>(ui::EF_RIGHT_MOUSE_BUTTON), |
| "EVENT_FLAGS must match"); |
| static_assert(ui::mojom::kEventFlagBackMouseButton == |
| static_cast<int32_t>(ui::EF_BACK_MOUSE_BUTTON), |
| "EVENT_FLAGS must match"); |
| static_assert(ui::mojom::kEventFlagForwardMouseButton == |
| static_cast<int32_t>(ui::EF_FORWARD_MOUSE_BUTTON), |
| "EVENT_FLAGS must match"); |
| |
| ui::mojom::EventType |
| StructTraits<ui::mojom::EventDataView, EventUniquePtr>::action( |
| const EventUniquePtr& event) { |
| return UIEventTypeToMojo(event->type()); |
| } |
| |
| int32_t StructTraits<ui::mojom::EventDataView, EventUniquePtr>::flags( |
| const EventUniquePtr& event) { |
| return event->flags(); |
| } |
| |
| int64_t StructTraits<ui::mojom::EventDataView, EventUniquePtr>::time_stamp( |
| const EventUniquePtr& event) { |
| return event->time_stamp().ToInternalValue(); |
| } |
| |
| ui::mojom::KeyDataPtr |
| StructTraits<ui::mojom::EventDataView, EventUniquePtr>::key_data( |
| const EventUniquePtr& event) { |
| if (!event->IsKeyEvent()) |
| return nullptr; |
| |
| const ui::KeyEvent* key_event = event->AsKeyEvent(); |
| ui::mojom::KeyDataPtr key_data(ui::mojom::KeyData::New()); |
| key_data->key_code = key_event->GetConflatedWindowsKeyCode(); |
| key_data->native_key_code = |
| ui::KeycodeConverter::DomCodeToNativeKeycode(key_event->code()); |
| key_data->is_char = key_event->is_char(); |
| key_data->character = key_event->GetCharacter(); |
| key_data->windows_key_code = static_cast<ui::mojom::KeyboardCode>( |
| key_event->GetLocatedWindowsKeyboardCode()); |
| key_data->text = key_event->GetText(); |
| key_data->unmodified_text = key_event->GetUnmodifiedText(); |
| |
| return key_data; |
| } |
| |
| ui::mojom::PointerDataPtr |
| StructTraits<ui::mojom::EventDataView, EventUniquePtr>::pointer_data( |
| const EventUniquePtr& event) { |
| if (!event->IsPointerEvent()) |
| return nullptr; |
| |
| const ui::PointerEvent* pointer_event = event->AsPointerEvent(); |
| ui::mojom::PointerDataPtr pointer_data(ui::mojom::PointerData::New()); |
| pointer_data->pointer_id = pointer_event->pointer_id(); |
| pointer_data->changed_button_flags = pointer_event->changed_button_flags(); |
| const ui::PointerDetails* pointer_details = &pointer_event->pointer_details(); |
| |
| switch (pointer_details->pointer_type) { |
| case ui::EventPointerType::POINTER_TYPE_MOUSE: |
| pointer_data->kind = ui::mojom::PointerKind::MOUSE; |
| break; |
| case ui::EventPointerType::POINTER_TYPE_TOUCH: |
| pointer_data->kind = ui::mojom::PointerKind::TOUCH; |
| break; |
| default: |
| NOTREACHED(); |
| } |
| |
| ui::mojom::BrushDataPtr brush_data(ui::mojom::BrushData::New()); |
| // TODO(rjk): this is in the wrong coordinate system |
| brush_data->width = pointer_details->radius_x; |
| brush_data->height = pointer_details->radius_y; |
| // TODO(rjk): update for touch_event->rotation_angle(); |
| brush_data->pressure = pointer_details->force; |
| brush_data->tilt_x = pointer_details->tilt_x; |
| brush_data->tilt_y = pointer_details->tilt_y; |
| pointer_data->brush_data = std::move(brush_data); |
| |
| // TODO(rjkroege): Plumb raw pointer events on windows. |
| // TODO(rjkroege): Handle force-touch on MacOS |
| // TODO(rjkroege): Adjust brush data appropriately for Android. |
| |
| ui::mojom::LocationDataPtr location_data(ui::mojom::LocationData::New()); |
| const ui::LocatedEvent* located_event = event->AsLocatedEvent(); |
| location_data->x = located_event->location_f().x(); |
| location_data->y = located_event->location_f().y(); |
| location_data->screen_x = located_event->root_location_f().x(); |
| location_data->screen_y = located_event->root_location_f().y(); |
| pointer_data->location = std::move(location_data); |
| |
| if (event->type() == ui::ET_POINTER_WHEEL_CHANGED) { |
| ui::mojom::WheelDataPtr wheel_data(ui::mojom::WheelData::New()); |
| |
| // TODO(rjkroege): Support page scrolling on windows by directly |
| // cracking into a mojo event when the native event is available. |
| wheel_data->mode = ui::mojom::WheelMode::LINE; |
| // TODO(rjkroege): Support precise scrolling deltas. |
| |
| if ((event->flags() & ui::EF_SHIFT_DOWN) != 0 && |
| pointer_details->offset.x() == 0) { |
| wheel_data->delta_x = pointer_details->offset.y(); |
| wheel_data->delta_y = 0; |
| wheel_data->delta_z = 0; |
| } else { |
| // TODO(rjkroege): support z in ui::Events. |
| wheel_data->delta_x = pointer_details->offset.x(); |
| wheel_data->delta_y = pointer_details->offset.y(); |
| wheel_data->delta_z = 0; |
| } |
| pointer_data->wheel_data = std::move(wheel_data); |
| } |
| |
| return pointer_data; |
| } |
| |
| bool StructTraits<ui::mojom::EventDataView, EventUniquePtr>::Read( |
| ui::mojom::EventDataView event, |
| EventUniquePtr* out) { |
| switch (event.action()) { |
| case ui::mojom::EventType::KEY_PRESSED: |
| case ui::mojom::EventType::KEY_RELEASED: { |
| ui::mojom::KeyDataPtr key_data; |
| if (!event.ReadKeyData<ui::mojom::KeyDataPtr>(&key_data)) |
| return false; |
| |
| if (key_data->is_char) { |
| out->reset(new ui::KeyEvent( |
| static_cast<base::char16>(key_data->character), |
| static_cast<ui::KeyboardCode>(key_data->key_code), event.flags())); |
| return true; |
| } |
| out->reset(new ui::KeyEvent( |
| event.action() == ui::mojom::EventType::KEY_PRESSED |
| ? ui::ET_KEY_PRESSED |
| : ui::ET_KEY_RELEASED, |
| |
| static_cast<ui::KeyboardCode>(key_data->key_code), event.flags())); |
| return true; |
| } |
| case ui::mojom::EventType::POINTER_DOWN: |
| case ui::mojom::EventType::POINTER_UP: |
| case ui::mojom::EventType::POINTER_MOVE: |
| case ui::mojom::EventType::POINTER_CANCEL: |
| case ui::mojom::EventType::MOUSE_EXIT: |
| case ui::mojom::EventType::POINTER_WHEEL_CHANGED: { |
| ui::mojom::PointerDataPtr pointer_data; |
| if (!event.ReadPointerData<ui::mojom::PointerDataPtr>(&pointer_data)) |
| return false; |
| |
| const gfx::Point location(pointer_data->location->x, |
| pointer_data->location->y); |
| const gfx::Point screen_location(pointer_data->location->screen_x, |
| pointer_data->location->screen_y); |
| |
| switch (pointer_data->kind) { |
| case ui::mojom::PointerKind::MOUSE: { |
| out->reset(new ui::PointerEvent( |
| MojoPointerEventTypeToUIEvent(event.action()), location, |
| screen_location, event.flags(), ui::PointerEvent::kMousePointerId, |
| pointer_data->changed_button_flags, |
| event.action() == ui::mojom::EventType::POINTER_WHEEL_CHANGED |
| ? ui::PointerDetails( |
| ui::EventPointerType::POINTER_TYPE_MOUSE, |
| gfx::Vector2d( |
| static_cast<int>(pointer_data->wheel_data->delta_x), |
| static_cast<int>( |
| pointer_data->wheel_data->delta_y))) |
| : ui::PointerDetails( |
| ui::EventPointerType::POINTER_TYPE_MOUSE), |
| ui::EventTimeForNow())); |
| return true; |
| } |
| case ui::mojom::PointerKind::TOUCH: { |
| out->reset(new ui::PointerEvent( |
| MojoPointerEventTypeToUIEvent(event.action()), location, |
| screen_location, event.flags(), pointer_data->pointer_id, |
| pointer_data->changed_button_flags, |
| ui::PointerDetails(ui::EventPointerType::POINTER_TYPE_TOUCH, |
| pointer_data->brush_data->width, |
| pointer_data->brush_data->height, |
| pointer_data->brush_data->pressure, |
| pointer_data->brush_data->tilt_x, |
| pointer_data->brush_data->tilt_y), |
| ui::EventTimeForNow())); |
| return true; |
| } |
| case ui::mojom::PointerKind::PEN: |
| NOTIMPLEMENTED(); |
| return false; |
| } |
| } |
| case ui::mojom::EventType::UNKNOWN: |
| return false; |
| } |
| |
| return false; |
| } |
| |
| } // namespace mojo |