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

Side by Side Diff: ui/events/platform/platform_event_builder.cc

Issue 862093002: Split the event library into a cross-platform and native part. Part 1. (Closed) Base URL: https://github.com/domokit/mojo.git@master
Patch Set: Rebase to ToT Created 5 years, 11 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
OLDNEW
(Empty)
1 // Copyright 2015 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/platform/platform_event_builder.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 "ui/events/event.h"
14 #include "ui/events/event_utils.h"
15
16 namespace ui {
17 namespace {
18
19 bool X11EventHasNonStandardState(const base::NativeEvent& event) {
20 #if defined(USE_X11)
21 const unsigned int kAllStateMask =
22 Button1Mask | Button2Mask | Button3Mask | Button4Mask | Button5Mask |
23 Mod1Mask | Mod2Mask | Mod3Mask | Mod4Mask | Mod5Mask | ShiftMask |
24 LockMask | ControlMask | AnyModifier;
25 return event && (event->xkey.state & ~kAllStateMask) != 0;
26 #else
27 return false;
28 #endif
29 }
30
31 bool IsX11SendEventTrue(const base::NativeEvent& event) {
32 #if defined(USE_X11)
33 return event && event->xany.send_event;
34 #else
35 return false;
36 #endif
37 }
38
39 KeyEvent* last_key_event_ = nullptr;
40 MouseEvent* last_click_event_ = nullptr;
41
42 // We can create a MouseEvent for a native event more than once. We set this
43 // to true when the next event either has a different timestamp or we see a
44 // release signalling that the press (click) event was completed.
45 bool last_click_complete_ = false;
46
47 bool IsRepeated(const base::NativeEvent& native_event, const KeyEvent& event) {
48 // A safe guard in case if there were continous key pressed events that are
49 // not auto repeat.
50 const int kMaxAutoRepeatTimeMs = 2000;
51 // Ignore key events that have non standard state masks as it may be
52 // reposted by an IME. IBUS-GTK uses this field to detect the
53 // re-posted event for example. crbug.com/385873.
54 if (X11EventHasNonStandardState(native_event))
55 return false;
56 if (event.is_char())
57 return false;
58 if (event.type() == ui::ET_KEY_RELEASED) {
59 delete last_key_event_;
60 last_key_event_ = NULL;
61 return false;
62 }
63 CHECK_EQ(ui::ET_KEY_PRESSED, event.type());
64 if (!last_key_event_) {
65 last_key_event_ = new KeyEvent(event);
66 return false;
67 }
68 if (event.key_code() == last_key_event_->key_code() &&
69 event.flags() == last_key_event_->flags() &&
70 (event.time_stamp() - last_key_event_->time_stamp()).InMilliseconds() <
71 kMaxAutoRepeatTimeMs) {
72 return true;
73 }
74 delete last_key_event_;
75 last_key_event_ = new KeyEvent(event);
76 return false;
77 }
78
79 } // namespace
80
81 // static
82 MouseEvent PlatformEventBuilder::BuildMouseEvent(
83 const base::NativeEvent& native_event) {
84 MouseEvent mouse_event;
85 FillEventFrom(native_event, &mouse_event);
86 FillLocatedEventFrom(native_event, &mouse_event);
87 FillMouseEventFrom(native_event, &mouse_event);
88 return mouse_event;
89 }
90
91 // static
92 MouseWheelEvent PlatformEventBuilder::BuildMouseWheelEvent(
93 const base::NativeEvent& native_event) {
94 MouseWheelEvent mouse_wheel_event;
95 FillEventFrom(native_event, &mouse_wheel_event);
96 FillLocatedEventFrom(native_event, &mouse_wheel_event);
97 FillMouseEventFrom(native_event, &mouse_wheel_event);
98 FillMouseWheelEventFrom(native_event, &mouse_wheel_event);
99 return mouse_wheel_event;
100 }
101
102 // static
103 TouchEvent PlatformEventBuilder::BuildTouchEvent(
104 const base::NativeEvent& native_event) {
105 TouchEvent touch_event;
106 FillEventFrom(native_event, &touch_event);
107 FillLocatedEventFrom(native_event, &touch_event);
108 FillTouchEventFrom(native_event, &touch_event);
109 return touch_event;
110 }
111
112 // static
113 KeyEvent PlatformEventBuilder::BuildKeyEvent(
114 const base::NativeEvent& native_event) {
115 KeyEvent key_event;
116 FillEventFrom(native_event, &key_event);
117 FillKeyEventFrom(native_event, &key_event);
118 return key_event;
119 }
120
121 // static
122 ScrollEvent PlatformEventBuilder::BuildScrollEvent(
123 const base::NativeEvent& native_event) {
124 ScrollEvent scroll_event;
125 FillEventFrom(native_event, &scroll_event);
126 FillLocatedEventFrom(native_event, &scroll_event);
127 FillMouseEventFrom(native_event, &scroll_event);
128 FillScrollEventFrom(native_event, &scroll_event);
129 return scroll_event;
130 }
131
132 // static
133 int PlatformEventBuilder::GetRepeatCount(const base::NativeEvent& native_event,
134 const MouseEvent& event) {
135 int click_count = 1;
136 if (last_click_event_) {
137 if (event.type() == ui::ET_MOUSE_RELEASED) {
138 if (event.changed_button_flags() ==
139 last_click_event_->changed_button_flags()) {
140 last_click_complete_ = true;
141 return last_click_event_->GetClickCount();
142 } else {
143 // If last_click_event_ has changed since this button was pressed
144 // return a click count of 1.
145 return click_count;
146 }
147 }
148 if (event.time_stamp() != last_click_event_->time_stamp())
149 last_click_complete_ = true;
150 if (!last_click_complete_ || IsX11SendEventTrue(native_event)) {
151 click_count = last_click_event_->GetClickCount();
152 } else if (MouseEvent::IsRepeatedClickEvent(*last_click_event_, event)) {
153 click_count = last_click_event_->GetClickCount() + 1;
154 }
155 delete last_click_event_;
156 }
157 last_click_event_ = new MouseEvent(event);
158 last_click_complete_ = false;
159 if (click_count > 3)
160 click_count = 3;
161 last_click_event_->SetClickCount(click_count);
162 return click_count;
163 }
164
165 // static
166 void PlatformEventBuilder::ResetLastClickForTest() {
167 if (last_click_event_) {
168 delete last_click_event_;
169 last_click_event_ = NULL;
170 last_click_complete_ = false;
171 }
172 }
173
174 // static
175 void PlatformEventBuilder::FillEventFrom(const base::NativeEvent& native_event,
176 Event* event) {
177 event->set_type(EventTypeFromNative(native_event));
178 event->set_time_stamp(EventTimeFromNative(native_event));
179 event->set_flags(EventFlagsFromNative(native_event));
180
181 #if defined(USE_X11)
182 if (native_event->type == GenericEvent) {
183 XIDeviceEvent* xiev =
184 static_cast<XIDeviceEvent*>(native_event->xcookie.data);
185 event->set_source_device_id(xiev->sourceid);
186 }
187 #endif
188 }
189
190 // static
191 void PlatformEventBuilder::FillLocatedEventFrom(
192 const base::NativeEvent& native_event,
193 LocatedEvent* located_event) {
194 gfx::PointF event_location = EventLocationFromNative(native_event);
195 located_event->set_location(event_location);
196 located_event->set_root_location(event_location);
197 located_event->set_screen_location(
198 EventSystemLocationFromNative(native_event));
199 }
200
201 // static
202 void PlatformEventBuilder::FillMouseEventFrom(
203 const base::NativeEvent& native_event,
204 MouseEvent* mouse_event) {
205 mouse_event->set_changed_button_flags(
206 GetChangedMouseButtonFlagsFromNative(native_event));
207
208 if (mouse_event->type() == ET_MOUSE_PRESSED ||
209 mouse_event->type() == ET_MOUSE_RELEASED) {
210 mouse_event->SetClickCount(GetRepeatCount(native_event, *mouse_event));
211 }
212 }
213
214 // static
215 void PlatformEventBuilder::FillMouseWheelEventFrom(
216 const base::NativeEvent& native_event,
217 MouseWheelEvent* mouse_wheel_event) {
218 mouse_wheel_event->set_offset(GetMouseWheelOffset(native_event));
219 }
220
221 // static
222 void PlatformEventBuilder::FillTouchEventFrom(
223 const base::NativeEvent& native_event,
224 TouchEvent* touch_event) {
225 touch_event->set_touch_id(GetTouchId(native_event));
226 touch_event->set_radius_x(GetTouchRadiusX(native_event));
227 touch_event->set_radius_y(GetTouchRadiusY(native_event));
228 touch_event->set_rotation_angle(GetTouchAngle(native_event));
229 touch_event->set_force(GetTouchForce(native_event));
230 }
231
232 // static
233 void PlatformEventBuilder::FillKeyEventFrom(
234 const base::NativeEvent& native_event,
235 KeyEvent* key_event) {
236 key_event->set_key_code(KeyboardCodeFromNative(native_event));
237 key_event->set_code(CodeFromNative(native_event));
238 key_event->set_is_char(IsCharFromNative(native_event));
239 key_event->set_platform_keycode(PlatformKeycodeFromNative(native_event));
240
241 if (IsRepeated(native_event, *key_event))
242 key_event->set_flags(key_event->flags() | ui::EF_IS_REPEAT);
243
244 #if defined(USE_X11)
245 key_event->NormalizeFlags();
246 #endif
247 #if defined(OS_WIN)
248 // Only Windows has native character events.
249 if (key_event->is_char())
250 key_event->set_character(native_event.wParam);
251 #endif
252 }
253
254 // static
255 void PlatformEventBuilder::FillScrollEventFrom(
256 const base::NativeEvent& native_event,
257 ScrollEvent* scroll_event) {
258 float x_offset = 0;
259 float y_offset = 0;
260 float x_offset_ordinal = 0;
261 float y_offset_ordinal = 0;
262 int finger_count = 0;
263
264 if (scroll_event->type() == ET_SCROLL) {
265 GetScrollOffsets(native_event, &x_offset, &y_offset, &x_offset_ordinal,
266 &y_offset_ordinal, &finger_count);
267 scroll_event->set_offset(x_offset, y_offset);
268 scroll_event->set_offset_ordinal(x_offset_ordinal, y_offset_ordinal);
269 scroll_event->set_finger_count(finger_count);
270 } else if (scroll_event->type() == ET_SCROLL_FLING_START ||
271 scroll_event->type() == ET_SCROLL_FLING_CANCEL) {
272 GetFlingData(native_event, &x_offset, &y_offset, &x_offset_ordinal,
273 &y_offset_ordinal, NULL);
274 scroll_event->set_offset(x_offset, y_offset);
275 scroll_event->set_offset_ordinal(x_offset_ordinal, y_offset_ordinal);
276 } else {
277 NOTREACHED() << "Unexpected event type " << scroll_event->type()
278 << " when constructing a ScrollEvent.";
279 }
280 }
281
282 } // namespace ui
OLDNEW
« no previous file with comments | « ui/events/platform/platform_event_builder.h ('k') | ui/events/platform/platform_event_builder_x_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698