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