Read from uhid device and insert events until there are no more events

to consume. Matches SDL2 BSD joystick driver behavior, and makes things
like "iBUFFALO Classic USB Gamepad" work with Retroarch.
This commit is contained in:
jmcneill 2015-03-03 19:14:04 +00:00
parent 71f3b106e3
commit 0f86df7444
2 changed files with 123 additions and 7 deletions

View file

@ -1,4 +1,4 @@
$NetBSD: distinfo,v 1.75 2015/02/25 12:48:34 jmcneill Exp $
$NetBSD: distinfo,v 1.76 2015/03/03 19:14:04 jmcneill Exp $
SHA1 (SDL-1.2.15.tar.gz) = 0c5f193ced810b0d7ce3ab06d808cbb5eef03a2c
RMD160 (SDL-1.2.15.tar.gz) = d4802a090cb4a24eeb0c8ce5690802f596d394c3
@ -6,7 +6,7 @@ Size (SDL-1.2.15.tar.gz) = 3920622 bytes
SHA1 (patch-aa) = 00fb7a85caf8fc9f08298d0a07a4587757fdffb0
SHA1 (patch-ac) = 8b2dddff9ad449b19b35ef364e2d960e46284563
SHA1 (patch-src_audio_sun_SDL__sunaudio.c) = 4b492b40d39e6444037dfda55766e4a149cc6c30
SHA1 (patch-src_joystick_bsd_SDL__sysjoystick.c) = ec19279b7b65c2390aa65dd2319df86006e44849
SHA1 (patch-src_joystick_bsd_SDL__sysjoystick.c) = 46029dda8975dcb891a5b14b718c27b034ce5b06
SHA1 (patch-src_video_quartz_SDL__QuartzVideo.h) = 19d952bade06dbd646e94f42139c38436969b1a8
SHA1 (patch-src_video_wscons_SDL__wsconsevents.c) = 1c874c46edb325907eda3bfa7580c788294f6d21
SHA1 (patch-src_video_wscons_SDL__wsconsevents__c.h) = 97206e2aca0b620005217d9d07ad1177516cac92

View file

