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

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

Issue 193813003: ozone: evdev: Add libgestures bindings for touchpad & mouse support (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: moved 1 space by 1 character Created 6 years, 8 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
OLDNEW
1 // Copyright 2014 The Chromium Authors. All rights reserved. 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 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "ui/events/ozone/evdev/event_factory_evdev.h" 5 #include "ui/events/ozone/evdev/event_factory_evdev.h"
6 6
7 #include <fcntl.h> 7 #include <fcntl.h>
8 #include <linux/input.h> 8 #include <linux/input.h>
9 9
10 #include "base/debug/trace_event.h" 10 #include "base/debug/trace_event.h"
11 #include "base/stl_util.h" 11 #include "base/stl_util.h"
12 #include "base/task_runner.h" 12 #include "base/task_runner.h"
13 #include "ui/events/ozone/evdev/cursor_delegate_evdev.h" 13 #include "ui/events/ozone/evdev/cursor_delegate_evdev.h"
14 #include "ui/events/ozone/evdev/device_manager_evdev.h" 14 #include "ui/events/ozone/evdev/device_manager_evdev.h"
15 #include "ui/events/ozone/evdev/event_device_info.h" 15 #include "ui/events/ozone/evdev/event_device_info.h"
16 #include "ui/events/ozone/evdev/key_event_converter_evdev.h" 16 #include "ui/events/ozone/evdev/key_event_converter_evdev.h"
17 #include "ui/events/ozone/evdev/touch_event_converter_evdev.h" 17 #include "ui/events/ozone/evdev/touch_event_converter_evdev.h"
18 18
19 #if defined(USE_UDEV) 19 #if defined(USE_UDEV)
20 #include "ui/events/ozone/evdev/device_manager_udev.h" 20 #include "ui/events/ozone/evdev/device_manager_udev.h"
21 #endif 21 #endif
22 22
23 #if defined(USE_EVDEV_GESTURES)
24 #include "ui/events/ozone/evdev/libgestures_glue/event_reader_libevdev_cros.h"
25 #include "ui/events/ozone/evdev/libgestures_glue/gesture_interpreter_libevdev_cr os.h"
26 #endif
27
23 #ifndef EVIOCSCLOCKID 28 #ifndef EVIOCSCLOCKID
24 #define EVIOCSCLOCKID _IOW('E', 0xa0, int) 29 #define EVIOCSCLOCKID _IOW('E', 0xa0, int)
25 #endif 30 #endif
26 31
27 namespace ui { 32 namespace ui {
28 33
29 namespace { 34 namespace {
30 35
31 bool IsTouchPad(const EventDeviceInfo& devinfo) { 36 bool UseGesturesLibraryForDevice(const EventDeviceInfo& devinfo) {
32 if (!devinfo.HasEventType(EV_ABS)) 37 if (devinfo.HasAbsXY() && !devinfo.IsMappedToScreen())
33 return false; 38 return true; // touchpad
34 39
35 return devinfo.HasKeyEvent(BTN_LEFT) || devinfo.HasKeyEvent(BTN_MIDDLE) || 40 if (devinfo.HasRelXY())
36 devinfo.HasKeyEvent(BTN_RIGHT) || devinfo.HasKeyEvent(BTN_TOOL_FINGER); 41 return true; // mouse
42
43 return false;
37 } 44 }
38 45
39 bool IsTouchScreen(const EventDeviceInfo& devinfo) { 46 scoped_ptr<EventConverterEvdev> CreateConverter(
40 return devinfo.HasEventType(EV_ABS) && !IsTouchPad(devinfo); 47 int fd,
48 const base::FilePath& path,
49 const EventDeviceInfo& devinfo,
50 const EventDispatchCallback& dispatch,
51 EventModifiersEvdev* modifiers,
52 CursorDelegateEvdev* cursor) {
53 #if defined(USE_EVDEV_GESTURES)
54 // Touchpad or mouse: use gestures library.
55 // EventReaderLibevdevCros -> GestureInterpreterLibevdevCros -> DispatchEvent
56 if (UseGesturesLibraryForDevice(devinfo)) {
57 scoped_ptr<GestureInterpreterLibevdevCros> gesture_interp = make_scoped_ptr(
58 new GestureInterpreterLibevdevCros(modifiers, cursor, dispatch));
59 scoped_ptr<EventReaderLibevdevCros> libevdev_reader =
60 make_scoped_ptr(new EventReaderLibevdevCros(
61 fd,
62 path,
63 gesture_interp.PassAs<EventReaderLibevdevCros::Delegate>()));
64 return libevdev_reader.PassAs<EventConverterEvdev>();
65 }
66 #endif
67
68 // Touchscreen: use TouchEventConverterEvdev.
69 scoped_ptr<EventConverterEvdev> converter;
70 if (devinfo.HasAbsXY())
71 return make_scoped_ptr<EventConverterEvdev>(
72 new TouchEventConverterEvdev(fd, path, devinfo, dispatch));
73
74 // Everything else: use KeyEventConverterEvdev.
75 return make_scoped_ptr<EventConverterEvdev>(
76 new KeyEventConverterEvdev(fd, path, modifiers, dispatch));
41 } 77 }
42 78
43 // Open an input device. Opening may put the calling thread to sleep, and 79 // Open an input device. Opening may put the calling thread to sleep, and
44 // therefore should be run on a thread where latency is not critical. We 80 // therefore should be run on a thread where latency is not critical. We
45 // run it on the FILE thread. 81 // run it on the FILE thread.
46 // 82 //
47 // This takes a TaskRunner and runs the reply on that thread, so that we 83 // This takes a TaskRunner and runs the reply on that thread, so that we
48 // can hop threads if necessary (back to the UI thread). 84 // can hop threads if necessary (back to the UI thread).
49 void OpenInputDevice( 85 void OpenInputDevice(
50 const base::FilePath& path, 86 const base::FilePath& path,
51 EventModifiersEvdev* modifiers, 87 EventModifiersEvdev* modifiers,
52 CursorDelegateEvdev* cursor, 88 CursorDelegateEvdev* cursor,
53 scoped_refptr<base::TaskRunner> reply_runner, 89 scoped_refptr<base::TaskRunner> reply_runner,
90 const EventDispatchCallback& dispatch,
54 base::Callback<void(scoped_ptr<EventConverterEvdev>)> reply_callback) { 91 base::Callback<void(scoped_ptr<EventConverterEvdev>)> reply_callback) {
55 TRACE_EVENT1("ozone", "OpenInputDevice", "path", path.value()); 92 TRACE_EVENT1("ozone", "OpenInputDevice", "path", path.value());
56 93
57 int fd = open(path.value().c_str(), O_RDONLY | O_NONBLOCK); 94 int fd = open(path.value().c_str(), O_RDONLY | O_NONBLOCK);
58 if (fd < 0) { 95 if (fd < 0) {
59 PLOG(ERROR) << "Cannot open '" << path.value(); 96 PLOG(ERROR) << "Cannot open '" << path.value();
60 return; 97 return;
61 } 98 }
62 99
63 // Use monotonic timestamps for events. The touch code in particular 100 // Use monotonic timestamps for events. The touch code in particular
64 // expects event timestamps to correlate to the monotonic clock 101 // expects event timestamps to correlate to the monotonic clock
65 // (base::TimeTicks). 102 // (base::TimeTicks).
66 unsigned int clk = CLOCK_MONOTONIC; 103 unsigned int clk = CLOCK_MONOTONIC;
67 if (ioctl(fd, EVIOCSCLOCKID, &clk)) 104 if (ioctl(fd, EVIOCSCLOCKID, &clk))
68 PLOG(ERROR) << "failed to set CLOCK_MONOTONIC"; 105 PLOG(ERROR) << "failed to set CLOCK_MONOTONIC";
69 106
70 EventDeviceInfo devinfo; 107 EventDeviceInfo devinfo;
71 if (!devinfo.Initialize(fd)) { 108 if (!devinfo.Initialize(fd)) {
72 LOG(ERROR) << "failed to get device information for " << path.value(); 109 LOG(ERROR) << "failed to get device information for " << path.value();
73 close(fd); 110 close(fd);
74 return; 111 return;
75 } 112 }
76 113
77 if (IsTouchPad(devinfo)) { 114 scoped_ptr<EventConverterEvdev> converter =
78 LOG(WARNING) << "touchpad device not supported: " << path.value(); 115 CreateConverter(fd, path, devinfo, dispatch, modifiers, cursor);
79 close(fd);
80 return;
81 }
82 116
83 // TODO(spang) Add more device types. 117 // Reply with the constructed converter.
84 scoped_ptr<EventConverterEvdev> converter; 118 reply_runner->PostTask(FROM_HERE,
85 if (IsTouchScreen(devinfo)) 119 base::Bind(reply_callback, base::Passed(&converter)));
86 converter.reset(new TouchEventConverterEvdev(fd, path, devinfo));
87 else if (devinfo.HasEventType(EV_KEY))
88 converter.reset(new KeyEventConverterEvdev(fd, path, modifiers));
89
90 if (converter) {
91 // Reply with the constructed converter.
92 reply_runner->PostTask(
93 FROM_HERE, base::Bind(reply_callback, base::Passed(&converter)));
94 } else {
95 close(fd);
96 }
97 } 120 }
98 121
99 // Close an input device. Closing may put the calling thread to sleep, and 122 // Close an input device. Closing may put the calling thread to sleep, and
100 // therefore should be run on a thread where latency is not critical. We 123 // therefore should be run on a thread where latency is not critical. We
101 // run it on the FILE thread. 124 // run it on the FILE thread.
102 void CloseInputDevice(const base::FilePath& path, 125 void CloseInputDevice(const base::FilePath& path,
103 scoped_ptr<EventConverterEvdev> converter) { 126 scoped_ptr<EventConverterEvdev> converter) {
104 TRACE_EVENT1("ozone", "CloseInputDevice", "path", path.value()); 127 TRACE_EVENT1("ozone", "CloseInputDevice", "path", path.value());
105 converter.reset(); 128 converter.reset();
106 } 129 }
107 130
108 } // namespace 131 } // namespace
109 132
110 EventFactoryEvdev::EventFactoryEvdev() 133 EventFactoryEvdev::EventFactoryEvdev()
111 : ui_task_runner_(base::MessageLoopProxy::current()), 134 : ui_task_runner_(base::MessageLoopProxy::current()),
112 file_task_runner_(base::MessageLoopProxy::current()), 135 file_task_runner_(base::MessageLoopProxy::current()),
113 cursor_(NULL), 136 cursor_(NULL),
137 dispatch_callback_(
138 base::Bind(base::IgnoreResult(&EventFactoryEvdev::DispatchEvent),
139 base::Unretained(this))),
114 weak_ptr_factory_(this) {} 140 weak_ptr_factory_(this) {}
115 141
116 EventFactoryEvdev::EventFactoryEvdev(CursorDelegateEvdev* cursor) 142 EventFactoryEvdev::EventFactoryEvdev(CursorDelegateEvdev* cursor)
117 : ui_task_runner_(base::MessageLoopProxy::current()), 143 : ui_task_runner_(base::MessageLoopProxy::current()),
118 file_task_runner_(base::MessageLoopProxy::current()), 144 file_task_runner_(base::MessageLoopProxy::current()),
119 cursor_(cursor), 145 cursor_(cursor),
146 dispatch_callback_(
147 base::Bind(base::IgnoreResult(&EventFactoryEvdev::DispatchEvent),
148 base::Unretained(this))),
120 weak_ptr_factory_(this) {} 149 weak_ptr_factory_(this) {}
121 150
122 EventFactoryEvdev::~EventFactoryEvdev() { STLDeleteValues(&converters_); } 151 EventFactoryEvdev::~EventFactoryEvdev() { STLDeleteValues(&converters_); }
123 152
153 void EventFactoryEvdev::DispatchEvent(Event* event) {
154 EventFactoryOzone::DispatchEvent(event);
155 }
156
124 void EventFactoryEvdev::AttachInputDevice( 157 void EventFactoryEvdev::AttachInputDevice(
125 const base::FilePath& path, 158 const base::FilePath& path,
126 scoped_ptr<EventConverterEvdev> converter) { 159 scoped_ptr<EventConverterEvdev> converter) {
127 TRACE_EVENT1("ozone", "AttachInputDevice", "path", path.value()); 160 TRACE_EVENT1("ozone", "AttachInputDevice", "path", path.value());
128 CHECK(ui_task_runner_->RunsTasksOnCurrentThread()); 161 CHECK(ui_task_runner_->RunsTasksOnCurrentThread());
129 162
130 // If we have an existing device, detach it. We don't want two 163 // If we have an existing device, detach it. We don't want two
131 // devices with the same name open at the same time. 164 // devices with the same name open at the same time.
132 if (converters_[path]) 165 if (converters_[path])
133 DetachInputDevice(path); 166 DetachInputDevice(path);
134 167
135 // Add initialized device to map. 168 // Add initialized device to map.
136 converters_[path] = converter.release(); 169 converters_[path] = converter.release();
137 converters_[path]->SetDispatchCallback(
138 base::Bind(base::IgnoreResult(&EventFactoryEvdev::DispatchEvent),
139 base::Unretained(this)));
140 converters_[path]->Start(); 170 converters_[path]->Start();
141 } 171 }
142 172
143 void EventFactoryEvdev::OnDeviceAdded(const base::FilePath& path) { 173 void EventFactoryEvdev::OnDeviceAdded(const base::FilePath& path) {
144 TRACE_EVENT1("ozone", "OnDeviceAdded", "path", path.value()); 174 TRACE_EVENT1("ozone", "OnDeviceAdded", "path", path.value());
145 175
146 // Dispatch task to open on FILE thread, since open may block. 176 // Dispatch task to open on FILE thread, since open may block.
147 file_task_runner_->PostTask( 177 file_task_runner_->PostTask(
148 FROM_HERE, 178 FROM_HERE,
149 base::Bind(&OpenInputDevice, 179 base::Bind(&OpenInputDevice,
150 path, 180 path,
151 &modifiers_, 181 &modifiers_,
152 cursor_, 182 cursor_,
153 ui_task_runner_, 183 ui_task_runner_,
184 dispatch_callback_,
154 base::Bind(&EventFactoryEvdev::AttachInputDevice, 185 base::Bind(&EventFactoryEvdev::AttachInputDevice,
155 weak_ptr_factory_.GetWeakPtr(), 186 weak_ptr_factory_.GetWeakPtr(),
156 path))); 187 path)));
157 } 188 }
158 189
159 void EventFactoryEvdev::DetachInputDevice(const base::FilePath& path) { 190 void EventFactoryEvdev::DetachInputDevice(const base::FilePath& path) {
160 TRACE_EVENT1("ozone", "DetachInputDevice", "path", path.value()); 191 TRACE_EVENT1("ozone", "DetachInputDevice", "path", path.value());
161 CHECK(ui_task_runner_->RunsTasksOnCurrentThread()); 192 CHECK(ui_task_runner_->RunsTasksOnCurrentThread());
162 193
163 // Remove device from map. 194 // Remove device from map.
(...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after
210 MouseEvent mouse_event(ET_MOUSE_MOVED, 241 MouseEvent mouse_event(ET_MOUSE_MOVED,
211 cursor_->location(), 242 cursor_->location(),
212 cursor_->location(), 243 cursor_->location(),
213 modifiers_.GetModifierFlags(), 244 modifiers_.GetModifierFlags(),
214 /* changed_button_flags */ 0); 245 /* changed_button_flags */ 0);
215 DispatchEvent(&mouse_event); 246 DispatchEvent(&mouse_event);
216 } 247 }
217 } 248 }
218 249
219 } // namespace ui 250 } // 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