Commit 56b7f4cf3100cd252a0325973fb9093ce0a629ee

Sam Lantinga 2019-06-08T14:40:27

Fixed bug 4583 - PollAllValues appears to use an incorrect index for all axes above 0x18 Noam Preil In src/joystick/linux/SDL_sysjoystick.c: The ConfigJoystick function's axes detection starts with a for loop using an index i for Linux's axes names. When i gets to ABS_HAT0X, it's set to ABS_HAT3Y and a continue statement appears, to skip the hats. This makes sense, as SDL handles hats separately from axes. However, in PollAllValues, *two* indices are used: a and b. Both start out the same, and remain so until the hats are reached. At that point, a becomes identical to the i from ConfigJoystick's loop, but b is equal to a - (ABS_HAT3Y - ABS_HAT0X), or a - 8. While all the joystick->hwdata->abs_* structures in ConfigJoystick used i - which would here be a - as both the index and the ioctl argument, PollAllValues uses b for the structure index and a as the ioctl argument. It would appear, however, that no joystick HAS such axes, and that the b index is entirely unnecessary. I tested three separate joysticks, and while that was far from a complete listing, I was unable to find a joystick with an axis above 0x08.

diff --git a/src/joystick/linux/SDL_sysjoystick.c b/src/joystick/linux/SDL_sysjoystick.c
index fd26415..0309f8c 100644
--- a/src/joystick/linux/SDL_sysjoystick.c
+++ b/src/joystick/linux/SDL_sysjoystick.c
@@ -818,36 +818,26 @@ static SDL_INLINE void
 PollAllValues(SDL_Joystick * joystick)
 {
     struct input_absinfo absinfo;
-    int a, b = 0;
+    int i;
 
     /* Poll all axis */
-    for (a = ABS_X; b < ABS_MAX; a++) {
-        switch (a) {
-        case ABS_HAT0X:
-        case ABS_HAT0Y:
-        case ABS_HAT1X:
-        case ABS_HAT1Y:
-        case ABS_HAT2X:
-        case ABS_HAT2Y:
-        case ABS_HAT3X:
-        case ABS_HAT3Y:
-            /* ingore hats */
-            break;
-        default:
-            if (joystick->hwdata->abs_correct[b].used) {
-                if (ioctl(joystick->hwdata->fd, EVIOCGABS(a), &absinfo) >= 0) {
-                    absinfo.value = AxisCorrect(joystick, b, absinfo.value);
+    for (i = ABS_X; i < ABS_MAX; i++) {
+        if (i == ABS_HAT0X) {
+            i = ABS_HAT3Y;
+            continue;
+        }
+        if (joystick->hwdata->abs_correct[i].used) {
+            if (ioctl(joystick->hwdata->fd, EVIOCGABS(i), &absinfo) >= 0) {
+                absinfo.value = AxisCorrect(joystick, i, absinfo.value);
 
 #ifdef DEBUG_INPUT_EVENTS
-                    printf("Joystick : Re-read Axis %d (%d) val= %d\n",
-                        joystick->hwdata->abs_map[b], a, absinfo.value);
+                printf("Joystick : Re-read Axis %d (%d) val= %d\n",
+                    joystick->hwdata->abs_map[i], i, absinfo.value);
 #endif
-                    SDL_PrivateJoystickAxis(joystick,
-                            joystick->hwdata->abs_map[b],
-                            absinfo.value);
-                }
+                SDL_PrivateJoystickAxis(joystick,
+                        joystick->hwdata->abs_map[i],
+                        absinfo.value);
             }
-            b++;
         }
     }
 }