[PATCH] Fix udev population of Bluetooth input device product IDs

Peter Hutterer peter.hutterer at who-t.net
Mon Aug 30 17:07:14 PDT 2010


On Mon, Aug 30, 2010 at 05:59:30PM -0400, Chase Douglas wrote:
> From: Chase Douglas <chase.douglas at ubuntu.com>
> 
> The udev device_added function takes the vendor and model IDs of added
> devices and converts them into an attribute that can be matched for by
> an InputClass configuration using MatchUSBID. Currently, the udev
> mechanism works for USB devices, but fails to work properly for
> Bluetooth devices. The product IDs of the event node are actually the
> IDs of the Bluetooth receiver instead of the device.
> 
> This patch reads the product ID from the PRODUCT property of the parent
> of the added device. This tag is set correctly for both USB and
> Bluetooth input devices. The following devices have been tested by
> specifying individual InputClass sections in xorg.conf:
> 
> * Apple Keyboard (Bluetooth)
> * Apple Magic Trackpad (Bluetooth)
> * Apple Magic Mouse (Bluetooth)
> * Microsoft Bluetooth Notebook Mouse 5000 (Bluetooth)
> * Microsoft IntelliMouse Optical (USB)
> * N-Trig Touchscreen (USB)
> * Wacom Bamboo Touch (USB)
> 
> Signed-off-by: Chase Douglas <chase.douglas at canonical.com>
> ---
>  config/udev.c |   49 ++++++++++++++++++++++++++++++++-----------------
>  1 files changed, 32 insertions(+), 17 deletions(-)
> 
> diff --git a/config/udev.c b/config/udev.c
> index 9934490..008cfc4 100644
> --- a/config/udev.c
> +++ b/config/udev.c
> @@ -51,6 +51,32 @@
>  
>  static struct udev_monitor *udev_monitor;
>  
> +static char *parse_usb_id(const char *product)
> +{
> +    const char *cur;
> +    char *next;
> +    int usb_vendor, usb_model;
> +
> +    if (!product)
> +        return NULL;
> +
> +    cur = strchr(product, '/');
> +    if (!cur)
> +        return NULL;
> +
> +    usb_vendor = strtoul(cur + 1, &next, 16);
> +    if (!next || next == cur + 1 || usb_vendor > 0xffff)
> +        return NULL;
> +
> +    cur = next;
> +    usb_model = strtoul(cur + 1, &next, 16);
> +    if (!next || next == cur + 1 || usb_model > 0xffff)
> +        return NULL;

same comment as in last patch, any particular reason you don't use sscanf?
rest looks good though.

Cheers,
  Peter

> +
> +    /* construct USB ID in lowercase hex - "0000:ffff" */
> +    return Xprintf("%04x:%04x", usb_vendor, usb_model);
> +}
> +
>  static void
>  device_added(struct udev_device *udev_device)
>  {
> @@ -58,7 +84,6 @@ device_added(struct udev_device *udev_device)
>      char *config_info = NULL;
>      const char *syspath;
>      const char *tags_prop;
> -    const char *usb_vendor = NULL, *usb_model = NULL;
>      const char *key, *value, *tmp;
>      InputOption *options = NULL, *tmpo;
>      InputAttributes attrs = {};
> @@ -94,6 +119,7 @@ device_added(struct udev_device *udev_device)
>      parent = udev_device_get_parent(udev_device);
>      if (parent) {
>          const char *ppath = udev_device_get_devnode(parent);
> +        const char *product = udev_device_get_property_value(parent, "PRODUCT");
>  
>          name = udev_device_get_sysattr_value(parent, "name");
>          LOG_SYSATTR(ppath, "name", name);
> @@ -104,7 +130,12 @@ device_added(struct udev_device *udev_device)
>  
>          attrs.pnp_id = udev_device_get_sysattr_value(parent, "id");
>          LOG_SYSATTR(ppath, "id", attrs.pnp_id);
> +
> +        attrs.usb_id = parse_usb_id(product);
> +        if (attrs.usb_id)
> +            LOG_PROPERTY(path, "PRODUCT", product);
>      }
> +
>      if (!name)
>          name = "(unnamed)";
>      else
> @@ -152,12 +183,6 @@ device_added(struct udev_device *udev_device)
>          } else if (!strcmp(key, "ID_VENDOR")) {
>              LOG_PROPERTY(path, key, value);
>              attrs.vendor = value;
> -        } else if (!strcmp(key, "ID_VENDOR_ID")) {
> -            LOG_PROPERTY(path, key, value);
> -            usb_vendor = value;
> -        } else if (!strcmp(key, "ID_VENDOR_MODEL")) {
> -            LOG_PROPERTY(path, key, value);
> -            usb_model = value;
>          } else if (!strcmp(key, "ID_INPUT_KEY")) {
>              LOG_PROPERTY(path, key, value);
>              attrs.flags |= ATTR_KEYBOARD;
> @@ -179,16 +204,6 @@ device_added(struct udev_device *udev_device)
>          }
>      }
>  
> -    /* construct USB ID in lowercase hex - "0000:ffff" */
> -    if (usb_vendor && usb_model) {
> -        attrs.usb_id = Xprintf("%s:%s", usb_vendor, usb_model);
> -        if (attrs.usb_id) {
> -            char *cur;
> -            for (cur = attrs.usb_id; *cur; cur++)
> -                *cur = tolower(*cur);
> -        }
> -    }
> -
>      LogMessage(X_INFO, "config/udev: Adding input device %s (%s)\n",
>                 name, path);
>      rc = NewInputDeviceRequest(options, &attrs, &dev);
> -- 
> 1.7.1
> 


More information about the xorg-devel mailing list