blob: f6be2f1a64e0e5ff93d5f612f67525e9f2767f88 [file] [log] [blame]
// 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