Home | History | Annotate | Download | only in events
      1 // Copyright (c) 2012 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 "ui/events/event.h"
      6 
      7 #if defined(USE_X11)
      8 #include <X11/extensions/XInput2.h>
      9 #include <X11/Xlib.h>
     10 #include <X11/keysym.h>
     11 #endif
     12 
     13 #include <cmath>
     14 #include <cstring>
     15 
     16 #include "base/metrics/histogram.h"
     17 #include "base/strings/stringprintf.h"
     18 #include "ui/events/event_utils.h"
     19 #include "ui/events/keycodes/keyboard_code_conversion.h"
     20 #include "ui/gfx/point3_f.h"
     21 #include "ui/gfx/point_conversions.h"
     22 #include "ui/gfx/transform.h"
     23 #include "ui/gfx/transform_util.h"
     24 
     25 #if defined(USE_X11)
     26 #include "ui/events/keycodes/keyboard_code_conversion_x.h"
     27 #elif defined(USE_OZONE)
     28 #include "ui/events/keycodes/keyboard_code_conversion.h"
     29 #endif
     30 
     31 namespace {
     32 
     33 std::string EventTypeName(ui::EventType type) {
     34 #define RETURN_IF_TYPE(t) if (type == ui::t)  return #t
     35 #define CASE_TYPE(t) case ui::t:  return #t
     36   switch (type) {
     37     CASE_TYPE(ET_UNKNOWN);
     38     CASE_TYPE(ET_MOUSE_PRESSED);
     39     CASE_TYPE(ET_MOUSE_DRAGGED);
     40     CASE_TYPE(ET_MOUSE_RELEASED);
     41     CASE_TYPE(ET_MOUSE_MOVED);
     42     CASE_TYPE(ET_MOUSE_ENTERED);
     43     CASE_TYPE(ET_MOUSE_EXITED);
     44     CASE_TYPE(ET_KEY_PRESSED);
     45     CASE_TYPE(ET_KEY_RELEASED);
     46     CASE_TYPE(ET_MOUSEWHEEL);
     47     CASE_TYPE(ET_MOUSE_CAPTURE_CHANGED);
     48     CASE_TYPE(ET_TOUCH_RELEASED);
     49     CASE_TYPE(ET_TOUCH_PRESSED);
     50     CASE_TYPE(ET_TOUCH_MOVED);
     51     CASE_TYPE(ET_TOUCH_CANCELLED);
     52     CASE_TYPE(ET_DROP_TARGET_EVENT);
     53     CASE_TYPE(ET_TRANSLATED_KEY_PRESS);
     54     CASE_TYPE(ET_TRANSLATED_KEY_RELEASE);
     55     CASE_TYPE(ET_GESTURE_SCROLL_BEGIN);
     56     CASE_TYPE(ET_GESTURE_SCROLL_END);
     57     CASE_TYPE(ET_GESTURE_SCROLL_UPDATE);
     58     CASE_TYPE(ET_GESTURE_SHOW_PRESS);
     59     CASE_TYPE(ET_GESTURE_WIN8_EDGE_SWIPE);
     60     CASE_TYPE(ET_GESTURE_TAP);
     61     CASE_TYPE(ET_GESTURE_TAP_DOWN);
     62     CASE_TYPE(ET_GESTURE_TAP_CANCEL);
     63     CASE_TYPE(ET_GESTURE_BEGIN);
     64     CASE_TYPE(ET_GESTURE_END);
     65     CASE_TYPE(ET_GESTURE_TWO_FINGER_TAP);
     66     CASE_TYPE(ET_GESTURE_PINCH_BEGIN);
     67     CASE_TYPE(ET_GESTURE_PINCH_END);
     68     CASE_TYPE(ET_GESTURE_PINCH_UPDATE);
     69     CASE_TYPE(ET_GESTURE_LONG_PRESS);
     70     CASE_TYPE(ET_GESTURE_LONG_TAP);
     71     CASE_TYPE(ET_GESTURE_SWIPE);
     72     CASE_TYPE(ET_GESTURE_TAP_UNCONFIRMED);
     73     CASE_TYPE(ET_GESTURE_DOUBLE_TAP);
     74     CASE_TYPE(ET_SCROLL);
     75     CASE_TYPE(ET_SCROLL_FLING_START);
     76     CASE_TYPE(ET_SCROLL_FLING_CANCEL);
     77     CASE_TYPE(ET_CANCEL_MODE);
     78     CASE_TYPE(ET_UMA_DATA);
     79     case ui::ET_LAST: NOTREACHED(); return std::string();
     80     // Don't include default, so that we get an error when new type is added.
     81   }
     82 #undef CASE_TYPE
     83 
     84   NOTREACHED();
     85   return std::string();
     86 }
     87 
     88 bool IsX11SendEventTrue(const base::NativeEvent& event) {
     89 #if defined(USE_X11)
     90   return event && event->xany.send_event;
     91 #else
     92   return false;
     93 #endif
     94 }
     95 
     96 bool X11EventHasNonStandardState(const base::NativeEvent& event) {
     97 #if defined(USE_X11)
     98   const unsigned int kAllStateMask =
     99       Button1Mask | Button2Mask | Button3Mask | Button4Mask | Button5Mask |
    100       Mod1Mask | Mod2Mask | Mod3Mask | Mod4Mask | Mod5Mask | ShiftMask |
    101       LockMask | ControlMask | AnyModifier;
    102   return event && (event->xkey.state & ~kAllStateMask) != 0;
    103 #else
    104   return false;
    105 #endif
    106 }
    107 
    108 }  // namespace
    109 
    110 namespace ui {
    111 
    112 ////////////////////////////////////////////////////////////////////////////////
    113 // Event
    114 
    115 // static
    116 scoped_ptr<Event> Event::Clone(const Event& event) {
    117   if (event.IsKeyEvent()) {
    118     return scoped_ptr<Event>(new KeyEvent(static_cast<const KeyEvent&>(event)));
    119   }
    120 
    121   if (event.IsMouseEvent()) {
    122     if (event.IsMouseWheelEvent()) {
    123       return scoped_ptr<Event>(
    124           new MouseWheelEvent(static_cast<const MouseWheelEvent&>(event)));
    125     }
    126 
    127     return scoped_ptr<Event>(
    128         new MouseEvent(static_cast<const MouseEvent&>(event)));
    129   }
    130 
    131   if (event.IsTouchEvent()) {
    132     return scoped_ptr<Event>(
    133         new TouchEvent(static_cast<const TouchEvent&>(event)));
    134   }
    135 
    136   if (event.IsGestureEvent()) {
    137     return scoped_ptr<Event>(
    138         new GestureEvent(static_cast<const GestureEvent&>(event)));
    139   }
    140 
    141   if (event.IsScrollEvent()) {
    142     return scoped_ptr<Event>(
    143         new ScrollEvent(static_cast<const ScrollEvent&>(event)));
    144   }
    145 
    146   return scoped_ptr<Event>(new Event(event));
    147 }
    148 
    149 Event::~Event() {
    150   if (delete_native_event_)
    151     ReleaseCopiedNativeEvent(native_event_);
    152 }
    153 
    154 GestureEvent* Event::AsGestureEvent() {
    155   CHECK(IsGestureEvent());
    156   return static_cast<GestureEvent*>(this);
    157 }
    158 
    159 const GestureEvent* Event::AsGestureEvent() const {
    160   CHECK(IsGestureEvent());
    161   return static_cast<const GestureEvent*>(this);
    162 }
    163 
    164 bool Event::HasNativeEvent() const {
    165   base::NativeEvent null_event;
    166   std::memset(&null_event, 0, sizeof(null_event));
    167   return !!std::memcmp(&native_event_, &null_event, sizeof(null_event));
    168 }
    169 
    170 void Event::StopPropagation() {
    171   // TODO(sad): Re-enable these checks once View uses dispatcher to dispatch
    172   // events.
    173   // CHECK(phase_ != EP_PREDISPATCH && phase_ != EP_POSTDISPATCH);
    174   CHECK(cancelable_);
    175   result_ = static_cast<EventResult>(result_ | ER_CONSUMED);
    176 }
    177 
    178 void Event::SetHandled() {
    179   // TODO(sad): Re-enable these checks once View uses dispatcher to dispatch
    180   // events.
    181   // CHECK(phase_ != EP_PREDISPATCH && phase_ != EP_POSTDISPATCH);
    182   CHECK(cancelable_);
    183   result_ = static_cast<EventResult>(result_ | ER_HANDLED);
    184 }
    185 
    186 Event::Event(EventType type, base::TimeDelta time_stamp, int flags)
    187     : type_(type),
    188       time_stamp_(time_stamp),
    189       flags_(flags),
    190       native_event_(base::NativeEvent()),
    191       delete_native_event_(false),
    192       cancelable_(true),
    193       target_(NULL),
    194       phase_(EP_PREDISPATCH),
    195       result_(ER_UNHANDLED),
    196       source_device_id_(ED_UNKNOWN_DEVICE) {
    197   if (type_ < ET_LAST)
    198     name_ = EventTypeName(type_);
    199 }
    200 
    201 Event::Event(const base::NativeEvent& native_event,
    202              EventType type,
    203              int flags)
    204     : type_(type),
    205       time_stamp_(EventTimeFromNative(native_event)),
    206       flags_(flags),
    207       native_event_(native_event),
    208       delete_native_event_(false),
    209       cancelable_(true),
    210       target_(NULL),
    211       phase_(EP_PREDISPATCH),
    212       result_(ER_UNHANDLED),
    213       source_device_id_(ED_UNKNOWN_DEVICE) {
    214   base::TimeDelta delta = EventTimeForNow() - time_stamp_;
    215   if (type_ < ET_LAST)
    216     name_ = EventTypeName(type_);
    217   UMA_HISTOGRAM_CUSTOM_COUNTS("Event.Latency.Browser",
    218                               delta.InMicroseconds(), 1, 1000000, 100);
    219   std::string name_for_event =
    220       base::StringPrintf("Event.Latency.Browser.%s", name_.c_str());
    221   base::HistogramBase* counter_for_type =
    222       base::Histogram::FactoryGet(
    223           name_for_event,
    224           1,
    225           1000000,
    226           100,
    227           base::HistogramBase::kUmaTargetedHistogramFlag);
    228   counter_for_type->Add(delta.InMicroseconds());
    229 
    230 #if defined(USE_X11)
    231   if (native_event->type == GenericEvent) {
    232     XIDeviceEvent* xiev =
    233         static_cast<XIDeviceEvent*>(native_event->xcookie.data);
    234     source_device_id_ = xiev->sourceid;
    235   }
    236 #endif
    237 }
    238 
    239 Event::Event(const Event& copy)
    240     : type_(copy.type_),
    241       time_stamp_(copy.time_stamp_),
    242       latency_(copy.latency_),
    243       flags_(copy.flags_),
    244       native_event_(CopyNativeEvent(copy.native_event_)),
    245       delete_native_event_(true),
    246       cancelable_(true),
    247       target_(NULL),
    248       phase_(EP_PREDISPATCH),
    249       result_(ER_UNHANDLED),
    250       source_device_id_(copy.source_device_id_) {
    251   if (type_ < ET_LAST)
    252     name_ = EventTypeName(type_);
    253 }
    254 
    255 void Event::SetType(EventType type) {
    256   if (type_ < ET_LAST)
    257     name_ = std::string();
    258   type_ = type;
    259   if (type_ < ET_LAST)
    260     name_ = EventTypeName(type_);
    261 }
    262 
    263 ////////////////////////////////////////////////////////////////////////////////
    264 // CancelModeEvent
    265 
    266 CancelModeEvent::CancelModeEvent()
    267     : Event(ET_CANCEL_MODE, base::TimeDelta(), 0) {
    268   set_cancelable(false);
    269 }
    270 
    271 CancelModeEvent::~CancelModeEvent() {
    272 }
    273 
    274 ////////////////////////////////////////////////////////////////////////////////
    275 // LocatedEvent
    276 
    277 LocatedEvent::~LocatedEvent() {
    278 }
    279 
    280 LocatedEvent::LocatedEvent(const base::NativeEvent& native_event)
    281     : Event(native_event,
    282             EventTypeFromNative(native_event),
    283             EventFlagsFromNative(native_event)),
    284       location_(EventLocationFromNative(native_event)),
    285       root_location_(location_) {
    286 }
    287 
    288 LocatedEvent::LocatedEvent(EventType type,
    289                            const gfx::PointF& location,
    290                            const gfx::PointF& root_location,
    291                            base::TimeDelta time_stamp,
    292                            int flags)
    293     : Event(type, time_stamp, flags),
    294       location_(location),
    295       root_location_(root_location) {
    296 }
    297 
    298 void LocatedEvent::UpdateForRootTransform(
    299     const gfx::Transform& reversed_root_transform) {
    300   // Transform has to be done at root level.
    301   gfx::Point3F p(location_);
    302   reversed_root_transform.TransformPoint(&p);
    303   location_ = p.AsPointF();
    304   root_location_ = location_;
    305 }
    306 
    307 ////////////////////////////////////////////////////////////////////////////////
    308 // MouseEvent
    309 
    310 MouseEvent::MouseEvent(const base::NativeEvent& native_event)
    311     : LocatedEvent(native_event),
    312       changed_button_flags_(
    313           GetChangedMouseButtonFlagsFromNative(native_event)) {
    314   if (type() == ET_MOUSE_PRESSED || type() == ET_MOUSE_RELEASED)
    315     SetClickCount(GetRepeatCount(*this));
    316 }
    317 
    318 MouseEvent::MouseEvent(EventType type,
    319                        const gfx::PointF& location,
    320                        const gfx::PointF& root_location,
    321                        int flags,
    322                        int changed_button_flags)
    323     : LocatedEvent(type, location, root_location, EventTimeForNow(), flags),
    324       changed_button_flags_(changed_button_flags) {
    325   if (this->type() == ET_MOUSE_MOVED && IsAnyButton())
    326     SetType(ET_MOUSE_DRAGGED);
    327 }
    328 
    329 // static
    330 bool MouseEvent::IsRepeatedClickEvent(
    331     const MouseEvent& event1,
    332     const MouseEvent& event2) {
    333   // These values match the Windows defaults.
    334   static const int kDoubleClickTimeMS = 500;
    335   static const int kDoubleClickWidth = 4;
    336   static const int kDoubleClickHeight = 4;
    337 
    338   if (event1.type() != ET_MOUSE_PRESSED ||
    339       event2.type() != ET_MOUSE_PRESSED)
    340     return false;
    341 
    342   // Compare flags, but ignore EF_IS_DOUBLE_CLICK to allow triple clicks.
    343   if ((event1.flags() & ~EF_IS_DOUBLE_CLICK) !=
    344       (event2.flags() & ~EF_IS_DOUBLE_CLICK))
    345     return false;
    346 
    347   base::TimeDelta time_difference = event2.time_stamp() - event1.time_stamp();
    348 
    349   if (time_difference.InMilliseconds() > kDoubleClickTimeMS)
    350     return false;
    351 
    352   if (std::abs(event2.x() - event1.x()) > kDoubleClickWidth / 2)
    353     return false;
    354 
    355   if (std::abs(event2.y() - event1.y()) > kDoubleClickHeight / 2)
    356     return false;
    357 
    358   return true;
    359 }
    360 
    361 // static
    362 int MouseEvent::GetRepeatCount(const MouseEvent& event) {
    363   int click_count = 1;
    364   if (last_click_event_) {
    365     if (event.type() == ui::ET_MOUSE_RELEASED) {
    366       if (event.changed_button_flags() ==
    367               last_click_event_->changed_button_flags()) {
    368         last_click_complete_ = true;
    369         return last_click_event_->GetClickCount();
    370       } else {
    371         // If last_click_event_ has changed since this button was pressed
    372         // return a click count of 1.
    373         return click_count;
    374       }
    375     }
    376     if (event.time_stamp() != last_click_event_->time_stamp())
    377       last_click_complete_ = true;
    378     if (!last_click_complete_ ||
    379         IsX11SendEventTrue(event.native_event())) {
    380       click_count = last_click_event_->GetClickCount();
    381     } else if (IsRepeatedClickEvent(*last_click_event_, event)) {
    382       click_count = last_click_event_->GetClickCount() + 1;
    383     }
    384     delete last_click_event_;
    385   }
    386   last_click_event_ = new MouseEvent(event);
    387   last_click_complete_ = false;
    388   if (click_count > 3)
    389     click_count = 3;
    390   last_click_event_->SetClickCount(click_count);
    391   return click_count;
    392 }
    393 
    394 void MouseEvent::ResetLastClickForTest() {
    395   if (last_click_event_) {
    396     delete last_click_event_;
    397     last_click_event_ = NULL;
    398     last_click_complete_ = false;
    399   }
    400 }
    401 
    402 // static
    403 MouseEvent* MouseEvent::last_click_event_ = NULL;
    404 bool MouseEvent::last_click_complete_ = false;
    405 
    406 int MouseEvent::GetClickCount() const {
    407   if (type() != ET_MOUSE_PRESSED && type() != ET_MOUSE_RELEASED)
    408     return 0;
    409 
    410   if (flags() & EF_IS_TRIPLE_CLICK)
    411     return 3;
    412   else if (flags() & EF_IS_DOUBLE_CLICK)
    413     return 2;
    414   else
    415     return 1;
    416 }
    417 
    418 void MouseEvent::SetClickCount(int click_count) {
    419   if (type() != ET_MOUSE_PRESSED && type() != ET_MOUSE_RELEASED)
    420     return;
    421 
    422   DCHECK(click_count > 0);
    423   DCHECK(click_count <= 3);
    424 
    425   int f = flags();
    426   switch (click_count) {
    427     case 1:
    428       f &= ~EF_IS_DOUBLE_CLICK;
    429       f &= ~EF_IS_TRIPLE_CLICK;
    430       break;
    431     case 2:
    432       f |= EF_IS_DOUBLE_CLICK;
    433       f &= ~EF_IS_TRIPLE_CLICK;
    434       break;
    435     case 3:
    436       f &= ~EF_IS_DOUBLE_CLICK;
    437       f |= EF_IS_TRIPLE_CLICK;
    438       break;
    439   }
    440   set_flags(f);
    441 }
    442 
    443 ////////////////////////////////////////////////////////////////////////////////
    444 // MouseWheelEvent
    445 
    446 MouseWheelEvent::MouseWheelEvent(const base::NativeEvent& native_event)
    447     : MouseEvent(native_event),
    448       offset_(GetMouseWheelOffset(native_event)) {
    449 }
    450 
    451 MouseWheelEvent::MouseWheelEvent(const ScrollEvent& scroll_event)
    452     : MouseEvent(scroll_event),
    453       offset_(scroll_event.x_offset(), scroll_event.y_offset()){
    454   SetType(ET_MOUSEWHEEL);
    455 }
    456 
    457 MouseWheelEvent::MouseWheelEvent(const MouseEvent& mouse_event,
    458                                  int x_offset,
    459                                  int y_offset)
    460     : MouseEvent(mouse_event), offset_(x_offset, y_offset) {
    461   DCHECK(type() == ET_MOUSEWHEEL);
    462 }
    463 
    464 MouseWheelEvent::MouseWheelEvent(const MouseWheelEvent& mouse_wheel_event)
    465     : MouseEvent(mouse_wheel_event),
    466       offset_(mouse_wheel_event.offset()) {
    467   DCHECK(type() == ET_MOUSEWHEEL);
    468 }
    469 
    470 MouseWheelEvent::MouseWheelEvent(const gfx::Vector2d& offset,
    471                                  const gfx::PointF& location,
    472                                  const gfx::PointF& root_location,
    473                                  int flags,
    474                                  int changed_button_flags)
    475     : MouseEvent(ui::ET_MOUSEWHEEL, location, root_location, flags,
    476                  changed_button_flags),
    477       offset_(offset) {
    478 }
    479 
    480 #if defined(OS_WIN)
    481 // This value matches windows WHEEL_DELTA.
    482 // static
    483 const int MouseWheelEvent::kWheelDelta = 120;
    484 #else
    485 // This value matches GTK+ wheel scroll amount.
    486 const int MouseWheelEvent::kWheelDelta = 53;
    487 #endif
    488 
    489 void MouseWheelEvent::UpdateForRootTransform(
    490     const gfx::Transform& inverted_root_transform) {
    491   LocatedEvent::UpdateForRootTransform(inverted_root_transform);
    492   gfx::DecomposedTransform decomp;
    493   bool success = gfx::DecomposeTransform(&decomp, inverted_root_transform);
    494   DCHECK(success);
    495   if (decomp.scale[0])
    496     offset_.set_x(offset_.x() * decomp.scale[0]);
    497   if (decomp.scale[1])
    498     offset_.set_y(offset_.y() * decomp.scale[1]);
    499 }
    500 
    501 ////////////////////////////////////////////////////////////////////////////////
    502 // TouchEvent
    503 
    504 TouchEvent::TouchEvent(const base::NativeEvent& native_event)
    505     : LocatedEvent(native_event),
    506       touch_id_(GetTouchId(native_event)),
    507       radius_x_(GetTouchRadiusX(native_event)),
    508       radius_y_(GetTouchRadiusY(native_event)),
    509       rotation_angle_(GetTouchAngle(native_event)),
    510       force_(GetTouchForce(native_event)) {
    511   latency()->AddLatencyNumberWithTimestamp(
    512       INPUT_EVENT_LATENCY_ORIGINAL_COMPONENT,
    513       0,
    514       0,
    515       base::TimeTicks::FromInternalValue(time_stamp().ToInternalValue()),
    516       1);
    517 
    518   latency()->AddLatencyNumber(INPUT_EVENT_LATENCY_UI_COMPONENT, 0, 0);
    519 
    520   if (type() == ET_TOUCH_PRESSED)
    521     IncrementTouchIdRefCount(native_event);
    522 }
    523 
    524 TouchEvent::TouchEvent(EventType type,
    525                        const gfx::PointF& location,
    526                        int touch_id,
    527                        base::TimeDelta time_stamp)
    528     : LocatedEvent(type, location, location, time_stamp, 0),
    529       touch_id_(touch_id),
    530       radius_x_(0.0f),
    531       radius_y_(0.0f),
    532       rotation_angle_(0.0f),
    533       force_(0.0f) {
    534   latency()->AddLatencyNumber(INPUT_EVENT_LATENCY_UI_COMPONENT, 0, 0);
    535 }
    536 
    537 TouchEvent::TouchEvent(EventType type,
    538                        const gfx::PointF& location,
    539                        int flags,
    540                        int touch_id,
    541                        base::TimeDelta time_stamp,
    542                        float radius_x,
    543                        float radius_y,
    544                        float angle,
    545                        float force)
    546     : LocatedEvent(type, location, location, time_stamp, flags),
    547       touch_id_(touch_id),
    548       radius_x_(radius_x),
    549       radius_y_(radius_y),
    550       rotation_angle_(angle),
    551       force_(force) {
    552   latency()->AddLatencyNumber(INPUT_EVENT_LATENCY_UI_COMPONENT, 0, 0);
    553 }
    554 
    555 TouchEvent::~TouchEvent() {
    556   // In ctor TouchEvent(native_event) we call GetTouchId() which in X11
    557   // platform setups the tracking_id to slot mapping. So in dtor here,
    558   // if this touch event is a release event, we clear the mapping accordingly.
    559   if (HasNativeEvent())
    560     ClearTouchIdIfReleased(native_event());
    561 }
    562 
    563 void TouchEvent::UpdateForRootTransform(
    564     const gfx::Transform& inverted_root_transform) {
    565   LocatedEvent::UpdateForRootTransform(inverted_root_transform);
    566   gfx::DecomposedTransform decomp;
    567   bool success = gfx::DecomposeTransform(&decomp, inverted_root_transform);
    568   DCHECK(success);
    569   if (decomp.scale[0])
    570     radius_x_ *= decomp.scale[0];
    571   if (decomp.scale[1])
    572     radius_y_ *= decomp.scale[1];
    573 }
    574 
    575 ////////////////////////////////////////////////////////////////////////////////
    576 // KeyEvent
    577 
    578 // static
    579 KeyEvent* KeyEvent::last_key_event_ = NULL;
    580 
    581 // static
    582 bool KeyEvent::IsRepeated(const KeyEvent& event) {
    583   // A safe guard in case if there were continous key pressed events that are
    584   // not auto repeat.
    585   const int kMaxAutoRepeatTimeMs = 2000;
    586   // Ignore key events that have non standard state masks as it may be
    587   // reposted by an IME. IBUS-GTK uses this field to detect the
    588   // re-posted event for example. crbug.com/385873.
    589   if (X11EventHasNonStandardState(event.native_event()))
    590     return false;
    591   if (event.is_char())
    592     return false;
    593   if (event.type() == ui::ET_KEY_RELEASED) {
    594     delete last_key_event_;
    595     last_key_event_ = NULL;
    596     return false;
    597   }
    598   CHECK_EQ(ui::ET_KEY_PRESSED, event.type());
    599   if (!last_key_event_) {
    600     last_key_event_ = new KeyEvent(event);
    601     return false;
    602   }
    603   if (event.key_code() == last_key_event_->key_code() &&
    604       event.flags() == last_key_event_->flags() &&
    605       (event.time_stamp() - last_key_event_->time_stamp()).InMilliseconds() <
    606       kMaxAutoRepeatTimeMs) {
    607     return true;
    608   }
    609   delete last_key_event_;
    610   last_key_event_ = new KeyEvent(event);
    611   return false;
    612 }
    613 
    614 KeyEvent::KeyEvent(const base::NativeEvent& native_event)
    615     : Event(native_event,
    616             EventTypeFromNative(native_event),
    617             EventFlagsFromNative(native_event)),
    618       key_code_(KeyboardCodeFromNative(native_event)),
    619       code_(CodeFromNative(native_event)),
    620       is_char_(IsCharFromNative(native_event)),
    621       platform_keycode_(PlatformKeycodeFromNative(native_event)),
    622       character_(0) {
    623   if (IsRepeated(*this))
    624     set_flags(flags() | ui::EF_IS_REPEAT);
    625 
    626 #if defined(USE_X11)
    627   NormalizeFlags();
    628 #endif
    629 #if defined(OS_WIN)
    630   // Only Windows has native character events.
    631   if (is_char_)
    632     character_ = native_event.wParam;
    633 #endif
    634 }
    635 
    636 KeyEvent::KeyEvent(EventType type,
    637                    KeyboardCode key_code,
    638                    int flags)
    639     : Event(type, EventTimeForNow(), flags),
    640       key_code_(key_code),
    641       is_char_(false),
    642       platform_keycode_(0),
    643       character_() {
    644 }
    645 
    646 KeyEvent::KeyEvent(EventType type,
    647                    KeyboardCode key_code,
    648                    const std::string& code,
    649                    int flags)
    650     : Event(type, EventTimeForNow(), flags),
    651       key_code_(key_code),
    652       code_(code),
    653       is_char_(false),
    654       platform_keycode_(0),
    655       character_(0) {
    656 }
    657 
    658 KeyEvent::KeyEvent(base::char16 character, KeyboardCode key_code, int flags)
    659     : Event(ET_KEY_PRESSED, EventTimeForNow(), flags),
    660       key_code_(key_code),
    661       code_(""),
    662       is_char_(true),
    663       platform_keycode_(0),
    664       character_(character) {
    665 }
    666 
    667 KeyEvent::KeyEvent(const KeyEvent& rhs)
    668     : Event(rhs),
    669       key_code_(rhs.key_code_),
    670       code_(rhs.code_),
    671       is_char_(rhs.is_char_),
    672       platform_keycode_(rhs.platform_keycode_),
    673       character_(rhs.character_) {
    674   if (rhs.extended_key_event_data_)
    675     extended_key_event_data_.reset(rhs.extended_key_event_data_->Clone());
    676 }
    677 
    678 KeyEvent& KeyEvent::operator=(const KeyEvent& rhs) {
    679   if (this != &rhs) {
    680     Event::operator=(rhs);
    681     key_code_ = rhs.key_code_;
    682     code_ = rhs.code_;
    683     is_char_ = rhs.is_char_;
    684     platform_keycode_ = rhs.platform_keycode_;
    685     character_ = rhs.character_;
    686 
    687     if (rhs.extended_key_event_data_)
    688       extended_key_event_data_.reset(rhs.extended_key_event_data_->Clone());
    689   }
    690   return *this;
    691 }
    692 
    693 KeyEvent::~KeyEvent() {}
    694 
    695 void KeyEvent::SetExtendedKeyEventData(scoped_ptr<ExtendedKeyEventData> data) {
    696   extended_key_event_data_ = data.Pass();
    697 }
    698 
    699 base::char16 KeyEvent::GetCharacter() const {
    700   if (is_char_ || character_)
    701     return character_;
    702 
    703   // TODO(kpschoedel): streamline these cases after settling Ozone
    704   // positional coding.
    705 #if defined(OS_WIN)
    706   // Native Windows character events always have is_char_ == true,
    707   // so this is a synthetic or native keystroke event.
    708   character_ = GetCharacterFromKeyCode(key_code_, flags());
    709   return character_;
    710 #elif defined(USE_X11)
    711   if (!native_event()) {
    712     character_ = GetCharacterFromKeyCode(key_code_, flags());
    713     return character_;
    714   }
    715 
    716   DCHECK(native_event()->type == KeyPress ||
    717          native_event()->type == KeyRelease ||
    718          (native_event()->type == GenericEvent &&
    719           (native_event()->xgeneric.evtype == XI_KeyPress ||
    720            native_event()->xgeneric.evtype == XI_KeyRelease)));
    721 
    722   // When a control key is held, prefer ASCII characters to non ASCII
    723   // characters in order to use it for shortcut keys.  GetCharacterFromKeyCode
    724   // returns 'a' for VKEY_A even if the key is actually bound to '' in X11.
    725   // GetCharacterFromXEvent returns '' in that case.
    726   return IsControlDown() ?
    727       GetCharacterFromKeyCode(key_code_, flags()) :
    728       GetCharacterFromXEvent(native_event());
    729 #else
    730   if (native_event()) {
    731     DCHECK(EventTypeFromNative(native_event()) == ET_KEY_PRESSED ||
    732            EventTypeFromNative(native_event()) == ET_KEY_RELEASED);
    733   }
    734 
    735   return GetCharacterFromKeyCode(key_code_, flags());
    736 #endif
    737 }
    738 
    739 base::char16 KeyEvent::GetText() const {
    740   if ((flags() & EF_CONTROL_DOWN) != 0) {
    741     return GetControlCharacterForKeycode(key_code_,
    742                                          (flags() & EF_SHIFT_DOWN) != 0);
    743   }
    744   return GetUnmodifiedText();
    745 }
    746 
    747 base::char16 KeyEvent::GetUnmodifiedText() const {
    748   if (!is_char_ && (key_code_ == VKEY_RETURN))
    749     return '\r';
    750   return GetCharacter();
    751 }
    752 
    753 bool KeyEvent::IsUnicodeKeyCode() const {
    754 #if defined(OS_WIN)
    755   if (!IsAltDown())
    756     return false;
    757   const int key = key_code();
    758   if (key >= VKEY_NUMPAD0 && key <= VKEY_NUMPAD9)
    759     return true;
    760   // Check whether the user is using the numeric keypad with num-lock off.
    761   // In that case, EF_EXTENDED will not be set; if it is set, the key event
    762   // originated from the relevant non-numpad dedicated key, e.g. [Insert].
    763   return (!(flags() & EF_EXTENDED) &&
    764           (key == VKEY_INSERT || key == VKEY_END  || key == VKEY_DOWN ||
    765            key == VKEY_NEXT   || key == VKEY_LEFT || key == VKEY_CLEAR ||
    766            key == VKEY_RIGHT  || key == VKEY_HOME || key == VKEY_UP ||
    767            key == VKEY_PRIOR));
    768 #else
    769   return false;
    770 #endif
    771 }
    772 
    773 void KeyEvent::NormalizeFlags() {
    774   int mask = 0;
    775   switch (key_code()) {
    776     case VKEY_CONTROL:
    777       mask = EF_CONTROL_DOWN;
    778       break;
    779     case VKEY_SHIFT:
    780       mask = EF_SHIFT_DOWN;
    781       break;
    782     case VKEY_MENU:
    783       mask = EF_ALT_DOWN;
    784       break;
    785     case VKEY_CAPITAL:
    786       mask = EF_CAPS_LOCK_DOWN;
    787       break;
    788     default:
    789       return;
    790   }
    791   if (type() == ET_KEY_PRESSED)
    792     set_flags(flags() | mask);
    793   else
    794     set_flags(flags() & ~mask);
    795 }
    796 
    797 bool KeyEvent::IsTranslated() const {
    798   switch (type()) {
    799     case ET_KEY_PRESSED:
    800     case ET_KEY_RELEASED:
    801       return false;
    802     case ET_TRANSLATED_KEY_PRESS:
    803     case ET_TRANSLATED_KEY_RELEASE:
    804       return true;
    805     default:
    806       NOTREACHED();
    807       return false;
    808   }
    809 }
    810 
    811 void KeyEvent::SetTranslated(bool translated) {
    812   switch (type()) {
    813     case ET_KEY_PRESSED:
    814     case ET_TRANSLATED_KEY_PRESS:
    815       SetType(translated ? ET_TRANSLATED_KEY_PRESS : ET_KEY_PRESSED);
    816       break;
    817     case ET_KEY_RELEASED:
    818     case ET_TRANSLATED_KEY_RELEASE:
    819       SetType(translated ? ET_TRANSLATED_KEY_RELEASE : ET_KEY_RELEASED);
    820       break;
    821     default:
    822       NOTREACHED();
    823   }
    824 }
    825 
    826 bool KeyEvent::IsRightSideKey() const {
    827   switch (key_code_) {
    828     case VKEY_CONTROL:
    829     case VKEY_SHIFT:
    830     case VKEY_MENU:
    831     case VKEY_LWIN:
    832 #if defined(USE_X11)
    833       // Under X11, setting code_ requires platform-dependent information, and
    834       // currently assumes that X keycodes are based on Linux evdev keycodes.
    835       // In certain test environments this is not the case, and code_ is not
    836       // set accurately, so we need a different mechanism. Fortunately X11 key
    837       // mapping preserves the left-right distinction, so testing keysyms works
    838       // if the value is available (as it is for all X11 native-based events).
    839       if (platform_keycode_) {
    840         return (platform_keycode_ == XK_Shift_R) ||
    841                (platform_keycode_ == XK_Control_R) ||
    842                (platform_keycode_ == XK_Alt_R) ||
    843                (platform_keycode_ == XK_Meta_R) ||
    844                (platform_keycode_ == XK_Super_R) ||
    845                (platform_keycode_ == XK_Hyper_R);
    846       }
    847       // Fall through to the generic code if we have no platform_keycode_.
    848       // Under X11, this must be a synthetic event, so we can require that
    849       // code_ be set correctly.
    850 #endif
    851       return ((code_.size() > 5) &&
    852               (code_.compare(code_.size() - 5, 5, "Right", 5)) == 0);
    853     default:
    854       return false;
    855   }
    856 }
    857 
    858 KeyboardCode KeyEvent::GetLocatedWindowsKeyboardCode() const {
    859   switch (key_code_) {
    860     case VKEY_SHIFT:
    861       return IsRightSideKey() ? VKEY_RSHIFT : VKEY_LSHIFT;
    862     case VKEY_CONTROL:
    863       return IsRightSideKey() ? VKEY_RCONTROL : VKEY_LCONTROL;
    864     case VKEY_MENU:
    865       return IsRightSideKey() ? VKEY_RMENU : VKEY_LMENU;
    866     case VKEY_LWIN:
    867       return IsRightSideKey() ? VKEY_RWIN : VKEY_LWIN;
    868     // TODO(kpschoedel): EF_NUMPAD_KEY is present only on X11. Currently this
    869     // function is only called on X11. Likely the tests here will be replaced
    870     // with a DOM-based code enumeration test in the course of Ozone
    871     // platform-indpendent key event work.
    872     case VKEY_0:
    873       return (flags() & EF_NUMPAD_KEY) ? VKEY_NUMPAD0 : VKEY_0;
    874     case VKEY_1:
    875       return (flags() & EF_NUMPAD_KEY) ? VKEY_NUMPAD1 : VKEY_1;
    876     case VKEY_2:
    877       return (flags() & EF_NUMPAD_KEY) ? VKEY_NUMPAD2 : VKEY_2;
    878     case VKEY_3:
    879       return (flags() & EF_NUMPAD_KEY) ? VKEY_NUMPAD3 : VKEY_3;
    880     case VKEY_4:
    881       return (flags() & EF_NUMPAD_KEY) ? VKEY_NUMPAD4 : VKEY_4;
    882     case VKEY_5:
    883       return (flags() & EF_NUMPAD_KEY) ? VKEY_NUMPAD5 : VKEY_5;
    884     case VKEY_6:
    885       return (flags() & EF_NUMPAD_KEY) ? VKEY_NUMPAD6 : VKEY_6;
    886     case VKEY_7:
    887       return (flags() & EF_NUMPAD_KEY) ? VKEY_NUMPAD7 : VKEY_7;
    888     case VKEY_8:
    889       return (flags() & EF_NUMPAD_KEY) ? VKEY_NUMPAD8 : VKEY_8;
    890     case VKEY_9:
    891       return (flags() & EF_NUMPAD_KEY) ? VKEY_NUMPAD9 : VKEY_9;
    892     default:
    893       return key_code_;
    894   }
    895 }
    896 
    897 uint16 KeyEvent::GetConflatedWindowsKeyCode() const {
    898   if (is_char_)
    899     return character_;
    900   return key_code_;
    901 }
    902 
    903 ////////////////////////////////////////////////////////////////////////////////
    904 // ScrollEvent
    905 
    906 ScrollEvent::ScrollEvent(const base::NativeEvent& native_event)
    907     : MouseEvent(native_event) {
    908   if (type() == ET_SCROLL) {
    909     GetScrollOffsets(native_event,
    910                      &x_offset_, &y_offset_,
    911                      &x_offset_ordinal_, &y_offset_ordinal_,
    912                      &finger_count_);
    913   } else if (type() == ET_SCROLL_FLING_START ||
    914              type() == ET_SCROLL_FLING_CANCEL) {
    915     GetFlingData(native_event,
    916                  &x_offset_, &y_offset_,
    917                  &x_offset_ordinal_, &y_offset_ordinal_,
    918                  NULL);
    919   } else {
    920     NOTREACHED() << "Unexpected event type " << type()
    921         << " when constructing a ScrollEvent.";
    922   }
    923 }
    924 
    925 ScrollEvent::ScrollEvent(EventType type,
    926                          const gfx::PointF& location,
    927                          base::TimeDelta time_stamp,
    928                          int flags,
    929                          float x_offset,
    930                          float y_offset,
    931                          float x_offset_ordinal,
    932                          float y_offset_ordinal,
    933                          int finger_count)
    934     : MouseEvent(type, location, location, flags, 0),
    935       x_offset_(x_offset),
    936       y_offset_(y_offset),
    937       x_offset_ordinal_(x_offset_ordinal),
    938       y_offset_ordinal_(y_offset_ordinal),
    939       finger_count_(finger_count) {
    940   set_time_stamp(time_stamp);
    941   CHECK(IsScrollEvent());
    942 }
    943 
    944 void ScrollEvent::Scale(const float factor) {
    945   x_offset_ *= factor;
    946   y_offset_ *= factor;
    947   x_offset_ordinal_ *= factor;
    948   y_offset_ordinal_ *= factor;
    949 }
    950 
    951 ////////////////////////////////////////////////////////////////////////////////
    952 // GestureEvent
    953 
    954 GestureEvent::GestureEvent(float x,
    955                            float y,
    956                            int flags,
    957                            base::TimeDelta time_stamp,
    958                            const GestureEventDetails& details)
    959     : LocatedEvent(details.type(),
    960                    gfx::PointF(x, y),
    961                    gfx::PointF(x, y),
    962                    time_stamp,
    963                    flags | EF_FROM_TOUCH),
    964       details_(details) {
    965 }
    966 
    967 GestureEvent::~GestureEvent() {
    968 }
    969 
    970 }  // namespace ui
    971