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 64 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
75 Atom label; | 75 Atom label; |
76 double max; | 76 double max; |
77 double min; | 77 double min; |
78 int mode; | 78 int mode; |
79 int number; | 79 int number; |
80 }; | 80 }; |
81 | 81 |
82 // Stores a copy of the XITouchClassInfo values so X11 device processing can | 82 // Stores a copy of the XITouchClassInfo values so X11 device processing can |
83 // 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. |
84 struct TouchClassInfo { | 84 struct TouchClassInfo { |
85 TouchClassInfo(const XITouchClassInfo& info) | 85 TouchClassInfo() : mode(0), num_touches(0) {} |
86 : mode(info.mode) {} | 86 |
| 87 explicit TouchClassInfo(const XITouchClassInfo& info) |
| 88 : mode(info.mode), num_touches(info.num_touches) {} |
87 | 89 |
88 int mode; | 90 int mode; |
| 91 int num_touches; |
89 }; | 92 }; |
90 | 93 |
91 struct DeviceInfo { | 94 struct DeviceInfo { |
92 DeviceInfo(const XIDeviceInfo& device, const base::FilePath& path) | 95 DeviceInfo(const XIDeviceInfo& device, const base::FilePath& path) |
93 : id(device.deviceid), | 96 : id(device.deviceid), |
94 name(device.name), | 97 name(device.name), |
95 use(device.use), | 98 use(device.use), |
96 enabled(device.enabled), | 99 enabled(device.enabled), |
97 path(path) { | 100 path(path) { |
98 for (int i = 0; i < device.num_classes; ++i) { | 101 for (int i = 0; i < device.num_classes; ++i) { |
99 switch (device.classes[i]->type) { | 102 switch (device.classes[i]->type) { |
100 case XIValuatorClass: | 103 case XIValuatorClass: |
101 valuator_class_infos.push_back(ValuatorClassInfo( | 104 valuator_class_infos.push_back(ValuatorClassInfo( |
102 *reinterpret_cast<XIValuatorClassInfo*>(device.classes[i]))); | 105 *reinterpret_cast<XIValuatorClassInfo*>(device.classes[i]))); |
103 break; | 106 break; |
104 case XITouchClass: | 107 case XITouchClass: |
105 touch_class_infos.push_back(TouchClassInfo( | 108 // A device can have at most one XITouchClassInfo. Ref: |
106 *reinterpret_cast<XITouchClassInfo*>(device.classes[i]))); | 109 // http://manpages.ubuntu.com/manpages/saucy/man3/XIQueryDevice.3.html |
| 110 DCHECK(!touch_class_info.mode); |
| 111 touch_class_info = TouchClassInfo( |
| 112 *reinterpret_cast<XITouchClassInfo*>(device.classes[i])); |
107 break; | 113 break; |
108 default: | 114 default: |
109 break; | 115 break; |
110 } | 116 } |
111 } | 117 } |
112 } | 118 } |
113 | 119 |
114 // Unique device identifier. | 120 // Unique device identifier. |
115 int id; | 121 int id; |
116 | 122 |
117 // Internal device name. | 123 // Internal device name. |
118 std::string name; | 124 std::string name; |
119 | 125 |
120 // Device type (ie: XIMasterPointer) | 126 // Device type (ie: XIMasterPointer) |
121 int use; | 127 int use; |
122 | 128 |
123 // Specifies if the device is enabled and can send events. | 129 // Specifies if the device is enabled and can send events. |
124 bool enabled; | 130 bool enabled; |
125 | 131 |
126 // Path to the actual device (ie: /dev/input/eventXX) | 132 // Path to the actual device (ie: /dev/input/eventXX) |
127 base::FilePath path; | 133 base::FilePath path; |
128 | 134 |
129 std::vector<ValuatorClassInfo> valuator_class_infos; | 135 std::vector<ValuatorClassInfo> valuator_class_infos; |
130 | 136 |
131 std::vector<TouchClassInfo> touch_class_infos; | 137 TouchClassInfo touch_class_info; |
132 }; | 138 }; |
133 | 139 |
134 // X11 display cache used on worker threads. This is filled on the UI thread and | 140 // X11 display cache used on worker threads. This is filled on the UI thread and |
135 // passed in to the worker threads. | 141 // passed in to the worker threads. |
136 struct DisplayState { | 142 struct DisplayState { |
137 Atom mt_position_x; | 143 Atom mt_position_x; |
138 Atom mt_position_y; | 144 Atom mt_position_y; |
139 }; | 145 }; |
140 | 146 |
141 // Returns true if |name| is the name of a known invalid keyboard device. Note, | 147 // Returns true if |name| is the name of a known invalid keyboard device. Note, |
(...skipping 121 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
263 } | 269 } |
264 } else if (display_state.mt_position_y == valuator.label) { | 270 } else if (display_state.mt_position_y == valuator.label) { |
265 // Ignore Y axis valuator with unexpected properties | 271 // Ignore Y axis valuator with unexpected properties |
266 if (valuator.number == 1 && valuator.mode == Absolute && | 272 if (valuator.number == 1 && valuator.mode == Absolute && |
267 valuator.min == 0.0) { | 273 valuator.min == 0.0) { |
268 max_y = valuator.max; | 274 max_y = valuator.max; |
269 } | 275 } |
270 } | 276 } |
271 } | 277 } |
272 | 278 |
273 for (const TouchClassInfo& info : device_info.touch_class_infos) { | 279 if (device_info.touch_class_info.mode) |
274 is_direct_touch = info.mode == XIDirectTouch; | 280 is_direct_touch = device_info.touch_class_info.mode == XIDirectTouch; |
275 } | |
276 | 281 |
277 // Touchscreens should have absolute X and Y axes, and be direct touch | 282 // Touchscreens should have absolute X and Y axes, and be direct touch |
278 // devices. | 283 // devices. |
279 if (max_x > 0.0 && max_y > 0.0 && is_direct_touch) { | 284 if (max_x > 0.0 && max_y > 0.0 && is_direct_touch) { |
280 InputDeviceType type = GetInputDeviceTypeFromPath(device_info.path); | 285 InputDeviceType type = GetInputDeviceTypeFromPath(device_info.path); |
281 // |max_x| and |max_y| are inclusive values, so we need to add 1 to get | 286 // |max_x| and |max_y| are inclusive values, so we need to add 1 to get |
282 // the size. | 287 // the size. |
283 devices.push_back(TouchscreenDevice( | 288 devices.push_back( |
284 device_info.id, | 289 TouchscreenDevice(device_info.id, type, device_info.name, |
285 type, | 290 gfx::Size(max_x + 1, max_y + 1), |
286 device_info.name, | 291 device_info.touch_class_info.num_touches)); |
287 gfx::Size(max_x + 1, max_y + 1))); | |
288 } | 292 } |
289 } | 293 } |
290 | 294 |
291 reply_runner->PostTask(FROM_HERE, base::Bind(callback, devices)); | 295 reply_runner->PostTask(FROM_HERE, base::Bind(callback, devices)); |
292 } | 296 } |
293 | 297 |
294 // Called on a worker thread to parse the device information. | 298 // Called on a worker thread to parse the device information. |
295 void HandleHotplugEventInWorker( | 299 void HandleHotplugEventInWorker( |
296 const std::vector<DeviceInfo>& devices, | 300 const std::vector<DeviceInfo>& devices, |
297 const DisplayState& display_state, | 301 const DisplayState& display_state, |
(...skipping 52 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
350 base::WorkerPool::PostTask(FROM_HERE, | 354 base::WorkerPool::PostTask(FROM_HERE, |
351 base::Bind(&HandleHotplugEventInWorker, | 355 base::Bind(&HandleHotplugEventInWorker, |
352 device_infos, | 356 device_infos, |
353 display_state, | 357 display_state, |
354 base::ThreadTaskRunnerHandle::Get(), | 358 base::ThreadTaskRunnerHandle::Get(), |
355 callbacks), | 359 callbacks), |
356 true /* task_is_slow */); | 360 true /* task_is_slow */); |
357 } | 361 } |
358 | 362 |
359 } // namespace ui | 363 } // namespace ui |
OLD | NEW |