diff --git a/src/joystick/bsd/SDL_sysjoystick.c b/src/joystick/bsd/SDL_sysjoystick.c index a6fe2f735..b43e13b3d 100644 --- a/src/joystick/bsd/SDL_sysjoystick.c +++ b/src/joystick/bsd/SDL_sysjoystick.c @@ -76,7 +76,7 @@ #include "../SDL_sysjoystick.h" #include "../SDL_joystick_c.h" -#define MAX_UHID_JOYS 16 +#define MAX_UHID_JOYS 64 #define MAX_JOY_JOYS 2 #define MAX_JOYS (MAX_UHID_JOYS + MAX_JOY_JOYS) @@ -286,7 +286,7 @@ SDL_SYS_JoystickOpen(SDL_Joystick * joy, int device_index) struct joystick_hwdata *hw; struct hid_item hitem; struct hid_data *hdata; - struct report *rep; + struct report *rep = NULL; int fd; int i; @@ -337,6 +337,38 @@ SDL_SYS_JoystickOpen(SDL_Joystick * joy, int device_index) #endif rep->rid = -1; /* XXX */ } +#if defined(__NetBSD__) + usb_device_descriptor_t udd; + struct usb_string_desc usd; + if (ioctl(fd, USB_GET_DEVICE_DESC, &udd) == -1) + goto desc_failed; + + /* Get default language */ + usd.usd_string_index = USB_LANGUAGE_TABLE; + usd.usd_language_id = 0; + if (ioctl(fd, USB_GET_STRING_DESC, &usd) == -1 || usd.usd_desc.bLength < 4) { + usd.usd_language_id = 0; + } else { + usd.usd_language_id = UGETW(usd.usd_desc.bString[0]); + } + + usd.usd_string_index = udd.iProduct; + if (ioctl(fd, USB_GET_STRING_DESC, &usd) == 0) { + char str[128]; + char *new_name = NULL; + int i; + for (i = 0; i < (usd.usd_desc.bLength >> 1) - 1 && i < sizeof(str) - 1; i++) { + str[i] = UGETW(usd.usd_desc.bString[i]); + } + str[i] = '\0'; + asprintf(&new_name, "%s @ %s", str, path); + if (new_name != NULL) { + free(joydevnames[SDL_SYS_numjoysticks]); + joydevnames[SDL_SYS_numjoysticks] = new_name; + } + } +desc_failed: +#endif if (report_alloc(rep, hw->repdesc, REPORT_INPUT) < 0) { goto usberr; } @@ -409,9 +441,21 @@ SDL_SYS_JoystickOpen(SDL_Joystick * joy, int device_index) if (hw->axis_map[i] > 0) hw->axis_map[i] = joy->naxes++; + if (joy->naxes == 0 && joy->nbuttons == 0 && joy->nhats == 0 && joy->nballs == 0) { + SDL_SetError("%s: Not a joystick, ignoring", hw->path); + goto usberr; + } + usbend: /* The poll blocks the event thread. */ fcntl(fd, F_SETFL, O_NONBLOCK); +#ifdef __NetBSD__ + /* Flush pending events */ + if (rep) { + while (read(joy->hwdata->fd, REP_BUF_DATA(rep), rep->size) == rep->size) + ; + } +#endif return (0); usberr: