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

Side by Side Diff: ui/events/ozone/evdev/event_factory_evdev.cc

Issue 1287103004: Sync ui/events to chromium @ https://codereview.chromium.org/1210203002 (Closed) Base URL: https://github.com/domokit/mojo.git@master
Patch Set: rebased Created 5 years, 4 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 2014 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/ozone/evdev/event_factory_evdev.h"
6
7 #include "base/bind.h"
8 #include "base/task_runner.h"
9 #include "base/thread_task_runner_handle.h"
10 #include "base/threading/worker_pool.h"
11 #include "base/time/time.h"
12 #include "base/trace_event/trace_event.h"
13 #include "ui/events/devices/device_data_manager.h"
14 #include "ui/events/devices/input_device.h"
15 #include "ui/events/event_utils.h"
16 #include "ui/events/ozone/device/device_event.h"
17 #include "ui/events/ozone/device/device_manager.h"
18 #include "ui/events/ozone/evdev/cursor_delegate_evdev.h"
19 #include "ui/events/ozone/evdev/input_controller_evdev.h"
20 #include "ui/events/ozone/evdev/input_device_factory_evdev.h"
21 #include "ui/events/ozone/evdev/input_device_factory_evdev_proxy.h"
22 #include "ui/events/ozone/evdev/input_injector_evdev.h"
23 #include "ui/events/ozone/evdev/touch_evdev_types.h"
24
25 namespace ui {
26
27 namespace {
28
29 // Thread safe dispatcher proxy for EventFactoryEvdev.
30 //
31 // This is used on the device I/O thread for dispatching to UI.
32 class ProxyDeviceEventDispatcher : public DeviceEventDispatcherEvdev {
33 public:
34 ProxyDeviceEventDispatcher(
35 scoped_refptr<base::SingleThreadTaskRunner> ui_thread_runner,
36 base::WeakPtr<EventFactoryEvdev> event_factory_evdev)
37 : ui_thread_runner_(ui_thread_runner),
38 event_factory_evdev_(event_factory_evdev) {}
39 ~ProxyDeviceEventDispatcher() override {}
40
41 // DeviceEventDispatcher:
42 void DispatchKeyEvent(const KeyEventParams& params) override {
43 ui_thread_runner_->PostTask(FROM_HERE,
44 base::Bind(&EventFactoryEvdev::DispatchKeyEvent,
45 event_factory_evdev_, params));
46 }
47
48 void DispatchMouseMoveEvent(const MouseMoveEventParams& params) override {
49 ui_thread_runner_->PostTask(
50 FROM_HERE, base::Bind(&EventFactoryEvdev::DispatchMouseMoveEvent,
51 event_factory_evdev_, params));
52 }
53
54 void DispatchMouseButtonEvent(const MouseButtonEventParams& params) override {
55 ui_thread_runner_->PostTask(
56 FROM_HERE, base::Bind(&EventFactoryEvdev::DispatchMouseButtonEvent,
57 event_factory_evdev_, params));
58 }
59
60 void DispatchMouseWheelEvent(const MouseWheelEventParams& params) override {
61 ui_thread_runner_->PostTask(
62 FROM_HERE, base::Bind(&EventFactoryEvdev::DispatchMouseWheelEvent,
63 event_factory_evdev_, params));
64 }
65
66 void DispatchScrollEvent(const ScrollEventParams& params) override {
67 ui_thread_runner_->PostTask(
68 FROM_HERE, base::Bind(&EventFactoryEvdev::DispatchScrollEvent,
69 event_factory_evdev_, params));
70 }
71
72 void DispatchTouchEvent(const TouchEventParams& params) override {
73 ui_thread_runner_->PostTask(
74 FROM_HERE, base::Bind(&EventFactoryEvdev::DispatchTouchEvent,
75 event_factory_evdev_, params));
76 }
77
78 void DispatchKeyboardDevicesUpdated(
79 const std::vector<KeyboardDevice>& devices) override {
80 ui_thread_runner_->PostTask(
81 FROM_HERE,
82 base::Bind(&EventFactoryEvdev::DispatchKeyboardDevicesUpdated,
83 event_factory_evdev_, devices));
84 }
85 void DispatchTouchscreenDevicesUpdated(
86 const std::vector<TouchscreenDevice>& devices) override {
87 ui_thread_runner_->PostTask(
88 FROM_HERE,
89 base::Bind(&EventFactoryEvdev::DispatchTouchscreenDevicesUpdated,
90 event_factory_evdev_, devices));
91 }
92 void DispatchMouseDevicesUpdated(
93 const std::vector<InputDevice>& devices) override {
94 ui_thread_runner_->PostTask(
95 FROM_HERE, base::Bind(&EventFactoryEvdev::DispatchMouseDevicesUpdated,
96 event_factory_evdev_, devices));
97 }
98 void DispatchTouchpadDevicesUpdated(
99 const std::vector<InputDevice>& devices) override {
100 ui_thread_runner_->PostTask(
101 FROM_HERE,
102 base::Bind(&EventFactoryEvdev::DispatchTouchpadDevicesUpdated,
103 event_factory_evdev_, devices));
104 }
105 void DispatchDeviceListsComplete() override {
106 ui_thread_runner_->PostTask(
107 FROM_HERE, base::Bind(&EventFactoryEvdev::DispatchDeviceListsComplete,
108 event_factory_evdev_));
109 }
110
111 private:
112 scoped_refptr<base::SingleThreadTaskRunner> ui_thread_runner_;
113 base::WeakPtr<EventFactoryEvdev> event_factory_evdev_;
114 };
115
116 } // namespace
117
118 EventFactoryEvdev::EventFactoryEvdev(CursorDelegateEvdev* cursor,
119 DeviceManager* device_manager,
120 KeyboardLayoutEngine* keyboard_layout)
121 : device_manager_(device_manager),
122 keyboard_(&modifiers_,
123 keyboard_layout,
124 base::Bind(&EventFactoryEvdev::DispatchUiEvent,
125 base::Unretained(this))),
126 cursor_(cursor),
127 input_controller_(&keyboard_, &button_map_),
128 touch_id_generator_(0),
129 weak_ptr_factory_(this) {
130 DCHECK(device_manager_);
131 }
132
133 EventFactoryEvdev::~EventFactoryEvdev() {
134 }
135
136 void EventFactoryEvdev::Init() {
137 DCHECK(!initialized_);
138
139 StartThread();
140
141 initialized_ = true;
142 }
143
144 scoped_ptr<SystemInputInjector> EventFactoryEvdev::CreateSystemInputInjector() {
145 // Use forwarding dispatcher for the injector rather than dispatching
146 // directly. We cannot assume it is safe to (re-)enter ui::Event dispatch
147 // synchronously from the injection point.
148 scoped_ptr<DeviceEventDispatcherEvdev> proxy_dispatcher(
149 new ProxyDeviceEventDispatcher(base::ThreadTaskRunnerHandle::Get(),
150 weak_ptr_factory_.GetWeakPtr()));
151 return make_scoped_ptr(
152 new InputInjectorEvdev(proxy_dispatcher.Pass(), cursor_));
153 }
154
155 void EventFactoryEvdev::DispatchKeyEvent(const KeyEventParams& params) {
156 TRACE_EVENT1("evdev", "EventFactoryEvdev::DispatchKeyEvent", "device",
157 params.device_id);
158 keyboard_.OnKeyChange(params.code, params.down, params.suppress_auto_repeat,
159 params.timestamp, params.device_id);
160 }
161
162 void EventFactoryEvdev::DispatchMouseMoveEvent(
163 const MouseMoveEventParams& params) {
164 TRACE_EVENT1("evdev", "EventFactoryEvdev::DispatchMouseMoveEvent", "device",
165 params.device_id);
166 MouseEvent event(ui::ET_MOUSE_MOVED, params.location, params.location,
167 params.timestamp, modifiers_.GetModifierFlags(),
168 /* changed_button_flags */ 0);
169 event.set_source_device_id(params.device_id);
170 DispatchUiEvent(&event);
171 }
172
173 void EventFactoryEvdev::DispatchMouseButtonEvent(
174 const MouseButtonEventParams& params) {
175 TRACE_EVENT1("evdev", "EventFactoryEvdev::DispatchMouseButtonEvent", "device",
176 params.device_id);
177
178 // Mouse buttons can be remapped, touchpad taps & clicks cannot.
179 unsigned int button = params.button;
180 if (params.allow_remap)
181 button = button_map_.GetMappedButton(button);
182
183 int modifier = EVDEV_MODIFIER_NONE;
184 switch (button) {
185 case BTN_LEFT:
186 modifier = EVDEV_MODIFIER_LEFT_MOUSE_BUTTON;
187 break;
188 case BTN_RIGHT:
189 modifier = EVDEV_MODIFIER_RIGHT_MOUSE_BUTTON;
190 break;
191 case BTN_MIDDLE:
192 modifier = EVDEV_MODIFIER_MIDDLE_MOUSE_BUTTON;
193 break;
194 case BTN_BACK:
195 modifier = EVDEV_MODIFIER_BACK_MOUSE_BUTTON;
196 break;
197 case BTN_FORWARD:
198 modifier = EVDEV_MODIFIER_FORWARD_MOUSE_BUTTON;
199 break;
200 default:
201 return;
202 }
203
204 int flag = modifiers_.GetEventFlagFromModifier(modifier);
205 bool was_down = modifiers_.GetModifierFlags() & flag;
206 modifiers_.UpdateModifier(modifier, params.down);
207 bool down = modifiers_.GetModifierFlags() & flag;
208
209 // Suppress nested clicks. EventModifiersEvdev counts presses, we only
210 // dispatch an event on 0-1 (first press) and 1-0 (last release) transitions.
211 if (down == was_down)
212 return;
213
214 MouseEvent event(params.down ? ui::ET_MOUSE_PRESSED : ui::ET_MOUSE_RELEASED,
215 params.location, params.location, params.timestamp,
216 modifiers_.GetModifierFlags() | flag,
217 /* changed_button_flags */ flag);
218 event.set_source_device_id(params.device_id);
219 DispatchUiEvent(&event);
220 }
221
222 void EventFactoryEvdev::DispatchMouseWheelEvent(
223 const MouseWheelEventParams& params) {
224 TRACE_EVENT1("evdev", "EventFactoryEvdev::DispatchMouseWheelEvent", "device",
225 params.device_id);
226 MouseWheelEvent event(params.delta, params.location, params.location,
227 params.timestamp, modifiers_.GetModifierFlags(),
228 0 /* changed_button_flags */);
229 event.set_source_device_id(params.device_id);
230 DispatchUiEvent(&event);
231 }
232
233 void EventFactoryEvdev::DispatchScrollEvent(const ScrollEventParams& params) {
234 TRACE_EVENT1("evdev", "EventFactoryEvdev::DispatchScrollEvent", "device",
235 params.device_id);
236 ScrollEvent event(params.type, params.location, params.timestamp,
237 modifiers_.GetModifierFlags(), params.delta.x(),
238 params.delta.y(), params.ordinal_delta.x(),
239 params.ordinal_delta.y(), params.finger_count);
240 event.set_source_device_id(params.device_id);
241 DispatchUiEvent(&event);
242 }
243
244 void EventFactoryEvdev::DispatchTouchEvent(const TouchEventParams& params) {
245 TRACE_EVENT1("evdev", "EventFactoryEvdev::DispatchTouchEvent", "device",
246 params.device_id);
247
248 float x = params.location.x();
249 float y = params.location.y();
250 double radius_x = params.radii.x();
251 double radius_y = params.radii.y();
252
253 // Transform the event to align touches to the image based on display mode.
254 DeviceDataManager::GetInstance()->ApplyTouchTransformer(params.device_id, &x,
255 &y);
256 DeviceDataManager::GetInstance()->ApplyTouchRadiusScale(params.device_id,
257 &radius_x);
258 DeviceDataManager::GetInstance()->ApplyTouchRadiusScale(params.device_id,
259 &radius_y);
260
261 // params.slot is guaranteed to be < kNumTouchEvdevSlots.
262 int touch_id = touch_id_generator_.GetGeneratedID(
263 params.device_id * kNumTouchEvdevSlots + params.slot);
264 TouchEvent touch_event(params.type, gfx::PointF(x, y),
265 modifiers_.GetModifierFlags(), touch_id,
266 params.timestamp, radius_x, radius_y,
267 /* angle */ 0.f, params.pressure);
268 touch_event.set_source_device_id(params.device_id);
269 DispatchUiEvent(&touch_event);
270
271 if (params.type == ET_TOUCH_RELEASED || params.type == ET_TOUCH_CANCELLED) {
272 touch_id_generator_.ReleaseGeneratedID(touch_event.touch_id());
273 }
274 }
275
276 void EventFactoryEvdev::DispatchUiEvent(Event* event) {
277 // DispatchEvent takes PlatformEvent which is void*. This function
278 // wraps it with the real type.
279 DispatchEvent(event);
280 }
281
282 void EventFactoryEvdev::DispatchKeyboardDevicesUpdated(
283 const std::vector<KeyboardDevice>& devices) {
284 TRACE_EVENT0("evdev", "EventFactoryEvdev::DispatchKeyboardDevicesUpdated");
285 DeviceHotplugEventObserver* observer = DeviceDataManager::GetInstance();
286 observer->OnKeyboardDevicesUpdated(devices);
287 }
288
289 void EventFactoryEvdev::DispatchTouchscreenDevicesUpdated(
290 const std::vector<TouchscreenDevice>& devices) {
291 TRACE_EVENT0("evdev", "EventFactoryEvdev::DispatchTouchscreenDevicesUpdated");
292 DeviceHotplugEventObserver* observer = DeviceDataManager::GetInstance();
293 observer->OnTouchscreenDevicesUpdated(devices);
294 }
295
296 void EventFactoryEvdev::DispatchMouseDevicesUpdated(
297 const std::vector<InputDevice>& devices) {
298 TRACE_EVENT0("evdev", "EventFactoryEvdev::DispatchMouseDevicesUpdated");
299
300 // There's no list of mice in DeviceDataManager.
301 input_controller_.set_has_mouse(devices.size() != 0);
302 DeviceHotplugEventObserver* observer = DeviceDataManager::GetInstance();
303 observer->OnMouseDevicesUpdated(devices);
304 }
305
306 void EventFactoryEvdev::DispatchTouchpadDevicesUpdated(
307 const std::vector<InputDevice>& devices) {
308 TRACE_EVENT0("evdev", "EventFactoryEvdev::DispatchTouchpadDevicesUpdated");
309
310 // There's no list of touchpads in DeviceDataManager.
311 input_controller_.set_has_touchpad(devices.size() != 0);
312 DeviceHotplugEventObserver* observer = DeviceDataManager::GetInstance();
313 observer->OnTouchpadDevicesUpdated(devices);
314 }
315
316 void EventFactoryEvdev::DispatchDeviceListsComplete() {
317 TRACE_EVENT0("evdev", "EventFactoryEvdev::DispatchDeviceListsComplete");
318 DeviceHotplugEventObserver* observer = DeviceDataManager::GetInstance();
319 observer->OnDeviceListsComplete();
320 }
321
322 void EventFactoryEvdev::OnDeviceEvent(const DeviceEvent& event) {
323 if (event.device_type() != DeviceEvent::INPUT)
324 return;
325
326 switch (event.action_type()) {
327 case DeviceEvent::ADD:
328 case DeviceEvent::CHANGE: {
329 TRACE_EVENT1("evdev", "EventFactoryEvdev::OnDeviceAdded", "path",
330 event.path().value());
331 input_device_factory_proxy_->AddInputDevice(NextDeviceId(), event.path());
332 break;
333 }
334 case DeviceEvent::REMOVE: {
335 TRACE_EVENT1("evdev", "EventFactoryEvdev::OnDeviceRemoved", "path",
336 event.path().value());
337 input_device_factory_proxy_->RemoveInputDevice(event.path());
338 break;
339 }
340 }
341 }
342
343 void EventFactoryEvdev::OnDispatcherListChanged() {
344 if (!initialized_)
345 Init();
346 }
347
348 void EventFactoryEvdev::WarpCursorTo(gfx::AcceleratedWidget widget,
349 const gfx::PointF& location) {
350 if (!cursor_)
351 return;
352
353 cursor_->MoveCursorTo(widget, location);
354
355 base::ThreadTaskRunnerHandle::Get()->PostTask(
356 FROM_HERE, base::Bind(&EventFactoryEvdev::DispatchMouseMoveEvent,
357 weak_ptr_factory_.GetWeakPtr(),
358 MouseMoveEventParams(-1 /* device_id */,
359 cursor_->GetLocation(),
360 EventTimeForNow())));
361 }
362
363 int EventFactoryEvdev::NextDeviceId() {
364 return ++last_device_id_;
365 }
366
367 void EventFactoryEvdev::StartThread() {
368 // Set up device factory.
369 scoped_ptr<DeviceEventDispatcherEvdev> proxy_dispatcher(
370 new ProxyDeviceEventDispatcher(base::ThreadTaskRunnerHandle::Get(),
371 weak_ptr_factory_.GetWeakPtr()));
372 thread_.Start(proxy_dispatcher.Pass(), cursor_,
373 base::Bind(&EventFactoryEvdev::OnThreadStarted,
374 weak_ptr_factory_.GetWeakPtr()));
375 }
376
377 void EventFactoryEvdev::OnThreadStarted(
378 scoped_ptr<InputDeviceFactoryEvdevProxy> input_device_factory) {
379 TRACE_EVENT0("evdev", "EventFactoryEvdev::OnThreadStarted");
380 input_device_factory_proxy_ = input_device_factory.Pass();
381
382 // Hook up device configuration.
383 input_controller_.SetInputDeviceFactory(input_device_factory_proxy_.get());
384
385 // Scan & monitor devices.
386 device_manager_->AddObserver(this);
387 device_manager_->ScanDevices(this);
388
389 // Notify device thread that initial scan is done.
390 input_device_factory_proxy_->OnStartupScanComplete();
391 }
392
393 } // namespace ui
OLDNEW
« no previous file with comments | « ui/events/ozone/evdev/event_factory_evdev.h ('k') | ui/events/ozone/evdev/event_modifiers_evdev.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698