mirror of https://github.com/encounter/SDL.git
joystick: Linux joysticks now recover better from dropped events.
Fixes Bugzilla #4830.
This commit is contained in:
parent
e594a6738a
commit
0e98040d43
|
@ -79,6 +79,10 @@
|
||||||
|
|
||||||
#include "../../core/linux/SDL_udev.h"
|
#include "../../core/linux/SDL_udev.h"
|
||||||
|
|
||||||
|
#if 0
|
||||||
|
#define DEBUG_INPUT_EVENTS 1
|
||||||
|
#endif
|
||||||
|
|
||||||
static int MaybeAddDevice(const char *path);
|
static int MaybeAddDevice(const char *path);
|
||||||
#if SDL_USE_LIBUDEV
|
#if SDL_USE_LIBUDEV
|
||||||
static int MaybeRemoveDevice(const char *path);
|
static int MaybeRemoveDevice(const char *path);
|
||||||
|
@ -838,7 +842,7 @@ LINUX_JoystickOpen(SDL_Joystick * joystick, int device_index)
|
||||||
item->hwdata = joystick->hwdata;
|
item->hwdata = joystick->hwdata;
|
||||||
|
|
||||||
/* mark joystick as fresh and ready */
|
/* mark joystick as fresh and ready */
|
||||||
joystick->hwdata->fresh = 1;
|
joystick->hwdata->fresh = SDL_TRUE;
|
||||||
|
|
||||||
return (0);
|
return (0);
|
||||||
}
|
}
|
||||||
|
@ -950,11 +954,12 @@ static SDL_INLINE void
|
||||||
PollAllValues(SDL_Joystick * joystick)
|
PollAllValues(SDL_Joystick * joystick)
|
||||||
{
|
{
|
||||||
struct input_absinfo absinfo;
|
struct input_absinfo absinfo;
|
||||||
|
unsigned long keyinfo[NBITS(KEY_MAX)];
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
/* Poll all axis */
|
/* Poll all axis */
|
||||||
for (i = ABS_X; i < ABS_MAX; i++) {
|
for (i = ABS_X; i < ABS_MAX; i++) {
|
||||||
if (i == ABS_HAT0X) {
|
if (i == ABS_HAT0X) { /* we handle hats in the next loop, skip them for now. */
|
||||||
i = ABS_HAT3Y;
|
i = ABS_HAT3Y;
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
@ -972,6 +977,37 @@ PollAllValues(SDL_Joystick * joystick)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Poll all hats */
|
||||||
|
for (i = ABS_HAT0X; i <= ABS_HAT3Y; i++) {
|
||||||
|
const int baseaxis = i - ABS_HAT0X;
|
||||||
|
const int hatidx = baseaxis / 2;
|
||||||
|
SDL_assert(hatidx < SDL_arraysize(joystick->hwdata->has_hat));
|
||||||
|
if (joystick->hwdata->has_hat[hatidx]) {
|
||||||
|
if (ioctl(joystick->hwdata->fd, EVIOCGABS(i), &absinfo) >= 0) {
|
||||||
|
const int hataxis = baseaxis % 2;
|
||||||
|
HandleHat(joystick, joystick->hwdata->hats_indices[hatidx], hataxis, absinfo.value);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Poll all buttons */
|
||||||
|
SDL_zeroa(keyinfo);
|
||||||
|
if (ioctl(joystick->hwdata->fd, EVIOCGKEY(sizeof (keyinfo)), keyinfo) >= 0) {
|
||||||
|
for (i = 0; i < KEY_MAX; i++) {
|
||||||
|
if (joystick->hwdata->has_key[i]) {
|
||||||
|
const Uint8 value = test_bit(i, keyinfo) ? SDL_PRESSED : SDL_RELEASED;
|
||||||
|
#ifdef DEBUG_INPUT_EVENTS
|
||||||
|
printf("Joystick : Re-read Button %d (%d) val= %d\n",
|
||||||
|
joystick->hwdata->key_map[i], i, value);
|
||||||
|
#endif
|
||||||
|
SDL_PrivateJoystickButton(joystick,
|
||||||
|
joystick->hwdata->key_map[i], value);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Joyballs are relative input, so there's no poll state. Events only! */
|
||||||
}
|
}
|
||||||
|
|
||||||
static SDL_INLINE void
|
static SDL_INLINE void
|
||||||
|
@ -983,13 +1019,21 @@ HandleInputEvents(SDL_Joystick * joystick)
|
||||||
|
|
||||||
if (joystick->hwdata->fresh) {
|
if (joystick->hwdata->fresh) {
|
||||||
PollAllValues(joystick);
|
PollAllValues(joystick);
|
||||||
joystick->hwdata->fresh = 0;
|
joystick->hwdata->fresh = SDL_FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
while ((len = read(joystick->hwdata->fd, events, (sizeof events))) > 0) {
|
while ((len = read(joystick->hwdata->fd, events, (sizeof events))) > 0) {
|
||||||
len /= sizeof(events[0]);
|
len /= sizeof(events[0]);
|
||||||
for (i = 0; i < len; ++i) {
|
for (i = 0; i < len; ++i) {
|
||||||
code = events[i].code;
|
code = events[i].code;
|
||||||
|
|
||||||
|
/* If the kernel sent a SYN_DROPPED, we are supposed to ignore the
|
||||||
|
rest of the packet (the end of it signified by a SYN_REPORT) */
|
||||||
|
if ( joystick->hwdata->recovering_from_dropped &&
|
||||||
|
((events[i].type != EV_SYN) || (code != SYN_REPORT)) ) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
switch (events[i].type) {
|
switch (events[i].type) {
|
||||||
case EV_KEY:
|
case EV_KEY:
|
||||||
SDL_PrivateJoystickButton(joystick,
|
SDL_PrivateJoystickButton(joystick,
|
||||||
|
@ -1037,7 +1081,13 @@ HandleInputEvents(SDL_Joystick * joystick)
|
||||||
#ifdef DEBUG_INPUT_EVENTS
|
#ifdef DEBUG_INPUT_EVENTS
|
||||||
printf("Event SYN_DROPPED detected\n");
|
printf("Event SYN_DROPPED detected\n");
|
||||||
#endif
|
#endif
|
||||||
PollAllValues(joystick);
|
joystick->hwdata->recovering_from_dropped = SDL_TRUE;
|
||||||
|
break;
|
||||||
|
case SYN_REPORT :
|
||||||
|
if (joystick->hwdata->recovering_from_dropped) {
|
||||||
|
joystick->hwdata->recovering_from_dropped = SDL_FALSE;
|
||||||
|
PollAllValues(joystick); /* try to sync up to current state now */
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
|
|
|
@ -62,7 +62,8 @@ struct joystick_hwdata
|
||||||
int coef[3];
|
int coef[3];
|
||||||
} abs_correct[ABS_MAX];
|
} abs_correct[ABS_MAX];
|
||||||
|
|
||||||
int fresh;
|
SDL_bool fresh;
|
||||||
|
SDL_bool recovering_from_dropped;
|
||||||
|
|
||||||
/* Steam Controller support */
|
/* Steam Controller support */
|
||||||
SDL_bool m_bSteamController;
|
SDL_bool m_bSteamController;
|
||||||
|
|
|
@ -167,6 +167,14 @@ loop(void *arg)
|
||||||
event.jbutton.which, event.jbutton.button);
|
event.jbutton.which, event.jbutton.button);
|
||||||
break;
|
break;
|
||||||
case SDL_KEYDOWN:
|
case SDL_KEYDOWN:
|
||||||
|
/* Press the L key to lag for 3 seconds, to see what happens
|
||||||
|
when SDL doesn't service the event loop quickly. */
|
||||||
|
if (event.key.keysym.sym == SDLK_l) {
|
||||||
|
SDL_Log("Lagging for 3 seconds...\n");
|
||||||
|
SDL_Delay(3000);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
if ((event.key.keysym.sym != SDLK_ESCAPE) &&
|
if ((event.key.keysym.sym != SDLK_ESCAPE) &&
|
||||||
(event.key.keysym.sym != SDLK_AC_BACK)) {
|
(event.key.keysym.sym != SDLK_AC_BACK)) {
|
||||||
break;
|
break;
|
||||||
|
|
Loading…
Reference in New Issue