[Spice-devel] [PATCH spice-gtk 3/7] usbutil: Add support for getting strings from usb.ids

Marc-André Lureau marcandre.lureau at gmail.com
Sun Feb 19 06:09:44 PST 2012


ack

On Sun, Feb 19, 2012 at 12:50 AM, Hans de Goede <hdegoede at redhat.com> wrote:
> Unfortunately not all device makers go to the "trouble" of adding device
> identification strings to a device's descriptors. This patch makes spice-gtk
> translate vid/pid into strings if the device lacks the strings.
>
> Signed-off-by: Hans de Goede <hdegoede at redhat.com>
> ---
>  configure.ac    |   21 ++++++++
>  gtk/Makefile.am |    1 +
>  gtk/usbutil.c   |  150 +++++++++++++++++++++++++++++++++++++++++++++++++++++++
>  3 files changed, 172 insertions(+), 0 deletions(-)
>
> diff --git a/configure.ac b/configure.ac
> index d8602fd..d2ac883 100644
> --- a/configure.ac
> +++ b/configure.ac
> @@ -426,6 +426,27 @@ AC_ARG_WITH([usb-acl-helper-dir],
>   [ACL_HELPER_DIR="${bindir}/"])
>  AC_SUBST([ACL_HELPER_DIR])
>
> +AC_ARG_WITH([usb-ids-path],
> +  AC_HELP_STRING([--with-usb-ids-path],
> +                 [Specify the path to usb.ids @<:@default=auto@:>@]),
> +  [USB_IDS="$with_usb_ids_path"],
> +  [USB_IDS="auto"])
> +AC_MSG_CHECKING([for usb.ids])
> +if test "x$USB_IDS" = "xauto"; then
> +  if test -n "$PKG_CONFIG"; then
> +    USB_IDS=$($PKG_CONFIG --variable=usbids usbutils)
> +  else
> +    USB_IDS=
> +  fi
> +fi
> +if test -n "$USB_IDS"; then
> +  AC_MSG_RESULT([$USB_IDS])
> +  AC_SUBST(USB_IDS)
> +  AC_DEFINE(WITH_USBIDS, [1], [Define if compiling with usb.ids support])
> +else
> +  AC_MSG_RESULT([not found])
> +fi
> +
>  AC_ARG_WITH([coroutine],
>   AS_HELP_STRING([--with-coroutine=@<:@ucontext/gthread/winfiber/auto@:>@],
>                  [use ucontext or GThread for coroutines @<:@default=auto@:>@]),
> diff --git a/gtk/Makefile.am b/gtk/Makefile.am
> index 2ad4494..fd2e477 100644
> --- a/gtk/Makefile.am
> +++ b/gtk/Makefile.am
> @@ -60,6 +60,7 @@ SPICE_COMMON_CPPFLAGS = \
>        -DSW_CANVAS_CACHE               \
>        -DSPICE_GTK_LOCALEDIR=\"${SPICE_GTK_LOCALEDIR}\" \
>        -DPNP_IDS=\""$(PNP_IDS)"\"\
> +       -DUSB_IDS=\""$(USB_IDS)"\"\
>        \
>        -I$(COMMON_DIR)                 \
>        -I$(CLIENT_DIR)                 \
> diff --git a/gtk/usbutil.c b/gtk/usbutil.c
> index 0d1361e..704f973 100644
> --- a/gtk/usbutil.c
> +++ b/gtk/usbutil.c
> @@ -23,6 +23,8 @@
>
>  #include <glib-object.h>
>  #include <glib/gi18n.h>
> +#include <ctype.h>
> +#include <stdlib.h>
>
>  #include "glib-compat.h"
>
> @@ -35,6 +37,27 @@
>  #endif
>  #include "usbutil.h"
>
> +#ifdef WITH_USBIDS
> +#define VENDOR_NAME_LEN (122 - sizeof(void *))
> +#define PRODUCT_NAME_LEN 126
> +
> +typedef struct _usb_product_info {
> +    guint16 product_id;
> +    char name[PRODUCT_NAME_LEN];
> +} usb_product_info;
> +
> +typedef struct _usb_vendor_info {
> +    usb_product_info *product_info;
> +    int product_count;
> +    guint16 vendor_id;
> +    char name[VENDOR_NAME_LEN];
> +} usb_vendor_info;
> +
> +GStaticMutex usbids_parse_mutex = G_STATIC_MUTEX_INIT;
> +int usbids_vendor_count;
> +usb_vendor_info *usbids_vendor_info;
> +#endif
> +
>  G_GNUC_INTERNAL
>  const char *spice_usbutil_libusb_strerror(enum libusb_error error_code)
>  {
> @@ -98,11 +121,112 @@ static gchar *spice_usbutil_get_sysfs_attribute(int bus, int address,
>  }
>  #endif
>
> +#ifdef WITH_USBIDS
> +static void spice_usbutil_parse_usbids(void)
> +{
> +    gchar *contents, *line, **lines;
> +    usb_product_info *product_info;
> +    int i, j, id, product_count = 0;
> +
> +    g_static_mutex_lock(&usbids_parse_mutex);
> +    if (usbids_vendor_count)
> +        goto leave;
> +
> +    if (!g_file_get_contents(USB_IDS, &contents, NULL, NULL)) {
> +        usbids_vendor_count = -1;
> +        goto leave;
> +    }
> +    lines = g_strsplit(contents, "\n", -1);
> +
> +    for (i = 0; lines[i]; i++) {
> +        if (!isxdigit(lines[i][0]) || !isxdigit(lines[i][1]))
> +            continue;
> +
> +        for (j = 1; lines[i + j] &&
> +                   (lines[i + j][0] == '\t' ||
> +                    lines[i + j][0] == '#'  ||
> +                    lines[i + j][0] == '\0'); j++) {
> +            if (lines[i + j][0] == '\t' && isxdigit(lines[i + j][1]))
> +                product_count++;
> +        }
> +        i += j - 1;
> +
> +        usbids_vendor_count++;
> +    }
> +
> +    usbids_vendor_info = g_new(usb_vendor_info, usbids_vendor_count);
> +    product_info = g_new(usb_product_info, product_count);
> +
> +    usbids_vendor_count = 0;
> +    for (i = 0; lines[i]; i++) {
> +        line = lines[i];
> +
> +        if (!isxdigit(line[0]) || !isxdigit(line[1]))
> +            continue;
> +
> +        id = strtoul(line, &line, 16);
> +        while(isspace(line[0]))
> +            line++;
> +        usbids_vendor_info[usbids_vendor_count].vendor_id = id;
> +        snprintf(usbids_vendor_info[usbids_vendor_count].name,
> +                 VENDOR_NAME_LEN, "%s", line);
> +
> +        product_count = 0;
> +        for (j = 1; lines[i + j] &&
> +                   (lines[i + j][0] == '\t' ||
> +                    lines[i + j][0] == '#'  ||
> +                    lines[i + j][0] == '\0'); j++) {
> +            line = lines[i + j];
> +
> +            if (line[0] != '\t' || !isxdigit(line[1]))
> +                continue;
> +
> +            id = strtoul(line + 1, &line, 16);
> +            while(isspace(line[0]))
> +                line++;
> +            product_info[product_count].product_id = id;
> +            snprintf(product_info[product_count].name,
> +                     PRODUCT_NAME_LEN, "%s", line);
> +
> +            product_count++;
> +        }
> +        i += j - 1;
> +
> +        usbids_vendor_info[usbids_vendor_count].product_count = product_count;
> +        usbids_vendor_info[usbids_vendor_count].product_info  = product_info;
> +        product_info += product_count;
> +        usbids_vendor_count++;
> +    }
> +
> +    g_strfreev(lines);
> +    g_free(contents);
> +
> +#if 0 /* Testing only */
> +    for (i = 0; i < usbids_vendor_count; i++) {
> +        printf("%04x  %s\n", usbids_vendor_info[i].vendor_id,
> +               usbids_vendor_info[i].name);
> +        product_info = usbids_vendor_info[i].product_info;
> +        for (j = 0; j < usbids_vendor_info[i].product_count; j++) {
> +            printf("\t%04x  %s\n", product_info[j].product_id,
> +                   product_info[j].name);
> +        }
> +    }
> +#endif
> +leave:
> +    g_static_mutex_unlock(&usbids_parse_mutex);
> +}
> +#endif
> +
>  G_GNUC_INTERNAL
>  void spice_usb_util_get_device_strings(int bus, int address,
>                                        int vendor_id, int product_id,
>                                        gchar **manufacturer, gchar **product)
>  {
> +#ifdef WITH_USBIDS
> +    usb_product_info *product_info;
> +    int i, j;
> +#endif
> +
>     g_return_if_fail(manufacturer != NULL);
>     g_return_if_fail(product != NULL);
>
> @@ -113,6 +237,32 @@ void spice_usb_util_get_device_strings(int bus, int address,
>     *manufacturer = spice_usbutil_get_sysfs_attribute(bus, address, "manufacturer");
>     *product = spice_usbutil_get_sysfs_attribute(bus, address, "product");
>  #endif
> +
> +#ifdef WITH_USBIDS
> +    if (!*manufacturer || !*product) {
> +        spice_usbutil_parse_usbids();
> +
> +        for (i = 0; i < usbids_vendor_count; i++) {
> +            if ((int)usbids_vendor_info[i].vendor_id != vendor_id)
> +                continue;
> +
> +            if (!*manufacturer && usbids_vendor_info[i].name[0])
> +                *manufacturer = g_strdup(usbids_vendor_info[i].name);
> +
> +            product_info = usbids_vendor_info[i].product_info;
> +            for (j = 0; j < usbids_vendor_info[i].product_count; j++) {
> +                if ((int)product_info[j].product_id != product_id)
> +                    continue;
> +
> +                if (!*product && product_info[j].name[0])
> +                    *product = g_strdup(product_info[j].name);
> +
> +                break;
> +            }
> +            break;
> +        }
> +    }
> +#endif
>     if (!*manufacturer)
>         *manufacturer = g_strdup(_("USB"));
>     if (!*product)
> --
> 1.7.7.5
>
> _______________________________________________
> Spice-devel mailing list
> Spice-devel at lists.freedesktop.org
> http://lists.freedesktop.org/mailman/listinfo/spice-devel



-- 
Marc-André Lureau


More information about the Spice-devel mailing list