From 5a079a2d114f96d4847d1ee305d5b7c16eeec50e Mon Sep 17 00:00:00 2001 From: 3gg <3gg@shellblade.net> Date: Sat, 27 Dec 2025 12:03:39 -0800 Subject: Initial commit --- .../SDL-3.2.8/src/joystick/bsd/SDL_bsdjoystick.c | 868 +++++++++++++++++++++ 1 file changed, 868 insertions(+) create mode 100644 contrib/SDL-3.2.8/src/joystick/bsd/SDL_bsdjoystick.c (limited to 'contrib/SDL-3.2.8/src/joystick/bsd') diff --git a/contrib/SDL-3.2.8/src/joystick/bsd/SDL_bsdjoystick.c b/contrib/SDL-3.2.8/src/joystick/bsd/SDL_bsdjoystick.c new file mode 100644 index 0000000..b3fd3e9 --- /dev/null +++ b/contrib/SDL-3.2.8/src/joystick/bsd/SDL_bsdjoystick.c @@ -0,0 +1,868 @@ +/* + Simple DirectMedia Layer + Copyright (C) 1997-2025 Sam Lantinga + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + arising from the use of this software. + + Permission is granted to anyone to use this software for any purpose, + including commercial applications, and to alter it and redistribute it + freely, subject to the following restrictions: + + 1. The origin of this software must not be misrepresented; you must not + claim that you wrote the original software. If you use this software + in a product, an acknowledgment in the product documentation would be + appreciated but is not required. + 2. Altered source versions must be plainly marked as such, and must not be + misrepresented as being the original software. + 3. This notice may not be removed or altered from any source distribution. +*/ +#include "SDL_internal.h" + +#ifdef SDL_JOYSTICK_USBHID + +/* + * Joystick driver for the uhid(4) / ujoy(4) interface found in OpenBSD, + * NetBSD and FreeBSD. + * + * Maintainer: + */ + +#include +#include + +#include +#include +#include + +#ifndef __FreeBSD_kernel_version +#define __FreeBSD_kernel_version __FreeBSD_version +#endif + +#ifdef HAVE_USB_H +#include +#endif +#ifdef __DragonFly__ +#include +#include +#else +#include +#include +#endif + +#ifdef HAVE_USBHID_H +#include +#elif defined(HAVE_LIBUSB_H) +#include +#elif defined(HAVE_LIBUSBHID_H) +#include +#endif + +#if defined(SDL_PLATFORM_FREEBSD) +#include +#if __FreeBSD_kernel_version > 800063 +#include +#elif defined(__DragonFly__) +#include +#endif +#include +#endif + +#ifdef SDL_HAVE_MACHINE_JOYSTICK_H +#include +#endif + +#include "../SDL_sysjoystick.h" +#include "../SDL_joystick_c.h" +#include "../hidapi/SDL_hidapijoystick_c.h" + +#if defined(SDL_PLATFORM_FREEBSD) || defined(SDL_HAVE_MACHINE_JOYSTICK_H) || defined(__FreeBSD_kernel__) || defined(__DragonFly_) +#define SUPPORT_JOY_GAMEPORT +#endif + +#define MAX_UHID_JOYS 64 +#define MAX_JOY_JOYS 2 +#define MAX_JOYS (MAX_UHID_JOYS + MAX_JOY_JOYS) + +#ifdef SDL_PLATFORM_OPENBSD + +#define HUG_DPAD_UP 0x90 +#define HUG_DPAD_DOWN 0x91 +#define HUG_DPAD_RIGHT 0x92 +#define HUG_DPAD_LEFT 0x93 + +#define HAT_UP 0x01 +#define HAT_RIGHT 0x02 +#define HAT_DOWN 0x04 +#define HAT_LEFT 0x08 + +#endif + +struct report +{ +#if defined(SDL_PLATFORM_FREEBSD) && (__FreeBSD_kernel_version > 900000) || \ + defined(__DragonFly__) + void *buf; // Buffer +#elif defined(SDL_PLATFORM_FREEBSD) && (__FreeBSD_kernel_version > 800063) + struct usb_gen_descriptor *buf; // Buffer +#else + struct usb_ctl_report *buf; // Buffer +#endif + size_t size; // Buffer size + int rid; // Report ID + enum + { + SREPORT_UNINIT, + SREPORT_CLEAN, + SREPORT_DIRTY + } status; +}; + +static struct +{ + int uhid_report; + hid_kind_t kind; + const char *name; +} const repinfo[] = { + { UHID_INPUT_REPORT, hid_input, "input" }, + { UHID_OUTPUT_REPORT, hid_output, "output" }, + { UHID_FEATURE_REPORT, hid_feature, "feature" } +}; + +enum +{ + REPORT_INPUT = 0, + REPORT_OUTPUT = 1, + REPORT_FEATURE = 2 +}; + +enum +{ + JOYAXE_X, + JOYAXE_Y, + JOYAXE_Z, + JOYAXE_SLIDER, + JOYAXE_WHEEL, + JOYAXE_RX, + JOYAXE_RY, + JOYAXE_RZ, + JOYAXE_count +}; + +struct joystick_hwdata +{ + int fd; + enum + { + BSDJOY_UHID, // uhid(4) + BSDJOY_JOY // joy(4) + } type; + + int naxes; + int nbuttons; + int nhats; + struct report_desc *repdesc; + struct report inreport; + int axis_map[JOYAXE_count]; /* map present JOYAXE_* to 0,1,.. */ +}; + +// A linked list of available joysticks +typedef struct SDL_joylist_item +{ + SDL_JoystickID device_instance; + char *path; // "/dev/uhid0" or whatever + char *name; // "SideWinder 3D Pro" or whatever + SDL_GUID guid; + dev_t devnum; + struct SDL_joylist_item *next; +} SDL_joylist_item; + +static SDL_joylist_item *SDL_joylist = NULL; +static SDL_joylist_item *SDL_joylist_tail = NULL; +static int numjoysticks = 0; + +static bool report_alloc(struct report *, struct report_desc *, int); +static void report_free(struct report *); + +#if defined(USBHID_UCR_DATA) || (defined(__FreeBSD_kernel__) && __FreeBSD_kernel_version <= 800063) +#define REP_BUF_DATA(rep) ((rep)->buf->ucr_data) +#elif (defined(SDL_PLATFORM_FREEBSD) && (__FreeBSD_kernel_version > 900000)) || \ + defined(__DragonFly__) +#define REP_BUF_DATA(rep) ((rep)->buf) +#elif (defined(SDL_PLATFORM_FREEBSD) && (__FreeBSD_kernel_version > 800063)) +#define REP_BUF_DATA(rep) ((rep)->buf->ugd_data) +#else +#define REP_BUF_DATA(rep) ((rep)->buf->data) +#endif + +static int usage_to_joyaxe(int usage) +{ + int joyaxe; + switch (usage) { + case HUG_X: + joyaxe = JOYAXE_X; + break; + case HUG_Y: + joyaxe = JOYAXE_Y; + break; + case HUG_Z: + joyaxe = JOYAXE_Z; + break; + case HUG_SLIDER: + joyaxe = JOYAXE_SLIDER; + break; + case HUG_WHEEL: + joyaxe = JOYAXE_WHEEL; + break; + case HUG_RX: + joyaxe = JOYAXE_RX; + break; + case HUG_RY: + joyaxe = JOYAXE_RY; + break; + case HUG_RZ: + joyaxe = JOYAXE_RZ; + break; + default: + joyaxe = -1; + } + return joyaxe; +} + +static void FreeJoylistItem(SDL_joylist_item *item) +{ + SDL_free(item->path); + SDL_free(item->name); + SDL_free(item); +} + +static void FreeHwData(struct joystick_hwdata *hw) +{ + if (hw->type == BSDJOY_UHID) { + report_free(&hw->inreport); + + if (hw->repdesc) { + hid_dispose_report_desc(hw->repdesc); + } + } + close(hw->fd); + SDL_free(hw); +} + +static struct joystick_hwdata *CreateHwData(const char *path) +{ + struct joystick_hwdata *hw; + struct hid_item hitem; + struct hid_data *hdata; + struct report *rep = NULL; + int fd; + int i; + + fd = open(path, O_RDONLY | O_CLOEXEC); + if (fd == -1) { + SDL_SetError("%s: %s", path, strerror(errno)); + return NULL; + } + + hw = (struct joystick_hwdata *) + SDL_calloc(1, sizeof(struct joystick_hwdata)); + if (!hw) { + close(fd); + return NULL; + } + hw->fd = fd; + +#ifdef SUPPORT_JOY_GAMEPORT + if (SDL_strncmp(path, "/dev/joy", 8) == 0) { + hw->type = BSDJOY_JOY; + hw->naxes = 2; + hw->nbuttons = 2; + } else +#endif + { + hw->type = BSDJOY_UHID; + { + int ax; + for (ax = 0; ax < JOYAXE_count; ax++) { + hw->axis_map[ax] = -1; + } + } + hw->repdesc = hid_get_report_desc(fd); + if (!hw->repdesc) { + SDL_SetError("%s: USB_GET_REPORT_DESC: %s", path, + strerror(errno)); + goto usberr; + } + rep = &hw->inreport; +#if defined(SDL_PLATFORM_FREEBSD) && (__FreeBSD_kernel_version > 800063) || defined(__FreeBSD_kernel__) || defined(__DragonFly__) + rep->rid = hid_get_report_id(fd); + if (rep->rid < 0) { +#else + if (ioctl(fd, USB_GET_REPORT_ID, &rep->rid) < 0) { +#endif + rep->rid = -1; // XXX + } + if (!report_alloc(rep, hw->repdesc, REPORT_INPUT)) { + goto usberr; + } + if (rep->size <= 0) { + SDL_SetError("%s: Input report descriptor has invalid length", + path); + goto usberr; + } +#if defined(USBHID_NEW) || (defined(SDL_PLATFORM_FREEBSD) && __FreeBSD_kernel_version >= 500111) || defined(__FreeBSD_kernel__) || defined(__DragonFly__) + hdata = hid_start_parse(hw->repdesc, 1 << hid_input, rep->rid); +#else + hdata = hid_start_parse(hw->repdesc, 1 << hid_input); +#endif + if (!hdata) { + SDL_SetError("%s: Cannot start HID parser", path); + goto usberr; + } + for (i = 0; i < JOYAXE_count; i++) { + hw->axis_map[i] = -1; + } + + while (hid_get_item(hdata, &hitem) > 0) { + switch (hitem.kind) { + case hid_input: + switch (HID_PAGE(hitem.usage)) { + case HUP_GENERIC_DESKTOP: + { + int usage = HID_USAGE(hitem.usage); + int joyaxe = usage_to_joyaxe(usage); + if (joyaxe >= 0) { + hw->axis_map[joyaxe] = 1; + } else if (usage == HUG_HAT_SWITCH +#ifdef SDL_PLATFORM_OPENBSD + || usage == HUG_DPAD_UP +#endif + ) { + hw->nhats++; + } + break; + } + case HUP_BUTTON: + { + int usage = HID_USAGE(hitem.usage); + if (usage > hw->nbuttons) { + hw->nbuttons = usage; + } + } break; + default: + break; + } + break; + default: + break; + } + } + hid_end_parse(hdata); + for (i = 0; i < JOYAXE_count; i++) { + if (hw->axis_map[i] > 0) { + hw->axis_map[i] = hw->naxes++; + } + } + + if (hw->naxes == 0 && hw->nbuttons == 0 && hw->nhats == 0) { + SDL_SetError("%s: Not a joystick, ignoring", path); + goto usberr; + } + } + + // The poll blocks the event thread. + fcntl(fd, F_SETFL, O_NONBLOCK); +#ifdef SDL_PLATFORM_NETBSD + // Flush pending events + if (rep) { + while (read(fd, REP_BUF_DATA(rep), rep->size) == rep->size) + ; + } +#endif + + return hw; + +usberr: + FreeHwData(hw); + return NULL; +} + +static bool MaybeAddDevice(const char *path) +{ + struct stat sb; + char *name = NULL; + SDL_GUID guid; + SDL_joylist_item *item; + struct joystick_hwdata *hw; + + if (!path) { + return false; + } + + if (stat(path, &sb) == -1) { + return false; + } + + // Check to make sure it's not already in list. + for (item = SDL_joylist; item; item = item->next) { + if (sb.st_rdev == item->devnum) { + return false; // already have this one + } + } + + hw = CreateHwData(path); + if (!hw) { + return false; + } + + if (hw->type == BSDJOY_JOY) { + name = SDL_strdup("Gameport joystick"); + guid = SDL_CreateJoystickGUIDForName(name); + } else { +#ifdef USB_GET_DEVICEINFO + struct usb_device_info di; + if (ioctl(hw->fd, USB_GET_DEVICEINFO, &di) != -1) { + name = SDL_CreateJoystickName(di.udi_vendorNo, di.udi_productNo, di.udi_vendor, di.udi_product); + guid = SDL_CreateJoystickGUID(SDL_HARDWARE_BUS_USB, di.udi_vendorNo, di.udi_productNo, di.udi_releaseNo, di.udi_vendor, di.udi_product, 0, 0); + + if (SDL_ShouldIgnoreJoystick(di.udi_vendorNo, di.udi_productNo, di.udi_releaseNo, name) || + SDL_JoystickHandledByAnotherDriver(&SDL_BSD_JoystickDriver, di.udi_vendorNo, di.udi_productNo, di.udi_releaseNo, name)) { + SDL_free(name); + FreeHwData(hw); + return false; + } + } +#endif // USB_GET_DEVICEINFO + } + if (!name) { + name = SDL_strdup(path); + guid = SDL_CreateJoystickGUIDForName(name); + } + FreeHwData(hw); + + item = (SDL_joylist_item *)SDL_calloc(1, sizeof(SDL_joylist_item)); + if (!item) { + SDL_free(name); + return false; + } + + item->devnum = sb.st_rdev; + item->path = SDL_strdup(path); + item->name = name; + item->guid = guid; + + if ((!item->path) || (!item->name)) { + FreeJoylistItem(item); + return false; + } + + item->device_instance = SDL_GetNextObjectID(); + if (!SDL_joylist_tail) { + SDL_joylist = SDL_joylist_tail = item; + } else { + SDL_joylist_tail->next = item; + SDL_joylist_tail = item; + } + + // Need to increment the joystick count before we post the event + ++numjoysticks; + + SDL_PrivateJoystickAdded(item->device_instance); + + return true; +} + +static bool BSD_JoystickInit(void) +{ + char s[16]; + int i; + + for (i = 0; i < MAX_UHID_JOYS; i++) { +#if defined(SDL_PLATFORM_OPENBSD) && (OpenBSD >= 202105) + SDL_snprintf(s, SDL_arraysize(s), "/dev/ujoy/%d", i); +#else + SDL_snprintf(s, SDL_arraysize(s), "/dev/uhid%d", i); +#endif + MaybeAddDevice(s); + } +#ifdef SUPPORT_JOY_GAMEPORT + for (i = 0; i < MAX_JOY_JOYS; i++) { + SDL_snprintf(s, SDL_arraysize(s), "/dev/joy%d", i); + MaybeAddDevice(s); + } +#endif // SUPPORT_JOY_GAMEPORT + + // Read the default USB HID usage table. + hid_init(NULL); + + return true; +} + +static int BSD_JoystickGetCount(void) +{ + return numjoysticks; +} + +static void BSD_JoystickDetect(void) +{ +} + +static bool BSD_JoystickIsDevicePresent(Uint16 vendor_id, Uint16 product_id, Uint16 version, const char *name) +{ + // We don't override any other drivers + return false; +} + +static SDL_joylist_item *GetJoystickByDevIndex(int device_index) +{ + SDL_joylist_item *item = SDL_joylist; + + if ((device_index < 0) || (device_index >= numjoysticks)) { + return NULL; + } + + while (device_index > 0) { + SDL_assert(item != NULL); + device_index--; + item = item->next; + } + + return item; +} + +static const char *BSD_JoystickGetDeviceName(int device_index) +{ + return GetJoystickByDevIndex(device_index)->name; +} + +static const char *BSD_JoystickGetDevicePath(int device_index) +{ + return GetJoystickByDevIndex(device_index)->path; +} + +static int BSD_JoystickGetDeviceSteamVirtualGamepadSlot(int device_index) +{ + return -1; +} + +static int BSD_JoystickGetDevicePlayerIndex(int device_index) +{ + return -1; +} + +static void BSD_JoystickSetDevicePlayerIndex(int device_index, int player_index) +{ +} + +static SDL_GUID BSD_JoystickGetDeviceGUID(int device_index) +{ + return GetJoystickByDevIndex(device_index)->guid; +} + +// Function to perform the mapping from device index to the instance id for this index +static SDL_JoystickID BSD_JoystickGetDeviceInstanceID(int device_index) +{ + return GetJoystickByDevIndex(device_index)->device_instance; +} + +static unsigned hatval_to_sdl(Sint32 hatval) +{ + static const unsigned hat_dir_map[8] = { + SDL_HAT_UP, SDL_HAT_RIGHTUP, SDL_HAT_RIGHT, SDL_HAT_RIGHTDOWN, + SDL_HAT_DOWN, SDL_HAT_LEFTDOWN, SDL_HAT_LEFT, SDL_HAT_LEFTUP + }; + unsigned result; + if ((hatval & 7) == hatval) + result = hat_dir_map[hatval]; + else + result = SDL_HAT_CENTERED; + return result; +} + +static bool BSD_JoystickOpen(SDL_Joystick *joy, int device_index) +{ + SDL_joylist_item *item = GetJoystickByDevIndex(device_index); + struct joystick_hwdata *hw; + + if (!item) { + return SDL_SetError("No such device"); + } + + hw = CreateHwData(item->path); + if (!hw) { + return false; + } + + joy->hwdata = hw; + joy->naxes = hw->naxes; + joy->nbuttons = hw->nbuttons; + joy->nhats = hw->nhats; + + return true; +} + +static void BSD_JoystickUpdate(SDL_Joystick *joy) +{ + struct hid_item hitem; + struct hid_data *hdata; + struct report *rep; + int nbutton, naxe = -1; + Sint32 v; +#ifdef SDL_PLATFORM_OPENBSD + Sint32 dpad[4] = { 0, 0, 0, 0 }; +#endif + Uint64 timestamp = SDL_GetTicksNS(); + +#ifdef SUPPORT_JOY_GAMEPORT + struct joystick gameport; + static int x, y, xmin = 0xffff, ymin = 0xffff, xmax = 0, ymax = 0; + + if (joy->hwdata->type == BSDJOY_JOY) { + while (read(joy->hwdata->fd, &gameport, sizeof(gameport)) == sizeof(gameport)) { + if (SDL_abs(x - gameport.x) > 8) { + x = gameport.x; + if (x < xmin) { + xmin = x; + } + if (x > xmax) { + xmax = x; + } + if (xmin == xmax) { + xmin--; + xmax++; + } + v = (((SDL_JOYSTICK_AXIS_MAX - SDL_JOYSTICK_AXIS_MIN) * ((Sint32)x - xmin)) / (xmax - xmin)) + SDL_JOYSTICK_AXIS_MIN; + SDL_SendJoystickAxis(timestamp, joy, 0, v); + } + if (SDL_abs(y - gameport.y) > 8) { + y = gameport.y; + if (y < ymin) { + ymin = y; + } + if (y > ymax) { + ymax = y; + } + if (ymin == ymax) { + ymin--; + ymax++; + } + v = (((SDL_JOYSTICK_AXIS_MAX - SDL_JOYSTICK_AXIS_MIN) * ((Sint32)y - ymin)) / (ymax - ymin)) + SDL_JOYSTICK_AXIS_MIN; + SDL_SendJoystickAxis(timestamp, joy, 1, v); + } + SDL_SendJoystickButton(timestamp, joy, 0, (gameport.b1 != 0)); + SDL_SendJoystickButton(timestamp, joy, 1, (gameport.b2 != 0)); + } + return; + } +#endif // SUPPORT_JOY_GAMEPORT + + rep = &joy->hwdata->inreport; + + while (read(joy->hwdata->fd, REP_BUF_DATA(rep), rep->size) == rep->size) { +#if defined(USBHID_NEW) || (defined(SDL_PLATFORM_FREEBSD) && __FreeBSD_kernel_version >= 500111) || defined(__FreeBSD_kernel__) || defined(__DragonFly__) + hdata = hid_start_parse(joy->hwdata->repdesc, 1 << hid_input, rep->rid); +#else + hdata = hid_start_parse(joy->hwdata->repdesc, 1 << hid_input); +#endif + if (!hdata) { + // fprintf(stderr, "%s: Cannot start HID parser\n", joy->hwdata->path); + continue; + } + + while (hid_get_item(hdata, &hitem) > 0) { + switch (hitem.kind) { + case hid_input: + switch (HID_PAGE(hitem.usage)) { + case HUP_GENERIC_DESKTOP: + { + int usage = HID_USAGE(hitem.usage); + int joyaxe = usage_to_joyaxe(usage); + if (joyaxe >= 0) { + naxe = joy->hwdata->axis_map[joyaxe]; + // scaleaxe + v = (Sint32)hid_get_data(REP_BUF_DATA(rep), &hitem); + v = (((SDL_JOYSTICK_AXIS_MAX - SDL_JOYSTICK_AXIS_MIN) * (v - hitem.logical_minimum)) / (hitem.logical_maximum - hitem.logical_minimum)) + SDL_JOYSTICK_AXIS_MIN; + SDL_SendJoystickAxis(timestamp, joy, naxe, v); + } else if (usage == HUG_HAT_SWITCH) { + v = (Sint32)hid_get_data(REP_BUF_DATA(rep), &hitem); + SDL_SendJoystickHat(timestamp, joy, 0, + hatval_to_sdl(v) - + hitem.logical_minimum); + } +#ifdef SDL_PLATFORM_OPENBSD + /* here D-pad directions are reported like separate buttons. + * calculate the SDL hat value from the 4 separate values. + */ + switch (usage) { + case HUG_DPAD_UP: + dpad[0] = (Sint32)hid_get_data(REP_BUF_DATA(rep), &hitem); + break; + case HUG_DPAD_DOWN: + dpad[1] = (Sint32)hid_get_data(REP_BUF_DATA(rep), &hitem); + break; + case HUG_DPAD_RIGHT: + dpad[2] = (Sint32)hid_get_data(REP_BUF_DATA(rep), &hitem); + break; + case HUG_DPAD_LEFT: + dpad[3] = (Sint32)hid_get_data(REP_BUF_DATA(rep), &hitem); + break; + //default: + // no-op + } + SDL_PrivateJoystickHat(joy, 0, (dpad[0] * HAT_UP) | + (dpad[1] * HAT_DOWN) | + (dpad[2] * HAT_RIGHT) | + (dpad[3] * HAT_LEFT) ); +#endif + break; + } + case HUP_BUTTON: + v = (Sint32)hid_get_data(REP_BUF_DATA(rep), &hitem); + nbutton = HID_USAGE(hitem.usage) - 1; // SDL buttons are zero-based + SDL_SendJoystickButton(timestamp, joy, nbutton, (v != 0)); + break; + default: + continue; + } + break; + default: + break; + } + } + hid_end_parse(hdata); + } +} + +// Function to close a joystick after use +static void BSD_JoystickClose(SDL_Joystick *joy) +{ + if (joy->hwdata) { + FreeHwData(joy->hwdata); + joy->hwdata = NULL; + } +} + +static void BSD_JoystickQuit(void) +{ + SDL_joylist_item *item = NULL; + SDL_joylist_item *next = NULL; + + for (item = SDL_joylist; item; item = next) { + next = item->next; + FreeJoylistItem(item); + } + + SDL_joylist = SDL_joylist_tail = NULL; + + numjoysticks = 0; +} + +static bool report_alloc(struct report *r, struct report_desc *rd, int repind) +{ + int len; + +#ifdef __DragonFly__ + len = hid_report_size(rd, repinfo[repind].kind, r->rid); +#elif defined(SDL_PLATFORM_FREEBSD) +#if (__FreeBSD_kernel_version >= 460000) || defined(__FreeBSD_kernel__) +#if (__FreeBSD_kernel_version <= 500111) + len = hid_report_size(rd, r->rid, repinfo[repind].kind); +#else + len = hid_report_size(rd, repinfo[repind].kind, r->rid); +#endif +#else + len = hid_report_size(rd, repinfo[repind].kind, &r->rid); +#endif +#else +#ifdef USBHID_NEW + len = hid_report_size(rd, repinfo[repind].kind, r->rid); +#else + len = hid_report_size(rd, repinfo[repind].kind, &r->rid); +#endif +#endif + + if (len < 0) { + return SDL_SetError("Negative HID report size"); + } + r->size = len; + + if (r->size > 0) { +#if defined(SDL_PLATFORM_FREEBSD) && (__FreeBSD_kernel_version > 900000) || defined(__DragonFly__) + r->buf = SDL_malloc(r->size); +#else + r->buf = SDL_malloc(sizeof(*r->buf) - sizeof(REP_BUF_DATA(r)) + + r->size); +#endif + if (!r->buf) { + return false; + } + } else { + r->buf = NULL; + } + + r->status = SREPORT_CLEAN; + return true; +} + +static void report_free(struct report *r) +{ + SDL_free(r->buf); + r->status = SREPORT_UNINIT; +} + +static bool BSD_JoystickRumble(SDL_Joystick *joystick, Uint16 low_frequency_rumble, Uint16 high_frequency_rumble) +{ + return SDL_Unsupported(); +} + +static bool BSD_JoystickRumbleTriggers(SDL_Joystick *joystick, Uint16 left_rumble, Uint16 right_rumble) +{ + return SDL_Unsupported(); +} + +static bool BSD_JoystickGetGamepadMapping(int device_index, SDL_GamepadMapping *out) +{ + return false; +} + +static bool BSD_JoystickSetLED(SDL_Joystick *joystick, Uint8 red, Uint8 green, Uint8 blue) +{ + return SDL_Unsupported(); +} + +static bool BSD_JoystickSendEffect(SDL_Joystick *joystick, const void *data, int size) +{ + return SDL_Unsupported(); +} + +static bool BSD_JoystickSetSensorsEnabled(SDL_Joystick *joystick, bool enabled) +{ + return SDL_Unsupported(); +} + +SDL_JoystickDriver SDL_BSD_JoystickDriver = { + BSD_JoystickInit, + BSD_JoystickGetCount, + BSD_JoystickDetect, + BSD_JoystickIsDevicePresent, + BSD_JoystickGetDeviceName, + BSD_JoystickGetDevicePath, + BSD_JoystickGetDeviceSteamVirtualGamepadSlot, + BSD_JoystickGetDevicePlayerIndex, + BSD_JoystickSetDevicePlayerIndex, + BSD_JoystickGetDeviceGUID, + BSD_JoystickGetDeviceInstanceID, + BSD_JoystickOpen, + BSD_JoystickRumble, + BSD_JoystickRumbleTriggers, + BSD_JoystickSetLED, + BSD_JoystickSendEffect, + BSD_JoystickSetSensorsEnabled, + BSD_JoystickUpdate, + BSD_JoystickClose, + BSD_JoystickQuit, + BSD_JoystickGetGamepadMapping +}; + +#endif // SDL_JOYSTICK_USBHID -- cgit v1.2.3