NetBSD: improved joystick support (thanks, Thomas!).
authorRyan C. Gordon <icculus@icculus.org>
Tue, 29 Dec 2015 02:29:56 -0500
changeset 9986081fbd89a347
parent 9985 091503bd5054
child 9987 d64783aac765
NetBSD: improved joystick support (thanks, Thomas!).

This patch skips non-joystick HID devices and gives joysticks on NetBSD
a human readable name.

Fixes Bugzilla #3178.
src/joystick/bsd/SDL_sysjoystick.c
     1.1 --- a/src/joystick/bsd/SDL_sysjoystick.c	Tue Dec 29 02:27:02 2015 -0500
     1.2 +++ b/src/joystick/bsd/SDL_sysjoystick.c	Tue Dec 29 02:29:56 2015 -0500
     1.3 @@ -76,7 +76,7 @@
     1.4  #include "../SDL_sysjoystick.h"
     1.5  #include "../SDL_joystick_c.h"
     1.6  
     1.7 -#define MAX_UHID_JOYS   16
     1.8 +#define MAX_UHID_JOYS   64
     1.9  #define MAX_JOY_JOYS    2
    1.10  #define MAX_JOYS    (MAX_UHID_JOYS + MAX_JOY_JOYS)
    1.11  
    1.12 @@ -286,7 +286,7 @@
    1.13      struct joystick_hwdata *hw;
    1.14      struct hid_item hitem;
    1.15      struct hid_data *hdata;
    1.16 -    struct report *rep;
    1.17 +    struct report *rep = NULL;
    1.18      int fd;
    1.19      int i;
    1.20  
    1.21 @@ -337,6 +337,38 @@
    1.22  #endif
    1.23          rep->rid = -1;          /* XXX */
    1.24      }
    1.25 +#if defined(__NetBSD__)
    1.26 +    usb_device_descriptor_t udd;
    1.27 +    struct usb_string_desc usd;
    1.28 +    if (ioctl(fd, USB_GET_DEVICE_DESC, &udd) == -1)
    1.29 +        goto desc_failed;
    1.30 +
    1.31 +    /* Get default language */
    1.32 +    usd.usd_string_index = USB_LANGUAGE_TABLE;
    1.33 +    usd.usd_language_id = 0;
    1.34 +    if (ioctl(fd, USB_GET_STRING_DESC, &usd) == -1 || usd.usd_desc.bLength < 4) {
    1.35 +        usd.usd_language_id = 0;
    1.36 +    } else {
    1.37 +        usd.usd_language_id = UGETW(usd.usd_desc.bString[0]);
    1.38 +    }
    1.39 +
    1.40 +    usd.usd_string_index = udd.iProduct;
    1.41 +    if (ioctl(fd, USB_GET_STRING_DESC, &usd) == 0) {
    1.42 +        char str[128];
    1.43 +        char *new_name = NULL;
    1.44 +        int i;
    1.45 +        for (i = 0; i < (usd.usd_desc.bLength >> 1) - 1 && i < sizeof(str) - 1; i++) {
    1.46 +            str[i] = UGETW(usd.usd_desc.bString[i]);
    1.47 +        }
    1.48 +        str[i] = '\0';
    1.49 +        asprintf(&new_name, "%s @ %s", str, path);
    1.50 +        if (new_name != NULL) {
    1.51 +            free(joydevnames[SDL_SYS_numjoysticks]);
    1.52 +            joydevnames[SDL_SYS_numjoysticks] = new_name;
    1.53 +        }
    1.54 +    }
    1.55 +desc_failed:
    1.56 +#endif
    1.57      if (report_alloc(rep, hw->repdesc, REPORT_INPUT) < 0) {
    1.58          goto usberr;
    1.59      }
    1.60 @@ -409,9 +441,21 @@
    1.61          if (hw->axis_map[i] > 0)
    1.62              hw->axis_map[i] = joy->naxes++;
    1.63  
    1.64 +    if (joy->naxes == 0 && joy->nbuttons == 0 && joy->nhats == 0 && joy->nballs == 0) {
    1.65 +        SDL_SetError("%s: Not a joystick, ignoring", hw->path);
    1.66 +        goto usberr;
    1.67 +    }
    1.68 +
    1.69    usbend:
    1.70      /* The poll blocks the event thread. */
    1.71      fcntl(fd, F_SETFL, O_NONBLOCK);
    1.72 +#ifdef __NetBSD__
    1.73 +    /* Flush pending events */
    1.74 +    if (rep) {
    1.75 +        while (read(joy->hwdata->fd, REP_BUF_DATA(rep), rep->size) == rep->size)
    1.76 +            ;
    1.77 +    }
    1.78 +#endif
    1.79  
    1.80      return (0);
    1.81    usberr: