diff options
author | keybuk@chromium.org <keybuk@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2012-05-04 01:47:46 +0000 |
---|---|---|
committer | keybuk@chromium.org <keybuk@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2012-05-04 01:47:46 +0000 |
commit | c174c8ff44d61901b3b80d37e90d29644bed0f75 (patch) | |
tree | d29c8318d6747960a62f35bc41cf22861eb77e62 /content/browser | |
parent | 8074478740c4e8a274fb0b1ae7f868c94141d1c1 (diff) | |
download | chromium_src-c174c8ff44d61901b3b80d37e90d29644bed0f75.zip chromium_src-c174c8ff44d61901b3b80d37e90d29644bed0f75.tar.gz chromium_src-c174c8ff44d61901b3b80d37e90d29644bed0f75.tar.bz2 |
gamepad: linux: use input device parent, not USB
The input device parent of a joystick device already has the vendor and
product id as well as a name attribute that combines the manufacturer
and product name, use this instead of the USB device parent giving us
support for non-USB (i.e. Bluetooth) gamepads.
BUG=chromium-os:30273
TEST=PS3 controller shows up with correct mappings when connected via Bluetooth.
Change-Id: Ifa9ed24a4c9b9a5b2c98aad862fc77a520233e0d
R=scottmg@chromium.org
Review URL: http://codereview.chromium.org/10346009
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@135272 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'content/browser')
-rw-r--r-- | content/browser/gamepad/platform_data_fetcher_linux.cc | 69 |
1 files changed, 49 insertions, 20 deletions
diff --git a/content/browser/gamepad/platform_data_fetcher_linux.cc b/content/browser/gamepad/platform_data_fetcher_linux.cc index 649f211..e322a4b 100644 --- a/content/browser/gamepad/platform_data_fetcher_linux.cc +++ b/content/browser/gamepad/platform_data_fetcher_linux.cc @@ -23,6 +23,8 @@ namespace { const char kInputSubsystem[] = "input"; +const char kUsbSubsystem[] = "usb"; +const char kUsbDeviceType[] = "usb_device"; const float kMaxLinuxAxisValue = 32767.0; void CloseFileDescriptorIfValid(int fd) { @@ -146,14 +148,14 @@ void GamepadPlatformDataFetcherLinux::RefreshDevice(udev_device* dev) { CloseFileDescriptorIfValid(device_fd); - // The device pointed to by dev contains information about the input - // device. In order to get the information about the USB device, get the - // parent device with the subsystem/devtype pair of "usb"/"usb_device". - // This function walks up the tree several levels. + // The device pointed to by dev contains information about the logical + // joystick device. In order to get the information about the physical + // hardware, get the parent device that is also in the "input" subsystem. + // This function should just walk up the tree one level. dev = udev_device_get_parent_with_subsystem_devtype( dev, - "usb", - "usb_device"); + kInputSubsystem, + NULL); if (!dev) { // Unable to get device information, don't use this device. device_fd = -1; @@ -168,22 +170,49 @@ void GamepadPlatformDataFetcherLinux::RefreshDevice(udev_device* dev) { return; } - const char* vendor_id = udev_device_get_sysattr_value(dev, "idVendor"); - const char* product_id = udev_device_get_sysattr_value(dev, "idProduct"); + const char* vendor_id = udev_device_get_sysattr_value(dev, "id/vendor"); + const char* product_id = udev_device_get_sysattr_value(dev, "id/product"); mapper = GetGamepadStandardMappingFunction(vendor_id, product_id); - const char* manufacturer = - udev_device_get_sysattr_value(dev, "manufacturer"); - const char* product = udev_device_get_sysattr_value(dev, "product"); - - // Driver returns utf-8 strings here, so combine in utf-8 and then convert - // to WebUChar to build the id string. - std::string id = base::StringPrintf("%s %s (%sVendor: %s Product: %s)", - manufacturer, - product, - mapper ? "STANDARD GAMEPAD " : "", - vendor_id, - product_id); + // Driver returns utf-8 strings here, so combine in utf-8 first and + // convert to WebUChar later once we've picked an id string. + const char* name = udev_device_get_sysattr_value(dev, "name"); + std::string name_string = base::StringPrintf("%s", name); + + // In many cases the information the input subsystem contains isn't + // as good as the information that the device bus has, walk up further + // to the subsystem/device type "usb"/"usb_device" and if this device + // has the same vendor/product id, prefer the description from that. + struct udev_device *usb_dev = udev_device_get_parent_with_subsystem_devtype( + dev, + kUsbSubsystem, + kUsbDeviceType); + if (usb_dev) { + const char* usb_vendor_id = + udev_device_get_sysattr_value(usb_dev, "idVendor"); + const char* usb_product_id = + udev_device_get_sysattr_value(usb_dev, "idProduct"); + + if (strcmp(vendor_id, usb_vendor_id) == 0 && + strcmp(product_id, usb_product_id) == 0) { + const char* manufacturer = + udev_device_get_sysattr_value(usb_dev, "manufacturer"); + const char* product = udev_device_get_sysattr_value(usb_dev, "product"); + + // Replace the previous name string with one containing the better + // information, again driver returns utf-8 strings here so combine + // in utf-8 for conversion to WebUChar below. + name_string = base::StringPrintf("%s %s", manufacturer, product); + } + } + + // Append the vendor and product information then convert the utf-8 + // id string to WebUChar. + std::string id = name_string + base::StringPrintf( + " (%sVendor: %s Product: %s)", + mapper ? "STANDARD GAMEPAD " : "", + vendor_id, + product_id); TruncateUTF8ToByteSize(id, WebGamepad::idLengthCap - 1, &id); string16 tmp16 = UTF8ToUTF16(id); memset(pad.id, 0, sizeof(pad.id)); |