early-access version 1617
This commit is contained in:
248
externals/SDL/src/hidapi/SDL_hidapi.c
vendored
248
externals/SDL/src/hidapi/SDL_hidapi.c
vendored
@@ -63,6 +63,7 @@
|
||||
#define make_path PLATFORM_make_path
|
||||
#define read_thread PLATFORM_read_thread
|
||||
|
||||
#undef HIDAPI_H__
|
||||
#if __LINUX__
|
||||
|
||||
#include "../../core/linux/SDL_udev.h"
|
||||
@@ -97,8 +98,6 @@ static const SDL_UDEV_Symbols *udev_ctx = NULL;
|
||||
#include "windows/hid.c"
|
||||
#define HAVE_PLATFORM_BACKEND 1
|
||||
#define udev_ctx 1
|
||||
#else
|
||||
#error Need a hid.c for this platform!
|
||||
#endif
|
||||
|
||||
#undef hid_device_
|
||||
@@ -129,6 +128,68 @@ static const SDL_UDEV_Symbols *udev_ctx = NULL;
|
||||
#undef make_path
|
||||
#undef read_thread
|
||||
|
||||
#ifdef SDL_JOYSTICK_HIDAPI_STEAMXBOX
|
||||
#define HAVE_DRIVER_BACKEND 1
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_DRIVER_BACKEND
|
||||
|
||||
/* DRIVER HIDAPI Implementation */
|
||||
|
||||
#define hid_device_ DRIVER_hid_device_
|
||||
#define hid_device DRIVER_hid_device
|
||||
#define hid_device_info DRIVER_hid_device_info
|
||||
#define hid_init DRIVER_hid_init
|
||||
#define hid_exit DRIVER_hid_exit
|
||||
#define hid_enumerate DRIVER_hid_enumerate
|
||||
#define hid_free_enumeration DRIVER_hid_free_enumeration
|
||||
#define hid_open DRIVER_hid_open
|
||||
#define hid_open_path DRIVER_hid_open_path
|
||||
#define hid_write DRIVER_hid_write
|
||||
#define hid_read_timeout DRIVER_hid_read_timeout
|
||||
#define hid_read DRIVER_hid_read
|
||||
#define hid_set_nonblocking DRIVER_hid_set_nonblocking
|
||||
#define hid_send_feature_report DRIVER_hid_send_feature_report
|
||||
#define hid_get_feature_report DRIVER_hid_get_feature_report
|
||||
#define hid_close DRIVER_hid_close
|
||||
#define hid_get_manufacturer_string DRIVER_hid_get_manufacturer_string
|
||||
#define hid_get_product_string DRIVER_hid_get_product_string
|
||||
#define hid_get_serial_number_string DRIVER_hid_get_serial_number_string
|
||||
#define hid_get_indexed_string DRIVER_hid_get_indexed_string
|
||||
#define hid_error DRIVER_hid_error
|
||||
|
||||
#ifdef SDL_JOYSTICK_HIDAPI_STEAMXBOX
|
||||
#undef HIDAPI_H__
|
||||
#include "steamxbox/hid.c"
|
||||
#else
|
||||
#error Need a driver hid.c for this platform!
|
||||
#endif
|
||||
|
||||
#undef hid_device_
|
||||
#undef hid_device
|
||||
#undef hid_device_info
|
||||
#undef hid_init
|
||||
#undef hid_exit
|
||||
#undef hid_enumerate
|
||||
#undef hid_free_enumeration
|
||||
#undef hid_open
|
||||
#undef hid_open_path
|
||||
#undef hid_write
|
||||
#undef hid_read_timeout
|
||||
#undef hid_read
|
||||
#undef hid_set_nonblocking
|
||||
#undef hid_send_feature_report
|
||||
#undef hid_get_feature_report
|
||||
#undef hid_close
|
||||
#undef hid_get_manufacturer_string
|
||||
#undef hid_get_product_string
|
||||
#undef hid_get_serial_number_string
|
||||
#undef hid_get_indexed_string
|
||||
#undef hid_error
|
||||
|
||||
#endif /* HAVE_DRIVER_BACKEND */
|
||||
|
||||
|
||||
#ifdef SDL_LIBUSB_DYNAMIC
|
||||
/* libusb HIDAPI Implementation */
|
||||
|
||||
@@ -298,23 +359,21 @@ SDL_libusb_get_string_descriptor(libusb_device_handle *dev,
|
||||
/* Shared HIDAPI Implementation */
|
||||
|
||||
#undef HIDAPI_H__
|
||||
#include "hidapi.h"
|
||||
#include "hidapi/hidapi.h"
|
||||
|
||||
struct hidapi_backend {
|
||||
#define F(x) typeof(x) *x
|
||||
F(hid_write);
|
||||
F(hid_read_timeout);
|
||||
F(hid_read);
|
||||
F(hid_set_nonblocking);
|
||||
F(hid_send_feature_report);
|
||||
F(hid_get_feature_report);
|
||||
F(hid_close);
|
||||
F(hid_get_manufacturer_string);
|
||||
F(hid_get_product_string);
|
||||
F(hid_get_serial_number_string);
|
||||
F(hid_get_indexed_string);
|
||||
F(hid_error);
|
||||
#undef F
|
||||
int (*hid_write)(hid_device* device, const unsigned char* data, size_t length);
|
||||
int (*hid_read_timeout)(hid_device* device, unsigned char* data, size_t length, int milliseconds);
|
||||
int (*hid_read)(hid_device* device, unsigned char* data, size_t length);
|
||||
int (*hid_set_nonblocking)(hid_device* device, int nonblock);
|
||||
int (*hid_send_feature_report)(hid_device* device, const unsigned char* data, size_t length);
|
||||
int (*hid_get_feature_report)(hid_device* device, unsigned char* data, size_t length);
|
||||
void (*hid_close)(hid_device* device);
|
||||
int (*hid_get_manufacturer_string)(hid_device* device, wchar_t* string, size_t maxlen);
|
||||
int (*hid_get_product_string)(hid_device* device, wchar_t* string, size_t maxlen);
|
||||
int (*hid_get_serial_number_string)(hid_device* device, wchar_t* string, size_t maxlen);
|
||||
int (*hid_get_indexed_string)(hid_device* device, int string_index, wchar_t* string, size_t maxlen);
|
||||
const wchar_t* (*hid_error)(hid_device* device);
|
||||
};
|
||||
|
||||
#if HAVE_PLATFORM_BACKEND
|
||||
@@ -334,6 +393,23 @@ static const struct hidapi_backend PLATFORM_Backend = {
|
||||
};
|
||||
#endif /* HAVE_PLATFORM_BACKEND */
|
||||
|
||||
#if HAVE_DRIVER_BACKEND
|
||||
static const struct hidapi_backend DRIVER_Backend = {
|
||||
(void*)DRIVER_hid_write,
|
||||
(void*)DRIVER_hid_read_timeout,
|
||||
(void*)DRIVER_hid_read,
|
||||
(void*)DRIVER_hid_set_nonblocking,
|
||||
(void*)DRIVER_hid_send_feature_report,
|
||||
(void*)DRIVER_hid_get_feature_report,
|
||||
(void*)DRIVER_hid_close,
|
||||
(void*)DRIVER_hid_get_manufacturer_string,
|
||||
(void*)DRIVER_hid_get_product_string,
|
||||
(void*)DRIVER_hid_get_serial_number_string,
|
||||
(void*)DRIVER_hid_get_indexed_string,
|
||||
(void*)DRIVER_hid_error
|
||||
};
|
||||
#endif /* HAVE_DRIVER_BACKEND */
|
||||
|
||||
#ifdef SDL_LIBUSB_DYNAMIC
|
||||
static const struct hidapi_backend LIBUSB_Backend = {
|
||||
(void*)LIBUSB_hid_write,
|
||||
@@ -361,7 +437,7 @@ struct _HIDDeviceWrapper
|
||||
static HIDDeviceWrapper *
|
||||
CreateHIDDeviceWrapper(hid_device *device, const struct hidapi_backend *backend)
|
||||
{
|
||||
HIDDeviceWrapper *ret = SDL_malloc(sizeof(*ret));
|
||||
HIDDeviceWrapper *ret = (HIDDeviceWrapper *)SDL_malloc(sizeof(*ret));
|
||||
ret->device = device;
|
||||
ret->backend = backend;
|
||||
return ret;
|
||||
@@ -420,6 +496,28 @@ LIBUSB_CopyHIDDeviceInfo(struct LIBUSB_hid_device_info *pSrc,
|
||||
}
|
||||
#endif /* SDL_LIBUSB_DYNAMIC */
|
||||
|
||||
#if HAVE_DRIVER_BACKEND
|
||||
static void
|
||||
DRIVER_CopyHIDDeviceInfo(struct DRIVER_hid_device_info *pSrc,
|
||||
struct hid_device_info *pDst)
|
||||
{
|
||||
COPY_IF_EXISTS(path)
|
||||
pDst->vendor_id = pSrc->vendor_id;
|
||||
pDst->product_id = pSrc->product_id;
|
||||
WCOPY_IF_EXISTS(serial_number)
|
||||
pDst->release_number = pSrc->release_number;
|
||||
WCOPY_IF_EXISTS(manufacturer_string)
|
||||
WCOPY_IF_EXISTS(product_string)
|
||||
pDst->usage_page = pSrc->usage_page;
|
||||
pDst->usage = pSrc->usage;
|
||||
pDst->interface_number = pSrc->interface_number;
|
||||
pDst->interface_class = pSrc->interface_class;
|
||||
pDst->interface_subclass = pSrc->interface_subclass;
|
||||
pDst->interface_protocol = pSrc->interface_protocol;
|
||||
pDst->next = NULL;
|
||||
}
|
||||
#endif /* HAVE_DRIVER_BACKEND */
|
||||
|
||||
#if HAVE_PLATFORM_BACKEND
|
||||
static void
|
||||
PLATFORM_CopyHIDDeviceInfo(struct PLATFORM_hid_device_info *pSrc,
|
||||
@@ -458,8 +556,9 @@ int HID_API_EXPORT HID_API_CALL hid_init(void)
|
||||
#ifdef SDL_LIBUSB_DYNAMIC
|
||||
libusb_ctx.libhandle = SDL_LoadObject(SDL_LIBUSB_DYNAMIC);
|
||||
if (libusb_ctx.libhandle != NULL) {
|
||||
SDL_bool loaded = SDL_TRUE;
|
||||
#define LOAD_LIBUSB_SYMBOL(func) \
|
||||
libusb_ctx.func = SDL_LoadFunction(libusb_ctx.libhandle, "libusb_" #func);
|
||||
if (!(libusb_ctx.func = SDL_LoadFunction(libusb_ctx.libhandle, "libusb_" #func))) {loaded = SDL_FALSE;}
|
||||
LOAD_LIBUSB_SYMBOL(init)
|
||||
LOAD_LIBUSB_SYMBOL(exit)
|
||||
LOAD_LIBUSB_SYMBOL(get_device_list)
|
||||
@@ -488,9 +587,17 @@ int HID_API_EXPORT HID_API_CALL hid_init(void)
|
||||
LOAD_LIBUSB_SYMBOL(handle_events_completed)
|
||||
#undef LOAD_LIBUSB_SYMBOL
|
||||
|
||||
if ((err = LIBUSB_hid_init()) < 0) {
|
||||
if (loaded == SDL_TRUE) {
|
||||
if ((err = LIBUSB_hid_init()) < 0) {
|
||||
SDL_UnloadObject(libusb_ctx.libhandle);
|
||||
libusb_ctx.libhandle = NULL;
|
||||
return err;
|
||||
}
|
||||
} else {
|
||||
SDL_UnloadObject(libusb_ctx.libhandle);
|
||||
return err;
|
||||
libusb_ctx.libhandle = NULL;
|
||||
/* SDL_LogWarn(SDL_LOG_CATEGORY_INPUT, SDL_LIBUSB_DYNAMIC " found but could not load function."); */
|
||||
/* ignore error: continue without libusb */
|
||||
}
|
||||
}
|
||||
#endif /* SDL_LIBUSB_DYNAMIC */
|
||||
@@ -502,13 +609,16 @@ int HID_API_EXPORT HID_API_CALL hid_init(void)
|
||||
if (udev_ctx && (err = PLATFORM_hid_init()) < 0) {
|
||||
#ifdef SDL_LIBUSB_DYNAMIC
|
||||
if (libusb_ctx.libhandle) {
|
||||
LIBUSB_hid_exit();
|
||||
SDL_UnloadObject(libusb_ctx.libhandle);
|
||||
libusb_ctx.libhandle = NULL;
|
||||
}
|
||||
#endif /* SDL_LIBUSB_DYNAMIC */
|
||||
return err;
|
||||
}
|
||||
#endif /* HAVE_PLATFORM_BACKEND */
|
||||
|
||||
SDL_hidapi_wasinit = SDL_TRUE;
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -519,6 +629,7 @@ int HID_API_EXPORT HID_API_CALL hid_exit(void)
|
||||
if (SDL_hidapi_wasinit == SDL_FALSE) {
|
||||
return 0;
|
||||
}
|
||||
SDL_hidapi_wasinit = SDL_FALSE;
|
||||
|
||||
#if HAVE_PLATFORM_BACKEND
|
||||
if (udev_ctx) {
|
||||
@@ -529,6 +640,7 @@ int HID_API_EXPORT HID_API_CALL hid_exit(void)
|
||||
if (libusb_ctx.libhandle) {
|
||||
err |= LIBUSB_hid_exit(); /* Ehhhhh */
|
||||
SDL_UnloadObject(libusb_ctx.libhandle);
|
||||
libusb_ctx.libhandle = NULL;
|
||||
}
|
||||
#endif /* SDL_LIBUSB_DYNAMIC */
|
||||
return err;
|
||||
@@ -540,22 +652,40 @@ struct hid_device_info HID_API_EXPORT * HID_API_CALL hid_enumerate(unsigned shor
|
||||
struct LIBUSB_hid_device_info *usb_devs = NULL;
|
||||
struct LIBUSB_hid_device_info *usb_dev;
|
||||
#endif
|
||||
#if HAVE_DRIVER_BACKEND
|
||||
struct DRIVER_hid_device_info* driver_devs = NULL;
|
||||
struct DRIVER_hid_device_info* driver_dev;
|
||||
#endif
|
||||
#if HAVE_PLATFORM_BACKEND
|
||||
struct PLATFORM_hid_device_info *raw_devs = NULL;
|
||||
struct PLATFORM_hid_device_info *raw_dev;
|
||||
#endif
|
||||
struct hid_device_info *devs = NULL, *last = NULL, *new_dev;
|
||||
|
||||
if (SDL_hidapi_wasinit == SDL_FALSE) {
|
||||
hid_init();
|
||||
if (hid_init() != 0) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
#ifdef SDL_LIBUSB_DYNAMIC
|
||||
if (libusb_ctx.libhandle) {
|
||||
usb_devs = LIBUSB_hid_enumerate(vendor_id, product_id);
|
||||
#ifdef DEBUG_HIDAPI
|
||||
SDL_Log("libusb devices found:");
|
||||
#endif
|
||||
for (usb_dev = usb_devs; usb_dev; usb_dev = usb_dev->next) {
|
||||
new_dev = (struct hid_device_info*) SDL_malloc(sizeof(struct hid_device_info));
|
||||
if (!new_dev) {
|
||||
LIBUSB_hid_free_enumeration(usb_devs);
|
||||
hid_free_enumeration(devs);
|
||||
SDL_OutOfMemory();
|
||||
return NULL;
|
||||
}
|
||||
LIBUSB_CopyHIDDeviceInfo(usb_dev, new_dev);
|
||||
#ifdef DEBUG_HIDAPI
|
||||
SDL_Log(" - %ls %ls 0x%.4hx 0x%.4hx",
|
||||
usb_dev->manufacturer_string, usb_dev->product_string,
|
||||
usb_dev->vendor_id, usb_dev->product_id);
|
||||
#endif
|
||||
|
||||
if (last != NULL) {
|
||||
last->next = new_dev;
|
||||
@@ -567,11 +697,34 @@ struct hid_device_info HID_API_EXPORT * HID_API_CALL hid_enumerate(unsigned shor
|
||||
}
|
||||
#endif /* SDL_LIBUSB_DYNAMIC */
|
||||
|
||||
#ifdef HAVE_DRIVER_BACKEND
|
||||
driver_devs = DRIVER_hid_enumerate(vendor_id, product_id);
|
||||
for (driver_dev = driver_devs; driver_dev; driver_dev = driver_dev->next) {
|
||||
new_dev = (struct hid_device_info*) SDL_malloc(sizeof(struct hid_device_info));
|
||||
DRIVER_CopyHIDDeviceInfo(driver_dev, new_dev);
|
||||
|
||||
if (last != NULL) {
|
||||
last->next = new_dev;
|
||||
} else {
|
||||
devs = new_dev;
|
||||
}
|
||||
last = new_dev;
|
||||
}
|
||||
#endif /* HAVE_DRIVER_BACKEND */
|
||||
|
||||
#if HAVE_PLATFORM_BACKEND
|
||||
if (udev_ctx) {
|
||||
raw_devs = PLATFORM_hid_enumerate(vendor_id, product_id);
|
||||
#ifdef DEBUG_HIDAPI
|
||||
SDL_Log("hidraw devices found:");
|
||||
#endif
|
||||
for (raw_dev = raw_devs; raw_dev; raw_dev = raw_dev->next) {
|
||||
SDL_bool bFound = SDL_FALSE;
|
||||
#ifdef DEBUG_HIDAPI
|
||||
SDL_Log(" - %ls %ls 0x%.4hx 0x%.4hx",
|
||||
raw_dev->manufacturer_string, raw_dev->product_string,
|
||||
raw_dev->vendor_id, raw_dev->product_id);
|
||||
#endif
|
||||
#ifdef SDL_LIBUSB_DYNAMIC
|
||||
for (usb_dev = usb_devs; usb_dev; usb_dev = usb_dev->next) {
|
||||
if (raw_dev->vendor_id == usb_dev->vendor_id &&
|
||||
@@ -581,9 +734,30 @@ struct hid_device_info HID_API_EXPORT * HID_API_CALL hid_enumerate(unsigned shor
|
||||
break;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
#ifdef HAVE_DRIVER_BACKEND
|
||||
for (driver_dev = driver_devs; driver_dev; driver_dev = driver_dev->next) {
|
||||
if (raw_dev->vendor_id == driver_dev->vendor_id &&
|
||||
raw_dev->product_id == driver_dev->product_id &&
|
||||
(raw_dev->interface_number < 0 || raw_dev->interface_number == driver_dev->interface_number)) {
|
||||
bFound = SDL_TRUE;
|
||||
break;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
if (!bFound) {
|
||||
new_dev = (struct hid_device_info*) SDL_malloc(sizeof(struct hid_device_info));
|
||||
if (!new_dev) {
|
||||
#ifdef SDL_LIBUSB_DYNAMIC
|
||||
if (libusb_ctx.libhandle) {
|
||||
LIBUSB_hid_free_enumeration(usb_devs);
|
||||
}
|
||||
#endif
|
||||
PLATFORM_hid_free_enumeration(raw_devs);
|
||||
hid_free_enumeration(devs);
|
||||
SDL_OutOfMemory();
|
||||
return NULL;
|
||||
}
|
||||
PLATFORM_CopyHIDDeviceInfo(raw_dev, new_dev);
|
||||
new_dev->next = NULL;
|
||||
|
||||
@@ -624,8 +798,8 @@ HID_API_EXPORT hid_device * HID_API_CALL hid_open(unsigned short vendor_id, unsi
|
||||
{
|
||||
hid_device *pDevice = NULL;
|
||||
|
||||
if (SDL_hidapi_wasinit == SDL_FALSE) {
|
||||
hid_init();
|
||||
if (hid_init() != 0) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
#if HAVE_PLATFORM_BACKEND
|
||||
@@ -636,6 +810,15 @@ HID_API_EXPORT hid_device * HID_API_CALL hid_open(unsigned short vendor_id, unsi
|
||||
return WrapHIDDevice(wrapper);
|
||||
}
|
||||
#endif /* HAVE_PLATFORM_BACKEND */
|
||||
|
||||
#if HAVE_DRIVER_BACKEND
|
||||
if ((pDevice = (hid_device*) DRIVER_hid_open(vendor_id, product_id, serial_number)) != NULL) {
|
||||
|
||||
HIDDeviceWrapper *wrapper = CreateHIDDeviceWrapper(pDevice, &DRIVER_Backend);
|
||||
return WrapHIDDevice(wrapper);
|
||||
}
|
||||
#endif /* HAVE_DRIVER_BACKEND */
|
||||
|
||||
#ifdef SDL_LIBUSB_DYNAMIC
|
||||
if (libusb_ctx.libhandle &&
|
||||
(pDevice = (hid_device*) LIBUSB_hid_open(vendor_id, product_id, serial_number)) != NULL) {
|
||||
@@ -644,6 +827,7 @@ HID_API_EXPORT hid_device * HID_API_CALL hid_open(unsigned short vendor_id, unsi
|
||||
return WrapHIDDevice(wrapper);
|
||||
}
|
||||
#endif /* SDL_LIBUSB_DYNAMIC */
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
@@ -651,8 +835,8 @@ HID_API_EXPORT hid_device * HID_API_CALL hid_open_path(const char *path, int bEx
|
||||
{
|
||||
hid_device *pDevice = NULL;
|
||||
|
||||
if (SDL_hidapi_wasinit == SDL_FALSE) {
|
||||
hid_init();
|
||||
if (hid_init() != 0) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
#if HAVE_PLATFORM_BACKEND
|
||||
@@ -663,6 +847,15 @@ HID_API_EXPORT hid_device * HID_API_CALL hid_open_path(const char *path, int bEx
|
||||
return WrapHIDDevice(wrapper);
|
||||
}
|
||||
#endif /* HAVE_PLATFORM_BACKEND */
|
||||
|
||||
#if HAVE_DRIVER_BACKEND
|
||||
if ((pDevice = (hid_device*) DRIVER_hid_open_path(path, bExclusive)) != NULL) {
|
||||
|
||||
HIDDeviceWrapper *wrapper = CreateHIDDeviceWrapper(pDevice, &DRIVER_Backend);
|
||||
return WrapHIDDevice(wrapper);
|
||||
}
|
||||
#endif /* HAVE_DRIVER_BACKEND */
|
||||
|
||||
#ifdef SDL_LIBUSB_DYNAMIC
|
||||
if (libusb_ctx.libhandle &&
|
||||
(pDevice = (hid_device*) LIBUSB_hid_open_path(path, bExclusive)) != NULL) {
|
||||
@@ -671,6 +864,7 @@ HID_API_EXPORT hid_device * HID_API_CALL hid_open_path(const char *path, int bEx
|
||||
return WrapHIDDevice(wrapper);
|
||||
}
|
||||
#endif /* SDL_LIBUSB_DYNAMIC */
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
52
externals/SDL/src/hidapi/android/hid.cpp
vendored
52
externals/SDL/src/hidapi/android/hid.cpp
vendored
@@ -436,6 +436,12 @@ public:
|
||||
g_JVM->AttachCurrentThread( &env, NULL );
|
||||
pthread_setspecific( g_ThreadKey, (void*)env );
|
||||
|
||||
if ( !g_HIDDeviceManagerCallbackHandler )
|
||||
{
|
||||
LOGV( "Device open without callback handler" );
|
||||
return false;
|
||||
}
|
||||
|
||||
m_bIsWaitingForOpen = false;
|
||||
m_bOpenResult = env->CallBooleanMethod( g_HIDDeviceManagerCallbackHandler, g_midHIDDeviceManagerOpen, m_nId );
|
||||
ExceptionCheck( env, "BOpen" );
|
||||
@@ -545,11 +551,18 @@ public:
|
||||
g_JVM->AttachCurrentThread( &env, NULL );
|
||||
pthread_setspecific( g_ThreadKey, (void*)env );
|
||||
|
||||
jbyteArray pBuf = NewByteArray( env, pData, nDataLen );
|
||||
int nRet = env->CallIntMethod( g_HIDDeviceManagerCallbackHandler, g_midHIDDeviceManagerSendOutputReport, m_nId, pBuf );
|
||||
ExceptionCheck( env, "SendOutputReport" );
|
||||
|
||||
env->DeleteLocalRef( pBuf );
|
||||
int nRet = -1;
|
||||
if ( g_HIDDeviceManagerCallbackHandler )
|
||||
{
|
||||
jbyteArray pBuf = NewByteArray( env, pData, nDataLen );
|
||||
nRet = env->CallIntMethod( g_HIDDeviceManagerCallbackHandler, g_midHIDDeviceManagerSendOutputReport, m_nId, pBuf );
|
||||
ExceptionCheck( env, "SendOutputReport" );
|
||||
env->DeleteLocalRef( pBuf );
|
||||
}
|
||||
else
|
||||
{
|
||||
LOGV( "SendOutputReport without callback handler" );
|
||||
}
|
||||
return nRet;
|
||||
}
|
||||
|
||||
@@ -560,10 +573,18 @@ public:
|
||||
g_JVM->AttachCurrentThread( &env, NULL );
|
||||
pthread_setspecific( g_ThreadKey, (void*)env );
|
||||
|
||||
jbyteArray pBuf = NewByteArray( env, pData, nDataLen );
|
||||
int nRet = env->CallIntMethod( g_HIDDeviceManagerCallbackHandler, g_midHIDDeviceManagerSendFeatureReport, m_nId, pBuf );
|
||||
ExceptionCheck( env, "SendFeatureReport" );
|
||||
env->DeleteLocalRef( pBuf );
|
||||
int nRet = -1;
|
||||
if ( g_HIDDeviceManagerCallbackHandler )
|
||||
{
|
||||
jbyteArray pBuf = NewByteArray( env, pData, nDataLen );
|
||||
nRet = env->CallIntMethod( g_HIDDeviceManagerCallbackHandler, g_midHIDDeviceManagerSendFeatureReport, m_nId, pBuf );
|
||||
ExceptionCheck( env, "SendFeatureReport" );
|
||||
env->DeleteLocalRef( pBuf );
|
||||
}
|
||||
else
|
||||
{
|
||||
LOGV( "SendFeatureReport without callback handler" );
|
||||
}
|
||||
return nRet;
|
||||
}
|
||||
|
||||
@@ -587,6 +608,12 @@ public:
|
||||
g_JVM->AttachCurrentThread( &env, NULL );
|
||||
pthread_setspecific( g_ThreadKey, (void*)env );
|
||||
|
||||
if ( !g_HIDDeviceManagerCallbackHandler )
|
||||
{
|
||||
LOGV( "GetFeatureReport without callback handler" );
|
||||
return -1;
|
||||
}
|
||||
|
||||
{
|
||||
hid_mutex_guard cvl( &m_cvLock );
|
||||
if ( m_bIsWaitingForFeatureReport )
|
||||
@@ -657,8 +684,11 @@ public:
|
||||
g_JVM->AttachCurrentThread( &env, NULL );
|
||||
pthread_setspecific( g_ThreadKey, (void*)env );
|
||||
|
||||
env->CallVoidMethod( g_HIDDeviceManagerCallbackHandler, g_midHIDDeviceManagerClose, m_nId );
|
||||
ExceptionCheck( env, "Close" );
|
||||
if ( g_HIDDeviceManagerCallbackHandler )
|
||||
{
|
||||
env->CallVoidMethod( g_HIDDeviceManagerCallbackHandler, g_midHIDDeviceManagerClose, m_nId );
|
||||
ExceptionCheck( env, "Close" );
|
||||
}
|
||||
|
||||
hid_mutex_guard dataLock( &m_dataLock );
|
||||
m_vecData.clear();
|
||||
|
28
externals/SDL/src/hidapi/libusb/hid.c
vendored
28
externals/SDL/src/hidapi/libusb/hid.c
vendored
@@ -524,17 +524,17 @@ static int is_xbox360(unsigned short vendor_id, const struct libusb_interface_de
|
||||
|
||||
static int is_xboxone(unsigned short vendor_id, const struct libusb_interface_descriptor *intf_desc)
|
||||
{
|
||||
static const int XB1_IFACE_SUBCLASS = 71;
|
||||
static const int XB1_IFACE_PROTOCOL = 208;
|
||||
static const int SUPPORTED_VENDORS[] = {
|
||||
0x045e, /* Microsoft */
|
||||
0x0738, /* Mad Catz */
|
||||
0x0e6f, /* PDP */
|
||||
0x0f0d, /* Hori */
|
||||
0x1532, /* Razer Wildcat */
|
||||
0x24c6, /* PowerA */
|
||||
0x2e24, /* Hyperkin */
|
||||
};
|
||||
static const int XB1_IFACE_SUBCLASS = 71;
|
||||
static const int XB1_IFACE_PROTOCOL = 208;
|
||||
static const int SUPPORTED_VENDORS[] = {
|
||||
0x045e, /* Microsoft */
|
||||
0x0738, /* Mad Catz */
|
||||
0x0e6f, /* PDP */
|
||||
0x0f0d, /* Hori */
|
||||
0x1532, /* Razer Wildcat */
|
||||
0x24c6, /* PowerA */
|
||||
0x2e24, /* Hyperkin */
|
||||
};
|
||||
|
||||
if (intf_desc->bInterfaceNumber == 0 &&
|
||||
intf_desc->bInterfaceClass == LIBUSB_CLASS_VENDOR_SPEC &&
|
||||
@@ -783,7 +783,7 @@ hid_device * hid_open(unsigned short vendor_id, unsigned short product_id, const
|
||||
return handle;
|
||||
}
|
||||
|
||||
static void read_callback(struct libusb_transfer *transfer)
|
||||
static void LIBUSB_CALL read_callback(struct libusb_transfer *transfer)
|
||||
{
|
||||
hid_device *dev = (hid_device *)transfer->user_data;
|
||||
int res;
|
||||
@@ -982,9 +982,9 @@ hid_device * HID_API_EXPORT hid_open_path(const char *path, int bExclusive)
|
||||
libusb_get_config_descriptor(usb_dev, 0, &conf_desc);
|
||||
if (!conf_desc)
|
||||
continue;
|
||||
for (j = 0; j < conf_desc->bNumInterfaces; j++) {
|
||||
for (j = 0; j < conf_desc->bNumInterfaces && !good_open; j++) {
|
||||
const struct libusb_interface *intf = &conf_desc->interface[j];
|
||||
for (k = 0; k < intf->num_altsetting; k++) {
|
||||
for (k = 0; k < intf->num_altsetting && !good_open; k++) {
|
||||
const struct libusb_interface_descriptor *intf_desc;
|
||||
intf_desc = &intf->altsetting[k];
|
||||
if (should_enumerate_interface(desc.idVendor, intf_desc)) {
|
||||
|
40
externals/SDL/src/hidapi/linux/hid.c
vendored
40
externals/SDL/src/hidapi/linux/hid.c
vendored
@@ -86,7 +86,7 @@ struct hid_device_ {
|
||||
int device_handle;
|
||||
int blocking;
|
||||
int uses_numbered_reports;
|
||||
int is_bluetooth;
|
||||
int needs_ble_hack;
|
||||
};
|
||||
|
||||
|
||||
@@ -119,7 +119,7 @@ static hid_device *new_hid_device(void)
|
||||
dev->device_handle = -1;
|
||||
dev->blocking = 1;
|
||||
dev->uses_numbered_reports = 0;
|
||||
dev->is_bluetooth = 0;
|
||||
dev->needs_ble_hack = 0;
|
||||
|
||||
return dev;
|
||||
}
|
||||
@@ -269,12 +269,12 @@ next_line:
|
||||
return (found_id && found_name && found_serial);
|
||||
}
|
||||
|
||||
static int is_bluetooth(hid_device *dev)
|
||||
static int is_BLE(hid_device *dev)
|
||||
{
|
||||
struct udev *udev;
|
||||
struct udev_device *udev_dev, *hid_dev;
|
||||
struct stat s;
|
||||
int ret = -1;
|
||||
int ret;
|
||||
|
||||
/* Create the udev object */
|
||||
udev = udev_new();
|
||||
@@ -284,13 +284,13 @@ static int is_bluetooth(hid_device *dev)
|
||||
}
|
||||
|
||||
/* Get the dev_t (major/minor numbers) from the file handle. */
|
||||
ret = fstat(dev->device_handle, &s);
|
||||
if (-1 == ret) {
|
||||
if (fstat(dev->device_handle, &s) < 0) {
|
||||
udev_unref(udev);
|
||||
return ret;
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* Open a udev device from the dev_t. 'c' means character device. */
|
||||
ret = 0;
|
||||
udev_dev = udev_device_new_from_devnum(udev, 'c', s.st_rdev);
|
||||
if (udev_dev) {
|
||||
hid_dev = udev_device_get_parent_with_subsystem_devtype(
|
||||
@@ -298,13 +298,13 @@ static int is_bluetooth(hid_device *dev)
|
||||
"hid",
|
||||
NULL);
|
||||
if (hid_dev) {
|
||||
unsigned short dev_vid;
|
||||
unsigned short dev_pid;
|
||||
int bus_type;
|
||||
unsigned short dev_vid = 0;
|
||||
unsigned short dev_pid = 0;
|
||||
int bus_type = 0;
|
||||
char *serial_number_utf8 = NULL;
|
||||
char *product_name_utf8 = NULL;
|
||||
|
||||
ret = parse_uevent_info(
|
||||
parse_uevent_info(
|
||||
udev_device_get_sysattr_value(hid_dev, "uevent"),
|
||||
&bus_type,
|
||||
&dev_vid,
|
||||
@@ -314,7 +314,12 @@ static int is_bluetooth(hid_device *dev)
|
||||
free(serial_number_utf8);
|
||||
free(product_name_utf8);
|
||||
|
||||
ret = (bus_type == BUS_BLUETOOTH);
|
||||
if (bus_type == BUS_BLUETOOTH) {
|
||||
/* Right now the Steam Controller is the only BLE device that we send feature reports to */
|
||||
if (dev_vid == 0x28de /* Valve */) {
|
||||
ret = 1;
|
||||
}
|
||||
}
|
||||
|
||||
/* hid_dev doesn't need to be (and can't be) unref'd.
|
||||
I'm not sure why, but it'll throw double-free() errors. */
|
||||
@@ -327,7 +332,6 @@ static int is_bluetooth(hid_device *dev)
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
static int get_device_string(hid_device *dev, enum device_string_id key, wchar_t *string, size_t maxlen)
|
||||
{
|
||||
struct udev *udev;
|
||||
@@ -715,7 +719,7 @@ hid_device * HID_API_EXPORT hid_open_path(const char *path, int bExclusive)
|
||||
dev->device_handle = open(path, O_RDWR);
|
||||
|
||||
/* If we have a good handle, return it. */
|
||||
if (dev->device_handle > 0) {
|
||||
if (dev->device_handle >= 0) {
|
||||
|
||||
/* Get the report descriptor */
|
||||
int res, desc_size = 0;
|
||||
@@ -741,7 +745,7 @@ hid_device * HID_API_EXPORT hid_open_path(const char *path, int bExclusive)
|
||||
rpt_desc.size);
|
||||
}
|
||||
|
||||
dev->is_bluetooth = (is_bluetooth(dev) == 1);
|
||||
dev->needs_ble_hack = (is_BLE(dev) == 1);
|
||||
|
||||
return dev;
|
||||
}
|
||||
@@ -840,8 +844,8 @@ int HID_API_EXPORT hid_get_feature_report(hid_device *dev, unsigned char *data,
|
||||
{
|
||||
int res;
|
||||
|
||||
/* It looks like HIDIOCGFEATURE() on Bluetooth devices doesn't return the report number */
|
||||
if (dev->is_bluetooth) {
|
||||
/* It looks like HIDIOCGFEATURE() on Bluetooth LE devices doesn't return the report number */
|
||||
if (dev->needs_ble_hack) {
|
||||
data[1] = data[0];
|
||||
++data;
|
||||
--length;
|
||||
@@ -849,7 +853,7 @@ int HID_API_EXPORT hid_get_feature_report(hid_device *dev, unsigned char *data,
|
||||
res = ioctl(dev->device_handle, HIDIOCGFEATURE(length), data);
|
||||
if (res < 0)
|
||||
perror("ioctl (GFEATURE)");
|
||||
else if (dev->is_bluetooth)
|
||||
else if (dev->needs_ble_hack)
|
||||
++res;
|
||||
|
||||
return res;
|
||||
|
111
externals/SDL/src/hidapi/windows/hid.c
vendored
111
externals/SDL/src/hidapi/windows/hid.c
vendored
@@ -68,6 +68,13 @@ typedef LONG NTSTATUS;
|
||||
report that we've seen is ~200-250ms so let's double that */
|
||||
#define HID_WRITE_TIMEOUT_MILLISECONDS 500
|
||||
|
||||
/* We will only enumerate devices that match these usages */
|
||||
#define USAGE_PAGE_GENERIC_DESKTOP 0x0001
|
||||
#define USAGE_JOYSTICK 0x0004
|
||||
#define USAGE_GAMEPAD 0x0005
|
||||
#define USAGE_MULTIAXISCONTROLLER 0x0008
|
||||
#define USB_VENDOR_VALVE 0x28de
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
@@ -307,25 +314,25 @@ int HID_API_EXPORT hid_exit(void)
|
||||
|
||||
int hid_blacklist(unsigned short vendor_id, unsigned short product_id)
|
||||
{
|
||||
// Corsair Gaming keyboard - Causes deadlock when asking for device details
|
||||
if ( vendor_id == 0x1B1C && product_id == 0x1B3D )
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
size_t i;
|
||||
static const struct { unsigned short vid; unsigned short pid; } known_bad[] = {
|
||||
/* Causes deadlock when asking for device details... */
|
||||
{ 0x1B1C, 0x1B3D }, /* Corsair Gaming keyboard */
|
||||
{ 0x1532, 0x0109 }, /* Razer Lycosa Gaming keyboard */
|
||||
{ 0x1532, 0x010B }, /* Razer Arctosa Gaming keyboard */
|
||||
{ 0x045E, 0x0822 }, /* Microsoft Precision Mouse */
|
||||
|
||||
// SPEEDLINK COMPETITION PRO - turns into an Android controller when enumerated
|
||||
if ( vendor_id == 0x0738 && product_id == 0x2217 )
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
/* Turns into an Android controller when enumerated... */
|
||||
{ 0x0738, 0x2217 } /* SPEEDLINK COMPETITION PRO */
|
||||
};
|
||||
|
||||
// Sound BlasterX G1 - Causes 10 second stalls when asking for manufacturer's string
|
||||
if ( vendor_id == 0x041E && product_id == 0x3249 )
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
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)) {
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
return 0;
|
||||
}
|
||||
|
||||
struct hid_device_info HID_API_EXPORT * HID_API_CALL hid_enumerate(unsigned short vendor_id, unsigned short product_id)
|
||||
@@ -402,6 +409,11 @@ struct hid_device_info HID_API_EXPORT * HID_API_CALL hid_enumerate(unsigned shor
|
||||
goto cont;
|
||||
}
|
||||
|
||||
/* XInput devices don't get real HID reports and are better handled by the raw input driver */
|
||||
if (strstr(device_interface_detail_data->DevicePath, "&ig_") != NULL) {
|
||||
goto cont;
|
||||
}
|
||||
|
||||
/* Make sure this device is of Setup Class "HIDClass" and has a
|
||||
driver bound to it. */
|
||||
/* In the main HIDAPI tree this is a loop which will erroneously open
|
||||
@@ -444,7 +456,7 @@ struct hid_device_info HID_API_EXPORT * HID_API_CALL hid_enumerate(unsigned shor
|
||||
if (write_handle == INVALID_HANDLE_VALUE) {
|
||||
/* Unable to open the device. */
|
||||
//register_error(dev, "CreateFile");
|
||||
goto cont_close;
|
||||
goto cont;
|
||||
}
|
||||
|
||||
|
||||
@@ -469,6 +481,30 @@ struct hid_device_info HID_API_EXPORT * HID_API_CALL hid_enumerate(unsigned shor
|
||||
wchar_t wstr[WSTR_LEN]; /* TODO: Determine Size */
|
||||
size_t len;
|
||||
|
||||
/* Get the Usage Page and Usage for this device. */
|
||||
hidp_res = HidD_GetPreparsedData(write_handle, &pp_data);
|
||||
if (hidp_res) {
|
||||
nt_res = HidP_GetCaps(pp_data, &caps);
|
||||
HidD_FreePreparsedData(pp_data);
|
||||
if (nt_res != HIDP_STATUS_SUCCESS) {
|
||||
goto cont_close;
|
||||
}
|
||||
}
|
||||
else {
|
||||
goto cont_close;
|
||||
}
|
||||
|
||||
/* SDL Modification: Ignore the device if it's not a gamepad. This limits compatibility
|
||||
risk from devices that may respond poorly to our string queries below. */
|
||||
if (attrib.VendorID != USB_VENDOR_VALVE) {
|
||||
if (caps.UsagePage != USAGE_PAGE_GENERIC_DESKTOP) {
|
||||
goto cont_close;
|
||||
}
|
||||
if (caps.Usage != USAGE_JOYSTICK && caps.Usage != USAGE_GAMEPAD && caps.Usage != USAGE_MULTIAXISCONTROLLER) {
|
||||
goto cont_close;
|
||||
}
|
||||
}
|
||||
|
||||
/* VID/PID match. Create the record. */
|
||||
tmp = (struct hid_device_info*) calloc(1, sizeof(struct hid_device_info));
|
||||
if (cur_dev) {
|
||||
@@ -478,20 +514,10 @@ struct hid_device_info HID_API_EXPORT * HID_API_CALL hid_enumerate(unsigned shor
|
||||
root = tmp;
|
||||
}
|
||||
cur_dev = tmp;
|
||||
|
||||
/* Get the Usage Page and Usage for this device. */
|
||||
hidp_res = HidD_GetPreparsedData(write_handle, &pp_data);
|
||||
if (hidp_res) {
|
||||
nt_res = HidP_GetCaps(pp_data, &caps);
|
||||
if (nt_res == HIDP_STATUS_SUCCESS) {
|
||||
cur_dev->usage_page = caps.UsagePage;
|
||||
cur_dev->usage = caps.Usage;
|
||||
}
|
||||
|
||||
HidD_FreePreparsedData(pp_data);
|
||||
}
|
||||
|
||||
/* Fill out the record */
|
||||
cur_dev->usage_page = caps.UsagePage;
|
||||
cur_dev->usage = caps.Usage;
|
||||
cur_dev->next = NULL;
|
||||
str = device_interface_detail_data->DevicePath;
|
||||
if (str) {
|
||||
@@ -694,6 +720,14 @@ static int hid_write_timeout(hid_device *dev, const unsigned char *data, size_t
|
||||
size_t stashed_length = length;
|
||||
unsigned char *buf;
|
||||
|
||||
#if 1
|
||||
/* If the application is writing to the device, it knows how much data to write.
|
||||
* This matches the behavior on other platforms. It's also important when writing
|
||||
* to Sony game controllers over Bluetooth, where there's a CRC at the end which
|
||||
* must not be tampered with.
|
||||
*/
|
||||
buf = (unsigned char *) data;
|
||||
#else
|
||||
/* Make sure the right number of bytes are passed to WriteFile. Windows
|
||||
expects the number of bytes which are in the _longest_ report (plus
|
||||
one for the report number) bytes even if the data is a report
|
||||
@@ -711,6 +745,7 @@ static int hid_write_timeout(hid_device *dev, const unsigned char *data, size_t
|
||||
memset(buf + length, 0, dev->output_report_length - length);
|
||||
length = dev->output_report_length;
|
||||
}
|
||||
#endif
|
||||
if (length > 512)
|
||||
{
|
||||
return hid_write_output_report( dev, data, stashed_length );
|
||||
@@ -891,12 +926,6 @@ int HID_API_EXPORT HID_API_CALL hid_get_feature_report(hid_device *dev, unsigned
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* bytes_returned does not include the first byte which contains the
|
||||
report ID. The data buffer actually contains one more byte than
|
||||
bytes_returned. */
|
||||
bytes_returned++;
|
||||
|
||||
|
||||
return bytes_returned;
|
||||
#endif
|
||||
}
|
||||
@@ -973,23 +1002,23 @@ HID_API_EXPORT const wchar_t * HID_API_CALL hid_error(hid_device *dev)
|
||||
/*#define S11*/
|
||||
#define P32
|
||||
#ifdef S11
|
||||
unsigned short VendorID = 0xa0a0;
|
||||
unsigned short VendorID = 0xa0a0;
|
||||
unsigned short ProductID = 0x0001;
|
||||
#endif
|
||||
|
||||
#ifdef P32
|
||||
unsigned short VendorID = 0x04d8;
|
||||
unsigned short VendorID = 0x04d8;
|
||||
unsigned short ProductID = 0x3f;
|
||||
#endif
|
||||
|
||||
#ifdef PICPGM
|
||||
unsigned short VendorID = 0x04d8;
|
||||
unsigned short ProductID = 0x0033;
|
||||
unsigned short VendorID = 0x04d8;
|
||||
unsigned short ProductID = 0x0033;
|
||||
#endif
|
||||
|
||||
int __cdecl main(int argc, char* argv[])
|
||||
{
|
||||
int res;
|
||||
int i, res;
|
||||
unsigned char buf[65];
|
||||
|
||||
UNREFERENCED_PARAMETER(argc);
|
||||
@@ -1025,7 +1054,7 @@ int __cdecl main(int argc, char* argv[])
|
||||
printf("Unable to read()\n");
|
||||
|
||||
/* Print out the returned buffer. */
|
||||
for (int i = 0; i < 4; i++)
|
||||
for (i = 0; i < 4; i++)
|
||||
printf("buf[%d]: %d\n", i, buf[i]);
|
||||
|
||||
return 0;
|
||||
|
Reference in New Issue
Block a user