Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(24)

Side by Side Diff: ui/base/event.cc

Issue 10908127: events: Move EventTarget into Event. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: . Created 8 years, 3 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « ui/aura/window_unittest.cc ('k') | ui/base/event_unittest.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
(Empty)
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/base/events/event.h"
6
7 #if defined(USE_X11)
8 #include <X11/Xlib.h>
9 #endif
10
11 #include <cstring>
12
13 #include "ui/base/keycodes/keyboard_code_conversion.h"
14 #include "ui/gfx/interpolated_transform.h"
15 #include "ui/gfx/point3.h"
16 #include "ui/gfx/transform.h"
17
18 #if defined(USE_X11)
19 #include "ui/base/keycodes/keyboard_code_conversion_x.h"
20 #endif
21
22 namespace {
23
24 base::NativeEvent CopyNativeEvent(const base::NativeEvent& event) {
25 #if defined(USE_X11)
26 if (!event || event->type == GenericEvent)
27 return NULL;
28 XEvent* copy = new XEvent;
29 *copy = *event;
30 return copy;
31 #elif defined(OS_WIN)
32 return event;
33 #else
34 NOTREACHED() <<
35 "Don't know how to copy base::NativeEvent for this platform";
36 return NULL;
37 #endif
38 }
39
40 } // namespace
41
42 namespace ui {
43
44 ////////////////////////////////////////////////////////////////////////////////
45 // Event
46
47 Event::~Event() {
48 #if defined(USE_X11)
49 if (delete_native_event_)
50 delete native_event_;
51 #endif
52 }
53
54 bool Event::HasNativeEvent() const {
55 base::NativeEvent null_event;
56 std::memset(&null_event, 0, sizeof(null_event));
57 return !!std::memcmp(&native_event_, &null_event, sizeof(null_event));
58 }
59
60 Event::Event(EventType type, int flags)
61 : type_(type),
62 time_stamp_(base::Time::NowFromSystemTime() - base::Time()),
63 flags_(flags),
64 delete_native_event_(false) {
65 Init();
66 }
67
68 Event::Event(const base::NativeEvent& native_event,
69 EventType type,
70 int flags)
71 : type_(type),
72 time_stamp_(EventTimeFromNative(native_event)),
73 flags_(flags),
74 delete_native_event_(false) {
75 InitWithNativeEvent(native_event);
76 }
77
78 Event::Event(const Event& copy)
79 : native_event_(::CopyNativeEvent(copy.native_event_)),
80 type_(copy.type_),
81 time_stamp_(copy.time_stamp_),
82 flags_(copy.flags_),
83 delete_native_event_(false) {
84 #if defined(USE_X11)
85 if (native_event_)
86 delete_native_event_ = true;
87 #endif
88 }
89
90 void Event::Init() {
91 std::memset(&native_event_, 0, sizeof(native_event_));
92 }
93
94 void Event::InitWithNativeEvent(const base::NativeEvent& native_event) {
95 native_event_ = native_event;
96 }
97
98 ////////////////////////////////////////////////////////////////////////////////
99 // LocatedEvent
100
101 LocatedEvent::~LocatedEvent() {
102 }
103
104 LocatedEvent::LocatedEvent(const base::NativeEvent& native_event)
105 : Event(native_event,
106 EventTypeFromNative(native_event),
107 EventFlagsFromNative(native_event)),
108 location_(EventLocationFromNative(native_event)),
109 root_location_(location_),
110 valid_system_location_(true),
111 system_location_(ui::EventSystemLocationFromNative(native_event)) {
112 }
113
114 LocatedEvent::LocatedEvent(EventType type,
115 const gfx::Point& location,
116 const gfx::Point& root_location,
117 int flags)
118 : Event(type, flags),
119 location_(location),
120 root_location_(root_location),
121 valid_system_location_(false),
122 system_location_(0, 0) {
123 }
124
125 void LocatedEvent::UpdateForRootTransform(const Transform& root_transform) {
126 // Transform has to be done at root level.
127 DCHECK_EQ(root_location_.x(), location_.x());
128 DCHECK_EQ(root_location_.y(), location_.y());
129 gfx::Point3f p(location_);
130 root_transform.TransformPointReverse(p);
131 root_location_ = location_ = p.AsPoint();
132 }
133
134 ////////////////////////////////////////////////////////////////////////////////
135 // MouseEvent
136
137 MouseEvent::MouseEvent(const base::NativeEvent& native_event)
138 : LocatedEvent(native_event),
139 changed_button_flags_(
140 GetChangedMouseButtonFlagsFromNative(native_event)) {
141 if (type() == ET_MOUSE_PRESSED)
142 SetClickCount(GetRepeatCount(*this));
143 }
144
145 MouseEvent::MouseEvent(EventType type,
146 const gfx::Point& location,
147 const gfx::Point& root_location,
148 int flags)
149 : LocatedEvent(type, location, root_location, flags),
150 changed_button_flags_(0) {
151 }
152
153 // static
154 bool MouseEvent::IsRepeatedClickEvent(
155 const MouseEvent& event1,
156 const MouseEvent& event2) {
157 // These values match the Windows defaults.
158 static const int kDoubleClickTimeMS = 500;
159 static const int kDoubleClickWidth = 4;
160 static const int kDoubleClickHeight = 4;
161
162 if (event1.type() != ET_MOUSE_PRESSED ||
163 event2.type() != ET_MOUSE_PRESSED)
164 return false;
165
166 // Compare flags, but ignore EF_IS_DOUBLE_CLICK to allow triple clicks.
167 if ((event1.flags() & ~EF_IS_DOUBLE_CLICK) !=
168 (event2.flags() & ~EF_IS_DOUBLE_CLICK))
169 return false;
170
171 base::TimeDelta time_difference = event2.time_stamp() - event1.time_stamp();
172
173 if (time_difference.InMilliseconds() > kDoubleClickTimeMS)
174 return false;
175
176 if (abs(event2.x() - event1.x()) > kDoubleClickWidth / 2)
177 return false;
178
179 if (abs(event2.y() - event1.y()) > kDoubleClickHeight / 2)
180 return false;
181
182 return true;
183 }
184
185 // static
186 int MouseEvent::GetRepeatCount(const MouseEvent& event) {
187 int click_count = 1;
188 if (last_click_event_) {
189 if (IsRepeatedClickEvent(*last_click_event_, event))
190 click_count = last_click_event_->GetClickCount() + 1;
191 delete last_click_event_;
192 }
193 last_click_event_ = new MouseEvent(event);
194 if (click_count > 3)
195 click_count = 3;
196 last_click_event_->SetClickCount(click_count);
197 return click_count;
198 }
199
200 // static
201 MouseEvent* MouseEvent::last_click_event_ = NULL;
202
203 int MouseEvent::GetClickCount() const {
204 if (type() != ET_MOUSE_PRESSED)
205 return 0;
206
207 if (flags() & EF_IS_TRIPLE_CLICK)
208 return 3;
209 else if (flags() & EF_IS_DOUBLE_CLICK)
210 return 2;
211 else
212 return 1;
213 }
214
215 void MouseEvent::SetClickCount(int click_count) {
216 if (type() != ET_MOUSE_PRESSED)
217 return;
218
219 DCHECK(click_count > 0);
220 DCHECK(click_count <= 3);
221
222 int f = flags();
223 switch (click_count) {
224 case 1:
225 f &= ~EF_IS_DOUBLE_CLICK;
226 f &= ~EF_IS_TRIPLE_CLICK;
227 break;
228 case 2:
229 f |= EF_IS_DOUBLE_CLICK;
230 f &= ~EF_IS_TRIPLE_CLICK;
231 break;
232 case 3:
233 f &= ~EF_IS_DOUBLE_CLICK;
234 f |= EF_IS_TRIPLE_CLICK;
235 break;
236 }
237 set_flags(f);
238 }
239
240 ////////////////////////////////////////////////////////////////////////////////
241 // MouseWheelEvent
242
243 MouseWheelEvent::MouseWheelEvent(const base::NativeEvent& native_event)
244 : MouseEvent(native_event),
245 offset_(GetMouseWheelOffset(native_event)) {
246 }
247
248 MouseWheelEvent::MouseWheelEvent(const ScrollEvent& scroll_event)
249 : MouseEvent(scroll_event),
250 offset_(scroll_event.y_offset()) {
251 set_type(ET_MOUSEWHEEL);
252 }
253
254 #if defined(OS_WIN)
255 // This value matches windows WHEEL_DELTA.
256 // static
257 const int MouseWheelEvent::kWheelDelta = 120;
258 #else
259 // This value matches GTK+ wheel scroll amount.
260 const int MouseWheelEvent::kWheelDelta = 53;
261 #endif
262
263 ////////////////////////////////////////////////////////////////////////////////
264 // TouchEvent
265
266 TouchEvent::TouchEvent(const base::NativeEvent& native_event)
267 : LocatedEvent(native_event),
268 touch_id_(GetTouchId(native_event)),
269 radius_x_(GetTouchRadiusX(native_event)),
270 radius_y_(GetTouchRadiusY(native_event)),
271 rotation_angle_(GetTouchAngle(native_event)),
272 force_(GetTouchForce(native_event)) {
273 }
274
275 TouchEvent::TouchEvent(EventType type,
276 const gfx::Point& location,
277 int touch_id,
278 base::TimeDelta time_stamp)
279 : LocatedEvent(type, location, location, 0),
280 touch_id_(touch_id),
281 radius_x_(0.0f),
282 radius_y_(0.0f),
283 rotation_angle_(0.0f),
284 force_(0.0f) {
285 set_time_stamp(time_stamp);
286 }
287
288 TouchEvent::~TouchEvent() {
289 }
290
291 void TouchEvent::UpdateForRootTransform(const Transform& root_transform) {
292 LocatedEvent::UpdateForRootTransform(root_transform);
293 gfx::Point3f scale;
294 InterpolatedTransform::FactorTRS(root_transform, NULL, NULL, &scale);
295 if (scale.x())
296 radius_x_ /= scale.x();
297 if (scale.y())
298 radius_y_ /= scale.y();
299 }
300
301 ////////////////////////////////////////////////////////////////////////////////
302 // TestTouchEvent
303
304 TestTouchEvent::TestTouchEvent(EventType type,
305 int x,
306 int y,
307 int flags,
308 int touch_id,
309 float radius_x,
310 float radius_y,
311 float angle,
312 float force)
313 : TouchEvent(type, gfx::Point(x, y), touch_id, base::TimeDelta()) {
314 set_flags(flags);
315 set_radius(radius_x, radius_y);
316 set_rotation_angle(angle);
317 set_force(force);
318 }
319
320 ////////////////////////////////////////////////////////////////////////////////
321 // KeyEvent
322
323 KeyEvent::KeyEvent(const base::NativeEvent& native_event, bool is_char)
324 : Event(native_event,
325 EventTypeFromNative(native_event),
326 EventFlagsFromNative(native_event)),
327 key_code_(KeyboardCodeFromNative(native_event)),
328 is_char_(is_char),
329 character_(0),
330 unmodified_character_(0) {
331 #if defined(USE_X11)
332 NormalizeFlags();
333 #endif
334 }
335
336 KeyEvent::KeyEvent(EventType type,
337 KeyboardCode key_code,
338 int flags)
339 : Event(type, flags),
340 key_code_(key_code),
341 is_char_(false),
342 character_(GetCharacterFromKeyCode(key_code, flags)),
343 unmodified_character_(0) {
344 }
345
346 uint16 KeyEvent::GetCharacter() const {
347 if (character_)
348 return character_;
349
350 #if defined(OS_WIN)
351 return (native_event().message == WM_CHAR) ? key_code_ :
352 GetCharacterFromKeyCode(key_code_, flags());
353 #elif defined(USE_X11)
354 if (!native_event())
355 return GetCharacterFromKeyCode(key_code_, flags());
356
357 DCHECK(native_event()->type == KeyPress ||
358 native_event()->type == KeyRelease);
359
360 uint16 ch = 0;
361 if (!IsControlDown())
362 ch = GetCharacterFromXEvent(native_event());
363 return ch ? ch : GetCharacterFromKeyCode(key_code_, flags());
364 #else
365 NOTIMPLEMENTED();
366 return 0;
367 #endif
368 }
369
370 uint16 KeyEvent::GetUnmodifiedCharacter() const {
371 if (unmodified_character_)
372 return unmodified_character_;
373
374 #if defined(OS_WIN)
375 // Looks like there is no way to get unmodified character on Windows.
376 return (native_event().message == WM_CHAR) ? key_code_ :
377 GetCharacterFromKeyCode(key_code_, flags() & EF_SHIFT_DOWN);
378 #elif defined(USE_X11)
379 if (!native_event())
380 return GetCharacterFromKeyCode(key_code_, flags() & EF_SHIFT_DOWN);
381
382 DCHECK(native_event()->type == KeyPress ||
383 native_event()->type == KeyRelease);
384
385 static const unsigned int kIgnoredModifiers = ControlMask | LockMask |
386 Mod1Mask | Mod2Mask | Mod3Mask | Mod4Mask | Mod5Mask;
387
388 XKeyEvent copy = native_event()->xkey; // bit-wise copy is safe.
389 // We can't use things like (native_event()->xkey.state & ShiftMask), as it
390 // may mask out bits used by X11 internally.
391 copy.state &= ~kIgnoredModifiers;
392 uint16 ch = GetCharacterFromXEvent(reinterpret_cast<XEvent*>(&copy));
393 return ch ? ch : GetCharacterFromKeyCode(key_code_, flags() & EF_SHIFT_DOWN);
394 #else
395 NOTIMPLEMENTED();
396 return 0;
397 #endif
398 }
399
400 KeyEvent* KeyEvent::Copy() {
401 KeyEvent* copy = new KeyEvent(::CopyNativeEvent(native_event()), is_char());
402 #if defined(USE_X11)
403 copy->set_delete_native_event(true);
404 #endif
405 return copy;
406 }
407
408 void KeyEvent::NormalizeFlags() {
409 int mask = 0;
410 switch (key_code()) {
411 case ui::VKEY_CONTROL:
412 mask = ui::EF_CONTROL_DOWN;
413 break;
414 case ui::VKEY_SHIFT:
415 mask = ui::EF_SHIFT_DOWN;
416 break;
417 case ui::VKEY_MENU:
418 mask = ui::EF_ALT_DOWN;
419 break;
420 case ui::VKEY_CAPITAL:
421 mask = ui::EF_CAPS_LOCK_DOWN;
422 break;
423 default:
424 return;
425 }
426 if (type() == ui::ET_KEY_PRESSED)
427 set_flags(flags() | mask);
428 else
429 set_flags(flags() & ~mask);
430 }
431
432 ////////////////////////////////////////////////////////////////////////////////
433 // TranslatedKeyEvent
434
435 TranslatedKeyEvent::TranslatedKeyEvent(const base::NativeEvent& native_event,
436 bool is_char)
437 : KeyEvent(native_event, is_char) {
438 set_type(type() == ET_KEY_PRESSED ?
439 ET_TRANSLATED_KEY_PRESS : ET_TRANSLATED_KEY_RELEASE);
440 }
441
442 TranslatedKeyEvent::TranslatedKeyEvent(bool is_press,
443 KeyboardCode key_code,
444 int flags)
445 : KeyEvent((is_press ? ET_TRANSLATED_KEY_PRESS : ET_TRANSLATED_KEY_RELEASE),
446 key_code,
447 flags) {
448 }
449
450 void TranslatedKeyEvent::ConvertToKeyEvent() {
451 set_type(type() == ET_TRANSLATED_KEY_PRESS ?
452 ET_KEY_PRESSED : ET_KEY_RELEASED);
453 }
454
455 ////////////////////////////////////////////////////////////////////////////////
456 // ScrollEvent
457
458 ScrollEvent::ScrollEvent(const base::NativeEvent& native_event)
459 : MouseEvent(native_event) {
460 if (type() == ET_SCROLL) {
461 GetScrollOffsets(native_event, &x_offset_, &y_offset_);
462 double start, end;
463 GetGestureTimes(native_event, &start, &end);
464 } else if (type() == ET_SCROLL_FLING_START) {
465 bool is_cancel;
466 GetFlingData(native_event, &x_offset_, &y_offset_, &is_cancel);
467 }
468 }
469
470 ////////////////////////////////////////////////////////////////////////////////
471 // GestureEvent
472
473 GestureEvent::GestureEvent(EventType type,
474 int x,
475 int y,
476 int flags,
477 base::TimeDelta time_stamp,
478 const GestureEventDetails& details,
479 unsigned int touch_ids_bitfield)
480 : LocatedEvent(type, gfx::Point(x, y), gfx::Point(x, y), flags),
481 details_(details),
482 touch_ids_bitfield_(touch_ids_bitfield) {
483 set_time_stamp(time_stamp);
484 }
485
486 GestureEvent::~GestureEvent() {
487 }
488
489 int GestureEvent::GetLowestTouchId() const {
490 if (touch_ids_bitfield_ == 0)
491 return -1;
492 int i = -1;
493 // Find the index of the least significant 1 bit
494 while (!(1 << ++i & touch_ids_bitfield_));
495 return i;
496 }
497
498 } // namespace ui
OLDNEW
« no previous file with comments | « ui/aura/window_unittest.cc ('k') | ui/base/event_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698