@ -1,4 +1,4 @@
$NetBSD: patch-src_joystick_bsd_SDL__sysjoystick.c,v 1.4 2015/02/25 12:48:34 jmcneill Exp $
$NetBSD: patch-src_joystick_bsd_SDL__sysjoystick.c,v 1.5 2015/03/03 19:14:04 jmcneill Exp $
--- src/joystick/bsd/SDL_sysjoystick.c.orig 2012-01-19 06:30:06.000000000 +0000
+++ src/joystick/bsd/SDL_sysjoystick.c
@ -25,15 +25,17 @@ $NetBSD: patch-src_joystick_bsd_SDL__sysjoystick.c,v 1.4 2015/02/25 12:48:34 jmc
#define REP_BUF_DATA(rep) ((rep)->buf->ugd_data)
#else
#define REP_BUF_DATA(rep) ((rep)->buf->data)
@@ -314,6 +316,38 @@ SDL_SYS_JoystickOpen(SDL_Joystick *joy)
@@ -314,6 +316,45 @@ SDL_SYS_JoystickOpen(SDL_Joystick *joy)
#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)
+ if (ioctl(fd, USB_GET_DEVICE_DESC, &udd) == -1) {
+ fprintf(stderr, "USB_GET_DEVICE_DESC failed: %s\n", strerror(errno));
+ goto desc_failed;
+ }
+
+ /* Get default language */
+ usd.usd_string_index = USB_LANGUAGE_TABLE;
@ -45,7 +47,12 @@ $NetBSD: patch-src_joystick_bsd_SDL__sysjoystick.c,v 1.4 2015/02/25 12:48:34 jmc
+ }
+
+ usd.usd_string_index = udd.iProduct;
+ if (ioctl(fd, USB_GET_STRING_DESC, &usd) == 0) {
+ int error = ioctl(fd, USB_GET_STRING_DESC, &usd);
+ if (error != 0 && usd.usd_language_id != 0) {
+ usd.usd_language_id = 0;
+ error = ioctl(fd, USB_GET_STRING_DESC, &usd);
+ }
+ if (error == 0) {
+ char str[128];
+ char *new_name = NULL;
+ int i;
@ -64,7 +71,7 @@ $NetBSD: patch-src_joystick_bsd_SDL__sysjoystick.c,v 1.4 2015/02/25 12:48:34 jmc
if (report_alloc(rep, hw->repdesc, REPORT_INPUT) < 0) {
goto usberr;
}
@@ -386,10 +420,21 @@ SDL_SYS_JoystickOpen(SDL_Joystick *joy)
@@ -386,10 +427,21 @@ SDL_SYS_JoystickOpen(SDL_Joystick *joy)
if (hw->axis_map[i] > 0)
hw->axis_map[i] = joy->naxes++;
@ -86,3 +93,112 @@ $NetBSD: patch-src_joystick_bsd_SDL__sysjoystick.c,v 1.4 2015/02/25 12:48:34 jmc
return (0);
usberr:
close(hw->fd);
@@ -459,63 +511,62 @@ SDL_SYS_JoystickUpdate(SDL_Joystick *joy
rep = &joy->hwdata->inreport;
- if (read(joy->hwdata->fd, REP_BUF_DATA(rep), rep->size) != rep->size) {
- return;
- }
+ while (read(joy->hwdata->fd, REP_BUF_DATA(rep), rep->size) == rep->size) {
#if defined(USBHID_NEW) || (defined(__FREEBSD__) && __FreeBSD_kernel_version >= 500111) || defined(__FreeBSD_kernel__)
- hdata = hid_start_parse(joy->hwdata->repdesc, 1 << hid_input, rep->rid);
+ hdata = hid_start_parse(joy->hwdata->repdesc, 1 << hid_input, rep->rid);
#else
- hdata = hid_start_parse(joy->hwdata->repdesc, 1 << hid_input);
+ hdata = hid_start_parse(joy->hwdata->repdesc, 1 << hid_input);
#endif
- if (hdata == NULL) {
- fprintf(stderr, "%s: Cannot start HID parser\n",
- joy->hwdata->path);
- return;
- }
+ if (hdata == NULL) {
+ fprintf(stderr, "%s: Cannot start HID parser\n",
+ joy->hwdata->path);
+ continue;
+ }
- for (nbutton = 0; hid_get_item(hdata, &hitem) > 0;) {
- switch (hitem.kind) {
- case hid_input:
- switch (HID_PAGE(hitem.usage)) {
- case HUP_GENERIC_DESKTOP: {
- unsigned usage = HID_USAGE(hitem.usage);
- int joyaxe = usage_to_joyaxe(usage);
- if (joyaxe >= 0) {
- naxe = joy->hwdata->axis_map[joyaxe];
- /* scaleaxe */
- v = (Sint32)hid_get_data(REP_BUF_DATA(rep),
- &hitem);
- v -= (hitem.logical_maximum + hitem.logical_minimum + 1)/2;
- v *= 32768/((hitem.logical_maximum - hitem.logical_minimum + 1)/2);
- if (v != joy->axes[naxe]) {
- SDL_PrivateJoystickAxis(joy, naxe, v);
+ for (nbutton = 0; hid_get_item(hdata, &hitem) > 0;) {
+ switch (hitem.kind) {
+ case hid_input:
+ switch (HID_PAGE(hitem.usage)) {
+ case HUP_GENERIC_DESKTOP: {
+ unsigned usage = HID_USAGE(hitem.usage);
+ int joyaxe = usage_to_joyaxe(usage);
+ if (joyaxe >= 0) {
+ naxe = joy->hwdata->axis_map[joyaxe];
+ /* scaleaxe */
+ v = (Sint32)hid_get_data(REP_BUF_DATA(rep),
+ &hitem);
+ v -= (hitem.logical_maximum + hitem.logical_minimum + 1)/2;
+ v *= 32768/((hitem.logical_maximum - hitem.logical_minimum + 1)/2);
+ if (v != joy->axes[naxe]) {
+ SDL_PrivateJoystickAxis(joy, naxe, v);
+ }
+ } else if (usage == HUG_HAT_SWITCH) {
+ v = (Sint32)hid_get_data(REP_BUF_DATA(rep),
+ &hitem);
+ SDL_PrivateJoystickHat(joy, 0,
+ hatval_to_sdl(v)-hitem.logical_minimum);
+ }
+ break;
}
- } else if (usage == HUG_HAT_SWITCH) {
- v = (Sint32)hid_get_data(REP_BUF_DATA(rep),
- &hitem);
- SDL_PrivateJoystickHat(joy, 0,
- hatval_to_sdl(v)-hitem.logical_minimum);
- }
- break;
- }
- case HUP_BUTTON:
- v = (Sint32)hid_get_data(REP_BUF_DATA(rep),
- &hitem);
- if (joy->buttons[nbutton] != v) {
- SDL_PrivateJoystickButton(joy,
- nbutton, v);
+ case HUP_BUTTON:
+ v = (Sint32)hid_get_data(REP_BUF_DATA(rep),
+ &hitem);
+ if (joy->buttons[nbutton] != v) {
+ SDL_PrivateJoystickButton(joy,
+ nbutton, v);
+ }
+ nbutton++;
+ break;
+ default:
+ continue;
}
- nbutton++;
break;
default:
- continue;
+ break;
}
- break;
- default:
- break;
}
+ hid_end_parse(hdata);
}
- hid_end_parse(hdata);
return;
}