Home | History | Annotate | Download | only in lib
      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 
     18 namespace mojo {
     19 
     20 COMPILE_ASSERT(static_cast<int32>(EVENT_FLAGS_NONE) ==
     21                static_cast<int32>(ui::EF_NONE),
     22                event_flags_should_match);
     23 COMPILE_ASSERT(static_cast<int32>(EVENT_FLAGS_CAPS_LOCK_DOWN) ==
     24                static_cast<int32>(ui::EF_CAPS_LOCK_DOWN),
     25                event_flags_should_match);
     26 COMPILE_ASSERT(static_cast<int32>(EVENT_FLAGS_SHIFT_DOWN) ==
     27                static_cast<int32>(ui::EF_SHIFT_DOWN),
     28                event_flags_should_match);
     29 COMPILE_ASSERT(static_cast<int32>(EVENT_FLAGS_CONTROL_DOWN) ==
     30                static_cast<int32>(ui::EF_CONTROL_DOWN),
     31                event_flags_should_match);
     32 COMPILE_ASSERT(static_cast<int32>(EVENT_FLAGS_ALT_DOWN) ==
     33                static_cast<int32>(ui::EF_ALT_DOWN),
     34                event_flags_should_match);
     35 COMPILE_ASSERT(static_cast<int32>(EVENT_FLAGS_LEFT_MOUSE_BUTTON) ==
     36                static_cast<int32>(ui::EF_LEFT_MOUSE_BUTTON),
     37                event_flags_should_match);
     38 COMPILE_ASSERT(static_cast<int32>(EVENT_FLAGS_MIDDLE_MOUSE_BUTTON) ==
     39                static_cast<int32>(ui::EF_MIDDLE_MOUSE_BUTTON),
     40                event_flags_should_match);
     41 COMPILE_ASSERT(static_cast<int32>(EVENT_FLAGS_RIGHT_MOUSE_BUTTON) ==
     42                static_cast<int32>(ui::EF_RIGHT_MOUSE_BUTTON),
     43                event_flags_should_match);
     44 COMPILE_ASSERT(static_cast<int32>(EVENT_FLAGS_COMMAND_DOWN) ==
     45                static_cast<int32>(ui::EF_COMMAND_DOWN),
     46                event_flags_should_match);
     47 COMPILE_ASSERT(static_cast<int32>(EVENT_FLAGS_EXTENDED) ==
     48                static_cast<int32>(ui::EF_EXTENDED),
     49                event_flags_should_match);
     50 COMPILE_ASSERT(static_cast<int32>(EVENT_FLAGS_IS_SYNTHESIZED) ==
     51                static_cast<int32>(ui::EF_IS_SYNTHESIZED),
     52                event_flags_should_match);
     53 COMPILE_ASSERT(static_cast<int32>(EVENT_FLAGS_ALTGR_DOWN) ==
     54                static_cast<int32>(ui::EF_ALTGR_DOWN),
     55                event_flags_should_match);
     56 COMPILE_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
     62 EventType 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
     79 ui::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
     93 EventPtr 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
    155 EventPtr TypeConverter<EventPtr, ui::KeyEvent>::Convert(
    156     const ui::KeyEvent& input) {
    157   return Event::From(static_cast<const ui::Event&>(input));
    158 }
    159 
    160 // static
    161 scoped_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