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