mirror of
https://github.com/TorqueGameEngines/Torque3D.git
synced 2026-03-14 01:40:50 +00:00
Updates the SDL library to the latest standard bugfix release
This commit is contained in:
parent
cb766f2878
commit
083d2175ea
1280 changed files with 343926 additions and 179615 deletions
File diff suppressed because it is too large
Load diff
|
|
@ -1,6 +1,6 @@
|
|||
/*
|
||||
Simple DirectMedia Layer
|
||||
Copyright (C) 1997-2022 Sam Lantinga <slouken@libsdl.org>
|
||||
Copyright (C) 1997-2023 Sam Lantinga <slouken@libsdl.org>
|
||||
|
||||
This software is provided 'as-is', without any express or implied
|
||||
warranty. In no event will the authors be held liable for any damages
|
||||
|
|
@ -22,7 +22,7 @@
|
|||
|
||||
#ifdef SDL_JOYSTICK_HIDAPI
|
||||
|
||||
#ifdef SDL_LIBUSB_DYNAMIC
|
||||
#ifdef HAVE_LIBUSB
|
||||
#define HAVE_ENABLE_GAMECUBE_ADAPTORS
|
||||
#endif
|
||||
|
||||
|
|
|
|||
|
|
@ -1085,12 +1085,25 @@ int hid_init(void)
|
|||
struct hid_device_info HID_API_EXPORT * HID_API_CALL hid_enumerate(unsigned short vendor_id, unsigned short product_id)
|
||||
{
|
||||
struct hid_device_info *root = NULL;
|
||||
const char *hint = SDL_GetHint(SDL_HINT_HIDAPI_IGNORE_DEVICES);
|
||||
|
||||
hid_mutex_guard l( &g_DevicesMutex );
|
||||
for ( hid_device_ref<CHIDDevice> pDevice = g_Devices; pDevice; pDevice = pDevice->next )
|
||||
{
|
||||
const hid_device_info *info = pDevice->GetDeviceInfo();
|
||||
if ( ( vendor_id == 0 && product_id == 0 ) ||
|
||||
( vendor_id == info->vendor_id && product_id == info->product_id ) )
|
||||
|
||||
/* See if there are any devices we should skip in enumeration */
|
||||
if (hint) {
|
||||
char vendor_match[16], product_match[16];
|
||||
SDL_snprintf(vendor_match, sizeof(vendor_match), "0x%.4x/0x0000", info->vendor_id);
|
||||
SDL_snprintf(product_match, sizeof(product_match), "0x%.4x/0x%.4x", info->vendor_id, info->product_id);
|
||||
if (SDL_strcasestr(hint, vendor_match) || SDL_strcasestr(hint, product_match)) {
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
if ( ( vendor_id == 0x0 || info->vendor_id == vendor_id ) &&
|
||||
( product_id == 0x0 || info->product_id == product_id ) )
|
||||
{
|
||||
hid_device_info *dev = CopyHIDDeviceInfo( info );
|
||||
dev->next = root;
|
||||
|
|
|
|||
|
|
@ -836,9 +836,20 @@ int HID_API_EXPORT hid_set_nonblocking(hid_device *dev, int nonblock)
|
|||
struct hid_device_info HID_API_EXPORT *hid_enumerate(unsigned short vendor_id, unsigned short product_id)
|
||||
{ @autoreleasepool {
|
||||
struct hid_device_info *root = NULL;
|
||||
|
||||
if ( ( vendor_id == 0 && product_id == 0 ) ||
|
||||
( vendor_id == VALVE_USB_VID && product_id == D0G_BLE2_PID ) )
|
||||
const char *hint = SDL_GetHint(SDL_HINT_HIDAPI_IGNORE_DEVICES);
|
||||
|
||||
/* See if there are any devices we should skip in enumeration */
|
||||
if (hint) {
|
||||
char vendor_match[16], product_match[16];
|
||||
SDL_snprintf(vendor_match, sizeof(vendor_match), "0x%.4x/0x0000", VALVE_USB_VID);
|
||||
SDL_snprintf(product_match, sizeof(product_match), "0x%.4x/0x%.4x", VALVE_USB_VID, D0G_BLE2_PID);
|
||||
if (SDL_strcasestr(hint, vendor_match) || SDL_strcasestr(hint, product_match)) {
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
if ( ( vendor_id == 0 || vendor_id == VALVE_USB_VID ) &&
|
||||
( product_id == 0 || product_id == D0G_BLE2_PID ) )
|
||||
{
|
||||
HIDBLEManager *bleManager = HIDBLEManager.sharedInstance;
|
||||
[bleManager updateConnectedSteamControllers:false];
|
||||
|
|
|
|||
|
|
@ -28,8 +28,35 @@
|
|||
*/
|
||||
|
||||
#include "../../SDL_internal.h"
|
||||
#include "SDL_thread.h"
|
||||
#include "../../thread/SDL_systhread.h"
|
||||
#include "SDL_hints.h"
|
||||
#include "SDL_mutex.h"
|
||||
#include "SDL_thread.h"
|
||||
|
||||
#ifdef realloc
|
||||
#undef realloc
|
||||
#endif
|
||||
#define realloc SDL_realloc
|
||||
#ifdef snprintf
|
||||
#undef snprintf
|
||||
#endif
|
||||
#define snprintf SDL_snprintf
|
||||
#ifdef strdup
|
||||
#undef strdup
|
||||
#endif
|
||||
#define strdup SDL_strdup
|
||||
#ifdef strncpy
|
||||
#undef strncpy
|
||||
#endif
|
||||
#define strncpy SDL_strlcpy
|
||||
#ifdef tolower
|
||||
#undef tolower
|
||||
#endif
|
||||
#define tolower SDL_tolower
|
||||
#ifdef wcsncpy
|
||||
#undef wcsncpy
|
||||
#endif
|
||||
#define wcsncpy SDL_wcslcpy
|
||||
|
||||
#ifndef HAVE_WCSDUP
|
||||
#ifdef HAVE__WCSDUP
|
||||
|
|
@ -51,7 +78,10 @@ static wchar_t *_dupwcs(const wchar_t *src)
|
|||
#endif /* HAVE_WCSDUP */
|
||||
|
||||
#include <libusb.h>
|
||||
#ifndef _WIN32
|
||||
#define HAVE_SETLOCALE
|
||||
#include <locale.h> /* setlocale */
|
||||
#endif
|
||||
|
||||
#include "../hidapi/hidapi.h"
|
||||
|
||||
|
|
@ -173,6 +203,10 @@ struct hid_device_ {
|
|||
int transfer_loop_finished;
|
||||
struct libusb_transfer *transfer;
|
||||
|
||||
/* Quirks */
|
||||
int skip_output_report_id;
|
||||
int no_output_reports_on_intr_ep;
|
||||
|
||||
/* List of received input reports. */
|
||||
struct input_report *input_reports;
|
||||
};
|
||||
|
|
@ -288,7 +322,7 @@ static int get_usage(uint8_t *report_descriptor, size_t size,
|
|||
/* Can't ever happen since size_code is & 0x3 */
|
||||
data_len = 0;
|
||||
break;
|
||||
};
|
||||
}
|
||||
key_size = 1;
|
||||
}
|
||||
|
||||
|
|
@ -529,6 +563,22 @@ static struct usb_string_cache_entry *usb_string_cache_insert()
|
|||
return new_entry;
|
||||
}
|
||||
|
||||
static int usb_string_can_cache(uint16_t vid, uint16_t pid)
|
||||
{
|
||||
if (!vid || !pid) {
|
||||
/* We can't cache these, they aren't unique */
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (vid == 0x0f0d && pid == 0x00dc) {
|
||||
/* HORI reuses this VID/PID for many different products */
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* We can cache these strings */
|
||||
return 1;
|
||||
}
|
||||
|
||||
static const struct usb_string_cache_entry *usb_string_cache_find(struct libusb_device_descriptor *desc, struct libusb_device_handle *handle)
|
||||
{
|
||||
struct usb_string_cache_entry *entry = NULL;
|
||||
|
|
@ -579,16 +629,18 @@ static char *make_path(libusb_device *dev, int interface_number)
|
|||
int HID_API_EXPORT hid_init(void)
|
||||
{
|
||||
if (!usb_context) {
|
||||
const char *locale;
|
||||
|
||||
/* Init Libusb */
|
||||
if (libusb_init(&usb_context))
|
||||
return -1;
|
||||
|
||||
#ifdef HAVE_SETLOCALE
|
||||
/* Set the locale if it's not set. */
|
||||
locale = setlocale(LC_CTYPE, NULL);
|
||||
if (!locale)
|
||||
setlocale(LC_CTYPE, "");
|
||||
{
|
||||
const char *locale = setlocale(LC_CTYPE, NULL);
|
||||
if (!locale)
|
||||
setlocale(LC_CTYPE, "");
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
|
@ -635,6 +687,9 @@ static int is_xbox360(unsigned short vendor_id, const struct libusb_interface_de
|
|||
0x1bad, /* Harmonix */
|
||||
0x20d6, /* PowerA */
|
||||
0x24c6, /* PowerA */
|
||||
0x2c22, /* Qanba */
|
||||
0x2dc8, /* 8BitDo */
|
||||
0x9886, /* ASTRO Gaming */
|
||||
};
|
||||
|
||||
if (intf_desc->bInterfaceClass == LIBUSB_CLASS_VENDOR_SPEC &&
|
||||
|
|
@ -656,13 +711,16 @@ static int is_xboxone(unsigned short vendor_id, const struct libusb_interface_de
|
|||
static const int XB1_IFACE_SUBCLASS = 71;
|
||||
static const int XB1_IFACE_PROTOCOL = 208;
|
||||
static const int SUPPORTED_VENDORS[] = {
|
||||
0x044f, /* Thrustmaster */
|
||||
0x045e, /* Microsoft */
|
||||
0x0738, /* Mad Catz */
|
||||
0x0e6f, /* PDP */
|
||||
0x0f0d, /* Hori */
|
||||
0x10f5, /* Turtle Beach */
|
||||
0x1532, /* Razer Wildcat */
|
||||
0x20d6, /* PowerA */
|
||||
0x24c6, /* PowerA */
|
||||
0x2dc8, /* 8BitDo */
|
||||
0x2e24, /* Hyperkin */
|
||||
};
|
||||
|
||||
|
|
@ -682,6 +740,8 @@ static int is_xboxone(unsigned short vendor_id, const struct libusb_interface_de
|
|||
|
||||
static int should_enumerate_interface(unsigned short vendor_id, const struct libusb_interface_descriptor *intf_desc)
|
||||
{
|
||||
//printf("Checking interface 0x%x %d/%d/%d/%d\n", vendor_id, intf_desc->bInterfaceNumber, intf_desc->bInterfaceClass, intf_desc->bInterfaceSubClass, intf_desc->bInterfaceProtocol);
|
||||
|
||||
if (intf_desc->bInterfaceClass == LIBUSB_CLASS_HID)
|
||||
return 1;
|
||||
|
||||
|
|
@ -706,6 +766,7 @@ struct hid_device_info HID_API_EXPORT *hid_enumerate(unsigned short vendor_id,
|
|||
|
||||
struct hid_device_info *root = NULL; /* return object */
|
||||
struct hid_device_info *cur_dev = NULL;
|
||||
const char *hint = SDL_GetHint(SDL_HINT_HIDAPI_IGNORE_DEVICES);
|
||||
|
||||
if(hid_init() < 0)
|
||||
return NULL;
|
||||
|
|
@ -723,10 +784,21 @@ struct hid_device_info HID_API_EXPORT *hid_enumerate(unsigned short vendor_id,
|
|||
unsigned short dev_vid = desc.idVendor;
|
||||
unsigned short dev_pid = desc.idProduct;
|
||||
|
||||
/* See if there are any devices we should skip in enumeration */
|
||||
if (hint) {
|
||||
char vendor_match[16], product_match[16];
|
||||
SDL_snprintf(vendor_match, sizeof(vendor_match), "0x%.4x/0x0000", dev_vid);
|
||||
SDL_snprintf(product_match, sizeof(product_match), "0x%.4x/0x%.4x", dev_vid, dev_pid);
|
||||
if (SDL_strcasestr(hint, vendor_match) || SDL_strcasestr(hint, product_match)) {
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
res = libusb_get_active_config_descriptor(dev, &conf_desc);
|
||||
if (res < 0)
|
||||
libusb_get_config_descriptor(dev, 0, &conf_desc);
|
||||
if (conf_desc) {
|
||||
|
||||
for (j = 0; j < conf_desc->bNumInterfaces; j++) {
|
||||
const struct libusb_interface *intf = &conf_desc->interface[j];
|
||||
for (k = 0; k < intf->num_altsetting; k++) {
|
||||
|
|
@ -764,7 +836,7 @@ struct hid_device_info HID_API_EXPORT *hid_enumerate(unsigned short vendor_id,
|
|||
get_usb_string(handle, desc.iSerialNumber);
|
||||
|
||||
/* Manufacturer and Product strings */
|
||||
if (dev_vid && dev_pid) {
|
||||
if (usb_string_can_cache(dev_vid, dev_pid)) {
|
||||
string_cache = usb_string_cache_find(&desc, handle);
|
||||
if (string_cache) {
|
||||
if (string_cache->vendor) {
|
||||
|
|
@ -994,8 +1066,9 @@ static void LIBUSB_CALL read_callback(struct libusb_transfer *transfer)
|
|||
}
|
||||
|
||||
|
||||
static int read_thread(void *param)
|
||||
static int SDLCALL read_thread(void *param)
|
||||
{
|
||||
int res;
|
||||
hid_device *dev = (hid_device *)param;
|
||||
uint8_t *buf;
|
||||
const size_t length = dev->input_ep_max_packet_size;
|
||||
|
|
@ -1014,14 +1087,18 @@ static int read_thread(void *param)
|
|||
|
||||
/* Make the first submission. Further submissions are made
|
||||
from inside read_callback() */
|
||||
libusb_submit_transfer(dev->transfer);
|
||||
res = libusb_submit_transfer(dev->transfer);
|
||||
if(res < 0) {
|
||||
LOG("libusb_submit_transfer failed: %d %s. Stopping read_thread from running\n", res, libusb_error_name(res));
|
||||
dev->shutdown_thread = 1;
|
||||
dev->transfer_loop_finished = 1;
|
||||
}
|
||||
|
||||
/* Notify the main thread that the read thread is up and running. */
|
||||
SDL_WaitThreadBarrier(&dev->barrier);
|
||||
|
||||
/* Handle all the events. */
|
||||
while (!dev->shutdown_thread) {
|
||||
int res;
|
||||
res = libusb_handle_events(usb_context);
|
||||
if (res < 0) {
|
||||
/* There was an error. */
|
||||
|
|
@ -1065,6 +1142,20 @@ static int read_thread(void *param)
|
|||
return 0;
|
||||
}
|
||||
|
||||
static void init_xbox360(libusb_device_handle *device_handle, unsigned short idVendor, unsigned short idProduct, struct libusb_config_descriptor *conf_desc)
|
||||
{
|
||||
if ((idVendor == 0x05ac && idProduct == 0x055b) /* Gamesir-G3w */ ||
|
||||
idVendor == 0x0f0d /* Hori Xbox controllers */) {
|
||||
unsigned char data[20];
|
||||
|
||||
/* The HORIPAD FPS for Nintendo Switch requires this to enable input reports.
|
||||
This VID/PID is also shared with other HORI controllers, but they all seem
|
||||
to be fine with this as well.
|
||||
*/
|
||||
libusb_control_transfer(device_handle, 0xC1, 0x01, 0x100, 0x0, data, sizeof(data), 100);
|
||||
}
|
||||
}
|
||||
|
||||
static void init_xboxone(libusb_device_handle *device_handle, unsigned short idVendor, unsigned short idProduct, struct libusb_config_descriptor *conf_desc)
|
||||
{
|
||||
static const int VENDOR_MICROSOFT = 0x045e;
|
||||
|
|
@ -1110,6 +1201,19 @@ static void init_xboxone(libusb_device_handle *device_handle, unsigned short idV
|
|||
}
|
||||
}
|
||||
|
||||
static void calculate_device_quirks(hid_device *dev, unsigned short idVendor, unsigned short idProduct)
|
||||
{
|
||||
static const int VENDOR_SONY = 0x054c;
|
||||
static const int PRODUCT_PS3_CONTROLLER = 0x0268;
|
||||
static const int PRODUCT_NAVIGATION_CONTROLLER = 0x042f;
|
||||
|
||||
if (idVendor == VENDOR_SONY &&
|
||||
(idProduct == PRODUCT_PS3_CONTROLLER || idProduct == PRODUCT_NAVIGATION_CONTROLLER)) {
|
||||
dev->skip_output_report_id = 1;
|
||||
dev->no_output_reports_on_intr_ep = 1;
|
||||
}
|
||||
}
|
||||
|
||||
hid_device * HID_API_EXPORT hid_open_path(const char *path, int bExclusive)
|
||||
{
|
||||
hid_device *dev = NULL;
|
||||
|
|
@ -1184,6 +1288,11 @@ hid_device * HID_API_EXPORT hid_open_path(const char *path, int bExclusive)
|
|||
break;
|
||||
}
|
||||
|
||||
/* Initialize XBox 360 controllers */
|
||||
if (is_xbox360(desc.idVendor, intf_desc)) {
|
||||
init_xbox360(dev->device_handle, desc.idVendor, desc.idProduct, conf_desc);
|
||||
}
|
||||
|
||||
/* Initialize XBox One controllers */
|
||||
if (is_xboxone(desc.idVendor, intf_desc)) {
|
||||
init_xboxone(dev->device_handle, desc.idVendor, desc.idProduct, conf_desc);
|
||||
|
|
@ -1230,7 +1339,9 @@ hid_device * HID_API_EXPORT hid_open_path(const char *path, int bExclusive)
|
|||
}
|
||||
}
|
||||
|
||||
dev->thread = SDL_CreateThread(read_thread, NULL, dev);
|
||||
calculate_device_quirks(dev, desc.idVendor, desc.idProduct);
|
||||
|
||||
dev->thread = SDL_CreateThreadInternal(read_thread, "libusb", 0, dev);
|
||||
|
||||
/* Wait here for the read thread to be initialized. */
|
||||
SDL_WaitThreadBarrier(&dev->barrier);
|
||||
|
|
@ -1262,11 +1373,11 @@ int HID_API_EXPORT hid_write(hid_device *dev, const unsigned char *data, size_t
|
|||
{
|
||||
int res;
|
||||
|
||||
if (dev->output_endpoint <= 0) {
|
||||
if (dev->output_endpoint <= 0 || dev->no_output_reports_on_intr_ep) {
|
||||
int report_number = data[0];
|
||||
int skipped_report_id = 0;
|
||||
|
||||
if (report_number == 0x0) {
|
||||
if (report_number == 0x0 || dev->skip_output_report_id) {
|
||||
data++;
|
||||
length--;
|
||||
skipped_report_id = 1;
|
||||
|
|
@ -1709,13 +1820,15 @@ static struct lang_map_entry lang_map[] = {
|
|||
|
||||
uint16_t get_usb_code_for_current_locale(void)
|
||||
{
|
||||
char *locale;
|
||||
char *locale = NULL;
|
||||
char search_string[64];
|
||||
char *ptr;
|
||||
struct lang_map_entry *lang;
|
||||
|
||||
/* Get the current locale. */
|
||||
#ifdef HAVE_SETLOCALE
|
||||
locale = setlocale(0, NULL);
|
||||
#endif
|
||||
if (!locale)
|
||||
return 0x0;
|
||||
|
||||
|
|
|
|||
|
|
@ -39,7 +39,7 @@ Bugs (hidraw implementation only):
|
|||
-----------------------------------
|
||||
On Kernel versions < 2.6.34, if your device uses numbered reports, an extra
|
||||
byte will be returned at the beginning of all reports returned from read()
|
||||
for hidraw devices. This is worked around in the libary. No action should be
|
||||
for hidraw devices. This is worked around in the library. No action should be
|
||||
necessary in the client library.
|
||||
|
||||
On Kernel versions < 2.6.35, reports will only be sent using a Set_Report
|
||||
|
|
|
|||
|
|
@ -22,6 +22,8 @@
|
|||
********************************************************/
|
||||
#include "../../SDL_internal.h"
|
||||
|
||||
#include "SDL_hints.h"
|
||||
|
||||
#ifndef _GNU_SOURCE
|
||||
#define _GNU_SOURCE /* needed for wcsdup() before glibc 2.10 */
|
||||
#endif
|
||||
|
|
@ -198,7 +200,7 @@ static int uses_numbered_reports(__u8 *report_descriptor, __u32 size) {
|
|||
/* Can't ever happen since size_code is & 0x3 */
|
||||
data_len = 0;
|
||||
break;
|
||||
};
|
||||
}
|
||||
key_size = 1;
|
||||
}
|
||||
|
||||
|
|
@ -219,7 +221,7 @@ parse_uevent_info(const char *uevent, unsigned *bus_type,
|
|||
unsigned short *vendor_id, unsigned short *product_id,
|
||||
char **serial_number_utf8, char **product_name_utf8)
|
||||
{
|
||||
char *tmp = strdup(uevent);
|
||||
char *tmp;
|
||||
char *saveptr = NULL;
|
||||
char *line;
|
||||
char *key;
|
||||
|
|
@ -229,6 +231,15 @@ parse_uevent_info(const char *uevent, unsigned *bus_type,
|
|||
int found_serial = 0;
|
||||
int found_name = 0;
|
||||
|
||||
if (!uevent) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
tmp = strdup(uevent);
|
||||
if (!tmp) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
line = strtok_r(tmp, "\n", &saveptr);
|
||||
while (line != NULL) {
|
||||
/* line: "KEY=value" */
|
||||
|
|
@ -472,6 +483,7 @@ struct hid_device_info HID_API_EXPORT *hid_enumerate(unsigned short vendor_id,
|
|||
struct hid_device_info *root = NULL; /* return object */
|
||||
struct hid_device_info *cur_dev = NULL;
|
||||
struct hid_device_info *prev_dev = NULL; /* previous device */
|
||||
const char *hint = SDL_GetHint(SDL_HINT_HIDAPI_IGNORE_DEVICES);
|
||||
|
||||
hid_init();
|
||||
|
||||
|
|
@ -543,6 +555,16 @@ struct hid_device_info HID_API_EXPORT *hid_enumerate(unsigned short vendor_id,
|
|||
goto next;
|
||||
}
|
||||
|
||||
/* See if there are any devices we should skip in enumeration */
|
||||
if (hint) {
|
||||
char vendor_match[16], product_match[16];
|
||||
SDL_snprintf(vendor_match, sizeof(vendor_match), "0x%.4x/0x0000", dev_vid);
|
||||
SDL_snprintf(product_match, sizeof(product_match), "0x%.4x/0x%.4x", dev_vid, dev_pid);
|
||||
if (SDL_strcasestr(hint, vendor_match) || SDL_strcasestr(hint, product_match)) {
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
/* Check the VID/PID against the arguments */
|
||||
if ((vendor_id == 0x0 || vendor_id == dev_vid) &&
|
||||
(product_id == 0x0 || product_id == dev_pid)) {
|
||||
|
|
@ -707,6 +729,8 @@ hid_device * hid_open(unsigned short vendor_id, unsigned short product_id, const
|
|||
|
||||
hid_device * HID_API_EXPORT hid_open_path(const char *path, int bExclusive)
|
||||
{
|
||||
const int MAX_ATTEMPTS = 10;
|
||||
int attempt;
|
||||
hid_device *dev = NULL;
|
||||
|
||||
hid_init();
|
||||
|
|
@ -714,7 +738,15 @@ hid_device * HID_API_EXPORT hid_open_path(const char *path, int bExclusive)
|
|||
dev = new_hid_device();
|
||||
|
||||
/* OPEN HERE */
|
||||
dev->device_handle = open(path, O_RDWR | O_CLOEXEC);
|
||||
for (attempt = 1; attempt <= MAX_ATTEMPTS; ++attempt) {
|
||||
dev->device_handle = open(path, O_RDWR | O_CLOEXEC);
|
||||
if (dev->device_handle < 0 && errno == EACCES) {
|
||||
/* udev might be setting up permissions, wait a bit and try again */
|
||||
usleep(1 * 1000);
|
||||
continue;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
/* If we have a good handle, return it. */
|
||||
if (dev->device_handle >= 0) {
|
||||
|
|
|
|||
|
|
@ -21,6 +21,8 @@
|
|||
********************************************************/
|
||||
#include "../../SDL_internal.h"
|
||||
|
||||
#include "SDL_hints.h"
|
||||
|
||||
/* See Apple Technical Note TN2187 for details on IOHidManager. */
|
||||
|
||||
#include <IOKit/hid/IOHIDManager.h>
|
||||
|
|
@ -156,11 +158,12 @@ static hid_device *new_hid_device(void)
|
|||
|
||||
static void free_hid_device(hid_device *dev)
|
||||
{
|
||||
struct input_report *rpt;
|
||||
if (!dev)
|
||||
return;
|
||||
|
||||
/* Delete any input reports still left over. */
|
||||
struct input_report *rpt = dev->input_reports;
|
||||
rpt = dev->input_reports;
|
||||
while (rpt) {
|
||||
struct input_report *next = rpt->next;
|
||||
free(rpt->data);
|
||||
|
|
@ -260,14 +263,12 @@ static int get_string_property(IOHIDDeviceRef device, CFStringRef prop, wchar_t
|
|||
buf[0] = 0;
|
||||
|
||||
if (str && CFGetTypeID(str) == CFStringGetTypeID()) {
|
||||
len --;
|
||||
|
||||
CFIndex str_len = CFStringGetLength(str);
|
||||
CFIndex used_buf_len, chars_copied;
|
||||
CFRange range;
|
||||
CFIndex str_len = CFStringGetLength(str);
|
||||
len --;
|
||||
range.location = 0;
|
||||
range.length = (str_len > len)? len: str_len;
|
||||
CFIndex used_buf_len;
|
||||
CFIndex chars_copied;
|
||||
chars_copied = CFStringGetBytes(str,
|
||||
range,
|
||||
kCFStringEncodingUTF32LE,
|
||||
|
|
@ -299,14 +300,12 @@ static int get_string_property_utf8(IOHIDDeviceRef device, CFStringRef prop, cha
|
|||
buf[0] = 0;
|
||||
|
||||
if (str && CFGetTypeID(str) == CFStringGetTypeID()) {
|
||||
len--;
|
||||
|
||||
CFIndex str_len = CFStringGetLength(str);
|
||||
CFIndex used_buf_len, chars_copied;
|
||||
CFRange range;
|
||||
CFIndex str_len = CFStringGetLength(str);
|
||||
len--;
|
||||
range.location = 0;
|
||||
range.length = (str_len > len)? len: str_len;
|
||||
CFIndex used_buf_len;
|
||||
CFIndex chars_copied;
|
||||
chars_copied = CFStringGetBytes(str,
|
||||
range,
|
||||
kCFStringEncodingUTF8,
|
||||
|
|
@ -517,7 +516,10 @@ struct hid_device_info HID_API_EXPORT *hid_enumerate(unsigned short vendor_id,
|
|||
struct hid_device_info *root = NULL; // return object
|
||||
struct hid_device_info *cur_dev = NULL;
|
||||
CFIndex num_devices;
|
||||
CFSetRef device_set;
|
||||
IOHIDDeviceRef *device_array;
|
||||
int i;
|
||||
const char *hint = SDL_GetHint(SDL_HINT_HIDAPI_IGNORE_DEVICES);
|
||||
|
||||
/* Set up the HID Manager if it hasn't been done */
|
||||
if (hid_init() < 0)
|
||||
|
|
@ -527,7 +529,7 @@ struct hid_device_info HID_API_EXPORT *hid_enumerate(unsigned short vendor_id,
|
|||
process_pending_events();
|
||||
|
||||
/* Get a list of the Devices */
|
||||
CFSetRef device_set = IOHIDManagerCopyDevices(hid_mgr);
|
||||
device_set = IOHIDManagerCopyDevices(hid_mgr);
|
||||
if (!device_set)
|
||||
return NULL;
|
||||
|
||||
|
|
@ -537,7 +539,7 @@ struct hid_device_info HID_API_EXPORT *hid_enumerate(unsigned short vendor_id,
|
|||
CFRelease(device_set);
|
||||
return NULL;
|
||||
}
|
||||
IOHIDDeviceRef *device_array = (IOHIDDeviceRef*)calloc(num_devices, sizeof(IOHIDDeviceRef));
|
||||
device_array = (IOHIDDeviceRef*)calloc(num_devices, sizeof(IOHIDDeviceRef));
|
||||
CFSetGetValues(device_set, (const void **) device_array);
|
||||
|
||||
/* Iterate over each device, making an entry for it. */
|
||||
|
|
@ -568,9 +570,19 @@ struct hid_device_info HID_API_EXPORT *hid_enumerate(unsigned short vendor_id,
|
|||
dev_vid = get_vendor_id(dev);
|
||||
dev_pid = get_product_id(dev);
|
||||
|
||||
/* See if there are any devices we should skip in enumeration */
|
||||
if (hint) {
|
||||
char vendor_match[16], product_match[16];
|
||||
SDL_snprintf(vendor_match, sizeof(vendor_match), "0x%.4x/0x0000", dev_vid);
|
||||
SDL_snprintf(product_match, sizeof(product_match), "0x%.4x/0x%.4x", dev_vid, dev_pid);
|
||||
if (SDL_strcasestr(hint, vendor_match) || SDL_strcasestr(hint, product_match)) {
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
/* Check the VID/PID against the arguments */
|
||||
if ((vendor_id == 0x0 && product_id == 0x0) ||
|
||||
(vendor_id == dev_vid && product_id == dev_pid)) {
|
||||
if ((vendor_id == 0x0 || dev_vid == vendor_id) &&
|
||||
(product_id == 0x0 || dev_pid == product_id)) {
|
||||
struct hid_device_info *tmp;
|
||||
|
||||
/* VID/PID match. Create the record. */
|
||||
|
|
@ -733,13 +745,14 @@ static void perform_signal_callback(void *context)
|
|||
static void *read_thread(void *param)
|
||||
{
|
||||
hid_device *dev = (hid_device *)param;
|
||||
CFRunLoopSourceContext ctx;
|
||||
SInt32 code;
|
||||
|
||||
/* Move the device's run loop to this thread. */
|
||||
IOHIDDeviceScheduleWithRunLoop(dev->device_handle, CFRunLoopGetCurrent(), dev->run_loop_mode);
|
||||
|
||||
/* Create the RunLoopSource which is used to signal the
|
||||
event loop to stop when hid_close() is called. */
|
||||
CFRunLoopSourceContext ctx;
|
||||
memset(&ctx, 0, sizeof(ctx));
|
||||
ctx.version = 0;
|
||||
ctx.info = dev;
|
||||
|
|
@ -756,11 +769,10 @@ static void *read_thread(void *param)
|
|||
|
||||
/* Run the Event Loop. CFRunLoopRunInMode() will dispatch HID input
|
||||
reports into the hid_report_callback(). */
|
||||
SInt32 code;
|
||||
while (!dev->shutdown_thread && !dev->disconnected) {
|
||||
code = CFRunLoopRunInMode(dev->run_loop_mode, 1000/*sec*/, FALSE);
|
||||
/* Return if the device has been disconnected */
|
||||
if (code == kCFRunLoopRunFinished) {
|
||||
if (code == kCFRunLoopRunFinished || code == kCFRunLoopRunStopped) {
|
||||
dev->disconnected = 1;
|
||||
break;
|
||||
}
|
||||
|
|
@ -796,23 +808,29 @@ static void *read_thread(void *param)
|
|||
|
||||
hid_device * HID_API_EXPORT hid_open_path(const char *path, int bExclusive)
|
||||
{
|
||||
int i;
|
||||
int i;
|
||||
hid_device *dev = NULL;
|
||||
CFIndex num_devices;
|
||||
|
||||
CFSetRef device_set;
|
||||
IOHIDDeviceRef *device_array;
|
||||
|
||||
dev = new_hid_device();
|
||||
|
||||
/* Set up the HID Manager if it hasn't been done */
|
||||
if (hid_init() < 0)
|
||||
return NULL;
|
||||
|
||||
|
||||
#if 0 /* We have a path because the IOHIDManager is already updated */
|
||||
/* give the IOHIDManager a chance to update itself */
|
||||
process_pending_events();
|
||||
|
||||
CFSetRef device_set = IOHIDManagerCopyDevices(hid_mgr);
|
||||
#endif
|
||||
|
||||
device_set = IOHIDManagerCopyDevices(hid_mgr);
|
||||
if (!device_set)
|
||||
return NULL;
|
||||
|
||||
num_devices = CFSetGetCount(device_set);
|
||||
IOHIDDeviceRef *device_array = (IOHIDDeviceRef *)calloc(num_devices, sizeof(IOHIDDeviceRef));
|
||||
device_array = (IOHIDDeviceRef *)calloc(num_devices, sizeof(IOHIDDeviceRef));
|
||||
CFSetGetValues(device_set, (const void **) device_array);
|
||||
for (i = 0; i < num_devices; i++) {
|
||||
char cbuf[BUF_LEN];
|
||||
|
|
@ -824,6 +842,7 @@ hid_device * HID_API_EXPORT hid_open_path(const char *path, int bExclusive)
|
|||
IOReturn ret = IOHIDDeviceOpen(os_dev, kIOHIDOptionsTypeNone);
|
||||
if (ret == kIOReturnSuccess) {
|
||||
char str[32];
|
||||
struct hid_device_list_node *node;
|
||||
|
||||
free(device_array);
|
||||
CFRelease(device_set);
|
||||
|
|
@ -836,7 +855,7 @@ hid_device * HID_API_EXPORT hid_open_path(const char *path, int bExclusive)
|
|||
|
||||
/* Create the Run Loop Mode for this device.
|
||||
printing the reference seems to work. */
|
||||
sprintf(str, "HIDAPI_%p", os_dev);
|
||||
snprintf(str, sizeof(str), "HIDAPI_%p", os_dev);
|
||||
dev->run_loop_mode =
|
||||
CFStringCreateWithCString(NULL, str, kCFStringEncodingASCII);
|
||||
|
||||
|
|
@ -845,7 +864,7 @@ hid_device * HID_API_EXPORT hid_open_path(const char *path, int bExclusive)
|
|||
os_dev, dev->input_report_buf, dev->max_input_report_len,
|
||||
&hid_report_callback, dev);
|
||||
|
||||
struct hid_device_list_node *node = (struct hid_device_list_node *)calloc(1, sizeof(struct hid_device_list_node));
|
||||
node = (struct hid_device_list_node *)calloc(1, sizeof(struct hid_device_list_node));
|
||||
node->dev = dev;
|
||||
node->next = device_list;
|
||||
device_list = node;
|
||||
|
|
@ -1083,13 +1102,13 @@ int HID_API_EXPORT hid_get_feature_report(hid_device *dev, unsigned char *data,
|
|||
{
|
||||
CFIndex len = length;
|
||||
IOReturn res;
|
||||
|
||||
int skipped_report_id = 0, report_number;
|
||||
|
||||
/* Return if the device has been unplugged. */
|
||||
if (dev->disconnected)
|
||||
return -1;
|
||||
|
||||
int skipped_report_id = 0;
|
||||
int report_number = data[0];
|
||||
report_number = data[0];
|
||||
if (report_number == 0x0) {
|
||||
/* Offset the return buffer by 1, so that the report ID
|
||||
will remain in byte 0. */
|
||||
|
|
|
|||
|
|
@ -21,6 +21,8 @@
|
|||
********************************************************/
|
||||
#include "../../SDL_internal.h"
|
||||
|
||||
#include "SDL_hints.h"
|
||||
|
||||
#include <windows.h>
|
||||
|
||||
#ifndef _WIN32_WINNT_WIN8
|
||||
|
|
@ -344,13 +346,14 @@ int hid_blacklist(unsigned short vendor_id, unsigned short product_id)
|
|||
{ 0x1532, 0x010B }, /* Razer Arctosa Gaming keyboard */
|
||||
{ 0x045E, 0x0822 }, /* Microsoft Precision Mouse */
|
||||
{ 0x0D8C, 0x0014 }, /* Sharkoon Skiller SGH2 headset */
|
||||
{ 0x1CCF, 0x0000 }, /* All Konami Amusement Devices */
|
||||
|
||||
/* Turns into an Android controller when enumerated... */
|
||||
{ 0x0738, 0x2217 } /* SPEEDLINK COMPETITION PRO */
|
||||
};
|
||||
|
||||
for (i = 0; i < (sizeof(known_bad)/sizeof(known_bad[0])); i++) {
|
||||
if ((vendor_id == known_bad[i].vid) && (product_id == known_bad[i].pid)) {
|
||||
if ((vendor_id == known_bad[i].vid) && (product_id == known_bad[i].pid || known_bad[i].pid == 0x0000)) {
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
|
@ -371,6 +374,7 @@ struct hid_device_info HID_API_EXPORT * HID_API_CALL hid_enumerate(unsigned shor
|
|||
SP_DEVICE_INTERFACE_DETAIL_DATA_A *device_interface_detail_data = NULL;
|
||||
HDEVINFO device_info_set = INVALID_HANDLE_VALUE;
|
||||
int device_index = 0;
|
||||
const char *hint = SDL_GetHint(SDL_HINT_HIDAPI_IGNORE_DEVICES);
|
||||
|
||||
if (hid_init() < 0)
|
||||
return NULL;
|
||||
|
|
@ -488,6 +492,16 @@ struct hid_device_info HID_API_EXPORT * HID_API_CALL hid_enumerate(unsigned shor
|
|||
HidD_GetAttributes(write_handle, &attrib);
|
||||
//wprintf(L"Product/Vendor: %x %x\n", attrib.ProductID, attrib.VendorID);
|
||||
|
||||
/* See if there are any devices we should skip in enumeration */
|
||||
if (hint) {
|
||||
char vendor_match[16], product_match[16];
|
||||
SDL_snprintf(vendor_match, sizeof(vendor_match), "0x%.4x/0x0000", attrib.VendorID);
|
||||
SDL_snprintf(product_match, sizeof(product_match), "0x%.4x/0x%.4x", attrib.VendorID, attrib.ProductID);
|
||||
if (SDL_strcasestr(hint, vendor_match) || SDL_strcasestr(hint, product_match)) {
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
/* Check the VID/PID to see if we should add this
|
||||
device to the enumeration list. */
|
||||
if ((vendor_id == 0x0 || attrib.VendorID == vendor_id) &&
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue