summaryrefslogtreecommitdiff
path: root/Source/3rdParty/SDL2/src/joystick/linux/SDL_sysjoystick.c
diff options
context:
space:
mode:
authorchai <chaifix@163.com>2019-01-31 18:38:35 +0800
committerchai <chaifix@163.com>2019-01-31 18:38:35 +0800
commit2ec55fd974a63b705a4777c256d2222c874fa043 (patch)
tree48f1fea59ee9fc713a28a9aac3f05b98dc5ae66f /Source/3rdParty/SDL2/src/joystick/linux/SDL_sysjoystick.c
parentc581dfbf1e849f393861d15e82aa6446c0c1c310 (diff)
*SDL project
Diffstat (limited to 'Source/3rdParty/SDL2/src/joystick/linux/SDL_sysjoystick.c')
-rw-r--r--Source/3rdParty/SDL2/src/joystick/linux/SDL_sysjoystick.c156
1 files changed, 114 insertions, 42 deletions
diff --git a/Source/3rdParty/SDL2/src/joystick/linux/SDL_sysjoystick.c b/Source/3rdParty/SDL2/src/joystick/linux/SDL_sysjoystick.c
index 457c4b8..06a2d9a 100644
--- a/Source/3rdParty/SDL2/src/joystick/linux/SDL_sysjoystick.c
+++ b/Source/3rdParty/SDL2/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 @@ typedef struct SDL_joylist_item
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 @@ IsJoystick(int fd, char *namebuf, const size_t namebuflen, SDL_JoystickGUID *gui
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 @@ IsJoystick(int fd, char *namebuf, const size_t namebuflen, SDL_JoystickGUID *gui
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 @@ MaybeAddDevice(const char *path)
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 @@ MaybeAddDevice(const char *path)
/* 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 @@ JoystickInitWithoutUdev(void)
MaybeAddDevice(path);
}
- return numjoysticks;
+ return 0;
}
#endif
@@ -430,7 +437,7 @@ JoystickInitWithUdev(void)
/* Force a scan to build the initial device list */
SDL_UDEV_Scan();
- return numjoysticks;
+ return 0;
}
#endif
@@ -455,7 +462,7 @@ static SDL_bool SteamControllerConnectedCallback(const char *name, SDL_JoystickG
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 @@ static SDL_bool SteamControllerConnectedCallback(const char *name, SDL_JoystickG
/* 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 @@ static void SteamControllerDisconnectedCallback(int device_instance)
}
}
-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 @@ SDL_SYS_JoystickInit(void)
#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 @@ JoystickByDevIndex(int device_index)
}
/* 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 @@ ConfigJoystick(SDL_Joystick * joystick, int fd)
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 @@ ConfigJoystick(SDL_Joystick * joystick, int fd)
}
}
}
+
+ 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 @@ ConfigJoystick(SDL_Joystick * joystick, int fd)
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 @@ SDL_SYS_JoystickOpen(SDL_Joystick * joystick, int device_index)
}
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 @@ SDL_SYS_JoystickOpen(SDL_Joystick * joystick, int device_index)
&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 @@ SDL_SYS_JoystickOpen(SDL_Joystick * joystick, int device_index)
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 @@ HandleInputEvents(SDL_Joystick * joystick)
}
}
-void
-SDL_SYS_JoystickUpdate(SDL_Joystick * joystick)
+static void
+LINUX_JoystickUpdate(SDL_Joystick * joystick)
{
int i;
@@ -990,10 +1053,14 @@ SDL_SYS_JoystickUpdate(SDL_Joystick * joystick)
}
/* 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 @@ SDL_SYS_JoystickClose(SDL_Joystick * joystick)
}
/* 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_SYS_JoystickQuit(void)
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_SYS_JoystickQuit(void)
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 */