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 #ifndef UI_EVENTS_EVENT_H_
      6 #define UI_EVENTS_EVENT_H_
      7 
      8 #include "base/basictypes.h"
      9 #include "base/compiler_specific.h"
     10 #include "base/event_types.h"
     11 #include "base/logging.h"
     12 #include "base/time/time.h"
     13 #include "ui/events/event_constants.h"
     14 #include "ui/events/gestures/gesture_types.h"
     15 #include "ui/events/keycodes/keyboard_codes.h"
     16 #include "ui/events/latency_info.h"
     17 #include "ui/gfx/point.h"
     18 
     19 namespace gfx {
     20 class Transform;
     21 }
     22 
     23 namespace ui {
     24 class EventTarget;
     25 
     26 class EVENTS_EXPORT Event {
     27  public:
     28   virtual ~Event();
     29 
     30   class DispatcherApi {
     31    public:
     32     explicit DispatcherApi(Event* event) : event_(event) {}
     33 
     34     void set_target(EventTarget* target) {
     35       event_->target_ = target;
     36     }
     37 
     38     void set_phase(EventPhase phase) { event_->phase_ = phase; }
     39     void set_result(int result) {
     40       event_->result_ = static_cast<EventResult>(result);
     41     }
     42 
     43    private:
     44     DispatcherApi();
     45     Event* event_;
     46 
     47     DISALLOW_COPY_AND_ASSIGN(DispatcherApi);
     48   };
     49 
     50   const base::NativeEvent& native_event() const { return native_event_; }
     51   EventType type() const { return type_; }
     52   const std::string& name() const { return name_; }
     53   // time_stamp represents time since machine was booted.
     54   const base::TimeDelta& time_stamp() const { return time_stamp_; }
     55   int flags() const { return flags_; }
     56 
     57   // This is only intended to be used externally by classes that are modifying
     58   // events in EventFilter::PreHandleKeyEvent().
     59   void set_flags(int flags) { flags_ = flags; }
     60 
     61   EventTarget* target() const { return target_; }
     62   EventPhase phase() const { return phase_; }
     63   EventResult result() const { return result_; }
     64 
     65   LatencyInfo* latency() { return &latency_; }
     66   const LatencyInfo* latency() const { return &latency_; }
     67   void set_latency(const LatencyInfo& latency) { latency_ = latency; }
     68 
     69   // By default, events are "cancelable", this means any default processing that
     70   // the containing abstraction layer may perform can be prevented by calling
     71   // SetHandled(). SetHandled() or StopPropagation() must not be called for
     72   // events that are not cancelable.
     73   bool cancelable() const { return cancelable_; }
     74 
     75   // The following methods return true if the respective keys were pressed at
     76   // the time the event was created.
     77   bool IsShiftDown() const { return (flags_ & EF_SHIFT_DOWN) != 0; }
     78   bool IsControlDown() const { return (flags_ & EF_CONTROL_DOWN) != 0; }
     79   bool IsCapsLockDown() const { return (flags_ & EF_CAPS_LOCK_DOWN) != 0; }
     80   bool IsAltDown() const { return (flags_ & EF_ALT_DOWN) != 0; }
     81   bool IsAltGrDown() const { return (flags_ & EF_ALTGR_DOWN) != 0; }
     82 
     83   bool IsKeyEvent() const {
     84     return type_ == ET_KEY_PRESSED ||
     85            type_ == ET_KEY_RELEASED ||
     86            type_ == ET_TRANSLATED_KEY_PRESS ||
     87            type_ == ET_TRANSLATED_KEY_RELEASE;
     88   }
     89 
     90   bool IsMouseEvent() const {
     91     return type_ == ET_MOUSE_PRESSED ||
     92            type_ == ET_MOUSE_DRAGGED ||
     93            type_ == ET_MOUSE_RELEASED ||
     94            type_ == ET_MOUSE_MOVED ||
     95            type_ == ET_MOUSE_ENTERED ||
     96            type_ == ET_MOUSE_EXITED ||
     97            type_ == ET_MOUSEWHEEL ||
     98            type_ == ET_MOUSE_CAPTURE_CHANGED;
     99   }
    100 
    101   bool IsTouchEvent() const {
    102     return type_ == ET_TOUCH_RELEASED ||
    103            type_ == ET_TOUCH_PRESSED ||
    104            type_ == ET_TOUCH_MOVED ||
    105            type_ == ET_TOUCH_STATIONARY ||
    106            type_ == ET_TOUCH_CANCELLED;
    107   }
    108 
    109   bool IsGestureEvent() const {
    110     switch (type_) {
    111       case ET_GESTURE_SCROLL_BEGIN:
    112       case ET_GESTURE_SCROLL_END:
    113       case ET_GESTURE_SCROLL_UPDATE:
    114       case ET_GESTURE_TAP:
    115       case ET_GESTURE_TAP_CANCEL:
    116       case ET_GESTURE_TAP_DOWN:
    117       case ET_GESTURE_BEGIN:
    118       case ET_GESTURE_END:
    119       case ET_GESTURE_TWO_FINGER_TAP:
    120       case ET_GESTURE_PINCH_BEGIN:
    121       case ET_GESTURE_PINCH_END:
    122       case ET_GESTURE_PINCH_UPDATE:
    123       case ET_GESTURE_LONG_PRESS:
    124       case ET_GESTURE_LONG_TAP:
    125       case ET_GESTURE_MULTIFINGER_SWIPE:
    126       case ET_GESTURE_SHOW_PRESS:
    127         // When adding a gesture event which is paired with an event which
    128         // occurs earlier, add the event to |IsEndingEvent|.
    129         return true;
    130 
    131       case ET_SCROLL_FLING_CANCEL:
    132       case ET_SCROLL_FLING_START:
    133         // These can be ScrollEvents too. EF_FROM_TOUCH determines if they're
    134         // Gesture or Scroll events.
    135         return (flags_ & EF_FROM_TOUCH) == EF_FROM_TOUCH;
    136 
    137       default:
    138         break;
    139     }
    140     return false;
    141   }
    142 
    143   // An ending event is paired with the event which started it. Setting capture
    144   // should not prevent ending events from getting to their initial target.
    145   bool IsEndingEvent() const {
    146     switch(type_) {
    147       case ui::ET_TOUCH_CANCELLED:
    148       case ui::ET_GESTURE_TAP_CANCEL:
    149       case ui::ET_GESTURE_END:
    150       case ui::ET_GESTURE_SCROLL_END:
    151       case ui::ET_GESTURE_PINCH_END:
    152         return true;
    153       default:
    154         return false;
    155     }
    156   }
    157 
    158   bool IsScrollEvent() const {
    159     // Flings can be GestureEvents too. EF_FROM_TOUCH determins if they're
    160     // Gesture or Scroll events.
    161     return type_ == ET_SCROLL ||
    162            ((type_ == ET_SCROLL_FLING_START ||
    163            type_ == ET_SCROLL_FLING_CANCEL) &&
    164            !(flags() & EF_FROM_TOUCH));
    165   }
    166 
    167   bool IsScrollGestureEvent() const {
    168     return type_ == ET_GESTURE_SCROLL_BEGIN ||
    169            type_ == ET_GESTURE_SCROLL_UPDATE ||
    170            type_ == ET_GESTURE_SCROLL_END;
    171   }
    172 
    173   bool IsFlingScrollEvent() const {
    174     return type_ == ET_SCROLL_FLING_CANCEL ||
    175            type_ == ET_SCROLL_FLING_START;
    176   }
    177 
    178   bool IsMouseWheelEvent() const {
    179     return type_ == ET_MOUSEWHEEL;
    180   }
    181 
    182   // Returns true if the event has a valid |native_event_|.
    183   bool HasNativeEvent() const;
    184 
    185   // Immediately stops the propagation of the event. This must be called only
    186   // from an EventHandler during an event-dispatch. Any event handler that may
    187   // be in the list will not receive the event after this is called.
    188   // Note that StopPropagation() can be called only for cancelable events.
    189   void StopPropagation();
    190   bool stopped_propagation() const { return !!(result_ & ER_CONSUMED); }
    191 
    192   // Marks the event as having been handled. A handled event does not reach the
    193   // next event phase. For example, if an event is handled during the pre-target
    194   // phase, then the event is dispatched to all pre-target handlers, but not to
    195   // the target or post-target handlers.
    196   // Note that SetHandled() can be called only for cancelable events.
    197   void SetHandled();
    198   bool handled() const { return result_ != ER_UNHANDLED; }
    199 
    200  protected:
    201   Event(EventType type, base::TimeDelta time_stamp, int flags);
    202   Event(const base::NativeEvent& native_event, EventType type, int flags);
    203   Event(const Event& copy);
    204   void SetType(EventType type);
    205   void set_delete_native_event(bool delete_native_event) {
    206     delete_native_event_ = delete_native_event;
    207   }
    208   void set_cancelable(bool cancelable) { cancelable_ = cancelable; }
    209 
    210   void set_time_stamp(const base::TimeDelta& time_stamp) {
    211     time_stamp_ = time_stamp;
    212   }
    213 
    214   void set_name(const std::string& name) { name_ = name; }
    215 
    216  private:
    217   friend class EventTestApi;
    218 
    219   // Safely initializes the native event members of this class.
    220   void Init();
    221   void InitWithNativeEvent(const base::NativeEvent& native_event);
    222 
    223   EventType type_;
    224   std::string name_;
    225   base::TimeDelta time_stamp_;
    226   LatencyInfo latency_;
    227   int flags_;
    228   base::NativeEvent native_event_;
    229   bool delete_native_event_;
    230   bool cancelable_;
    231   EventTarget* target_;
    232   EventPhase phase_;
    233   EventResult result_;
    234 };
    235 
    236 class EVENTS_EXPORT CancelModeEvent : public Event {
    237  public:
    238   CancelModeEvent();
    239   virtual ~CancelModeEvent();
    240 };
    241 
    242 class EVENTS_EXPORT LocatedEvent : public Event {
    243  public:
    244   virtual ~LocatedEvent();
    245 
    246   int x() const { return location_.x(); }
    247   int y() const { return location_.y(); }
    248   void set_location(const gfx::Point& location) { location_ = location; }
    249   gfx::Point location() const { return location_; }
    250   void set_root_location(const gfx::Point& root_location) {
    251     root_location_ = root_location;
    252   }
    253   gfx::Point root_location() const { return root_location_; }
    254 
    255   // Transform the locations using |inverted_root_transform|.
    256   // This is applied to both |location_| and |root_location_|.
    257   virtual void UpdateForRootTransform(
    258       const gfx::Transform& inverted_root_transform);
    259 
    260   template <class T> void ConvertLocationToTarget(T* source, T* target) {
    261     if (target && target != source)
    262       T::ConvertPointToTarget(source, target, &location_);
    263   }
    264 
    265  protected:
    266   friend class LocatedEventTestApi;
    267   explicit LocatedEvent(const base::NativeEvent& native_event);
    268 
    269   // Create a new LocatedEvent which is identical to the provided model.
    270   // If source / target windows are provided, the model location will be
    271   // converted from |source| coordinate system to |target| coordinate system.
    272   template <class T>
    273   LocatedEvent(const LocatedEvent& model, T* source, T* target)
    274       : Event(model),
    275         location_(model.location_),
    276         root_location_(model.root_location_) {
    277     ConvertLocationToTarget(source, target);
    278   }
    279 
    280   // Used for synthetic events in testing.
    281   LocatedEvent(EventType type,
    282                const gfx::Point& location,
    283                const gfx::Point& root_location,
    284                base::TimeDelta time_stamp,
    285                int flags);
    286 
    287   gfx::Point location_;
    288 
    289   // |location_| multiplied by an optional transformation matrix for
    290   // rotations, animations and skews.
    291   gfx::Point root_location_;
    292 };
    293 
    294 class EVENTS_EXPORT MouseEvent : public LocatedEvent {
    295  public:
    296   explicit MouseEvent(const base::NativeEvent& native_event);
    297 
    298   // Create a new MouseEvent based on the provided model.
    299   // Uses the provided |type| and |flags| for the new event.
    300   // If source / target windows are provided, the model location will be
    301   // converted from |source| coordinate system to |target| coordinate system.
    302   template <class T>
    303   MouseEvent(const MouseEvent& model, T* source, T* target)
    304       : LocatedEvent(model, source, target),
    305         changed_button_flags_(model.changed_button_flags_) {
    306   }
    307 
    308   template <class T>
    309   MouseEvent(const MouseEvent& model,
    310              T* source,
    311              T* target,
    312              EventType type,
    313              int flags)
    314       : LocatedEvent(model, source, target),
    315         changed_button_flags_(model.changed_button_flags_) {
    316     SetType(type);
    317     set_flags(flags);
    318   }
    319 
    320   // Used for synthetic events in testing and by the gesture recognizer.
    321   MouseEvent(EventType type,
    322              const gfx::Point& location,
    323              const gfx::Point& root_location,
    324              int flags);
    325 
    326   // Conveniences to quickly test what button is down
    327   bool IsOnlyLeftMouseButton() const {
    328     return (flags() & EF_LEFT_MOUSE_BUTTON) &&
    329       !(flags() & (EF_MIDDLE_MOUSE_BUTTON | EF_RIGHT_MOUSE_BUTTON));
    330   }
    331 
    332   bool IsLeftMouseButton() const {
    333     return (flags() & EF_LEFT_MOUSE_BUTTON) != 0;
    334   }
    335 
    336   bool IsOnlyMiddleMouseButton() const {
    337     return (flags() & EF_MIDDLE_MOUSE_BUTTON) &&
    338       !(flags() & (EF_LEFT_MOUSE_BUTTON | EF_RIGHT_MOUSE_BUTTON));
    339   }
    340 
    341   bool IsMiddleMouseButton() const {
    342     return (flags() & EF_MIDDLE_MOUSE_BUTTON) != 0;
    343   }
    344 
    345   bool IsOnlyRightMouseButton() const {
    346     return (flags() & EF_RIGHT_MOUSE_BUTTON) &&
    347       !(flags() & (EF_LEFT_MOUSE_BUTTON | EF_MIDDLE_MOUSE_BUTTON));
    348   }
    349 
    350   bool IsRightMouseButton() const {
    351     return (flags() & EF_RIGHT_MOUSE_BUTTON) != 0;
    352   }
    353 
    354   bool IsAnyButton() const {
    355     return (flags() & (EF_LEFT_MOUSE_BUTTON | EF_MIDDLE_MOUSE_BUTTON |
    356                        EF_RIGHT_MOUSE_BUTTON)) != 0;
    357   }
    358 
    359   // Compares two mouse down events and returns true if the second one should
    360   // be considered a repeat of the first.
    361   static bool IsRepeatedClickEvent(
    362       const MouseEvent& event1,
    363       const MouseEvent& event2);
    364 
    365   // Get the click count. Can be 1, 2 or 3 for mousedown messages, 0 otherwise.
    366   int GetClickCount() const;
    367 
    368   // Set the click count for a mousedown message. Can be 1, 2 or 3.
    369   void SetClickCount(int click_count);
    370 
    371   // Identifies the button that changed. During a press this corresponds to the
    372   // button that was pressed and during a release this corresponds to the button
    373   // that was released.
    374   // NOTE: during a press and release flags() contains the complete set of
    375   // flags. Use this to determine the button that was pressed or released.
    376   int changed_button_flags() const { return changed_button_flags_; }
    377 
    378  private:
    379   // Returns the repeat count based on the previous mouse click, if it is
    380   // recent enough and within a small enough distance.
    381   static int GetRepeatCount(const MouseEvent& click_event);
    382 
    383   // See description above getter for details.
    384   int changed_button_flags_;
    385 
    386   static MouseEvent* last_click_event_;
    387 };
    388 
    389 class ScrollEvent;
    390 
    391 class EVENTS_EXPORT MouseWheelEvent : public MouseEvent {
    392  public:
    393   // See |offset| for details.
    394   static const int kWheelDelta;
    395 
    396   explicit MouseWheelEvent(const base::NativeEvent& native_event);
    397   explicit MouseWheelEvent(const ScrollEvent& scroll_event);
    398   MouseWheelEvent(const MouseEvent& mouse_event, int x_offset, int y_offset);
    399   MouseWheelEvent(const MouseWheelEvent& mouse_wheel_event);
    400 
    401   template <class T>
    402   MouseWheelEvent(const MouseWheelEvent& model,
    403                   T* source,
    404                   T* target,
    405                   EventType type,
    406                   int flags)
    407       : MouseEvent(model, source, target, type, flags),
    408         offset_(model.x_offset(), model.y_offset()){
    409   }
    410 
    411   // The amount to scroll. This is in multiples of kWheelDelta.
    412   // Note: x_offset() > 0/y_offset() > 0 means scroll left/up.
    413   int x_offset() const { return offset_.x(); }
    414   int y_offset() const { return offset_.y(); }
    415   const gfx::Vector2d& offset() const { return offset_; }
    416 
    417   // Overridden from LocatedEvent.
    418   virtual void UpdateForRootTransform(
    419       const gfx::Transform& inverted_root_transform) OVERRIDE;
    420 
    421  private:
    422   gfx::Vector2d offset_;
    423 };
    424 
    425 class EVENTS_EXPORT TouchEvent : public LocatedEvent {
    426  public:
    427   explicit TouchEvent(const base::NativeEvent& native_event);
    428 
    429   // Create a new TouchEvent which is identical to the provided model.
    430   // If source / target windows are provided, the model location will be
    431   // converted from |source| coordinate system to |target| coordinate system.
    432   template <class T>
    433   TouchEvent(const TouchEvent& model, T* source, T* target)
    434       : LocatedEvent(model, source, target),
    435         touch_id_(model.touch_id_),
    436         radius_x_(model.radius_x_),
    437         radius_y_(model.radius_y_),
    438         rotation_angle_(model.rotation_angle_),
    439         force_(model.force_) {
    440   }
    441 
    442   TouchEvent(EventType type,
    443              const gfx::Point& root_location,
    444              int touch_id,
    445              base::TimeDelta time_stamp);
    446 
    447   TouchEvent(EventType type,
    448              const gfx::Point& location,
    449              int flags,
    450              int touch_id,
    451              base::TimeDelta timestamp,
    452              float radius_x,
    453              float radius_y,
    454              float angle,
    455              float force);
    456 
    457   virtual ~TouchEvent();
    458 
    459   int touch_id() const { return touch_id_; }
    460   float radius_x() const { return radius_x_; }
    461   float radius_y() const { return radius_y_; }
    462   float rotation_angle() const { return rotation_angle_; }
    463   float force() const { return force_; }
    464 
    465   // Relocate the touch-point to a new |origin|.
    466   // This is useful when touch event is in X Root Window coordinates,
    467   // and it needs to be mapped into Aura Root Window coordinates.
    468   void Relocate(const gfx::Point& origin);
    469 
    470   // Used for unit tests.
    471   void set_radius_x(const float r) { radius_x_ = r; }
    472   void set_radius_y(const float r) { radius_y_ = r; }
    473 
    474   // Overridden from LocatedEvent.
    475   virtual void UpdateForRootTransform(
    476       const gfx::Transform& inverted_root_transform) OVERRIDE;
    477 
    478  protected:
    479   void set_radius(float radius_x, float radius_y) {
    480     radius_x_ = radius_x;
    481     radius_y_ = radius_y;
    482   }
    483 
    484   void set_rotation_angle(float rotation_angle) {
    485     rotation_angle_ = rotation_angle;
    486   }
    487 
    488   void set_force(float force) { force_ = force; }
    489 
    490  private:
    491   // The identity (typically finger) of the touch starting at 0 and incrementing
    492   // for each separable additional touch that the hardware can detect.
    493   const int touch_id_;
    494 
    495   // Radius of the X (major) axis of the touch ellipse. 0.0 if unknown.
    496   float radius_x_;
    497 
    498   // Radius of the Y (minor) axis of the touch ellipse. 0.0 if unknown.
    499   float radius_y_;
    500 
    501   // Angle of the major axis away from the X axis. Default 0.0.
    502   float rotation_angle_;
    503 
    504   // Force (pressure) of the touch. Normalized to be [0, 1]. Default to be 0.0.
    505   float force_;
    506 };
    507 
    508 class EVENTS_EXPORT KeyEvent : public Event {
    509  public:
    510   KeyEvent(const base::NativeEvent& native_event, bool is_char);
    511 
    512   // Used for synthetic events.
    513   KeyEvent(EventType type, KeyboardCode key_code, int flags, bool is_char);
    514 
    515   // Used for synthetic events with code of DOM KeyboardEvent (e.g. 'KeyA')
    516   // See also: ui/events/keycodes/dom4/keycode_converter_data.h
    517   KeyEvent(EventType type, KeyboardCode key_code, const std::string& code,
    518            int flags, bool is_char);
    519 
    520   // This allows an I18N virtual keyboard to fabricate a keyboard event that
    521   // does not have a corresponding KeyboardCode (example: U+00E1 Latin small
    522   // letter A with acute, U+0410 Cyrillic capital letter A).
    523   void set_character(uint16 character) { character_ = character; }
    524 
    525   // Gets the character generated by this key event. It only supports Unicode
    526   // BMP characters.
    527   uint16 GetCharacter() const;
    528 
    529   KeyboardCode key_code() const { return key_code_; }
    530   bool is_char() const { return is_char_; }
    531 
    532   // This is only intended to be used externally by classes that are modifying
    533   // events in EventFilter::PreHandleKeyEvent().  set_character() should also be
    534   // called.
    535   void set_key_code(KeyboardCode key_code) { key_code_ = key_code; }
    536 
    537   // Returns true for [Alt]+<num-pad digit> Unicode alt key codes used by Win.
    538   // TODO(msw): Additional work may be needed for analogues on other platforms.
    539   bool IsUnicodeKeyCode() const;
    540 
    541   std::string code() const { return code_; }
    542 
    543   // Normalizes flags_ to make it Windows/Mac compatible. Since the way
    544   // of setting modifier mask on X is very different than Windows/Mac as shown
    545   // in http://crbug.com/127142#c8, the normalization is necessary.
    546   void NormalizeFlags();
    547 
    548  private:
    549   KeyboardCode key_code_;
    550 
    551   // String of 'code' defined in DOM KeyboardEvent (e.g. 'KeyA', 'Space')
    552   // http://www.w3.org/TR/uievents/#keyboard-key-codes.
    553   //
    554   // This value represents the physical position in the keyboard and can be
    555   // converted from / to keyboard scan code like XKB.
    556   std::string code_;
    557 
    558   // True if this is a translated character event (vs. a raw key down). Both
    559   // share the same type: ET_KEY_PRESSED.
    560   bool is_char_;
    561 
    562   uint16 character_;
    563 };
    564 
    565 // A key event which is translated by an input method (IME).
    566 // For example, if an IME receives a KeyEvent(VKEY_SPACE), and it does not
    567 // consume the key, the IME usually generates and dispatches a
    568 // TranslatedKeyEvent(VKEY_SPACE) event. If the IME receives a KeyEvent and
    569 // it does consume the event, it might dispatch a
    570 // TranslatedKeyEvent(VKEY_PROCESSKEY) event as defined in the DOM spec.
    571 class EVENTS_EXPORT TranslatedKeyEvent : public KeyEvent {
    572  public:
    573   TranslatedKeyEvent(const base::NativeEvent& native_event, bool is_char);
    574 
    575   // Used for synthetic events such as a VKEY_PROCESSKEY key event.
    576   TranslatedKeyEvent(bool is_press, KeyboardCode key_code, int flags);
    577 
    578   // Changes the type() of the object from ET_TRANSLATED_KEY_* to ET_KEY_* so
    579   // that RenderWidgetHostViewAura and NativeWidgetAura could handle the event.
    580   void ConvertToKeyEvent();
    581 
    582  private:
    583   DISALLOW_COPY_AND_ASSIGN(TranslatedKeyEvent);
    584 };
    585 
    586 class EVENTS_EXPORT ScrollEvent : public MouseEvent {
    587  public:
    588   explicit ScrollEvent(const base::NativeEvent& native_event);
    589   template <class T>
    590   ScrollEvent(const ScrollEvent& model,
    591               T* source,
    592               T* target)
    593       : MouseEvent(model, source, target),
    594         x_offset_(model.x_offset_),
    595         y_offset_(model.y_offset_),
    596         x_offset_ordinal_(model.x_offset_ordinal_),
    597         y_offset_ordinal_(model.y_offset_ordinal_),
    598         finger_count_(model.finger_count_){
    599   }
    600 
    601   // Used for tests.
    602   ScrollEvent(EventType type,
    603               const gfx::Point& location,
    604               base::TimeDelta time_stamp,
    605               int flags,
    606               float x_offset,
    607               float y_offset,
    608               float x_offset_ordinal,
    609               float y_offset_ordinal,
    610               int finger_count);
    611 
    612   // Scale the scroll event's offset value.
    613   // This is useful in the multi-monitor setup where it needs to be scaled
    614   // to provide a consistent user experience.
    615   void Scale(const float factor);
    616 
    617   float x_offset() const { return x_offset_; }
    618   float y_offset() const { return y_offset_; }
    619   float x_offset_ordinal() const { return x_offset_ordinal_; }
    620   float y_offset_ordinal() const { return y_offset_ordinal_; }
    621   int finger_count() const { return finger_count_; }
    622 
    623  private:
    624   // Potential accelerated offsets.
    625   float x_offset_;
    626   float y_offset_;
    627   // Unaccelerated offsets.
    628   float x_offset_ordinal_;
    629   float y_offset_ordinal_;
    630   // Number of fingers on the pad.
    631   int finger_count_;
    632 };
    633 
    634 class EVENTS_EXPORT GestureEvent : public LocatedEvent {
    635  public:
    636   GestureEvent(EventType type,
    637                int x,
    638                int y,
    639                int flags,
    640                base::TimeDelta time_stamp,
    641                const GestureEventDetails& details,
    642                unsigned int touch_ids_bitfield);
    643 
    644   // Create a new GestureEvent which is identical to the provided model.
    645   // If source / target windows are provided, the model location will be
    646   // converted from |source| coordinate system to |target| coordinate system.
    647   template <typename T>
    648   GestureEvent(const GestureEvent& model, T* source, T* target)
    649       : LocatedEvent(model, source, target),
    650         details_(model.details_),
    651         touch_ids_bitfield_(model.touch_ids_bitfield_) {
    652   }
    653 
    654   virtual ~GestureEvent();
    655 
    656   const GestureEventDetails& details() const { return details_; }
    657 
    658   // Returns the lowest touch-id of any of the touches which make up this
    659   // gesture. If there are no touches associated with this gesture, returns -1.
    660   int GetLowestTouchId() const;
    661 
    662  private:
    663   GestureEventDetails details_;
    664 
    665   // The set of indices of ones in the binary representation of
    666   // touch_ids_bitfield_ is the set of touch_ids associate with this gesture.
    667   // This value is stored as a bitfield because the number of touch ids varies,
    668   // but we currently don't need more than 32 touches at a time.
    669   const unsigned int touch_ids_bitfield_;
    670 };
    671 
    672 }  // namespace ui
    673 
    674 #endif  // UI_EVENTS_EVENT_H_
    675