Mac and Linux SDL2 binary snapshots
Edward Rudd
2019-04-09 9cd2e9ec8fc0127393dfce9c0359d500c8c238be
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;
@@ -332,7 +339,7 @@
         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 */