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..9d5a77b044f9d56746682984bb862db9384fda97 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 { |
@@ -52,6 +56,7 @@ const char* kCachedAtomList[] = { |
XI_MOUSE, |
XI_TOUCHPAD, |
XI_TOUCHSCREEN, |
+ XI_PROP_PRODUCT_ID, |
NULL, |
}; |
@@ -113,9 +118,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 +153,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 +259,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 +279,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 +298,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 +351,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 +443,31 @@ 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. |
+ 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, |
+ atom_cache_.GetAtom(XI_PROP_PRODUCT_ID), 0, 2, 0, |
+ XA_INTEGER, &type, &format_return, &num_items_return, |
+ &bytes_after_return, |
+ reinterpret_cast<unsigned char**>(&product_info)) == 0 && |
+ product_info) { |
+ if (num_items_return == 2) { |
+ vendor = product_info[0]; |
+ product = product_info[1]; |
+ } |
+ XFree(product_info); |
+ } |
+ |
+ 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 +484,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 |