1// Copyright 2014 The Chromium Authors. All rights reserved. 2// Use of this source code is governed by a BSD-style license that can be 3// found in the LICENSE file. 4 5#include "mojo/services/public/cpp/input_events/input_events_type_converters.h" 6 7#if defined(USE_X11) 8#include <X11/extensions/XInput2.h> 9#include <X11/Xlib.h> 10#endif 11 12#include "mojo/services/public/cpp/geometry/geometry_type_converters.h" 13#include "mojo/services/public/cpp/input_events/lib/mojo_extended_key_event_data.h" 14#include "mojo/services/public/interfaces/input_events/input_events.mojom.h" 15#include "ui/events/event_utils.h" 16#include "ui/events/keycodes/keyboard_codes.h" 17 18namespace mojo { 19 20COMPILE_ASSERT(static_cast<int32>(EVENT_FLAGS_NONE) == 21 static_cast<int32>(ui::EF_NONE), 22 event_flags_should_match); 23COMPILE_ASSERT(static_cast<int32>(EVENT_FLAGS_CAPS_LOCK_DOWN) == 24 static_cast<int32>(ui::EF_CAPS_LOCK_DOWN), 25 event_flags_should_match); 26COMPILE_ASSERT(static_cast<int32>(EVENT_FLAGS_SHIFT_DOWN) == 27 static_cast<int32>(ui::EF_SHIFT_DOWN), 28 event_flags_should_match); 29COMPILE_ASSERT(static_cast<int32>(EVENT_FLAGS_CONTROL_DOWN) == 30 static_cast<int32>(ui::EF_CONTROL_DOWN), 31 event_flags_should_match); 32COMPILE_ASSERT(static_cast<int32>(EVENT_FLAGS_ALT_DOWN) == 33 static_cast<int32>(ui::EF_ALT_DOWN), 34 event_flags_should_match); 35COMPILE_ASSERT(static_cast<int32>(EVENT_FLAGS_LEFT_MOUSE_BUTTON) == 36 static_cast<int32>(ui::EF_LEFT_MOUSE_BUTTON), 37 event_flags_should_match); 38COMPILE_ASSERT(static_cast<int32>(EVENT_FLAGS_MIDDLE_MOUSE_BUTTON) == 39 static_cast<int32>(ui::EF_MIDDLE_MOUSE_BUTTON), 40 event_flags_should_match); 41COMPILE_ASSERT(static_cast<int32>(EVENT_FLAGS_RIGHT_MOUSE_BUTTON) == 42 static_cast<int32>(ui::EF_RIGHT_MOUSE_BUTTON), 43 event_flags_should_match); 44COMPILE_ASSERT(static_cast<int32>(EVENT_FLAGS_COMMAND_DOWN) == 45 static_cast<int32>(ui::EF_COMMAND_DOWN), 46 event_flags_should_match); 47COMPILE_ASSERT(static_cast<int32>(EVENT_FLAGS_EXTENDED) == 48 static_cast<int32>(ui::EF_EXTENDED), 49 event_flags_should_match); 50COMPILE_ASSERT(static_cast<int32>(EVENT_FLAGS_IS_SYNTHESIZED) == 51 static_cast<int32>(ui::EF_IS_SYNTHESIZED), 52 event_flags_should_match); 53COMPILE_ASSERT(static_cast<int32>(EVENT_FLAGS_ALTGR_DOWN) == 54 static_cast<int32>(ui::EF_ALTGR_DOWN), 55 event_flags_should_match); 56COMPILE_ASSERT(static_cast<int32>(EVENT_FLAGS_MOD3_DOWN) == 57 static_cast<int32>(ui::EF_MOD3_DOWN), 58 event_flags_should_match); 59 60 61// static 62EventType TypeConverter<EventType, ui::EventType>::Convert(ui::EventType type) { 63#define MOJO_INPUT_EVENT_NAME(name) case ui::ET_##name: return EVENT_TYPE_##name 64 65 switch (type) { 66#include "mojo/services/public/cpp/input_events/lib/input_event_names.h" 67 case ui::ET_LAST: 68 NOTREACHED(); 69 break; 70 } 71 72#undef MOJO_INPUT_EVENT_NAME 73 74 NOTREACHED(); 75 return EVENT_TYPE_UNKNOWN; 76} 77 78// static 79ui::EventType TypeConverter<ui::EventType, EventType>::Convert(EventType type) { 80#define MOJO_INPUT_EVENT_NAME(name) case EVENT_TYPE_##name: return ui::ET_##name 81 82 switch (type) { 83#include "mojo/services/public/cpp/input_events/lib/input_event_names.h" 84 } 85 86#undef MOJO_INPUT_EVENT_NAME 87 88 NOTREACHED(); 89 return ui::ET_UNKNOWN; 90} 91 92// static 93EventPtr TypeConverter<EventPtr, ui::Event>::Convert(const ui::Event& input) { 94 EventPtr event(Event::New()); 95 event->action = ConvertTo<EventType>(input.type()); 96 event->flags = EventFlags(input.flags()); 97 event->time_stamp = input.time_stamp().ToInternalValue(); 98 99 if (input.IsMouseEvent() || input.IsTouchEvent()) { 100 const ui::LocatedEvent* located_event = 101 static_cast<const ui::LocatedEvent*>(&input); 102 103 LocationDataPtr location_data(LocationData::New()); 104 location_data->in_view_location = Point::From(located_event->location()); 105 if (input.HasNativeEvent()) { 106 location_data->screen_location = 107 Point::From(ui::EventSystemLocationFromNative(input.native_event())); 108 } 109 110 event->location_data = location_data.Pass(); 111 } 112 113 if (input.IsTouchEvent()) { 114 const ui::TouchEvent* touch_event = 115 static_cast<const ui::TouchEvent*>(&input); 116 TouchDataPtr touch_data(TouchData::New()); 117 touch_data->pointer_id = touch_event->touch_id(); 118 event->touch_data = touch_data.Pass(); 119 } else if (input.IsKeyEvent()) { 120 const ui::KeyEvent* key_event = static_cast<const ui::KeyEvent*>(&input); 121 KeyDataPtr key_data(KeyData::New()); 122 key_data->key_code = key_event->GetConflatedWindowsKeyCode(); 123 key_data->native_key_code = key_event->platform_keycode(); 124 key_data->is_char = key_event->is_char(); 125 key_data->character = key_event->GetCharacter(); 126 127 if (key_event->extended_key_event_data()) { 128 const MojoExtendedKeyEventData* data = 129 static_cast<const MojoExtendedKeyEventData*>( 130 key_event->extended_key_event_data()); 131 key_data->windows_key_code = static_cast<mojo::KeyboardCode>( 132 data->windows_key_code()); 133 key_data->text = data->text(); 134 key_data->unmodified_text = data->unmodified_text(); 135 } else { 136 key_data->windows_key_code = static_cast<mojo::KeyboardCode>( 137 key_event->GetLocatedWindowsKeyboardCode()); 138 key_data->text = key_event->GetText(); 139 key_data->unmodified_text = key_event->GetUnmodifiedText(); 140 } 141 142 event->key_data = key_data.Pass(); 143 } else if (input.IsMouseWheelEvent()) { 144 const ui::MouseWheelEvent* wheel_event = 145 static_cast<const ui::MouseWheelEvent*>(&input); 146 MouseWheelDataPtr wheel_data(MouseWheelData::New()); 147 wheel_data->x_offset = wheel_event->x_offset(); 148 wheel_data->y_offset = wheel_event->y_offset(); 149 event->wheel_data = wheel_data.Pass(); 150 } 151 return event.Pass(); 152} 153 154// static 155EventPtr TypeConverter<EventPtr, ui::KeyEvent>::Convert( 156 const ui::KeyEvent& input) { 157 return Event::From(static_cast<const ui::Event&>(input)); 158} 159 160// static 161scoped_ptr<ui::Event> TypeConverter<scoped_ptr<ui::Event>, EventPtr>::Convert( 162 const EventPtr& input) { 163 scoped_ptr<ui::Event> ui_event; 164 ui::EventType ui_event_type = ConvertTo<ui::EventType>(input->action); 165 166 gfx::Point location; 167 if (!input->location_data.is_null() && 168 !input->location_data->in_view_location.is_null()) { 169 location = input->location_data->in_view_location.To<gfx::Point>(); 170 } 171 172 switch (input->action) { 173 case ui::ET_KEY_PRESSED: 174 case ui::ET_KEY_RELEASED: { 175 scoped_ptr<ui::KeyEvent> key_event; 176 if (input->key_data->is_char) { 177 key_event.reset(new ui::KeyEvent( 178 static_cast<base::char16>(input->key_data->character), 179 static_cast<ui::KeyboardCode>( 180 input->key_data->key_code), 181 input->flags)); 182 } else { 183 key_event.reset(new ui::KeyEvent( 184 ui_event_type, 185 static_cast<ui::KeyboardCode>( 186 input->key_data->key_code), 187 input->flags)); 188 } 189 key_event->SetExtendedKeyEventData(scoped_ptr<ui::ExtendedKeyEventData>( 190 new MojoExtendedKeyEventData( 191 static_cast<int32_t>(input->key_data->windows_key_code), 192 input->key_data->text, 193 input->key_data->unmodified_text))); 194 key_event->set_platform_keycode(input->key_data->native_key_code); 195 ui_event = key_event.PassAs<ui::KeyEvent>(); 196 break; 197 } 198 case EVENT_TYPE_MOUSE_PRESSED: 199 case EVENT_TYPE_MOUSE_DRAGGED: 200 case EVENT_TYPE_MOUSE_RELEASED: 201 case EVENT_TYPE_MOUSE_MOVED: 202 case EVENT_TYPE_MOUSE_ENTERED: 203 case EVENT_TYPE_MOUSE_EXITED: { 204 // TODO: last flags isn't right. Need to send changed_flags. 205 ui_event.reset(new ui::MouseEvent( 206 ui_event_type, 207 location, 208 location, 209 ui::EventFlags(input->flags), 210 ui::EventFlags(input->flags))); 211 break; 212 } 213 case EVENT_TYPE_MOUSEWHEEL: { 214 const gfx::Vector2d offset(input->wheel_data->x_offset, 215 input->wheel_data->y_offset); 216 ui_event.reset(new ui::MouseWheelEvent(offset, 217 location, 218 location, 219 ui::EventFlags(input->flags), 220 ui::EventFlags(input->flags))); 221 break; 222 } 223 case EVENT_TYPE_TOUCH_MOVED: 224 case EVENT_TYPE_TOUCH_PRESSED: 225 case EVENT_TYPE_TOUCH_CANCELLED: 226 case EVENT_TYPE_TOUCH_RELEASED: { 227 ui_event.reset(new ui::TouchEvent( 228 ui_event_type, 229 location, 230 ui::EventFlags(input->flags), 231 input->touch_data->pointer_id, 232 base::TimeDelta::FromInternalValue(input->time_stamp), 233 0.f, 0.f, 0.f, 0.f)); 234 break; 235 } 236 default: 237 // TODO: support other types. 238 // NOTIMPLEMENTED(); 239 ; 240 } 241 // TODO: need to support time_stamp. 242 return ui_event.Pass(); 243} 244 245} // namespace mojo 246