Chromium Code Reviews| Index: ui/events/platform/x11/x11_hotplug_event_handler.cc |
| diff --git a/ui/events/platform/x11/x11_hotplug_event_handler.cc b/ui/events/platform/x11/x11_hotplug_event_handler.cc |
| index 5e69c23041eb9ed6133ed4ce29958cbed5b8d1f0..44d723915020bbd341d9883051a138b8e0878a79 100644 |
| --- a/ui/events/platform/x11/x11_hotplug_event_handler.cc |
| +++ b/ui/events/platform/x11/x11_hotplug_event_handler.cc |
| @@ -32,6 +32,10 @@ |
| #include "ui/events/devices/touchscreen_device.h" |
| #include "ui/gfx/x/x11_types.h" |
| +#ifndef XI_PROP_PRODUCT_ID |
| +#define XI_PROP_PRODUCT_ID "Device Product ID" |
| +#endif |
| + |
| namespace ui { |
| namespace { |
| @@ -113,9 +117,13 @@ struct TouchClassInfo { |
| struct DeviceInfo { |
| DeviceInfo(const XIDeviceInfo& device, |
| DeviceType type, |
| - const base::FilePath& path) |
| + const base::FilePath& path, |
| + uint16_t vendor, |
| + uint16_t product) |
| : id(device.deviceid), |
| name(device.name), |
| + vendor_id(vendor), |
| + product_id(product), |
| use(device.use), |
| type(type), |
| path(path) { |
| @@ -144,6 +152,10 @@ struct DeviceInfo { |
| // Internal device name. |
| std::string name; |
| + // USB-style device identifiers. |
| + uint16_t vendor_id; |
| + uint16_t product_id; |
| + |
| // Device type (ie: XIMasterPointer) |
| int use; |
| @@ -246,7 +258,8 @@ void HandleKeyboardDevicesInWorker( |
| if (IsKnownInvalidKeyboardDevice(device_info.name)) |
| continue; // Skip invalid devices. |
| InputDeviceType type = GetInputDeviceTypeFromPath(device_info.path); |
| - devices.push_back(KeyboardDevice(device_info.id, type)); |
| + KeyboardDevice keyboard(device_info.id, type, device_info.name); |
| + devices.push_back(keyboard); |
| } |
| reply_runner->PostTask(FROM_HERE, base::Bind(callback, devices)); |
| @@ -265,7 +278,7 @@ void HandleMouseDevicesInWorker(const std::vector<DeviceInfo>& device_infos, |
| } |
| InputDeviceType type = GetInputDeviceTypeFromPath(device_info.path); |
| - devices.push_back(InputDevice(device_info.id, type)); |
| + devices.push_back(InputDevice(device_info.id, type, device_info.name)); |
| } |
| reply_runner->PostTask(FROM_HERE, base::Bind(callback, devices)); |
| @@ -284,7 +297,7 @@ void HandleTouchpadDevicesInWorker(const std::vector<DeviceInfo>& device_infos, |
| } |
| InputDeviceType type = GetInputDeviceTypeFromPath(device_info.path); |
| - devices.push_back(InputDevice(device_info.id, type)); |
| + devices.push_back(InputDevice(device_info.id, type, device_info.name)); |
| } |
| reply_runner->PostTask(FROM_HERE, base::Bind(callback, devices)); |
| @@ -337,9 +350,10 @@ void HandleTouchscreenDevicesInWorker( |
| InputDeviceType type = GetInputDeviceTypeFromPath(device_info.path); |
| // |max_x| and |max_y| are inclusive values, so we need to add 1 to get |
| // the size. |
| - devices.push_back(TouchscreenDevice( |
| - device_info.id, type, gfx::Size(max_x + 1, max_y + 1), |
| - device_info.touch_class_info.num_touches)); |
| + devices.push_back( |
| + TouchscreenDevice(device_info.id, type, device_info.name, |
| + gfx::Size(max_x + 1, max_y + 1), |
| + device_info.touch_class_info.num_touches)); |
| } |
| } |
| @@ -428,8 +442,29 @@ void X11HotplugEventHandler::OnHotplugEvent() { |
| (device.deviceid >= 0 && device.deviceid < kMaxDeviceNum) |
| ? device_types[device.deviceid] |
| : DEVICE_TYPE_OTHER; |
| - device_infos.push_back( |
| - DeviceInfo(device, device_type, GetDevicePath(display, device))); |
| + |
| + // Obtain the USB-style vendor and product identifiers. |
| + // (On Linux, XI2 makes this available for all evdev devices. |
| + Atom product_id_atom = |
| + XInternAtom(gfx::GetXDisplay(), XI_PROP_PRODUCT_ID, 1); |
|
sadrul
2015/04/09 20:44:29
Use atom_cache_ instead.
kpschoedel
2015/04/09 21:22:14
Done.
|
| + uint32_t* product_info; |
| + Atom type; |
| + int format_return; |
| + unsigned long num_items_return; |
| + unsigned long bytes_after_return; |
| + uint16_t vendor = 0; |
| + uint16_t product = 0; |
| + if (XIGetProperty(gfx::GetXDisplay(), device.deviceid, product_id_atom, 0, |
| + 2, 0, XA_INTEGER, &type, &format_return, |
| + &num_items_return, &bytes_after_return, |
| + reinterpret_cast<unsigned char**>(&product_info)) == 0 && |
| + product_info) { |
| + vendor = product_info[0]; |
| + product = product_info[1]; |
| + } |
|
sadrul
2015/04/09 20:44:29
Whoops. I think |product_info| is leaking. XFree
kpschoedel
2015/04/09 21:22:15
Done. (It used to leak in EventRewriter, too.)
|
| + |
| + device_infos.push_back(DeviceInfo( |
| + device, device_type, GetDevicePath(display, device), vendor, product)); |
| } |
| // X11 is not thread safe, so first get all the required state. |
| @@ -446,13 +481,11 @@ void X11HotplugEventHandler::OnHotplugEvent() { |
| // Parsing the device information may block, so delegate the operation to a |
| // worker thread. Once the device information is extracted the parsed devices |
| // will be returned via the callbacks. |
| - base::WorkerPool::PostTask(FROM_HERE, |
| - base::Bind(&HandleHotplugEventInWorker, |
| - device_infos, |
| - display_state, |
| - base::ThreadTaskRunnerHandle::Get(), |
| - callbacks), |
| - true /* task_is_slow */); |
| + base::WorkerPool::PostTask( |
| + FROM_HERE, |
| + base::Bind(&HandleHotplugEventInWorker, device_infos, display_state, |
| + base::ThreadTaskRunnerHandle::Get(), callbacks), |
| + true /* task_is_slow */); |
| } |
| } // namespace ui |