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