| // Copyright 2014 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 "mojo/converters/input_events/input_events_type_converters.h" |
| |
| #if defined(USE_X11) |
| #include <X11/extensions/XInput2.h> |
| #include <X11/Xlib.h> |
| #endif |
| |
| #include "mojo/converters/geometry/geometry_type_converters.h" |
| #include "mojo/converters/input_events/mojo_extended_key_event_data.h" |
| #include "third_party/mojo_services/src/input_events/public/interfaces/input_events.mojom.h" |
| #include "ui/events/event_utils.h" |
| #include "ui/events/keycodes/keyboard_codes.h" |
| |
| namespace mojo { |
| |
| COMPILE_ASSERT(static_cast<int32>(EVENT_FLAGS_NONE) == |
| static_cast<int32>(ui::EF_NONE), |
| event_flags_should_match); |
| COMPILE_ASSERT(static_cast<int32>(EVENT_FLAGS_CAPS_LOCK_DOWN) == |
| static_cast<int32>(ui::EF_CAPS_LOCK_DOWN), |
| event_flags_should_match); |
| COMPILE_ASSERT(static_cast<int32>(EVENT_FLAGS_SHIFT_DOWN) == |
| static_cast<int32>(ui::EF_SHIFT_DOWN), |
| event_flags_should_match); |
| COMPILE_ASSERT(static_cast<int32>(EVENT_FLAGS_CONTROL_DOWN) == |
| static_cast<int32>(ui::EF_CONTROL_DOWN), |
| event_flags_should_match); |
| COMPILE_ASSERT(static_cast<int32>(EVENT_FLAGS_ALT_DOWN) == |
| static_cast<int32>(ui::EF_ALT_DOWN), |
| event_flags_should_match); |
| COMPILE_ASSERT(static_cast<int32>(EVENT_FLAGS_LEFT_MOUSE_BUTTON) == |
| static_cast<int32>(ui::EF_LEFT_MOUSE_BUTTON), |
| event_flags_should_match); |
| COMPILE_ASSERT(static_cast<int32>(EVENT_FLAGS_MIDDLE_MOUSE_BUTTON) == |
| static_cast<int32>(ui::EF_MIDDLE_MOUSE_BUTTON), |
| event_flags_should_match); |
| COMPILE_ASSERT(static_cast<int32>(EVENT_FLAGS_RIGHT_MOUSE_BUTTON) == |
| static_cast<int32>(ui::EF_RIGHT_MOUSE_BUTTON), |
| event_flags_should_match); |
| COMPILE_ASSERT(static_cast<int32>(EVENT_FLAGS_COMMAND_DOWN) == |
| static_cast<int32>(ui::EF_COMMAND_DOWN), |
| event_flags_should_match); |
| COMPILE_ASSERT(static_cast<int32>(EVENT_FLAGS_EXTENDED) == |
| static_cast<int32>(ui::EF_EXTENDED), |
| event_flags_should_match); |
| COMPILE_ASSERT(static_cast<int32>(EVENT_FLAGS_IS_SYNTHESIZED) == |
| static_cast<int32>(ui::EF_IS_SYNTHESIZED), |
| event_flags_should_match); |
| COMPILE_ASSERT(static_cast<int32>(EVENT_FLAGS_ALTGR_DOWN) == |
| static_cast<int32>(ui::EF_ALTGR_DOWN), |
| event_flags_should_match); |
| COMPILE_ASSERT(static_cast<int32>(EVENT_FLAGS_MOD3_DOWN) == |
| static_cast<int32>(ui::EF_MOD3_DOWN), |
| event_flags_should_match); |
| |
| |
| // static |
| EventType TypeConverter<EventType, ui::EventType>::Convert(ui::EventType type) { |
| #define MOJO_INPUT_EVENT_NAME(name) case ui::ET_##name: return EVENT_TYPE_##name |
| |
| switch (type) { |
| #include "mojo/converters/input_events/input_event_names.h" |
| case ui::ET_LAST: |
| NOTREACHED(); |
| break; |
| } |
| |
| #undef MOJO_INPUT_EVENT_NAME |
| |
| NOTREACHED(); |
| return EVENT_TYPE_UNKNOWN; |
| } |
| |
| // static |
| ui::EventType TypeConverter<ui::EventType, EventType>::Convert(EventType type) { |
| #define MOJO_INPUT_EVENT_NAME(name) case EVENT_TYPE_##name: return ui::ET_##name |
| |
| switch (type) { |
| #include "mojo/converters/input_events/input_event_names.h" |
| } |
| |
| #undef MOJO_INPUT_EVENT_NAME |
| |
| NOTREACHED(); |
| return ui::ET_UNKNOWN; |
| } |
| |
| // static |
| EventPtr TypeConverter<EventPtr, ui::Event>::Convert(const ui::Event& input) { |
| EventPtr event(Event::New()); |
| event->action = ConvertTo<EventType>(input.type()); |
| event->flags = EventFlags(input.flags()); |
| event->time_stamp = input.time_stamp().ToInternalValue(); |
| |
| if (input.IsMouseEvent() || input.IsTouchEvent()) { |
| const ui::LocatedEvent* located_event = |
| static_cast<const ui::LocatedEvent*>(&input); |
| |
| LocationDataPtr location_data(LocationData::New()); |
| location_data->in_view_location = Point::From(located_event->location()); |
| if (input.HasNativeEvent()) { |
| location_data->screen_location = |
| Point::From(ui::EventSystemLocationFromNative(input.native_event())); |
| } |
| |
| event->location_data = location_data.Pass(); |
| } |
| |
| if (input.IsTouchEvent()) { |
| const ui::TouchEvent* touch_event = |
| static_cast<const ui::TouchEvent*>(&input); |
| TouchDataPtr touch_data(TouchData::New()); |
| touch_data->pointer_id = touch_event->touch_id(); |
| event->touch_data = touch_data.Pass(); |
| } else if (input.IsKeyEvent()) { |
| const ui::KeyEvent* key_event = static_cast<const ui::KeyEvent*>(&input); |
| KeyDataPtr key_data(KeyData::New()); |
| key_data->key_code = key_event->GetConflatedWindowsKeyCode(); |
| key_data->native_key_code = key_event->platform_keycode(); |
| key_data->is_char = key_event->is_char(); |
| key_data->character = key_event->GetCharacter(); |
| |
| if (key_event->extended_key_event_data()) { |
| const MojoExtendedKeyEventData* data = |
| static_cast<const MojoExtendedKeyEventData*>( |
| key_event->extended_key_event_data()); |
| key_data->windows_key_code = static_cast<mojo::KeyboardCode>( |
| data->windows_key_code()); |
| key_data->text = data->text(); |
| key_data->unmodified_text = data->unmodified_text(); |
| } else { |
| key_data->windows_key_code = static_cast<mojo::KeyboardCode>( |
| key_event->GetLocatedWindowsKeyboardCode()); |
| key_data->text = key_event->GetText(); |
| key_data->unmodified_text = key_event->GetUnmodifiedText(); |
| } |
| |
| event->key_data = key_data.Pass(); |
| } else if (input.IsMouseWheelEvent()) { |
| const ui::MouseWheelEvent* wheel_event = |
| static_cast<const ui::MouseWheelEvent*>(&input); |
| MouseWheelDataPtr wheel_data(MouseWheelData::New()); |
| wheel_data->x_offset = wheel_event->x_offset(); |
| wheel_data->y_offset = wheel_event->y_offset(); |
| event->wheel_data = wheel_data.Pass(); |
| } |
| return event.Pass(); |
| } |
| |
| // static |
| EventPtr TypeConverter<EventPtr, ui::KeyEvent>::Convert( |
| const ui::KeyEvent& input) { |
| return Event::From(static_cast<const ui::Event&>(input)); |
| } |
| |
| // static |
| scoped_ptr<ui::Event> TypeConverter<scoped_ptr<ui::Event>, EventPtr>::Convert( |
| const EventPtr& input) { |
| scoped_ptr<ui::Event> ui_event; |
| ui::EventType ui_event_type = ConvertTo<ui::EventType>(input->action); |
| |
| gfx::Point location; |
| if (!input->location_data.is_null() && |
| !input->location_data->in_view_location.is_null()) { |
| location = input->location_data->in_view_location.To<gfx::Point>(); |
| } |
| |
| switch (input->action) { |
| case ui::ET_KEY_PRESSED: |
| case ui::ET_KEY_RELEASED: { |
| scoped_ptr<ui::KeyEvent> key_event; |
| if (input->key_data->is_char) { |
| key_event.reset(new ui::KeyEvent( |
| static_cast<base::char16>(input->key_data->character), |
| static_cast<ui::KeyboardCode>( |
| input->key_data->key_code), |
| input->flags)); |
| } else { |
| key_event.reset(new ui::KeyEvent( |
| ui_event_type, |
| static_cast<ui::KeyboardCode>( |
| input->key_data->key_code), |
| input->flags)); |
| } |
| key_event->SetExtendedKeyEventData(scoped_ptr<ui::ExtendedKeyEventData>( |
| new MojoExtendedKeyEventData( |
| static_cast<int32_t>(input->key_data->windows_key_code), |
| input->key_data->text, |
| input->key_data->unmodified_text))); |
| key_event->set_platform_keycode(input->key_data->native_key_code); |
| ui_event = key_event.Pass(); |
| break; |
| } |
| case EVENT_TYPE_MOUSE_PRESSED: |
| case EVENT_TYPE_MOUSE_DRAGGED: |
| case EVENT_TYPE_MOUSE_RELEASED: |
| case EVENT_TYPE_MOUSE_MOVED: |
| case EVENT_TYPE_MOUSE_ENTERED: |
| case EVENT_TYPE_MOUSE_EXITED: { |
| // TODO: last flags isn't right. Need to send changed_flags. |
| ui_event.reset(new ui::MouseEvent( |
| ui_event_type, |
| location, |
| location, |
| ui::EventFlags(input->flags), |
| ui::EventFlags(input->flags))); |
| break; |
| } |
| case EVENT_TYPE_MOUSEWHEEL: { |
| const gfx::Vector2d offset(input->wheel_data->x_offset, |
| input->wheel_data->y_offset); |
| ui_event.reset(new ui::MouseWheelEvent(offset, |
| location, |
| location, |
| ui::EventFlags(input->flags), |
| ui::EventFlags(input->flags))); |
| break; |
| } |
| case EVENT_TYPE_TOUCH_MOVED: |
| case EVENT_TYPE_TOUCH_PRESSED: |
| case EVENT_TYPE_TOUCH_CANCELLED: |
| case EVENT_TYPE_TOUCH_RELEASED: { |
| ui_event.reset(new ui::TouchEvent( |
| ui_event_type, |
| location, |
| ui::EventFlags(input->flags), |
| input->touch_data->pointer_id, |
| base::TimeDelta::FromInternalValue(input->time_stamp), |
| 0.f, 0.f, 0.f, 0.f)); |
| break; |
| } |
| default: |
| // TODO: support other types. |
| // NOTIMPLEMENTED(); |
| ; |
| } |
| // TODO: need to support time_stamp. |
| return ui_event.Pass(); |
| } |
| |
| } // namespace mojo |