OLD | NEW |
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/platform/x11/x11_hotplug_event_handler.h" | 5 #include "ui/events/platform/x11/x11_hotplug_event_handler.h" |
6 | 6 |
7 #include <X11/Xatom.h> | 7 #include <X11/Xatom.h> |
8 #include <X11/extensions/XInput.h> | 8 #include <X11/extensions/XInput.h> |
9 #include <X11/extensions/XInput2.h> | 9 #include <X11/extensions/XInput2.h> |
10 | 10 |
(...skipping 28 matching lines...) Expand all Loading... |
39 // Names of all known internal devices that should not be considered as | 39 // Names of all known internal devices that should not be considered as |
40 // keyboards. | 40 // keyboards. |
41 // TODO(rsadam@): Identify these devices using udev rules. (Crbug.com/420728.) | 41 // TODO(rsadam@): Identify these devices using udev rules. (Crbug.com/420728.) |
42 const char* kKnownInvalidKeyboardDeviceNames[] = {"Power Button", | 42 const char* kKnownInvalidKeyboardDeviceNames[] = {"Power Button", |
43 "Sleep Button", | 43 "Sleep Button", |
44 "Video Bus"}; | 44 "Video Bus"}; |
45 | 45 |
46 const char* kCachedAtomList[] = { | 46 const char* kCachedAtomList[] = { |
47 "Abs MT Position X", | 47 "Abs MT Position X", |
48 "Abs MT Position Y", | 48 "Abs MT Position Y", |
| 49 XI_KEYBOARD, |
| 50 XI_MOUSE, |
| 51 XI_TOUCHPAD, |
| 52 XI_TOUCHSCREEN, |
49 NULL, | 53 NULL, |
50 }; | 54 }; |
51 | 55 |
| 56 enum DeviceType { |
| 57 DEVICE_TYPE_KEYBOARD, |
| 58 DEVICE_TYPE_MOUSE, |
| 59 DEVICE_TYPE_TOUCHPAD, |
| 60 DEVICE_TYPE_TOUCHSCREEN, |
| 61 DEVICE_TYPE_OTHER |
| 62 }; |
| 63 |
52 typedef base::Callback<void(const std::vector<KeyboardDevice>&)> | 64 typedef base::Callback<void(const std::vector<KeyboardDevice>&)> |
53 KeyboardDeviceCallback; | 65 KeyboardDeviceCallback; |
54 | 66 |
55 typedef base::Callback<void(const std::vector<TouchscreenDevice>&)> | 67 typedef base::Callback<void(const std::vector<TouchscreenDevice>&)> |
56 TouchscreenDeviceCallback; | 68 TouchscreenDeviceCallback; |
57 | 69 |
| 70 typedef base::Callback<void(const std::vector<InputDevice>&)> |
| 71 InputDeviceCallback; |
| 72 |
58 // Used for updating the state on the UI thread once device information is | 73 // Used for updating the state on the UI thread once device information is |
59 // parsed on helper threads. | 74 // parsed on helper threads. |
60 struct UiCallbacks { | 75 struct UiCallbacks { |
61 KeyboardDeviceCallback keyboard_callback; | 76 KeyboardDeviceCallback keyboard_callback; |
62 TouchscreenDeviceCallback touchscreen_callback; | 77 TouchscreenDeviceCallback touchscreen_callback; |
| 78 InputDeviceCallback mouse_callback; |
| 79 InputDeviceCallback touchpad_callback; |
63 }; | 80 }; |
64 | 81 |
65 // Stores a copy of the XIValuatorClassInfo values so X11 device processing can | 82 // Stores a copy of the XIValuatorClassInfo values so X11 device processing can |
66 // happen on a worker thread. This is needed since X11 structs are not copyable. | 83 // happen on a worker thread. This is needed since X11 structs are not copyable. |
67 struct ValuatorClassInfo { | 84 struct ValuatorClassInfo { |
68 ValuatorClassInfo(const XIValuatorClassInfo& info) | 85 ValuatorClassInfo(const XIValuatorClassInfo& info) |
69 : label(info.label), | 86 : label(info.label), |
70 max(info.max), | 87 max(info.max), |
71 min(info.min), | 88 min(info.min), |
72 mode(info.mode), | 89 mode(info.mode), |
(...skipping 12 matching lines...) Expand all Loading... |
85 TouchClassInfo() : mode(0), num_touches(0) {} | 102 TouchClassInfo() : mode(0), num_touches(0) {} |
86 | 103 |
87 explicit TouchClassInfo(const XITouchClassInfo& info) | 104 explicit TouchClassInfo(const XITouchClassInfo& info) |
88 : mode(info.mode), num_touches(info.num_touches) {} | 105 : mode(info.mode), num_touches(info.num_touches) {} |
89 | 106 |
90 int mode; | 107 int mode; |
91 int num_touches; | 108 int num_touches; |
92 }; | 109 }; |
93 | 110 |
94 struct DeviceInfo { | 111 struct DeviceInfo { |
95 DeviceInfo(const XIDeviceInfo& device, const base::FilePath& path) | 112 DeviceInfo(const XIDeviceInfo& device, |
| 113 DeviceType type, |
| 114 const base::FilePath& path) |
96 : id(device.deviceid), | 115 : id(device.deviceid), |
97 name(device.name), | 116 name(device.name), |
98 use(device.use), | 117 use(device.use), |
99 enabled(device.enabled), | 118 type(type), |
100 path(path) { | 119 path(path) { |
101 for (int i = 0; i < device.num_classes; ++i) { | 120 for (int i = 0; i < device.num_classes; ++i) { |
102 switch (device.classes[i]->type) { | 121 switch (device.classes[i]->type) { |
103 case XIValuatorClass: | 122 case XIValuatorClass: |
104 valuator_class_infos.push_back(ValuatorClassInfo( | 123 valuator_class_infos.push_back(ValuatorClassInfo( |
105 *reinterpret_cast<XIValuatorClassInfo*>(device.classes[i]))); | 124 *reinterpret_cast<XIValuatorClassInfo*>(device.classes[i]))); |
106 break; | 125 break; |
107 case XITouchClass: | 126 case XITouchClass: |
108 // A device can have at most one XITouchClassInfo. Ref: | 127 // A device can have at most one XITouchClassInfo. Ref: |
109 // http://manpages.ubuntu.com/manpages/saucy/man3/XIQueryDevice.3.html | 128 // http://manpages.ubuntu.com/manpages/saucy/man3/XIQueryDevice.3.html |
110 DCHECK(!touch_class_info.mode); | 129 DCHECK(!touch_class_info.mode); |
111 touch_class_info = TouchClassInfo( | 130 touch_class_info = TouchClassInfo( |
112 *reinterpret_cast<XITouchClassInfo*>(device.classes[i])); | 131 *reinterpret_cast<XITouchClassInfo*>(device.classes[i])); |
113 break; | 132 break; |
114 default: | 133 default: |
115 break; | 134 break; |
116 } | 135 } |
117 } | 136 } |
118 } | 137 } |
119 | 138 |
120 // Unique device identifier. | 139 // Unique device identifier. |
121 int id; | 140 int id; |
122 | 141 |
123 // Internal device name. | 142 // Internal device name. |
124 std::string name; | 143 std::string name; |
125 | 144 |
126 // Device type (ie: XIMasterPointer) | 145 // Device type (ie: XIMasterPointer) |
127 int use; | 146 int use; |
128 | 147 |
129 // Specifies if the device is enabled and can send events. | 148 // Specifies the type of the device. |
130 bool enabled; | 149 DeviceType type; |
131 | 150 |
132 // Path to the actual device (ie: /dev/input/eventXX) | 151 // Path to the actual device (ie: /dev/input/eventXX) |
133 base::FilePath path; | 152 base::FilePath path; |
134 | 153 |
135 std::vector<ValuatorClassInfo> valuator_class_infos; | 154 std::vector<ValuatorClassInfo> valuator_class_infos; |
136 | 155 |
137 TouchClassInfo touch_class_info; | 156 TouchClassInfo touch_class_info; |
138 }; | 157 }; |
139 | 158 |
140 // X11 display cache used on worker threads. This is filled on the UI thread and | 159 // X11 display cache used on worker threads. This is filled on the UI thread and |
141 // passed in to the worker threads. | 160 // passed in to the worker threads. |
142 struct DisplayState { | 161 struct DisplayState { |
143 Atom mt_position_x; | 162 Atom mt_position_x; |
144 Atom mt_position_y; | 163 Atom mt_position_y; |
145 }; | 164 }; |
146 | 165 |
147 // Returns true if |name| is the name of a known invalid keyboard device. Note, | 166 // Returns true if |name| is the name of a known invalid keyboard device. Note, |
148 // this may return false negatives. | 167 // this may return false negatives. |
149 bool IsKnownInvalidKeyboardDevice(const std::string& name) { | 168 bool IsKnownInvalidKeyboardDevice(const std::string& name) { |
| 169 std::string trimmed(name); |
| 170 base::TrimWhitespaceASCII(name, base::TRIM_TRAILING, &trimmed); |
150 for (const char* device_name : kKnownInvalidKeyboardDeviceNames) { | 171 for (const char* device_name : kKnownInvalidKeyboardDeviceNames) { |
151 if (name == device_name) | 172 if (trimmed == device_name) |
152 return true; | 173 return true; |
153 } | 174 } |
154 return false; | 175 return false; |
155 } | 176 } |
156 | 177 |
157 // Returns true if |name| is the name of a known XTEST device. Note, this may | 178 // Returns true if |name| is the name of a known XTEST device. Note, this may |
158 // return false negatives. | 179 // return false negatives. |
159 bool IsTestKeyboard(const std::string& name) { | 180 bool IsTestDevice(const std::string& name) { |
160 return name.find("XTEST") != std::string::npos; | 181 return name.find("XTEST") != std::string::npos; |
161 } | 182 } |
162 | 183 |
163 base::FilePath GetDevicePath(XDisplay* dpy, const XIDeviceInfo& device) { | 184 base::FilePath GetDevicePath(XDisplay* dpy, const XIDeviceInfo& device) { |
164 // Skip the main pointer and keyboard since XOpenDevice() generates a | 185 // Skip the main pointer and keyboard since XOpenDevice() generates a |
165 // BadDevice error when passed these devices. | 186 // BadDevice error when passed these devices. |
166 if (device.use == XIMasterPointer || device.use == XIMasterKeyboard) | 187 if (device.use == XIMasterPointer || device.use == XIMasterKeyboard) |
167 return base::FilePath(); | 188 return base::FilePath(); |
168 | 189 |
169 // Input device has a property "Device Node" pointing to its dev input node, | 190 // Input device has a property "Device Node" pointing to its dev input node, |
(...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
209 | 230 |
210 // Helper used to parse keyboard information. When it is done it uses | 231 // Helper used to parse keyboard information. When it is done it uses |
211 // |reply_runner| and |callback| to update the state on the UI thread. | 232 // |reply_runner| and |callback| to update the state on the UI thread. |
212 void HandleKeyboardDevicesInWorker( | 233 void HandleKeyboardDevicesInWorker( |
213 const std::vector<DeviceInfo>& device_infos, | 234 const std::vector<DeviceInfo>& device_infos, |
214 scoped_refptr<base::TaskRunner> reply_runner, | 235 scoped_refptr<base::TaskRunner> reply_runner, |
215 const KeyboardDeviceCallback& callback) { | 236 const KeyboardDeviceCallback& callback) { |
216 std::vector<KeyboardDevice> devices; | 237 std::vector<KeyboardDevice> devices; |
217 | 238 |
218 for (const DeviceInfo& device_info : device_infos) { | 239 for (const DeviceInfo& device_info : device_infos) { |
219 if (!device_info.enabled || device_info.use != XISlaveKeyboard) | 240 if (device_info.type != DEVICE_TYPE_KEYBOARD) |
| 241 continue; |
| 242 if (device_info.use != XISlaveKeyboard) |
220 continue; // Assume all keyboards are keyboard slaves | 243 continue; // Assume all keyboards are keyboard slaves |
221 std::string device_name(device_info.name); | 244 if (IsKnownInvalidKeyboardDevice(device_info.name)) |
222 base::TrimWhitespaceASCII(device_name, base::TRIM_TRAILING, &device_name); | |
223 if (IsTestKeyboard(device_name)) | |
224 continue; // Skip test devices. | |
225 if (IsKnownInvalidKeyboardDevice(device_name)) | |
226 continue; // Skip invalid devices. | 245 continue; // Skip invalid devices. |
227 InputDeviceType type = GetInputDeviceTypeFromPath(device_info.path); | 246 InputDeviceType type = GetInputDeviceTypeFromPath(device_info.path); |
228 devices.push_back(KeyboardDevice(device_info.id, type)); | 247 devices.push_back(KeyboardDevice(device_info.id, type)); |
229 } | 248 } |
230 | 249 |
231 reply_runner->PostTask(FROM_HERE, base::Bind(callback, devices)); | 250 reply_runner->PostTask(FROM_HERE, base::Bind(callback, devices)); |
232 } | 251 } |
233 | 252 |
| 253 // Helper used to parse mouse information. When it is done it uses |
| 254 // |reply_runner| and |callback| to update the state on the UI thread. |
| 255 void HandleMouseDevicesInWorker(const std::vector<DeviceInfo>& device_infos, |
| 256 scoped_refptr<base::TaskRunner> reply_runner, |
| 257 const InputDeviceCallback& callback) { |
| 258 std::vector<InputDevice> devices; |
| 259 for (const DeviceInfo& device_info : device_infos) { |
| 260 if (device_info.type != DEVICE_TYPE_MOUSE || |
| 261 device_info.use != XISlavePointer) { |
| 262 continue; |
| 263 } |
| 264 |
| 265 InputDeviceType type = GetInputDeviceTypeFromPath(device_info.path); |
| 266 devices.push_back(InputDevice(device_info.id, type)); |
| 267 } |
| 268 |
| 269 reply_runner->PostTask(FROM_HERE, base::Bind(callback, devices)); |
| 270 } |
| 271 |
| 272 // Helper used to parse touchpad information. When it is done it uses |
| 273 // |reply_runner| and |callback| to update the state on the UI thread. |
| 274 void HandleTouchpadDevicesInWorker(const std::vector<DeviceInfo>& device_infos, |
| 275 scoped_refptr<base::TaskRunner> reply_runner, |
| 276 const InputDeviceCallback& callback) { |
| 277 std::vector<InputDevice> devices; |
| 278 for (const DeviceInfo& device_info : device_infos) { |
| 279 if (device_info.type != DEVICE_TYPE_TOUCHPAD || |
| 280 device_info.use != XISlavePointer) { |
| 281 continue; |
| 282 } |
| 283 |
| 284 InputDeviceType type = GetInputDeviceTypeFromPath(device_info.path); |
| 285 devices.push_back(InputDevice(device_info.id, type)); |
| 286 } |
| 287 |
| 288 reply_runner->PostTask(FROM_HERE, base::Bind(callback, devices)); |
| 289 } |
| 290 |
234 // Helper used to parse touchscreen information. When it is done it uses | 291 // Helper used to parse touchscreen information. When it is done it uses |
235 // |reply_runner| and |callback| to update the state on the UI thread. | 292 // |reply_runner| and |callback| to update the state on the UI thread. |
236 void HandleTouchscreenDevicesInWorker( | 293 void HandleTouchscreenDevicesInWorker( |
237 const std::vector<DeviceInfo>& device_infos, | 294 const std::vector<DeviceInfo>& device_infos, |
238 const DisplayState& display_state, | 295 const DisplayState& display_state, |
239 scoped_refptr<base::TaskRunner> reply_runner, | 296 scoped_refptr<base::TaskRunner> reply_runner, |
240 const TouchscreenDeviceCallback& callback) { | 297 const TouchscreenDeviceCallback& callback) { |
241 std::vector<TouchscreenDevice> devices; | 298 std::vector<TouchscreenDevice> devices; |
242 if (display_state.mt_position_x == None || | 299 if (display_state.mt_position_x == None || |
243 display_state.mt_position_y == None) | 300 display_state.mt_position_y == None) |
244 return; | 301 return; |
245 | 302 |
246 std::set<int> no_match_touchscreen; | |
247 for (const DeviceInfo& device_info : device_infos) { | 303 for (const DeviceInfo& device_info : device_infos) { |
248 if (!device_info.enabled || (device_info.use != XIFloatingSlave | 304 if (device_info.type != DEVICE_TYPE_TOUCHSCREEN || |
249 && device_info.use != XISlavePointer)) | 305 (device_info.use != XIFloatingSlave && |
| 306 device_info.use != XISlavePointer)) { |
| 307 continue; |
| 308 } |
| 309 |
| 310 // Touchscreens should be direct touch devices. |
| 311 if (device_info.touch_class_info.mode != XIDirectTouch) |
250 continue; | 312 continue; |
251 | 313 |
252 double max_x = -1.0; | 314 double max_x = -1.0; |
253 double max_y = -1.0; | 315 double max_y = -1.0; |
254 bool is_direct_touch = false; | |
255 | 316 |
256 for (const ValuatorClassInfo& valuator : device_info.valuator_class_infos) { | 317 for (const ValuatorClassInfo& valuator : device_info.valuator_class_infos) { |
257 if (display_state.mt_position_x == valuator.label) { | 318 if (display_state.mt_position_x == valuator.label) { |
258 // Ignore X axis valuator with unexpected properties | 319 // Ignore X axis valuator with unexpected properties |
259 if (valuator.number == 0 && valuator.mode == Absolute && | 320 if (valuator.number == 0 && valuator.mode == Absolute && |
260 valuator.min == 0.0) { | 321 valuator.min == 0.0) { |
261 max_x = valuator.max; | 322 max_x = valuator.max; |
262 } | 323 } |
263 } else if (display_state.mt_position_y == valuator.label) { | 324 } else if (display_state.mt_position_y == valuator.label) { |
264 // Ignore Y axis valuator with unexpected properties | 325 // Ignore Y axis valuator with unexpected properties |
265 if (valuator.number == 1 && valuator.mode == Absolute && | 326 if (valuator.number == 1 && valuator.mode == Absolute && |
266 valuator.min == 0.0) { | 327 valuator.min == 0.0) { |
267 max_y = valuator.max; | 328 max_y = valuator.max; |
268 } | 329 } |
269 } | 330 } |
270 } | 331 } |
271 | 332 |
272 if (device_info.touch_class_info.mode) | 333 // Touchscreens should have absolute X and Y axes. |
273 is_direct_touch = device_info.touch_class_info.mode == XIDirectTouch; | 334 if (max_x > 0.0 && max_y > 0.0) { |
274 | |
275 // Touchscreens should have absolute X and Y axes, and be direct touch | |
276 // devices. | |
277 if (max_x > 0.0 && max_y > 0.0 && is_direct_touch) { | |
278 InputDeviceType type = GetInputDeviceTypeFromPath(device_info.path); | 335 InputDeviceType type = GetInputDeviceTypeFromPath(device_info.path); |
279 // |max_x| and |max_y| are inclusive values, so we need to add 1 to get | 336 // |max_x| and |max_y| are inclusive values, so we need to add 1 to get |
280 // the size. | 337 // the size. |
281 devices.push_back(TouchscreenDevice( | 338 devices.push_back(TouchscreenDevice( |
282 device_info.id, type, gfx::Size(max_x + 1, max_y + 1), | 339 device_info.id, type, gfx::Size(max_x + 1, max_y + 1), |
283 device_info.touch_class_info.num_touches)); | 340 device_info.touch_class_info.num_touches)); |
284 } | 341 } |
285 } | 342 } |
286 | 343 |
287 reply_runner->PostTask(FROM_HERE, base::Bind(callback, devices)); | 344 reply_runner->PostTask(FROM_HERE, base::Bind(callback, devices)); |
288 } | 345 } |
289 | 346 |
290 // Called on a worker thread to parse the device information. | 347 // Called on a worker thread to parse the device information. |
291 void HandleHotplugEventInWorker( | 348 void HandleHotplugEventInWorker( |
292 const std::vector<DeviceInfo>& devices, | 349 const std::vector<DeviceInfo>& devices, |
293 const DisplayState& display_state, | 350 const DisplayState& display_state, |
294 scoped_refptr<base::TaskRunner> reply_runner, | 351 scoped_refptr<base::TaskRunner> reply_runner, |
295 const UiCallbacks& callbacks) { | 352 const UiCallbacks& callbacks) { |
296 HandleTouchscreenDevicesInWorker( | 353 HandleTouchscreenDevicesInWorker( |
297 devices, display_state, reply_runner, callbacks.touchscreen_callback); | 354 devices, display_state, reply_runner, callbacks.touchscreen_callback); |
298 HandleKeyboardDevicesInWorker( | 355 HandleKeyboardDevicesInWorker( |
299 devices, reply_runner, callbacks.keyboard_callback); | 356 devices, reply_runner, callbacks.keyboard_callback); |
| 357 HandleMouseDevicesInWorker(devices, reply_runner, callbacks.mouse_callback); |
| 358 HandleTouchpadDevicesInWorker(devices, reply_runner, |
| 359 callbacks.touchpad_callback); |
300 } | 360 } |
301 | 361 |
302 DeviceHotplugEventObserver* GetHotplugEventObserver() { | 362 DeviceHotplugEventObserver* GetHotplugEventObserver() { |
303 return DeviceDataManager::GetInstance(); | 363 return DeviceDataManager::GetInstance(); |
304 } | 364 } |
305 | 365 |
306 void OnKeyboardDevices(const std::vector<KeyboardDevice>& devices) { | 366 void OnKeyboardDevices(const std::vector<KeyboardDevice>& devices) { |
307 GetHotplugEventObserver()->OnKeyboardDevicesUpdated(devices); | 367 GetHotplugEventObserver()->OnKeyboardDevicesUpdated(devices); |
308 } | 368 } |
309 | 369 |
310 void OnTouchscreenDevices(const std::vector<TouchscreenDevice>& devices) { | 370 void OnTouchscreenDevices(const std::vector<TouchscreenDevice>& devices) { |
311 GetHotplugEventObserver()->OnTouchscreenDevicesUpdated(devices); | 371 GetHotplugEventObserver()->OnTouchscreenDevicesUpdated(devices); |
312 } | 372 } |
313 | 373 |
| 374 void OnMouseDevices(const std::vector<InputDevice>& devices) { |
| 375 GetHotplugEventObserver()->OnMouseDevicesUpdated(devices); |
| 376 } |
| 377 |
| 378 void OnTouchpadDevices(const std::vector<InputDevice>& devices) { |
| 379 GetHotplugEventObserver()->OnTouchpadDevicesUpdated(devices); |
| 380 } |
| 381 |
314 } // namespace | 382 } // namespace |
315 | 383 |
316 X11HotplugEventHandler::X11HotplugEventHandler() | 384 X11HotplugEventHandler::X11HotplugEventHandler() |
317 : atom_cache_(gfx::GetXDisplay(), kCachedAtomList) { | 385 : atom_cache_(gfx::GetXDisplay(), kCachedAtomList) { |
318 } | 386 } |
319 | 387 |
320 X11HotplugEventHandler::~X11HotplugEventHandler() { | 388 X11HotplugEventHandler::~X11HotplugEventHandler() { |
321 } | 389 } |
322 | 390 |
323 void X11HotplugEventHandler::OnHotplugEvent() { | 391 void X11HotplugEventHandler::OnHotplugEvent() { |
324 const XIDeviceList& device_list = | |
325 DeviceListCacheX11::GetInstance()->GetXI2DeviceList(gfx::GetXDisplay()); | |
326 Display* display = gfx::GetXDisplay(); | 392 Display* display = gfx::GetXDisplay(); |
| 393 const XDeviceList& device_list_xi = |
| 394 DeviceListCacheX11::GetInstance()->GetXDeviceList(display); |
| 395 const XIDeviceList& device_list_xi2 = |
| 396 DeviceListCacheX11::GetInstance()->GetXI2DeviceList(display); |
| 397 |
| 398 const int kMaxDeviceNum = 128; |
| 399 DeviceType device_types[kMaxDeviceNum]; |
| 400 for (int i = 0; i < kMaxDeviceNum; ++i) |
| 401 device_types[i] = DEVICE_TYPE_OTHER; |
| 402 |
| 403 for (int i = 0; i < device_list_xi.count; ++i) { |
| 404 int id = device_list_xi[i].id; |
| 405 if (id < 0 || id >= kMaxDeviceNum) |
| 406 continue; |
| 407 |
| 408 Atom type = device_list_xi[i].type; |
| 409 if (type == atom_cache_.GetAtom(XI_KEYBOARD)) |
| 410 device_types[id] = DEVICE_TYPE_KEYBOARD; |
| 411 else if (type == atom_cache_.GetAtom(XI_MOUSE)) |
| 412 device_types[id] = DEVICE_TYPE_MOUSE; |
| 413 else if (type == atom_cache_.GetAtom(XI_TOUCHPAD)) |
| 414 device_types[id] = DEVICE_TYPE_TOUCHPAD; |
| 415 else if (type == atom_cache_.GetAtom(XI_TOUCHSCREEN)) |
| 416 device_types[id] = DEVICE_TYPE_TOUCHSCREEN; |
| 417 } |
327 | 418 |
328 std::vector<DeviceInfo> device_infos; | 419 std::vector<DeviceInfo> device_infos; |
329 for (int i = 0; i < device_list.count; ++i) { | 420 for (int i = 0; i < device_list_xi2.count; ++i) { |
330 const XIDeviceInfo& device = device_list[i]; | 421 const XIDeviceInfo& device = device_list_xi2[i]; |
331 device_infos.push_back(DeviceInfo(device, GetDevicePath(display, device))); | 422 if (!device.enabled || IsTestDevice(device.name)) |
| 423 continue; |
| 424 |
| 425 DeviceType device_type = |
| 426 (device.deviceid >= 0 && device.deviceid < kMaxDeviceNum) |
| 427 ? device_types[device.deviceid] |
| 428 : DEVICE_TYPE_OTHER; |
| 429 device_infos.push_back( |
| 430 DeviceInfo(device, device_type, GetDevicePath(display, device))); |
332 } | 431 } |
333 | 432 |
334 // X11 is not thread safe, so first get all the required state. | 433 // X11 is not thread safe, so first get all the required state. |
335 DisplayState display_state; | 434 DisplayState display_state; |
336 display_state.mt_position_x = atom_cache_.GetAtom("Abs MT Position X"); | 435 display_state.mt_position_x = atom_cache_.GetAtom("Abs MT Position X"); |
337 display_state.mt_position_y = atom_cache_.GetAtom("Abs MT Position Y"); | 436 display_state.mt_position_y = atom_cache_.GetAtom("Abs MT Position Y"); |
338 | 437 |
339 UiCallbacks callbacks; | 438 UiCallbacks callbacks; |
340 callbacks.keyboard_callback = base::Bind(&OnKeyboardDevices); | 439 callbacks.keyboard_callback = base::Bind(&OnKeyboardDevices); |
341 callbacks.touchscreen_callback = base::Bind(&OnTouchscreenDevices); | 440 callbacks.touchscreen_callback = base::Bind(&OnTouchscreenDevices); |
342 // TODO(pkotwicz): Compute the lists of mice and touchpads and send the new | 441 callbacks.mouse_callback = base::Bind(&OnMouseDevices); |
343 // lists to DeviceHotplugEventObserver. | 442 callbacks.touchpad_callback = base::Bind(&OnTouchpadDevices); |
344 | 443 |
345 // Parsing the device information may block, so delegate the operation to a | 444 // Parsing the device information may block, so delegate the operation to a |
346 // worker thread. Once the device information is extracted the parsed devices | 445 // worker thread. Once the device information is extracted the parsed devices |
347 // will be returned via the callbacks. | 446 // will be returned via the callbacks. |
348 base::WorkerPool::PostTask(FROM_HERE, | 447 base::WorkerPool::PostTask(FROM_HERE, |
349 base::Bind(&HandleHotplugEventInWorker, | 448 base::Bind(&HandleHotplugEventInWorker, |
350 device_infos, | 449 device_infos, |
351 display_state, | 450 display_state, |
352 base::ThreadTaskRunnerHandle::Get(), | 451 base::ThreadTaskRunnerHandle::Get(), |
353 callbacks), | 452 callbacks), |
354 true /* task_is_slow */); | 453 true /* task_is_slow */); |
355 } | 454 } |
356 | 455 |
357 } // namespace ui | 456 } // namespace ui |
OLD | NEW |