From 9cd2e9ec8fc0127393dfce9c0359d500c8c238be Mon Sep 17 00:00:00 2001
From: Edward Rudd <urkle@outoforder.cc>
Date: Tue, 09 Apr 2019 02:22:50 +0000
Subject: [PATCH] updae source to 2.0.9 source

---
 source/src/joystick/linux/SDL_sysjoystick.c |  156 ++++++++++++++++++++++++++++++++++++++--------------
 1 files changed, 114 insertions(+), 42 deletions(-)

diff --git a/source/src/joystick/linux/SDL_sysjoystick.c b/source/src/joystick/linux/SDL_sysjoystick.c
index 457c4b8..06a2d9a 100644
--- a/source/src/joystick/linux/SDL_sysjoystick.c
+++ b/source/src/joystick/linux/SDL_sysjoystick.c
@@ -29,10 +29,11 @@
 /* This is the Linux implementation of the SDL joystick API */
 
 #include <sys/stat.h>
-#include <unistd.h>
+#include <errno.h>              /* errno, strerror */
 #include <fcntl.h>
-#include <sys/ioctl.h>
 #include <limits.h>             /* For the definition of PATH_MAX */
+#include <sys/ioctl.h>
+#include <unistd.h>
 #include <linux/joystick.h>
 
 #include "SDL_assert.h"
@@ -43,6 +44,7 @@
 #include "../SDL_joystick_c.h"
 #include "../steam/SDL_steamcontroller.h"
 #include "SDL_sysjoystick_c.h"
+#include "../hidapi/SDL_hidapijoystick_c.h"
 
 /* This isn't defined in older Linux kernel headers */
 #ifndef SYN_DROPPED
@@ -76,7 +78,6 @@
 static SDL_joylist_item *SDL_joylist = NULL;
 static SDL_joylist_item *SDL_joylist_tail = NULL;
 static int numjoysticks = 0;
-static int instance_counter = 0;
 
 
 #define test_bit(nr, addr) \
@@ -209,6 +210,13 @@
         return 0;
     }
 
+#ifdef SDL_JOYSTICK_HIDAPI
+    if (HIDAPI_IsDevicePresent(inpid.vendor, inpid.product, inpid.version)) {
+        /* The HIDAPI driver is taking care of this device */
+        return 0;
+    }
+#endif
+
     /* Check the joystick blacklist */
     id = MAKE_VIDPID(inpid.vendor, inpid.product);
     for (i = 0; i < SDL_arraysize(joystick_blacklist); ++i) {
@@ -239,8 +247,7 @@
         SDL_strlcpy((char*)guid16, namebuf, sizeof(guid->data) - 4);
     }
 
-    if (SDL_IsGameControllerNameAndGUID(namebuf, *guid) &&
-        SDL_ShouldIgnoreGameController(namebuf, *guid)) {
+    if (SDL_ShouldIgnoreJoystick(namebuf, *guid)) {
         return 0;
     }
     return 1;
@@ -325,14 +332,14 @@
     item->name = SDL_strdup(namebuf);
     item->guid = guid;
 
-    if ( (item->path == NULL) || (item->name == NULL) ) {
+    if ((item->path == NULL) || (item->name == NULL)) {
          SDL_free(item->path);
          SDL_free(item->name);
          SDL_free(item);
          return -1;
     }
 
-    item->device_instance = instance_counter++;
+    item->device_instance = SDL_GetNextJoystickInstanceID();
     if (SDL_joylist_tail == NULL) {
         SDL_joylist = SDL_joylist_tail = item;
     } else {
@@ -343,7 +350,7 @@
     /* Need to increment the joystick count before we post the event */
     ++numjoysticks;
 
-    SDL_PrivateJoystickAdded(numjoysticks - 1);
+    SDL_PrivateJoystickAdded(item->device_instance);
 
     return numjoysticks;
 }
@@ -409,7 +416,7 @@
         MaybeAddDevice(path);
     }
 
-    return numjoysticks;
+    return 0;
 }
 #endif
 
@@ -430,7 +437,7 @@
     /* Force a scan to build the initial device list */
     SDL_UDEV_Scan();
 
-    return numjoysticks;
+    return 0;
 }
 #endif
 
@@ -455,7 +462,7 @@
          return SDL_FALSE;
     }
 
-    *device_instance = item->device_instance = instance_counter++;
+    *device_instance = item->device_instance = SDL_GetNextJoystickInstanceID();
     if (SDL_joylist_tail == NULL) {
         SDL_joylist = SDL_joylist_tail = item;
     } else {
@@ -466,7 +473,7 @@
     /* Need to increment the joystick count before we post the event */
     ++numjoysticks;
 
-    SDL_PrivateJoystickAdded(numjoysticks - 1);
+    SDL_PrivateJoystickAdded(item->device_instance);
 
     return SDL_TRUE;
 }
@@ -505,8 +512,8 @@
     }
 }
 
-int
-SDL_SYS_JoystickInit(void)
+static int
+LINUX_JoystickInit(void)
 {
     /* First see if the user specified one or more joysticks to use */
     if (SDL_getenv("SDL_JOYSTICK_DEVICE") != NULL) {
@@ -534,14 +541,14 @@
 #endif
 }
 
-int
-SDL_SYS_NumJoysticks(void)
+static int
+LINUX_JoystickGetCount(void)
 {
     return numjoysticks;
 }
 
-void
-SDL_SYS_JoystickDetect(void)
+static void
+LINUX_JoystickDetect(void)
 {
 #if SDL_USE_LIBUDEV
     SDL_UDEV_Poll();
@@ -569,14 +576,27 @@
 }
 
 /* Function to get the device-dependent name of a joystick */
-const char *
-SDL_SYS_JoystickNameForDeviceIndex(int device_index)
+static const char *
+LINUX_JoystickGetDeviceName(int device_index)
 {
     return JoystickByDevIndex(device_index)->name;
 }
 
+static int
+LINUX_JoystickGetDevicePlayerIndex(int device_index)
+{
+    return -1;
+}
+
+static SDL_JoystickGUID
+LINUX_JoystickGetDeviceGUID( int device_index )
+{
+    return JoystickByDevIndex(device_index)->guid;
+}
+
 /* Function to perform the mapping from device index to the instance id for this index */
-SDL_JoystickID SDL_SYS_GetInstanceIdOfDeviceIndex(int device_index)
+static SDL_JoystickID
+LINUX_JoystickGetDeviceInstanceID(int device_index)
 {
     return JoystickByDevIndex(device_index)->device_instance;
 }
@@ -624,6 +644,7 @@
     unsigned long keybit[NBITS(KEY_MAX)] = { 0 };
     unsigned long absbit[NBITS(ABS_MAX)] = { 0 };
     unsigned long relbit[NBITS(REL_MAX)] = { 0 };
+    unsigned long ffbit[NBITS(FF_MAX)] = { 0 };
 
     /* See if this device uses the new unified event API */
     if ((ioctl(fd, EVIOCGBIT(EV_KEY, sizeof(keybit)), keybit) >= 0) &&
@@ -719,6 +740,15 @@
             }
         }
     }
+
+    if (ioctl(fd, EVIOCGBIT(EV_FF, sizeof(ffbit)), ffbit) >= 0) {
+        if (test_bit(FF_RUMBLE, ffbit)) {
+            joystick->hwdata->ff_rumble = SDL_TRUE;
+        }
+        if (test_bit(FF_SINE, ffbit)) {
+            joystick->hwdata->ff_sine = SDL_TRUE;
+        }
+    }
 }
 
 
@@ -727,8 +757,8 @@
    This should fill the nbuttons and naxes fields of the joystick structure.
    It returns 0, or -1 if there is an error.
  */
-int
-SDL_SYS_JoystickOpen(SDL_Joystick * joystick, int device_index)
+static int
+LINUX_JoystickOpen(SDL_Joystick * joystick, int device_index)
 {
     SDL_joylist_item *item = JoystickByDevIndex(device_index);
 
@@ -744,6 +774,7 @@
     }
     joystick->hwdata->item = item;
     joystick->hwdata->guid = item->guid;
+    joystick->hwdata->effect.id = -1;
     joystick->hwdata->m_bSteamController = item->m_bSteamController;
 
     if (item->m_bSteamController) {
@@ -752,7 +783,7 @@
                                      &joystick->naxes,
                                      &joystick->nhats);
     } else {
-        int fd = open(item->path, O_RDONLY, 0);
+        int fd = open(item->path, O_RDWR, 0);
         if (fd < 0) {
             SDL_free(joystick->hwdata);
             joystick->hwdata = NULL;
@@ -784,10 +815,42 @@
     return (0);
 }
 
-/* Function to determine if this joystick is attached to the system right now */
-SDL_bool SDL_SYS_JoystickAttached(SDL_Joystick *joystick)
+static int
+LINUX_JoystickRumble(SDL_Joystick * joystick, Uint16 low_frequency_rumble, Uint16 high_frequency_rumble, Uint32 duration_ms)
 {
-    return joystick->hwdata->item != NULL;
+    struct input_event event;
+
+    if (joystick->hwdata->ff_rumble) {
+        struct ff_effect *effect = &joystick->hwdata->effect;
+
+        effect->type = FF_RUMBLE;
+        effect->replay.length = SDL_min(duration_ms, 32767);
+        effect->u.rumble.strong_magnitude = low_frequency_rumble;
+        effect->u.rumble.weak_magnitude = high_frequency_rumble;
+    } else if (joystick->hwdata->ff_sine) {
+        /* Scale and average the two rumble strengths */
+        Sint16 magnitude = (Sint16)(((low_frequency_rumble / 2) + (high_frequency_rumble / 2)) / 2);
+        struct ff_effect *effect = &joystick->hwdata->effect;
+
+        effect->type = FF_PERIODIC;
+        effect->replay.length = SDL_min(duration_ms, 32767);
+        effect->u.periodic.waveform = FF_SINE;
+        effect->u.periodic.magnitude = magnitude;
+    } else {
+        return SDL_Unsupported();
+    }
+
+    if (ioctl(joystick->hwdata->fd, EVIOCSFF, &joystick->hwdata->effect) < 0) {
+        return SDL_SetError("Couldn't update rumble effect: %s", strerror(errno));
+    }
+
+    event.type = EV_FF;
+    event.code = joystick->hwdata->effect.id;
+    event.value = 1;
+    if (write(joystick->hwdata->fd, &event, sizeof(event)) < 0) {
+        return SDL_SetError("Couldn't start rumble effect: %s", strerror(errno));
+    }
+    return 0;
 }
 
 static SDL_INLINE void
@@ -963,8 +1026,8 @@
     }
 }
 
-void
-SDL_SYS_JoystickUpdate(SDL_Joystick * joystick)
+static void
+LINUX_JoystickUpdate(SDL_Joystick * joystick)
 {
     int i;
 
@@ -990,10 +1053,14 @@
 }
 
 /* Function to close a joystick after use */
-void
-SDL_SYS_JoystickClose(SDL_Joystick * joystick)
+static void
+LINUX_JoystickClose(SDL_Joystick * joystick)
 {
     if (joystick->hwdata) {
+        if (joystick->hwdata->effect.id >= 0) {
+            ioctl(joystick->hwdata->fd, EVIOCRMFF, joystick->hwdata->effect.id);
+            joystick->hwdata->effect.id = -1;
+        }
         if (joystick->hwdata->fd >= 0) {
             close(joystick->hwdata->fd);
         }
@@ -1008,8 +1075,8 @@
 }
 
 /* Function to perform any system-specific joystick related cleanup */
-void
-SDL_SYS_JoystickQuit(void)
+static void
+LINUX_JoystickQuit(void)
 {
     SDL_joylist_item *item = NULL;
     SDL_joylist_item *next = NULL;
@@ -1024,7 +1091,6 @@
     SDL_joylist = SDL_joylist_tail = NULL;
 
     numjoysticks = 0;
-    instance_counter = 0;
 
 #if SDL_USE_LIBUDEV
     SDL_UDEV_DelCallback(joystick_udev_callback);
@@ -1034,15 +1100,21 @@
     SDL_QuitSteamControllers();
 }
 
-SDL_JoystickGUID SDL_SYS_JoystickGetDeviceGUID( int device_index )
+SDL_JoystickDriver SDL_LINUX_JoystickDriver =
 {
-    return JoystickByDevIndex(device_index)->guid;
-}
-
-SDL_JoystickGUID SDL_SYS_JoystickGetGUID(SDL_Joystick * joystick)
-{
-    return joystick->hwdata->guid;
-}
+    LINUX_JoystickInit,
+    LINUX_JoystickGetCount,
+    LINUX_JoystickDetect,
+    LINUX_JoystickGetDeviceName,
+    LINUX_JoystickGetDevicePlayerIndex,
+    LINUX_JoystickGetDeviceGUID,
+    LINUX_JoystickGetDeviceInstanceID,
+    LINUX_JoystickOpen,
+    LINUX_JoystickRumble,
+    LINUX_JoystickUpdate,
+    LINUX_JoystickClose,
+    LINUX_JoystickQuit,
+};
 
 #endif /* SDL_JOYSTICK_LINUX */
 

--
Gitblit v1.9.3