31 #include "../SDL_internal.h"
34 #ifdef SDL_JOYSTICK_HIDAPI
38 #define hid_device_ PLATFORM_hid_device_
39 #define hid_device PLATFORM_hid_device
40 #define hid_device_info PLATFORM_hid_device_info
41 #define hid_init PLATFORM_hid_init
42 #define hid_exit PLATFORM_hid_exit
43 #define hid_enumerate PLATFORM_hid_enumerate
44 #define hid_free_enumeration PLATFORM_hid_free_enumeration
45 #define hid_open PLATFORM_hid_open
46 #define hid_open_path PLATFORM_hid_open_path
47 #define hid_write PLATFORM_hid_write
48 #define hid_read_timeout PLATFORM_hid_read_timeout
49 #define hid_read PLATFORM_hid_read
50 #define hid_set_nonblocking PLATFORM_hid_set_nonblocking
51 #define hid_send_feature_report PLATFORM_hid_send_feature_report
52 #define hid_get_feature_report PLATFORM_hid_get_feature_report
53 #define hid_close PLATFORM_hid_close
54 #define hid_get_manufacturer_string PLATFORM_hid_get_manufacturer_string
55 #define hid_get_product_string PLATFORM_hid_get_product_string
56 #define hid_get_serial_number_string PLATFORM_hid_get_serial_number_string
57 #define hid_get_indexed_string PLATFORM_hid_get_indexed_string
58 #define hid_error PLATFORM_hid_error
59 #define new_hid_device PLATFORM_new_hid_device
60 #define free_hid_device PLATFORM_free_hid_device
61 #define input_report PLATFORM_input_report
62 #define return_data PLATFORM_return_data
63 #define make_path PLATFORM_make_path
64 #define read_thread PLATFORM_read_thread
68 #include "../../core/linux/SDL_udev.h"
70 static const SDL_UDEV_Symbols *udev_ctx =
NULL;
72 #define udev_device_get_sysattr_value udev_ctx->udev_device_get_sysattr_value
73 #define udev_new udev_ctx->udev_new
74 #define udev_unref udev_ctx->udev_unref
75 #define udev_device_new_from_devnum udev_ctx->udev_device_new_from_devnum
76 #define udev_device_get_parent_with_subsystem_devtype udev_ctx->udev_device_get_parent_with_subsystem_devtype
77 #define udev_device_unref udev_ctx->udev_device_unref
78 #define udev_enumerate_new udev_ctx->udev_enumerate_new
79 #define udev_enumerate_add_match_subsystem udev_ctx->udev_enumerate_add_match_subsystem
80 #define udev_enumerate_scan_devices udev_ctx->udev_enumerate_scan_devices
81 #define udev_enumerate_get_list_entry udev_ctx->udev_enumerate_get_list_entry
82 #define udev_list_entry_get_name udev_ctx->udev_list_entry_get_name
83 #define udev_device_new_from_syspath udev_ctx->udev_device_new_from_syspath
84 #define udev_device_get_devnode udev_ctx->udev_device_get_devnode
85 #define udev_list_entry_get_next udev_ctx->udev_list_entry_get_next
86 #define udev_enumerate_unref udev_ctx->udev_enumerate_unref
88 #include "linux/hid.c"
89 #define HAVE_PLATFORM_BACKEND 1
94 #define HAVE_PLATFORM_BACKEND 1
97 #include "windows/hid.c"
98 #define HAVE_PLATFORM_BACKEND 1
101 #error Need a hid.c for this platform!
106 #undef hid_device_info
110 #undef hid_free_enumeration
114 #undef hid_read_timeout
116 #undef hid_set_nonblocking
117 #undef hid_send_feature_report
118 #undef hid_get_feature_report
120 #undef hid_get_manufacturer_string
121 #undef hid_get_product_string
122 #undef hid_get_serial_number_string
123 #undef hid_get_indexed_string
125 #undef new_hid_device
126 #undef free_hid_device
132 #ifdef SDL_LIBUSB_DYNAMIC
142 int (*
init)(libusb_context **
ctx);
143 void (*exit)(libusb_context *
ctx);
144 ssize_t (*get_device_list)(libusb_context *
ctx, libusb_device ***list);
146 int (*get_device_descriptor)(libusb_device *dev,
struct libusb_device_descriptor *desc);
147 int (*get_active_config_descriptor)(libusb_device *dev,
struct libusb_config_descriptor **
config);
148 int (*get_config_descriptor)(
151 struct libusb_config_descriptor **
config
153 void (*free_config_descriptor)(
struct libusb_config_descriptor *
config);
154 uint8_t (*get_bus_number)(libusb_device *dev);
155 uint8_t (*get_device_address)(libusb_device *dev);
156 int (*open)(libusb_device *dev, libusb_device_handle **dev_handle);
157 void (*close)(libusb_device_handle *dev_handle);
158 int (*claim_interface)(libusb_device_handle *dev_handle,
int interface_number);
159 int (*release_interface)(libusb_device_handle *dev_handle,
int interface_number);
160 int (*kernel_driver_active)(libusb_device_handle *dev_handle,
int interface_number);
161 int (*detach_kernel_driver)(libusb_device_handle *dev_handle,
int interface_number);
162 int (*attach_kernel_driver)(libusb_device_handle *dev_handle,
int interface_number);
163 int (*set_interface_alt_setting)(libusb_device_handle *dev,
int interface_number,
int alternate_setting);
164 struct libusb_transfer * (*alloc_transfer)(
int iso_packets);
165 int (*submit_transfer)(
struct libusb_transfer *transfer);
166 int (*cancel_transfer)(
struct libusb_transfer *transfer);
167 void (*free_transfer)(
struct libusb_transfer *transfer);
168 int (*control_transfer)(
169 libusb_device_handle *dev_handle,
178 int (*interrupt_transfer)(
179 libusb_device_handle *dev_handle,
180 unsigned char endpoint,
186 int (*handle_events)(libusb_context *
ctx);
187 int (*handle_events_completed)(libusb_context *
ctx,
int *completed);
190 #define libusb_init libusb_ctx.init
191 #define libusb_exit libusb_ctx.exit
192 #define libusb_get_device_list libusb_ctx.get_device_list
193 #define libusb_free_device_list libusb_ctx.free_device_list
194 #define libusb_get_device_descriptor libusb_ctx.get_device_descriptor
195 #define libusb_get_active_config_descriptor libusb_ctx.get_active_config_descriptor
196 #define libusb_get_config_descriptor libusb_ctx.get_config_descriptor
197 #define libusb_free_config_descriptor libusb_ctx.free_config_descriptor
198 #define libusb_get_bus_number libusb_ctx.get_bus_number
199 #define libusb_get_device_address libusb_ctx.get_device_address
200 #define libusb_open libusb_ctx.open
201 #define libusb_close libusb_ctx.close
202 #define libusb_claim_interface libusb_ctx.claim_interface
203 #define libusb_release_interface libusb_ctx.release_interface
204 #define libusb_kernel_driver_active libusb_ctx.kernel_driver_active
205 #define libusb_detach_kernel_driver libusb_ctx.detach_kernel_driver
206 #define libusb_attach_kernel_driver libusb_ctx.attach_kernel_driver
207 #define libusb_set_interface_alt_setting libusb_ctx.set_interface_alt_setting
208 #define libusb_alloc_transfer libusb_ctx.alloc_transfer
209 #define libusb_submit_transfer libusb_ctx.submit_transfer
210 #define libusb_cancel_transfer libusb_ctx.cancel_transfer
211 #define libusb_free_transfer libusb_ctx.free_transfer
212 #define libusb_control_transfer libusb_ctx.control_transfer
213 #define libusb_interrupt_transfer libusb_ctx.interrupt_transfer
214 #define libusb_handle_events libusb_ctx.handle_events
215 #define libusb_handle_events_completed libusb_ctx.handle_events_completed
217 #define hid_device_ LIBUSB_hid_device_
218 #define hid_device LIBUSB_hid_device
219 #define hid_device_info LIBUSB_hid_device_info
220 #define hid_init LIBUSB_hid_init
221 #define hid_exit LIBUSB_hid_exit
222 #define hid_enumerate LIBUSB_hid_enumerate
223 #define hid_free_enumeration LIBUSB_hid_free_enumeration
224 #define hid_open LIBUSB_hid_open
225 #define hid_open_path LIBUSB_hid_open_path
226 #define hid_write LIBUSB_hid_write
227 #define hid_read_timeout LIBUSB_hid_read_timeout
228 #define hid_read LIBUSB_hid_read
229 #define hid_set_nonblocking LIBUSB_hid_set_nonblocking
230 #define hid_send_feature_report LIBUSB_hid_send_feature_report
231 #define hid_get_feature_report LIBUSB_hid_get_feature_report
232 #define hid_close LIBUSB_hid_close
233 #define hid_get_manufacturer_string LIBUSB_hid_get_manufacturer_string
234 #define hid_get_product_string LIBUSB_hid_get_product_string
235 #define hid_get_serial_number_string LIBUSB_hid_get_serial_number_string
236 #define hid_get_indexed_string LIBUSB_hid_get_indexed_string
237 #define hid_error LIBUSB_hid_error
238 #define new_hid_device LIBUSB_new_hid_device
239 #define free_hid_device LIBUSB_free_hid_device
240 #define input_report LIBUSB_input_report
241 #define return_data LIBUSB_return_data
242 #define make_path LIBUSB_make_path
243 #define read_thread LIBUSB_read_thread
249 SDL_libusb_get_string_descriptor(libusb_device_handle *dev,
253 return libusb_control_transfer(dev,
254 LIBUSB_ENDPOINT_IN | 0
x0,
255 LIBUSB_REQUEST_GET_DESCRIPTOR,
256 (LIBUSB_DT_STRING << 8) | descriptor_index,
262 #define libusb_get_string_descriptor SDL_libusb_get_string_descriptor
270 #undef hid_device_info
274 #undef hid_free_enumeration
278 #undef hid_read_timeout
280 #undef hid_set_nonblocking
281 #undef hid_send_feature_report
282 #undef hid_get_feature_report
284 #undef hid_get_manufacturer_string
285 #undef hid_get_product_string
286 #undef hid_get_serial_number_string
287 #undef hid_get_indexed_string
289 #undef new_hid_device
290 #undef free_hid_device
303 struct hidapi_backend {
304 #define F(x) typeof(x) *x
320 #if HAVE_PLATFORM_BACKEND
321 static const struct hidapi_backend PLATFORM_Backend = {
322 (
void*)PLATFORM_hid_write,
323 (
void*)PLATFORM_hid_read_timeout,
324 (
void*)PLATFORM_hid_read,
325 (
void*)PLATFORM_hid_set_nonblocking,
326 (
void*)PLATFORM_hid_send_feature_report,
327 (
void*)PLATFORM_hid_get_feature_report,
328 (
void*)PLATFORM_hid_close,
329 (
void*)PLATFORM_hid_get_manufacturer_string,
330 (
void*)PLATFORM_hid_get_product_string,
331 (
void*)PLATFORM_hid_get_serial_number_string,
332 (
void*)PLATFORM_hid_get_indexed_string,
333 (
void*)PLATFORM_hid_error
337 #ifdef SDL_LIBUSB_DYNAMIC
338 static const struct hidapi_backend LIBUSB_Backend = {
339 (
void*)LIBUSB_hid_write,
340 (
void*)LIBUSB_hid_read_timeout,
341 (
void*)LIBUSB_hid_read,
342 (
void*)LIBUSB_hid_set_nonblocking,
343 (
void*)LIBUSB_hid_send_feature_report,
344 (
void*)LIBUSB_hid_get_feature_report,
345 (
void*)LIBUSB_hid_close,
346 (
void*)LIBUSB_hid_get_manufacturer_string,
347 (
void*)LIBUSB_hid_get_product_string,
348 (
void*)LIBUSB_hid_get_serial_number_string,
349 (
void*)LIBUSB_hid_get_indexed_string,
350 (
void*)LIBUSB_hid_error
354 typedef struct _HIDDeviceWrapper HIDDeviceWrapper;
355 struct _HIDDeviceWrapper
358 const struct hidapi_backend *backend;
361 static HIDDeviceWrapper *
362 CreateHIDDeviceWrapper(
hid_device *
device,
const struct hidapi_backend *backend)
364 HIDDeviceWrapper *ret =
SDL_malloc(
sizeof(*ret));
366 ret->backend = backend;
371 WrapHIDDevice(HIDDeviceWrapper *wrapper)
376 static HIDDeviceWrapper *
379 return (HIDDeviceWrapper *)
device;
383 DeleteHIDDeviceWrapper(HIDDeviceWrapper *
device)
388 #define COPY_IF_EXISTS(var) \
389 if (pSrc->var != NULL) { \
390 pDst->var = SDL_strdup(pSrc->var); \
394 #define WCOPY_IF_EXISTS(var) \
395 if (pSrc->var != NULL) { \
396 pDst->var = SDL_wcsdup(pSrc->var); \
401 #ifdef SDL_LIBUSB_DYNAMIC
403 LIBUSB_CopyHIDDeviceInfo(
struct LIBUSB_hid_device_info *pSrc,
409 WCOPY_IF_EXISTS(serial_number)
411 WCOPY_IF_EXISTS(manufacturer_string)
412 WCOPY_IF_EXISTS(product_string)
414 pDst->
usage = pSrc->usage;
423 #if HAVE_PLATFORM_BACKEND
425 PLATFORM_CopyHIDDeviceInfo(
struct PLATFORM_hid_device_info *pSrc,
431 WCOPY_IF_EXISTS(serial_number)
433 WCOPY_IF_EXISTS(manufacturer_string)
434 WCOPY_IF_EXISTS(product_string)
436 pDst->
usage = pSrc->usage;
445 #undef COPY_IF_EXISTS
446 #undef WCOPY_IF_EXISTS
454 if (SDL_hidapi_wasinit ==
SDL_TRUE) {
458 #ifdef SDL_LIBUSB_DYNAMIC
460 if (libusb_ctx.libhandle !=
NULL) {
461 #define LOAD_LIBUSB_SYMBOL(func) \
462 libusb_ctx.func = SDL_LoadFunction(libusb_ctx.libhandle, "libusb_" #func);
463 LOAD_LIBUSB_SYMBOL(
init)
464 LOAD_LIBUSB_SYMBOL(exit)
465 LOAD_LIBUSB_SYMBOL(get_device_list)
467 LOAD_LIBUSB_SYMBOL(get_device_descriptor)
468 LOAD_LIBUSB_SYMBOL(get_active_config_descriptor)
469 LOAD_LIBUSB_SYMBOL(get_config_descriptor)
470 LOAD_LIBUSB_SYMBOL(free_config_descriptor)
471 LOAD_LIBUSB_SYMBOL(get_bus_number)
472 LOAD_LIBUSB_SYMBOL(get_device_address)
473 LOAD_LIBUSB_SYMBOL(open)
474 LOAD_LIBUSB_SYMBOL(close)
475 LOAD_LIBUSB_SYMBOL(claim_interface)
476 LOAD_LIBUSB_SYMBOL(release_interface)
477 LOAD_LIBUSB_SYMBOL(kernel_driver_active)
478 LOAD_LIBUSB_SYMBOL(detach_kernel_driver)
479 LOAD_LIBUSB_SYMBOL(attach_kernel_driver)
480 LOAD_LIBUSB_SYMBOL(set_interface_alt_setting)
481 LOAD_LIBUSB_SYMBOL(alloc_transfer)
482 LOAD_LIBUSB_SYMBOL(submit_transfer)
483 LOAD_LIBUSB_SYMBOL(cancel_transfer)
484 LOAD_LIBUSB_SYMBOL(free_transfer)
485 LOAD_LIBUSB_SYMBOL(control_transfer)
486 LOAD_LIBUSB_SYMBOL(interrupt_transfer)
487 LOAD_LIBUSB_SYMBOL(handle_events)
488 LOAD_LIBUSB_SYMBOL(handle_events_completed)
489 #undef LOAD_LIBUSB_SYMBOL
491 if ((err = LIBUSB_hid_init()) < 0) {
498 #if HAVE_PLATFORM_BACKEND
500 udev_ctx = SDL_UDEV_GetUdevSyms();
502 if (udev_ctx && (err = PLATFORM_hid_init()) < 0) {
503 #ifdef SDL_LIBUSB_DYNAMIC
504 if (libusb_ctx.libhandle) {
523 #if HAVE_PLATFORM_BACKEND
525 err = PLATFORM_hid_exit();
528 #ifdef SDL_LIBUSB_DYNAMIC
529 if (libusb_ctx.libhandle) {
530 err |= LIBUSB_hid_exit();
539 #ifdef SDL_LIBUSB_DYNAMIC
540 struct LIBUSB_hid_device_info *usb_devs =
NULL;
541 struct LIBUSB_hid_device_info *usb_dev;
543 #if HAVE_PLATFORM_BACKEND
544 struct PLATFORM_hid_device_info *raw_devs =
NULL;
545 struct PLATFORM_hid_device_info *raw_dev;
553 #ifdef SDL_LIBUSB_DYNAMIC
554 if (libusb_ctx.libhandle) {
556 for (usb_dev = usb_devs; usb_dev; usb_dev = usb_dev->next) {
558 LIBUSB_CopyHIDDeviceInfo(usb_dev, new_dev);
561 last->next = new_dev;
570 #if HAVE_PLATFORM_BACKEND
573 for (raw_dev = raw_devs; raw_dev; raw_dev = raw_dev->next) {
575 #ifdef SDL_LIBUSB_DYNAMIC
576 for (usb_dev = usb_devs; usb_dev; usb_dev = usb_dev->next) {
577 if (raw_dev->vendor_id == usb_dev->vendor_id &&
578 raw_dev->product_id == usb_dev->product_id &&
579 (raw_dev->interface_number < 0 || raw_dev->interface_number == usb_dev->interface_number)) {
587 PLATFORM_CopyHIDDeviceInfo(raw_dev, new_dev);
588 new_dev->next =
NULL;
591 last->next = new_dev;
598 PLATFORM_hid_free_enumeration(raw_devs);
602 #ifdef SDL_LIBUSB_DYNAMIC
603 if (libusb_ctx.libhandle) {
604 LIBUSB_hid_free_enumeration(usb_devs);
631 #if HAVE_PLATFORM_BACKEND
635 HIDDeviceWrapper *wrapper = CreateHIDDeviceWrapper(pDevice, &PLATFORM_Backend);
636 return WrapHIDDevice(wrapper);
639 #ifdef SDL_LIBUSB_DYNAMIC
640 if (libusb_ctx.libhandle &&
643 HIDDeviceWrapper *wrapper = CreateHIDDeviceWrapper(pDevice, &LIBUSB_Backend);
644 return WrapHIDDevice(wrapper);
658 #if HAVE_PLATFORM_BACKEND
662 HIDDeviceWrapper *wrapper = CreateHIDDeviceWrapper(pDevice, &PLATFORM_Backend);
663 return WrapHIDDevice(wrapper);
666 #ifdef SDL_LIBUSB_DYNAMIC
667 if (libusb_ctx.libhandle &&
670 HIDDeviceWrapper *wrapper = CreateHIDDeviceWrapper(pDevice, &LIBUSB_Backend);
671 return WrapHIDDevice(wrapper);
679 HIDDeviceWrapper *wrapper = UnwrapHIDDevice(
device);
680 return wrapper->backend->hid_write(wrapper->device,
data,
length);
685 HIDDeviceWrapper *wrapper = UnwrapHIDDevice(
device);
686 return wrapper->backend->hid_read_timeout(wrapper->device,
data,
length, milliseconds);
691 HIDDeviceWrapper *wrapper = UnwrapHIDDevice(
device);
692 return wrapper->backend->hid_read(wrapper->device,
data,
length);
697 HIDDeviceWrapper *wrapper = UnwrapHIDDevice(
device);
698 return wrapper->backend->hid_set_nonblocking(wrapper->device, nonblock);
703 HIDDeviceWrapper *wrapper = UnwrapHIDDevice(
device);
704 return wrapper->backend->hid_send_feature_report(wrapper->device,
data,
length);
709 HIDDeviceWrapper *wrapper = UnwrapHIDDevice(
device);
710 return wrapper->backend->hid_get_feature_report(wrapper->device,
data,
length);
715 HIDDeviceWrapper *wrapper = UnwrapHIDDevice(
device);
716 wrapper->backend->hid_close(wrapper->device);
717 DeleteHIDDeviceWrapper(wrapper);
722 HIDDeviceWrapper *wrapper = UnwrapHIDDevice(
device);
723 return wrapper->backend->hid_get_manufacturer_string(wrapper->device,
string, maxlen);
728 HIDDeviceWrapper *wrapper = UnwrapHIDDevice(
device);
729 return wrapper->backend->hid_get_product_string(wrapper->device,
string, maxlen);
734 HIDDeviceWrapper *wrapper = UnwrapHIDDevice(
device);
735 return wrapper->backend->hid_get_serial_number_string(wrapper->device,
string, maxlen);
740 HIDDeviceWrapper *wrapper = UnwrapHIDDevice(
device);
741 return wrapper->backend->hid_get_indexed_string(wrapper->device, string_index,
string, maxlen);
746 HIDDeviceWrapper *wrapper = UnwrapHIDDevice(
device);
747 return wrapper->backend->hid_error(wrapper->device);