• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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/gtest_prod_util.h"
12 #include "base/logging.h"
13 #include "base/memory/scoped_ptr.h"
14 #include "base/time/time.h"
15 #include "ui/events/event_constants.h"
16 #include "ui/events/gesture_event_details.h"
17 #include "ui/events/gestures/gesture_types.h"
18 #include "ui/events/keycodes/keyboard_codes.h"
19 #include "ui/events/latency_info.h"
20 #include "ui/gfx/point.h"
21 #include "ui/gfx/point_conversions.h"
22 
23 namespace gfx {
24 class Transform;
25 }
26 
27 namespace ui {
28 class EventTarget;
29 
30 class EVENTS_EXPORT Event {
31  public:
32   static scoped_ptr<Event> Clone(const Event& event);
33 
34   virtual ~Event();
35 
36   class DispatcherApi {
37    public:
DispatcherApi(Event * event)38     explicit DispatcherApi(Event* event) : event_(event) {}
39 
set_target(EventTarget * target)40     void set_target(EventTarget* target) {
41       event_->target_ = target;
42     }
43 
set_phase(EventPhase phase)44     void set_phase(EventPhase phase) { event_->phase_ = phase; }
set_result(int result)45     void set_result(int result) {
46       event_->result_ = static_cast<EventResult>(result);
47     }
48 
49    private:
50     DispatcherApi();
51     Event* event_;
52 
53     DISALLOW_COPY_AND_ASSIGN(DispatcherApi);
54   };
55 
native_event()56   const base::NativeEvent& native_event() const { return native_event_; }
type()57   EventType type() const { return type_; }
name()58   const std::string& name() const { return name_; }
59   // time_stamp represents time since machine was booted.
time_stamp()60   const base::TimeDelta& time_stamp() const { return time_stamp_; }
flags()61   int flags() const { return flags_; }
62 
63   // This is only intended to be used externally by classes that are modifying
64   // events in an EventRewriter.
set_flags(int flags)65   void set_flags(int flags) { flags_ = flags; }
66 
target()67   EventTarget* target() const { return target_; }
phase()68   EventPhase phase() const { return phase_; }
result()69   EventResult result() const { return result_; }
70 
latency()71   LatencyInfo* latency() { return &latency_; }
latency()72   const LatencyInfo* latency() const { return &latency_; }
set_latency(const LatencyInfo & latency)73   void set_latency(const LatencyInfo& latency) { latency_ = latency; }
74 
source_device_id()75   int source_device_id() const { return source_device_id_; }
76 
77   // By default, events are "cancelable", this means any default processing that
78   // the containing abstraction layer may perform can be prevented by calling
79   // SetHandled(). SetHandled() or StopPropagation() must not be called for
80   // events that are not cancelable.
cancelable()81   bool cancelable() const { return cancelable_; }
82 
83   // The following methods return true if the respective keys were pressed at
84   // the time the event was created.
IsShiftDown()85   bool IsShiftDown() const { return (flags_ & EF_SHIFT_DOWN) != 0; }
IsControlDown()86   bool IsControlDown() const { return (flags_ & EF_CONTROL_DOWN) != 0; }
IsCapsLockDown()87   bool IsCapsLockDown() const { return (flags_ & EF_CAPS_LOCK_DOWN) != 0; }
IsAltDown()88   bool IsAltDown() const { return (flags_ & EF_ALT_DOWN) != 0; }
IsAltGrDown()89   bool IsAltGrDown() const { return (flags_ & EF_ALTGR_DOWN) != 0; }
IsCommandDown()90   bool IsCommandDown() const { return (flags_ & EF_COMMAND_DOWN) != 0; }
IsRepeat()91   bool IsRepeat() const { return (flags_ & EF_IS_REPEAT) != 0; }
92 
IsKeyEvent()93   bool IsKeyEvent() const {
94     return type_ == ET_KEY_PRESSED ||
95            type_ == ET_KEY_RELEASED ||
96            type_ == ET_TRANSLATED_KEY_PRESS ||
97            type_ == ET_TRANSLATED_KEY_RELEASE;
98   }
99 
IsMouseEvent()100   bool IsMouseEvent() const {
101     return type_ == ET_MOUSE_PRESSED ||
102            type_ == ET_MOUSE_DRAGGED ||
103            type_ == ET_MOUSE_RELEASED ||
104            type_ == ET_MOUSE_MOVED ||
105            type_ == ET_MOUSE_ENTERED ||
106            type_ == ET_MOUSE_EXITED ||
107            type_ == ET_MOUSEWHEEL ||
108            type_ == ET_MOUSE_CAPTURE_CHANGED;
109   }
110 
IsTouchEvent()111   bool IsTouchEvent() const {
112     return type_ == ET_TOUCH_RELEASED ||
113            type_ == ET_TOUCH_PRESSED ||
114            type_ == ET_TOUCH_MOVED ||
115            type_ == ET_TOUCH_CANCELLED;
116   }
117 
IsGestureEvent()118   bool IsGestureEvent() const {
119     switch (type_) {
120       case ET_GESTURE_SCROLL_BEGIN:
121       case ET_GESTURE_SCROLL_END:
122       case ET_GESTURE_SCROLL_UPDATE:
123       case ET_GESTURE_TAP:
124       case ET_GESTURE_TAP_CANCEL:
125       case ET_GESTURE_TAP_DOWN:
126       case ET_GESTURE_BEGIN:
127       case ET_GESTURE_END:
128       case ET_GESTURE_TWO_FINGER_TAP:
129       case ET_GESTURE_PINCH_BEGIN:
130       case ET_GESTURE_PINCH_END:
131       case ET_GESTURE_PINCH_UPDATE:
132       case ET_GESTURE_LONG_PRESS:
133       case ET_GESTURE_LONG_TAP:
134       case ET_GESTURE_SWIPE:
135       case ET_GESTURE_SHOW_PRESS:
136       case ET_GESTURE_WIN8_EDGE_SWIPE:
137         // When adding a gesture event which is paired with an event which
138         // occurs earlier, add the event to |IsEndingEvent|.
139         return true;
140 
141       case ET_SCROLL_FLING_CANCEL:
142       case ET_SCROLL_FLING_START:
143         // These can be ScrollEvents too. EF_FROM_TOUCH determines if they're
144         // Gesture or Scroll events.
145         return (flags_ & EF_FROM_TOUCH) == EF_FROM_TOUCH;
146 
147       default:
148         break;
149     }
150     return false;
151   }
152 
153   // An ending event is paired with the event which started it. Setting capture
154   // should not prevent ending events from getting to their initial target.
IsEndingEvent()155   bool IsEndingEvent() const {
156     switch(type_) {
157       case ui::ET_TOUCH_CANCELLED:
158       case ui::ET_GESTURE_TAP_CANCEL:
159       case ui::ET_GESTURE_END:
160       case ui::ET_GESTURE_SCROLL_END:
161       case ui::ET_GESTURE_PINCH_END:
162         return true;
163       default:
164         return false;
165     }
166   }
167 
IsScrollEvent()168   bool IsScrollEvent() const {
169     // Flings can be GestureEvents too. EF_FROM_TOUCH determins if they're
170     // Gesture or Scroll events.
171     return type_ == ET_SCROLL ||
172            ((type_ == ET_SCROLL_FLING_START ||
173            type_ == ET_SCROLL_FLING_CANCEL) &&
174            !(flags() & EF_FROM_TOUCH));
175   }
176 
IsScrollGestureEvent()177   bool IsScrollGestureEvent() const {
178     return type_ == ET_GESTURE_SCROLL_BEGIN ||
179            type_ == ET_GESTURE_SCROLL_UPDATE ||
180            type_ == ET_GESTURE_SCROLL_END;
181   }
182 
IsFlingScrollEvent()183   bool IsFlingScrollEvent() const {
184     return type_ == ET_SCROLL_FLING_CANCEL ||
185            type_ == ET_SCROLL_FLING_START;
186   }
187 
IsMouseWheelEvent()188   bool IsMouseWheelEvent() const {
189     return type_ == ET_MOUSEWHEEL;
190   }
191 
IsLocatedEvent()192   bool IsLocatedEvent() const {
193     return IsMouseEvent() || IsScrollEvent() || IsTouchEvent() ||
194            IsGestureEvent();
195   }
196 
197   // Convenience methods to cast |this| to a GestureEvent. IsGestureEvent()
198   // must be true as a precondition to calling these methods.
199   GestureEvent* AsGestureEvent();
200   const GestureEvent* AsGestureEvent() const;
201 
202   // Returns true if the event has a valid |native_event_|.
203   bool HasNativeEvent() const;
204 
205   // Immediately stops the propagation of the event. This must be called only
206   // from an EventHandler during an event-dispatch. Any event handler that may
207   // be in the list will not receive the event after this is called.
208   // Note that StopPropagation() can be called only for cancelable events.
209   void StopPropagation();
stopped_propagation()210   bool stopped_propagation() const { return !!(result_ & ER_CONSUMED); }
211 
212   // Marks the event as having been handled. A handled event does not reach the
213   // next event phase. For example, if an event is handled during the pre-target
214   // phase, then the event is dispatched to all pre-target handlers, but not to
215   // the target or post-target handlers.
216   // Note that SetHandled() can be called only for cancelable events.
217   void SetHandled();
handled()218   bool handled() const { return result_ != ER_UNHANDLED; }
219 
220  protected:
221   Event(EventType type, base::TimeDelta time_stamp, int flags);
222   Event(const base::NativeEvent& native_event, EventType type, int flags);
223   Event(const Event& copy);
224   void SetType(EventType type);
set_delete_native_event(bool delete_native_event)225   void set_delete_native_event(bool delete_native_event) {
226     delete_native_event_ = delete_native_event;
227   }
set_cancelable(bool cancelable)228   void set_cancelable(bool cancelable) { cancelable_ = cancelable; }
229 
set_time_stamp(const base::TimeDelta & time_stamp)230   void set_time_stamp(const base::TimeDelta& time_stamp) {
231     time_stamp_ = time_stamp;
232   }
233 
set_name(const std::string & name)234   void set_name(const std::string& name) { name_ = name; }
235 
236  private:
237   friend class EventTestApi;
238 
239   EventType type_;
240   std::string name_;
241   base::TimeDelta time_stamp_;
242   LatencyInfo latency_;
243   int flags_;
244   base::NativeEvent native_event_;
245   bool delete_native_event_;
246   bool cancelable_;
247   EventTarget* target_;
248   EventPhase phase_;
249   EventResult result_;
250 
251   // The device id the event came from, or ED_UNKNOWN_DEVICE if the information
252   // is not available.
253   int source_device_id_;
254 };
255 
256 class EVENTS_EXPORT CancelModeEvent : public Event {
257  public:
258   CancelModeEvent();
259   virtual ~CancelModeEvent();
260 };
261 
262 class EVENTS_EXPORT LocatedEvent : public Event {
263  public:
264   virtual ~LocatedEvent();
265 
x()266   float x() const { return location_.x(); }
y()267   float y() const { return location_.y(); }
set_location(const gfx::PointF & location)268   void set_location(const gfx::PointF& location) { location_ = location; }
269   // TODO(tdresser): Always return floating point location. See
270   // crbug.com/337824.
location()271   gfx::Point location() const { return gfx::ToFlooredPoint(location_); }
location_f()272   const gfx::PointF& location_f() const { return location_; }
set_root_location(const gfx::PointF & root_location)273   void set_root_location(const gfx::PointF& root_location) {
274     root_location_ = root_location;
275   }
root_location()276   gfx::Point root_location() const {
277     return gfx::ToFlooredPoint(root_location_);
278   }
root_location_f()279   const gfx::PointF& root_location_f() const {
280     return root_location_;
281   }
282 
283   // Transform the locations using |inverted_root_transform|.
284   // This is applied to both |location_| and |root_location_|.
285   virtual void UpdateForRootTransform(
286       const gfx::Transform& inverted_root_transform);
287 
ConvertLocationToTarget(T * source,T * target)288   template <class T> void ConvertLocationToTarget(T* source, T* target) {
289     if (!target || target == source)
290       return;
291     // TODO(tdresser): Rewrite ConvertPointToTarget to use PointF. See
292     // crbug.com/337824.
293     gfx::Point offset = gfx::ToFlooredPoint(location_);
294     T::ConvertPointToTarget(source, target, &offset);
295     gfx::Vector2d diff = gfx::ToFlooredPoint(location_) - offset;
296     location_= location_ - diff;
297   }
298 
299  protected:
300   friend class LocatedEventTestApi;
301   explicit LocatedEvent(const base::NativeEvent& native_event);
302 
303   // Create a new LocatedEvent which is identical to the provided model.
304   // If source / target windows are provided, the model location will be
305   // converted from |source| coordinate system to |target| coordinate system.
306   template <class T>
LocatedEvent(const LocatedEvent & model,T * source,T * target)307   LocatedEvent(const LocatedEvent& model, T* source, T* target)
308       : Event(model),
309         location_(model.location_),
310         root_location_(model.root_location_) {
311     ConvertLocationToTarget(source, target);
312   }
313 
314   // Used for synthetic events in testing.
315   LocatedEvent(EventType type,
316                const gfx::PointF& location,
317                const gfx::PointF& root_location,
318                base::TimeDelta time_stamp,
319                int flags);
320 
321   gfx::PointF location_;
322 
323   // |location_| multiplied by an optional transformation matrix for
324   // rotations, animations and skews.
325   gfx::PointF root_location_;
326 };
327 
328 class EVENTS_EXPORT MouseEvent : public LocatedEvent {
329  public:
330   explicit MouseEvent(const base::NativeEvent& native_event);
331 
332   // Create a new MouseEvent based on the provided model.
333   // Uses the provided |type| and |flags| for the new event.
334   // If source / target windows are provided, the model location will be
335   // converted from |source| coordinate system to |target| coordinate system.
336   template <class T>
MouseEvent(const MouseEvent & model,T * source,T * target)337   MouseEvent(const MouseEvent& model, T* source, T* target)
338       : LocatedEvent(model, source, target),
339         changed_button_flags_(model.changed_button_flags_) {
340   }
341 
342   template <class T>
MouseEvent(const MouseEvent & model,T * source,T * target,EventType type,int flags)343   MouseEvent(const MouseEvent& model,
344              T* source,
345              T* target,
346              EventType type,
347              int flags)
348       : LocatedEvent(model, source, target),
349         changed_button_flags_(model.changed_button_flags_) {
350     SetType(type);
351     set_flags(flags);
352   }
353 
354   // Used for synthetic events in testing and by the gesture recognizer.
355   MouseEvent(EventType type,
356              const gfx::PointF& location,
357              const gfx::PointF& root_location,
358              int flags,
359              int changed_button_flags);
360 
361   // Conveniences to quickly test what button is down
IsOnlyLeftMouseButton()362   bool IsOnlyLeftMouseButton() const {
363     return (flags() & EF_LEFT_MOUSE_BUTTON) &&
364       !(flags() & (EF_MIDDLE_MOUSE_BUTTON | EF_RIGHT_MOUSE_BUTTON));
365   }
366 
IsLeftMouseButton()367   bool IsLeftMouseButton() const {
368     return (flags() & EF_LEFT_MOUSE_BUTTON) != 0;
369   }
370 
IsOnlyMiddleMouseButton()371   bool IsOnlyMiddleMouseButton() const {
372     return (flags() & EF_MIDDLE_MOUSE_BUTTON) &&
373       !(flags() & (EF_LEFT_MOUSE_BUTTON | EF_RIGHT_MOUSE_BUTTON));
374   }
375 
IsMiddleMouseButton()376   bool IsMiddleMouseButton() const {
377     return (flags() & EF_MIDDLE_MOUSE_BUTTON) != 0;
378   }
379 
IsOnlyRightMouseButton()380   bool IsOnlyRightMouseButton() const {
381     return (flags() & EF_RIGHT_MOUSE_BUTTON) &&
382       !(flags() & (EF_LEFT_MOUSE_BUTTON | EF_MIDDLE_MOUSE_BUTTON));
383   }
384 
IsRightMouseButton()385   bool IsRightMouseButton() const {
386     return (flags() & EF_RIGHT_MOUSE_BUTTON) != 0;
387   }
388 
IsAnyButton()389   bool IsAnyButton() const {
390     return (flags() & (EF_LEFT_MOUSE_BUTTON | EF_MIDDLE_MOUSE_BUTTON |
391                        EF_RIGHT_MOUSE_BUTTON)) != 0;
392   }
393 
394   // Compares two mouse down events and returns true if the second one should
395   // be considered a repeat of the first.
396   static bool IsRepeatedClickEvent(
397       const MouseEvent& event1,
398       const MouseEvent& event2);
399 
400   // Get the click count. Can be 1, 2 or 3 for mousedown messages, 0 otherwise.
401   int GetClickCount() const;
402 
403   // Set the click count for a mousedown message. Can be 1, 2 or 3.
404   void SetClickCount(int click_count);
405 
406   // Identifies the button that changed. During a press this corresponds to the
407   // button that was pressed and during a release this corresponds to the button
408   // that was released.
409   // NOTE: during a press and release flags() contains the complete set of
410   // flags. Use this to determine the button that was pressed or released.
changed_button_flags()411   int changed_button_flags() const { return changed_button_flags_; }
412 
413   // Updates the button that changed.
set_changed_button_flags(int flags)414   void set_changed_button_flags(int flags) { changed_button_flags_ = flags; }
415 
416  private:
417   FRIEND_TEST_ALL_PREFIXES(EventTest, DoubleClickRequiresRelease);
418   FRIEND_TEST_ALL_PREFIXES(EventTest, SingleClickRightLeft);
419 
420   // Returns the repeat count based on the previous mouse click, if it is
421   // recent enough and within a small enough distance.
422   static int GetRepeatCount(const MouseEvent& click_event);
423 
424   // Resets the last_click_event_ for unit tests.
425   static void ResetLastClickForTest();
426 
427   // See description above getter for details.
428   int changed_button_flags_;
429 
430   static MouseEvent* last_click_event_;
431 
432   // We can create a MouseEvent for a native event more than once. We set this
433   // to true when the next event either has a different timestamp or we see a
434   // release signalling that the press (click) event was completed.
435   static bool last_click_complete_;
436 };
437 
438 class ScrollEvent;
439 
440 class EVENTS_EXPORT MouseWheelEvent : public MouseEvent {
441  public:
442   // See |offset| for details.
443   static const int kWheelDelta;
444 
445   explicit MouseWheelEvent(const base::NativeEvent& native_event);
446   explicit MouseWheelEvent(const ScrollEvent& scroll_event);
447   MouseWheelEvent(const MouseEvent& mouse_event, int x_offset, int y_offset);
448   MouseWheelEvent(const MouseWheelEvent& mouse_wheel_event);
449 
450   template <class T>
MouseWheelEvent(const MouseWheelEvent & model,T * source,T * target)451   MouseWheelEvent(const MouseWheelEvent& model,
452                   T* source,
453                   T* target)
454       : MouseEvent(model, source, target, model.type(), model.flags()),
455         offset_(model.x_offset(), model.y_offset()) {
456   }
457 
458   // Used for synthetic events in testing and by the gesture recognizer.
459   MouseWheelEvent(const gfx::Vector2d& offset,
460                   const gfx::PointF& location,
461                   const gfx::PointF& root_location,
462                   int flags,
463                   int changed_button_flags);
464 
465   // The amount to scroll. This is in multiples of kWheelDelta.
466   // Note: x_offset() > 0/y_offset() > 0 means scroll left/up.
x_offset()467   int x_offset() const { return offset_.x(); }
y_offset()468   int y_offset() const { return offset_.y(); }
offset()469   const gfx::Vector2d& offset() const { return offset_; }
470 
471   // Overridden from LocatedEvent.
472   virtual void UpdateForRootTransform(
473       const gfx::Transform& inverted_root_transform) OVERRIDE;
474 
475  private:
476   gfx::Vector2d offset_;
477 };
478 
479 class EVENTS_EXPORT TouchEvent : public LocatedEvent {
480  public:
481   explicit TouchEvent(const base::NativeEvent& native_event);
482 
483   // Create a new TouchEvent which is identical to the provided model.
484   // If source / target windows are provided, the model location will be
485   // converted from |source| coordinate system to |target| coordinate system.
486   template <class T>
TouchEvent(const TouchEvent & model,T * source,T * target)487   TouchEvent(const TouchEvent& model, T* source, T* target)
488       : LocatedEvent(model, source, target),
489         touch_id_(model.touch_id_),
490         radius_x_(model.radius_x_),
491         radius_y_(model.radius_y_),
492         rotation_angle_(model.rotation_angle_),
493         force_(model.force_) {
494   }
495 
496   TouchEvent(EventType type,
497              const gfx::PointF& location,
498              int touch_id,
499              base::TimeDelta time_stamp);
500 
501   TouchEvent(EventType type,
502              const gfx::PointF& location,
503              int flags,
504              int touch_id,
505              base::TimeDelta timestamp,
506              float radius_x,
507              float radius_y,
508              float angle,
509              float force);
510 
511   virtual ~TouchEvent();
512 
touch_id()513   int touch_id() const { return touch_id_; }
radius_x()514   float radius_x() const { return radius_x_; }
radius_y()515   float radius_y() const { return radius_y_; }
rotation_angle()516   float rotation_angle() const { return rotation_angle_; }
force()517   float force() const { return force_; }
518 
519   // Used for unit tests.
set_radius_x(const float r)520   void set_radius_x(const float r) { radius_x_ = r; }
set_radius_y(const float r)521   void set_radius_y(const float r) { radius_y_ = r; }
522 
523   // Overridden from LocatedEvent.
524   virtual void UpdateForRootTransform(
525       const gfx::Transform& inverted_root_transform) OVERRIDE;
526 
527  protected:
set_radius(float radius_x,float radius_y)528   void set_radius(float radius_x, float radius_y) {
529     radius_x_ = radius_x;
530     radius_y_ = radius_y;
531   }
532 
set_rotation_angle(float rotation_angle)533   void set_rotation_angle(float rotation_angle) {
534     rotation_angle_ = rotation_angle;
535   }
536 
set_force(float force)537   void set_force(float force) { force_ = force; }
538 
539  private:
540   // The identity (typically finger) of the touch starting at 0 and incrementing
541   // for each separable additional touch that the hardware can detect.
542   const int touch_id_;
543 
544   // Radius of the X (major) axis of the touch ellipse. 0.0 if unknown.
545   float radius_x_;
546 
547   // Radius of the Y (minor) axis of the touch ellipse. 0.0 if unknown.
548   float radius_y_;
549 
550   // Angle of the major axis away from the X axis. Default 0.0.
551   float rotation_angle_;
552 
553   // Force (pressure) of the touch. Normalized to be [0, 1]. Default to be 0.0.
554   float force_;
555 };
556 
557 // An interface that individual platforms can use to store additional data on
558 // KeyEvent.
559 //
560 // Currently only used in mojo.
561 class EVENTS_EXPORT ExtendedKeyEventData {
562  public:
~ExtendedKeyEventData()563   virtual ~ExtendedKeyEventData() {}
564 
565   virtual ExtendedKeyEventData* Clone() const = 0;
566 };
567 
568 // A KeyEvent is really two distinct classes, melded together due to the
569 // DOM legacy of Windows key events: a keystroke event (is_char_ == false),
570 // or a character event (is_char_ == true).
571 //
572 // For a keystroke event,
573 // -- is_char_ is false.
574 // -- type() can be any one of ET_KEY_PRESSED, ET_KEY_RELEASED,
575 //    ET_TRANSLATED_KEY_PRESS, or ET_TRANSLATED_KEY_RELEASE.
576 // -- character_ functions as a bypass or cache for GetCharacter().
577 // -- key_code_ is a VKEY_ value associated with the key. For printable
578 //    characters, this may or may not be a mapped value, imitating MS Windows:
579 //    if the mapped key generates a character that has an associated VKEY_
580 //    code, then key_code_ is that code; if not, then key_code_ is the unmapped
581 //    VKEY_ code. For example, US, Greek, Cyrillic, Japanese, etc. all use
582 //    VKEY_Q for the key beside Tab, while French uses VKEY_A.
583 // -- code_ is in one-to-one correspondence with a physical keyboard
584 //    location, and does not vary depending on key layout.
585 //
586 // For a character event,
587 // -- is_char_ is true.
588 // -- type() is ET_KEY_PRESSED.
589 // -- character_ is a UTF-16 character value.
590 // -- key_code_ is conflated with character_ by some code, because both
591 //    arrive in the wParam field of a Windows event.
592 // -- code_ is the empty string.
593 //
594 class EVENTS_EXPORT KeyEvent : public Event {
595  public:
596   // Create a KeyEvent from a NativeEvent. For Windows this native event can
597   // be either a keystroke message (WM_KEYUP/WM_KEYDOWN) or a character message
598   // (WM_CHAR). Other systems have only keystroke events.
599   explicit KeyEvent(const base::NativeEvent& native_event);
600 
601   // Create a keystroke event.
602   KeyEvent(EventType type, KeyboardCode key_code, int flags);
603 
604   // Create a character event.
605   KeyEvent(base::char16 character, KeyboardCode key_code, int flags);
606 
607   // Used for synthetic events with code of DOM KeyboardEvent (e.g. 'KeyA')
608   // See also: ui/events/keycodes/dom4/keycode_converter_data.h
609   KeyEvent(EventType type,
610            KeyboardCode key_code,
611            const std::string& code,
612            int flags);
613 
614   KeyEvent(const KeyEvent& rhs);
615 
616   KeyEvent& operator=(const KeyEvent& rhs);
617 
618   virtual ~KeyEvent();
619 
620   // TODO(erg): While we transition to mojo, we have to hack around a mismatch
621   // in our event types. Our ui::Events don't really have all the data we need
622   // to process key events, and we instead do per-platform conversions with
623   // native HWNDs or XEvents. And we can't reliably send those native data
624   // types across mojo types in a cross-platform way. So instead, we set the
625   // resulting data when read across IPC boundaries.
626   void SetExtendedKeyEventData(scoped_ptr<ExtendedKeyEventData> data);
extended_key_event_data()627   const ExtendedKeyEventData* extended_key_event_data() const {
628     return extended_key_event_data_.get();
629   }
630 
631   // This bypasses the normal mapping from keystroke events to characters,
632   // which allows an I18N virtual keyboard to fabricate a keyboard event that
633   // does not have a corresponding KeyboardCode (example: U+00E1 Latin small
634   // letter A with acute, U+0410 Cyrillic capital letter A).
set_character(base::char16 character)635   void set_character(base::char16 character) { character_ = character; }
636 
637   // Gets the character generated by this key event. It only supports Unicode
638   // BMP characters.
639   base::char16 GetCharacter() const;
640 
641   // If this is a keystroke event with key_code_ VKEY_RETURN, returns '\r';
642   // otherwise returns the same as GetCharacter().
643   base::char16 GetUnmodifiedText() const;
644 
645   // If the Control key is down in the event, returns a layout-independent
646   // character (corresponding to US layout); otherwise returns the same
647   // as GetUnmodifiedText().
648   base::char16 GetText() const;
649 
650   // Gets the platform key code. For XKB, this is the xksym value.
set_platform_keycode(uint32 keycode)651   void set_platform_keycode(uint32 keycode) { platform_keycode_ = keycode; }
platform_keycode()652   uint32 platform_keycode() const { return platform_keycode_; }
653 
654   // Gets the associated (Windows-based) KeyboardCode for this key event.
655   // Historically, this has also been used to obtain the character associated
656   // with a character event, because both use the Window message 'wParam' field.
657   // This should be avoided; if necessary for backwards compatibility, use
658   // GetConflatedWindowsKeyCode().
key_code()659   KeyboardCode key_code() const { return key_code_; }
660 
661   // True if this is a character event, false if this is a keystroke event.
is_char()662   bool is_char() const { return is_char_; }
663 
664   // This is only intended to be used externally by classes that are modifying
665   // events in an EventRewriter.
set_key_code(KeyboardCode key_code)666   void set_key_code(KeyboardCode key_code) { key_code_ = key_code; }
667 
668   // Returns the same value as key_code(), except that located codes are
669   // returned in place of non-located ones (e.g. VKEY_LSHIFT or VKEY_RSHIFT
670   // instead of VKEY_SHIFT). This is a hybrid of semantic and physical
671   // for legacy DOM reasons.
672   KeyboardCode GetLocatedWindowsKeyboardCode() const;
673 
674   // For a keystroke event, returns the same value as key_code().
675   // For a character event, returns the same value as GetCharacter().
676   // This exists for backwards compatibility with Windows key events.
677   uint16 GetConflatedWindowsKeyCode() const;
678 
679   // Returns true for [Alt]+<num-pad digit> Unicode alt key codes used by Win.
680   // TODO(msw): Additional work may be needed for analogues on other platforms.
681   bool IsUnicodeKeyCode() const;
682 
code()683   std::string code() const { return code_; }
684 
685   // Normalizes flags_ so that it describes the state after the event.
686   // (Native X11 event flags describe the state before the event.)
687   void NormalizeFlags();
688 
689   // Returns true if the key event has already been processed by an input method
690   // and there is no need to pass the key event to the input method again.
691   bool IsTranslated() const;
692   // Marks this key event as translated or not translated.
693   void SetTranslated(bool translated);
694 
695  protected:
696   friend class KeyEventTestApi;
697 
698   // This allows a subclass TranslatedKeyEvent to be a non character event.
set_is_char(bool is_char)699   void set_is_char(bool is_char) { is_char_ = is_char; }
700 
701  private:
702   // True if the key press originated from a 'right' key (VKEY_RSHIFT, etc.).
703   bool IsRightSideKey() const;
704 
705   KeyboardCode key_code_;
706 
707   // String of 'code' defined in DOM KeyboardEvent (e.g. 'KeyA', 'Space')
708   // http://www.w3.org/TR/uievents/#keyboard-key-codes.
709   //
710   // This value represents the physical position in the keyboard and can be
711   // converted from / to keyboard scan code like XKB.
712   std::string code_;
713 
714   // True if this is a character event, false if this is a keystroke event.
715   bool is_char_;
716 
717   // The platform related keycode value. For XKB, it's keysym value.
718   // For now, this is used for CharacterComposer in ChromeOS.
719   uint32 platform_keycode_;
720 
721   // String of 'key' defined in DOM KeyboardEvent (e.g. 'a', 'â')
722   // http://www.w3.org/TR/uievents/#keyboard-key-codes.
723   //
724   // This value represents the text that the key event will insert to input
725   // field. For key with modifier key, it may have specifial text.
726   // e.g. CTRL+A has '\x01'.
727   mutable base::char16 character_;
728 
729   // Parts of our event handling require raw native events (see both the
730   // windows and linux implementations of web_input_event in content/). Because
731   // mojo instead serializes and deserializes events in potentially different
732   // processes, we need to have a mechanism to keep track of this data.
733   scoped_ptr<ExtendedKeyEventData> extended_key_event_data_;
734 
735   static bool IsRepeated(const KeyEvent& event);
736 
737   static KeyEvent* last_key_event_;
738 };
739 
740 class EVENTS_EXPORT ScrollEvent : public MouseEvent {
741  public:
742   explicit ScrollEvent(const base::NativeEvent& native_event);
743   template <class T>
ScrollEvent(const ScrollEvent & model,T * source,T * target)744   ScrollEvent(const ScrollEvent& model,
745               T* source,
746               T* target)
747       : MouseEvent(model, source, target),
748         x_offset_(model.x_offset_),
749         y_offset_(model.y_offset_),
750         x_offset_ordinal_(model.x_offset_ordinal_),
751         y_offset_ordinal_(model.y_offset_ordinal_),
752         finger_count_(model.finger_count_){
753   }
754 
755   // Used for tests.
756   ScrollEvent(EventType type,
757               const gfx::PointF& location,
758               base::TimeDelta time_stamp,
759               int flags,
760               float x_offset,
761               float y_offset,
762               float x_offset_ordinal,
763               float y_offset_ordinal,
764               int finger_count);
765 
766   // Scale the scroll event's offset value.
767   // This is useful in the multi-monitor setup where it needs to be scaled
768   // to provide a consistent user experience.
769   void Scale(const float factor);
770 
x_offset()771   float x_offset() const { return x_offset_; }
y_offset()772   float y_offset() const { return y_offset_; }
x_offset_ordinal()773   float x_offset_ordinal() const { return x_offset_ordinal_; }
y_offset_ordinal()774   float y_offset_ordinal() const { return y_offset_ordinal_; }
finger_count()775   int finger_count() const { return finger_count_; }
776 
777  private:
778   // Potential accelerated offsets.
779   float x_offset_;
780   float y_offset_;
781   // Unaccelerated offsets.
782   float x_offset_ordinal_;
783   float y_offset_ordinal_;
784   // Number of fingers on the pad.
785   int finger_count_;
786 };
787 
788 class EVENTS_EXPORT GestureEvent : public LocatedEvent {
789  public:
790   GestureEvent(float x,
791                float y,
792                int flags,
793                base::TimeDelta time_stamp,
794                const GestureEventDetails& details);
795 
796   // Create a new GestureEvent which is identical to the provided model.
797   // If source / target windows are provided, the model location will be
798   // converted from |source| coordinate system to |target| coordinate system.
799   template <typename T>
GestureEvent(const GestureEvent & model,T * source,T * target)800   GestureEvent(const GestureEvent& model, T* source, T* target)
801       : LocatedEvent(model, source, target),
802         details_(model.details_) {
803   }
804 
805   virtual ~GestureEvent();
806 
details()807   const GestureEventDetails& details() const { return details_; }
808 
809  private:
810   GestureEventDetails details_;
811 };
812 
813 }  // namespace ui
814 
815 #endif  // UI_EVENTS_EVENT_H_
816