SDL_hidapi.c (35245B)
1 /* 2 Simple DirectMedia Layer 3 Copyright (C) 1997-2020 Sam Lantinga <slouken@libsdl.org> 4 5 This software is provided 'as-is', without any express or implied 6 warranty. In no event will the authors be held liable for any damages 7 arising from the use of this software. 8 9 Permission is granted to anyone to use this software for any purpose, 10 including commercial applications, and to alter it and redistribute it 11 freely, subject to the following restrictions: 12 13 1. The origin of this software must not be misrepresented; you must not 14 claim that you wrote the original software. If you use this software 15 in a product, an acknowledgment in the product documentation would be 16 appreciated but is not required. 17 2. Altered source versions must be plainly marked as such, and must not be 18 misrepresented as being the original software. 19 3. This notice may not be removed or altered from any source distribution. 20 */ 21 22 /* Original hybrid wrapper for Linux by Valve Software. Their original notes: 23 * 24 * The libusb version doesn't support Bluetooth, but not all Linux 25 * distributions allow access to /dev/hidraw* 26 * 27 * This merges the two, at a small performance cost, until distributions 28 * have granted access to /dev/hidraw* 29 */ 30 31 #include "../SDL_internal.h" 32 #include "SDL_loadso.h" 33 34 #ifdef SDL_JOYSTICK_HIDAPI 35 36 /* Platform HIDAPI Implementation */ 37 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 65 66 #undef HIDAPI_H__ 67 #if __LINUX__ 68 69 #include "../../core/linux/SDL_udev.h" 70 #if SDL_USE_LIBUDEV 71 static const SDL_UDEV_Symbols *udev_ctx = NULL; 72 73 #define udev_device_get_sysattr_value udev_ctx->udev_device_get_sysattr_value 74 #define udev_new udev_ctx->udev_new 75 #define udev_unref udev_ctx->udev_unref 76 #define udev_device_new_from_devnum udev_ctx->udev_device_new_from_devnum 77 #define udev_device_get_parent_with_subsystem_devtype udev_ctx->udev_device_get_parent_with_subsystem_devtype 78 #define udev_device_unref udev_ctx->udev_device_unref 79 #define udev_enumerate_new udev_ctx->udev_enumerate_new 80 #define udev_enumerate_add_match_subsystem udev_ctx->udev_enumerate_add_match_subsystem 81 #define udev_enumerate_scan_devices udev_ctx->udev_enumerate_scan_devices 82 #define udev_enumerate_get_list_entry udev_ctx->udev_enumerate_get_list_entry 83 #define udev_list_entry_get_name udev_ctx->udev_list_entry_get_name 84 #define udev_device_new_from_syspath udev_ctx->udev_device_new_from_syspath 85 #define udev_device_get_devnode udev_ctx->udev_device_get_devnode 86 #define udev_list_entry_get_next udev_ctx->udev_list_entry_get_next 87 #define udev_enumerate_unref udev_ctx->udev_enumerate_unref 88 89 #include "linux/hid.c" 90 #define HAVE_PLATFORM_BACKEND 1 91 #endif /* SDL_USE_LIBUDEV */ 92 93 #elif __MACOSX__ 94 #include "mac/hid.c" 95 #define HAVE_PLATFORM_BACKEND 1 96 #define udev_ctx 1 97 #elif __WINDOWS__ 98 #include "windows/hid.c" 99 #define HAVE_PLATFORM_BACKEND 1 100 #define udev_ctx 1 101 #endif 102 103 #undef hid_device_ 104 #undef hid_device 105 #undef hid_device_info 106 #undef hid_init 107 #undef hid_exit 108 #undef hid_enumerate 109 #undef hid_free_enumeration 110 #undef hid_open 111 #undef hid_open_path 112 #undef hid_write 113 #undef hid_read_timeout 114 #undef hid_read 115 #undef hid_set_nonblocking 116 #undef hid_send_feature_report 117 #undef hid_get_feature_report 118 #undef hid_close 119 #undef hid_get_manufacturer_string 120 #undef hid_get_product_string 121 #undef hid_get_serial_number_string 122 #undef hid_get_indexed_string 123 #undef hid_error 124 #undef new_hid_device 125 #undef free_hid_device 126 #undef input_report 127 #undef return_data 128 #undef make_path 129 #undef read_thread 130 131 #ifdef SDL_JOYSTICK_HIDAPI_STEAMXBOX 132 #define HAVE_DRIVER_BACKEND 1 133 #endif 134 135 #ifdef HAVE_DRIVER_BACKEND 136 137 /* DRIVER HIDAPI Implementation */ 138 139 #define hid_device_ DRIVER_hid_device_ 140 #define hid_device DRIVER_hid_device 141 #define hid_device_info DRIVER_hid_device_info 142 #define hid_init DRIVER_hid_init 143 #define hid_exit DRIVER_hid_exit 144 #define hid_enumerate DRIVER_hid_enumerate 145 #define hid_free_enumeration DRIVER_hid_free_enumeration 146 #define hid_open DRIVER_hid_open 147 #define hid_open_path DRIVER_hid_open_path 148 #define hid_write DRIVER_hid_write 149 #define hid_read_timeout DRIVER_hid_read_timeout 150 #define hid_read DRIVER_hid_read 151 #define hid_set_nonblocking DRIVER_hid_set_nonblocking 152 #define hid_send_feature_report DRIVER_hid_send_feature_report 153 #define hid_get_feature_report DRIVER_hid_get_feature_report 154 #define hid_close DRIVER_hid_close 155 #define hid_get_manufacturer_string DRIVER_hid_get_manufacturer_string 156 #define hid_get_product_string DRIVER_hid_get_product_string 157 #define hid_get_serial_number_string DRIVER_hid_get_serial_number_string 158 #define hid_get_indexed_string DRIVER_hid_get_indexed_string 159 #define hid_error DRIVER_hid_error 160 161 #ifdef SDL_JOYSTICK_HIDAPI_STEAMXBOX 162 #undef HIDAPI_H__ 163 #include "steamxbox/hid.c" 164 #else 165 #error Need a driver hid.c for this platform! 166 #endif 167 168 #undef hid_device_ 169 #undef hid_device 170 #undef hid_device_info 171 #undef hid_init 172 #undef hid_exit 173 #undef hid_enumerate 174 #undef hid_free_enumeration 175 #undef hid_open 176 #undef hid_open_path 177 #undef hid_write 178 #undef hid_read_timeout 179 #undef hid_read 180 #undef hid_set_nonblocking 181 #undef hid_send_feature_report 182 #undef hid_get_feature_report 183 #undef hid_close 184 #undef hid_get_manufacturer_string 185 #undef hid_get_product_string 186 #undef hid_get_serial_number_string 187 #undef hid_get_indexed_string 188 #undef hid_error 189 190 #endif /* HAVE_DRIVER_BACKEND */ 191 192 193 #ifdef SDL_LIBUSB_DYNAMIC 194 /* libusb HIDAPI Implementation */ 195 196 /* Include this now, for our dynamically-loaded libusb context */ 197 #include <libusb.h> 198 199 static struct 200 { 201 void* libhandle; 202 203 int (*init)(libusb_context **ctx); 204 void (*exit)(libusb_context *ctx); 205 ssize_t (*get_device_list)(libusb_context *ctx, libusb_device ***list); 206 void (*free_device_list)(libusb_device **list, int unref_devices); 207 int (*get_device_descriptor)(libusb_device *dev, struct libusb_device_descriptor *desc); 208 int (*get_active_config_descriptor)(libusb_device *dev, struct libusb_config_descriptor **config); 209 int (*get_config_descriptor)( 210 libusb_device *dev, 211 uint8_t config_index, 212 struct libusb_config_descriptor **config 213 ); 214 void (*free_config_descriptor)(struct libusb_config_descriptor *config); 215 uint8_t (*get_bus_number)(libusb_device *dev); 216 uint8_t (*get_device_address)(libusb_device *dev); 217 int (*open)(libusb_device *dev, libusb_device_handle **dev_handle); 218 void (*close)(libusb_device_handle *dev_handle); 219 int (*claim_interface)(libusb_device_handle *dev_handle, int interface_number); 220 int (*release_interface)(libusb_device_handle *dev_handle, int interface_number); 221 int (*kernel_driver_active)(libusb_device_handle *dev_handle, int interface_number); 222 int (*detach_kernel_driver)(libusb_device_handle *dev_handle, int interface_number); 223 int (*attach_kernel_driver)(libusb_device_handle *dev_handle, int interface_number); 224 int (*set_interface_alt_setting)(libusb_device_handle *dev, int interface_number, int alternate_setting); 225 struct libusb_transfer * (*alloc_transfer)(int iso_packets); 226 int (*submit_transfer)(struct libusb_transfer *transfer); 227 int (*cancel_transfer)(struct libusb_transfer *transfer); 228 void (*free_transfer)(struct libusb_transfer *transfer); 229 int (*control_transfer)( 230 libusb_device_handle *dev_handle, 231 uint8_t request_type, 232 uint8_t bRequest, 233 uint16_t wValue, 234 uint16_t wIndex, 235 unsigned char *data, 236 uint16_t wLength, 237 unsigned int timeout 238 ); 239 int (*interrupt_transfer)( 240 libusb_device_handle *dev_handle, 241 unsigned char endpoint, 242 unsigned char *data, 243 int length, 244 int *actual_length, 245 unsigned int timeout 246 ); 247 int (*handle_events)(libusb_context *ctx); 248 int (*handle_events_completed)(libusb_context *ctx, int *completed); 249 } libusb_ctx; 250 251 #define libusb_init libusb_ctx.init 252 #define libusb_exit libusb_ctx.exit 253 #define libusb_get_device_list libusb_ctx.get_device_list 254 #define libusb_free_device_list libusb_ctx.free_device_list 255 #define libusb_get_device_descriptor libusb_ctx.get_device_descriptor 256 #define libusb_get_active_config_descriptor libusb_ctx.get_active_config_descriptor 257 #define libusb_get_config_descriptor libusb_ctx.get_config_descriptor 258 #define libusb_free_config_descriptor libusb_ctx.free_config_descriptor 259 #define libusb_get_bus_number libusb_ctx.get_bus_number 260 #define libusb_get_device_address libusb_ctx.get_device_address 261 #define libusb_open libusb_ctx.open 262 #define libusb_close libusb_ctx.close 263 #define libusb_claim_interface libusb_ctx.claim_interface 264 #define libusb_release_interface libusb_ctx.release_interface 265 #define libusb_kernel_driver_active libusb_ctx.kernel_driver_active 266 #define libusb_detach_kernel_driver libusb_ctx.detach_kernel_driver 267 #define libusb_attach_kernel_driver libusb_ctx.attach_kernel_driver 268 #define libusb_set_interface_alt_setting libusb_ctx.set_interface_alt_setting 269 #define libusb_alloc_transfer libusb_ctx.alloc_transfer 270 #define libusb_submit_transfer libusb_ctx.submit_transfer 271 #define libusb_cancel_transfer libusb_ctx.cancel_transfer 272 #define libusb_free_transfer libusb_ctx.free_transfer 273 #define libusb_control_transfer libusb_ctx.control_transfer 274 #define libusb_interrupt_transfer libusb_ctx.interrupt_transfer 275 #define libusb_handle_events libusb_ctx.handle_events 276 #define libusb_handle_events_completed libusb_ctx.handle_events_completed 277 278 #define hid_device_ LIBUSB_hid_device_ 279 #define hid_device LIBUSB_hid_device 280 #define hid_device_info LIBUSB_hid_device_info 281 #define hid_init LIBUSB_hid_init 282 #define hid_exit LIBUSB_hid_exit 283 #define hid_enumerate LIBUSB_hid_enumerate 284 #define hid_free_enumeration LIBUSB_hid_free_enumeration 285 #define hid_open LIBUSB_hid_open 286 #define hid_open_path LIBUSB_hid_open_path 287 #define hid_write LIBUSB_hid_write 288 #define hid_read_timeout LIBUSB_hid_read_timeout 289 #define hid_read LIBUSB_hid_read 290 #define hid_set_nonblocking LIBUSB_hid_set_nonblocking 291 #define hid_send_feature_report LIBUSB_hid_send_feature_report 292 #define hid_get_feature_report LIBUSB_hid_get_feature_report 293 #define hid_close LIBUSB_hid_close 294 #define hid_get_manufacturer_string LIBUSB_hid_get_manufacturer_string 295 #define hid_get_product_string LIBUSB_hid_get_product_string 296 #define hid_get_serial_number_string LIBUSB_hid_get_serial_number_string 297 #define hid_get_indexed_string LIBUSB_hid_get_indexed_string 298 #define hid_error LIBUSB_hid_error 299 #define new_hid_device LIBUSB_new_hid_device 300 #define free_hid_device LIBUSB_free_hid_device 301 #define input_report LIBUSB_input_report 302 #define return_data LIBUSB_return_data 303 #define make_path LIBUSB_make_path 304 #define read_thread LIBUSB_read_thread 305 306 #ifndef __FreeBSD__ 307 /* this is awkwardly inlined, so we need to re-implement it here 308 * so we can override the libusb_control_transfer call */ 309 static int 310 SDL_libusb_get_string_descriptor(libusb_device_handle *dev, 311 uint8_t descriptor_index, uint16_t lang_id, 312 unsigned char *data, int length) 313 { 314 return libusb_control_transfer(dev, 315 LIBUSB_ENDPOINT_IN | 0x0, /* Endpoint 0 IN */ 316 LIBUSB_REQUEST_GET_DESCRIPTOR, 317 (LIBUSB_DT_STRING << 8) | descriptor_index, 318 lang_id, 319 data, 320 (uint16_t) length, 321 1000); 322 } 323 #define libusb_get_string_descriptor SDL_libusb_get_string_descriptor 324 #endif /* __FreeBSD__ */ 325 326 #undef HIDAPI_H__ 327 #include "libusb/hid.c" 328 329 #undef hid_device_ 330 #undef hid_device 331 #undef hid_device_info 332 #undef hid_init 333 #undef hid_exit 334 #undef hid_enumerate 335 #undef hid_free_enumeration 336 #undef hid_open 337 #undef hid_open_path 338 #undef hid_write 339 #undef hid_read_timeout 340 #undef hid_read 341 #undef hid_set_nonblocking 342 #undef hid_send_feature_report 343 #undef hid_get_feature_report 344 #undef hid_close 345 #undef hid_get_manufacturer_string 346 #undef hid_get_product_string 347 #undef hid_get_serial_number_string 348 #undef hid_get_indexed_string 349 #undef hid_error 350 #undef new_hid_device 351 #undef free_hid_device 352 #undef input_report 353 #undef return_data 354 #undef make_path 355 #undef read_thread 356 357 #endif /* SDL_LIBUSB_DYNAMIC */ 358 359 /* Shared HIDAPI Implementation */ 360 361 #undef HIDAPI_H__ 362 #include "hidapi/hidapi.h" 363 364 struct hidapi_backend { 365 int (*hid_write)(hid_device* device, const unsigned char* data, size_t length); 366 int (*hid_read_timeout)(hid_device* device, unsigned char* data, size_t length, int milliseconds); 367 int (*hid_read)(hid_device* device, unsigned char* data, size_t length); 368 int (*hid_set_nonblocking)(hid_device* device, int nonblock); 369 int (*hid_send_feature_report)(hid_device* device, const unsigned char* data, size_t length); 370 int (*hid_get_feature_report)(hid_device* device, unsigned char* data, size_t length); 371 void (*hid_close)(hid_device* device); 372 int (*hid_get_manufacturer_string)(hid_device* device, wchar_t* string, size_t maxlen); 373 int (*hid_get_product_string)(hid_device* device, wchar_t* string, size_t maxlen); 374 int (*hid_get_serial_number_string)(hid_device* device, wchar_t* string, size_t maxlen); 375 int (*hid_get_indexed_string)(hid_device* device, int string_index, wchar_t* string, size_t maxlen); 376 const wchar_t* (*hid_error)(hid_device* device); 377 }; 378 379 #if HAVE_PLATFORM_BACKEND 380 static const struct hidapi_backend PLATFORM_Backend = { 381 (void*)PLATFORM_hid_write, 382 (void*)PLATFORM_hid_read_timeout, 383 (void*)PLATFORM_hid_read, 384 (void*)PLATFORM_hid_set_nonblocking, 385 (void*)PLATFORM_hid_send_feature_report, 386 (void*)PLATFORM_hid_get_feature_report, 387 (void*)PLATFORM_hid_close, 388 (void*)PLATFORM_hid_get_manufacturer_string, 389 (void*)PLATFORM_hid_get_product_string, 390 (void*)PLATFORM_hid_get_serial_number_string, 391 (void*)PLATFORM_hid_get_indexed_string, 392 (void*)PLATFORM_hid_error 393 }; 394 #endif /* HAVE_PLATFORM_BACKEND */ 395 396 #if HAVE_DRIVER_BACKEND 397 static const struct hidapi_backend DRIVER_Backend = { 398 (void*)DRIVER_hid_write, 399 (void*)DRIVER_hid_read_timeout, 400 (void*)DRIVER_hid_read, 401 (void*)DRIVER_hid_set_nonblocking, 402 (void*)DRIVER_hid_send_feature_report, 403 (void*)DRIVER_hid_get_feature_report, 404 (void*)DRIVER_hid_close, 405 (void*)DRIVER_hid_get_manufacturer_string, 406 (void*)DRIVER_hid_get_product_string, 407 (void*)DRIVER_hid_get_serial_number_string, 408 (void*)DRIVER_hid_get_indexed_string, 409 (void*)DRIVER_hid_error 410 }; 411 #endif /* HAVE_DRIVER_BACKEND */ 412 413 #ifdef SDL_LIBUSB_DYNAMIC 414 static const struct hidapi_backend LIBUSB_Backend = { 415 (void*)LIBUSB_hid_write, 416 (void*)LIBUSB_hid_read_timeout, 417 (void*)LIBUSB_hid_read, 418 (void*)LIBUSB_hid_set_nonblocking, 419 (void*)LIBUSB_hid_send_feature_report, 420 (void*)LIBUSB_hid_get_feature_report, 421 (void*)LIBUSB_hid_close, 422 (void*)LIBUSB_hid_get_manufacturer_string, 423 (void*)LIBUSB_hid_get_product_string, 424 (void*)LIBUSB_hid_get_serial_number_string, 425 (void*)LIBUSB_hid_get_indexed_string, 426 (void*)LIBUSB_hid_error 427 }; 428 #endif /* SDL_LIBUSB_DYNAMIC */ 429 430 typedef struct _HIDDeviceWrapper HIDDeviceWrapper; 431 struct _HIDDeviceWrapper 432 { 433 hid_device *device; /* must be first field */ 434 const struct hidapi_backend *backend; 435 }; 436 437 static HIDDeviceWrapper * 438 CreateHIDDeviceWrapper(hid_device *device, const struct hidapi_backend *backend) 439 { 440 HIDDeviceWrapper *ret = (HIDDeviceWrapper *)SDL_malloc(sizeof(*ret)); 441 ret->device = device; 442 ret->backend = backend; 443 return ret; 444 } 445 446 static hid_device * 447 WrapHIDDevice(HIDDeviceWrapper *wrapper) 448 { 449 return (hid_device *)wrapper; 450 } 451 452 static HIDDeviceWrapper * 453 UnwrapHIDDevice(hid_device *device) 454 { 455 return (HIDDeviceWrapper *)device; 456 } 457 458 static void 459 DeleteHIDDeviceWrapper(HIDDeviceWrapper *device) 460 { 461 SDL_free(device); 462 } 463 464 #define COPY_IF_EXISTS(var) \ 465 if (pSrc->var != NULL) { \ 466 pDst->var = SDL_strdup(pSrc->var); \ 467 } else { \ 468 pDst->var = NULL; \ 469 } 470 #define WCOPY_IF_EXISTS(var) \ 471 if (pSrc->var != NULL) { \ 472 pDst->var = SDL_wcsdup(pSrc->var); \ 473 } else { \ 474 pDst->var = NULL; \ 475 } 476 477 #ifdef SDL_LIBUSB_DYNAMIC 478 static void 479 LIBUSB_CopyHIDDeviceInfo(struct LIBUSB_hid_device_info *pSrc, 480 struct hid_device_info *pDst) 481 { 482 COPY_IF_EXISTS(path) 483 pDst->vendor_id = pSrc->vendor_id; 484 pDst->product_id = pSrc->product_id; 485 WCOPY_IF_EXISTS(serial_number) 486 pDst->release_number = pSrc->release_number; 487 WCOPY_IF_EXISTS(manufacturer_string) 488 WCOPY_IF_EXISTS(product_string) 489 pDst->usage_page = pSrc->usage_page; 490 pDst->usage = pSrc->usage; 491 pDst->interface_number = pSrc->interface_number; 492 pDst->interface_class = pSrc->interface_class; 493 pDst->interface_subclass = pSrc->interface_subclass; 494 pDst->interface_protocol = pSrc->interface_protocol; 495 pDst->next = NULL; 496 } 497 #endif /* SDL_LIBUSB_DYNAMIC */ 498 499 #if HAVE_DRIVER_BACKEND 500 static void 501 DRIVER_CopyHIDDeviceInfo(struct DRIVER_hid_device_info *pSrc, 502 struct hid_device_info *pDst) 503 { 504 COPY_IF_EXISTS(path) 505 pDst->vendor_id = pSrc->vendor_id; 506 pDst->product_id = pSrc->product_id; 507 WCOPY_IF_EXISTS(serial_number) 508 pDst->release_number = pSrc->release_number; 509 WCOPY_IF_EXISTS(manufacturer_string) 510 WCOPY_IF_EXISTS(product_string) 511 pDst->usage_page = pSrc->usage_page; 512 pDst->usage = pSrc->usage; 513 pDst->interface_number = pSrc->interface_number; 514 pDst->interface_class = pSrc->interface_class; 515 pDst->interface_subclass = pSrc->interface_subclass; 516 pDst->interface_protocol = pSrc->interface_protocol; 517 pDst->next = NULL; 518 } 519 #endif /* HAVE_DRIVER_BACKEND */ 520 521 #if HAVE_PLATFORM_BACKEND 522 static void 523 PLATFORM_CopyHIDDeviceInfo(struct PLATFORM_hid_device_info *pSrc, 524 struct hid_device_info *pDst) 525 { 526 COPY_IF_EXISTS(path) 527 pDst->vendor_id = pSrc->vendor_id; 528 pDst->product_id = pSrc->product_id; 529 WCOPY_IF_EXISTS(serial_number) 530 pDst->release_number = pSrc->release_number; 531 WCOPY_IF_EXISTS(manufacturer_string) 532 WCOPY_IF_EXISTS(product_string) 533 pDst->usage_page = pSrc->usage_page; 534 pDst->usage = pSrc->usage; 535 pDst->interface_number = pSrc->interface_number; 536 pDst->interface_class = pSrc->interface_class; 537 pDst->interface_subclass = pSrc->interface_subclass; 538 pDst->interface_protocol = pSrc->interface_protocol; 539 pDst->next = NULL; 540 } 541 #endif /* HAVE_PLATFORM_BACKEND */ 542 543 #undef COPY_IF_EXISTS 544 #undef WCOPY_IF_EXISTS 545 546 static SDL_bool SDL_hidapi_wasinit = SDL_FALSE; 547 548 int HID_API_EXPORT HID_API_CALL hid_init(void) 549 { 550 int err; 551 552 if (SDL_hidapi_wasinit == SDL_TRUE) { 553 return 0; 554 } 555 556 #ifdef SDL_LIBUSB_DYNAMIC 557 libusb_ctx.libhandle = SDL_LoadObject(SDL_LIBUSB_DYNAMIC); 558 if (libusb_ctx.libhandle != NULL) { 559 SDL_bool loaded = SDL_TRUE; 560 #define LOAD_LIBUSB_SYMBOL(func) \ 561 if (!(libusb_ctx.func = SDL_LoadFunction(libusb_ctx.libhandle, "libusb_" #func))) {loaded = SDL_FALSE;} 562 LOAD_LIBUSB_SYMBOL(init) 563 LOAD_LIBUSB_SYMBOL(exit) 564 LOAD_LIBUSB_SYMBOL(get_device_list) 565 LOAD_LIBUSB_SYMBOL(free_device_list) 566 LOAD_LIBUSB_SYMBOL(get_device_descriptor) 567 LOAD_LIBUSB_SYMBOL(get_active_config_descriptor) 568 LOAD_LIBUSB_SYMBOL(get_config_descriptor) 569 LOAD_LIBUSB_SYMBOL(free_config_descriptor) 570 LOAD_LIBUSB_SYMBOL(get_bus_number) 571 LOAD_LIBUSB_SYMBOL(get_device_address) 572 LOAD_LIBUSB_SYMBOL(open) 573 LOAD_LIBUSB_SYMBOL(close) 574 LOAD_LIBUSB_SYMBOL(claim_interface) 575 LOAD_LIBUSB_SYMBOL(release_interface) 576 LOAD_LIBUSB_SYMBOL(kernel_driver_active) 577 LOAD_LIBUSB_SYMBOL(detach_kernel_driver) 578 LOAD_LIBUSB_SYMBOL(attach_kernel_driver) 579 LOAD_LIBUSB_SYMBOL(set_interface_alt_setting) 580 LOAD_LIBUSB_SYMBOL(alloc_transfer) 581 LOAD_LIBUSB_SYMBOL(submit_transfer) 582 LOAD_LIBUSB_SYMBOL(cancel_transfer) 583 LOAD_LIBUSB_SYMBOL(free_transfer) 584 LOAD_LIBUSB_SYMBOL(control_transfer) 585 LOAD_LIBUSB_SYMBOL(interrupt_transfer) 586 LOAD_LIBUSB_SYMBOL(handle_events) 587 LOAD_LIBUSB_SYMBOL(handle_events_completed) 588 #undef LOAD_LIBUSB_SYMBOL 589 590 if (loaded == SDL_TRUE) { 591 if ((err = LIBUSB_hid_init()) < 0) { 592 SDL_UnloadObject(libusb_ctx.libhandle); 593 libusb_ctx.libhandle = NULL; 594 return err; 595 } 596 } else { 597 SDL_UnloadObject(libusb_ctx.libhandle); 598 libusb_ctx.libhandle = NULL; 599 /* SDL_LogWarn(SDL_LOG_CATEGORY_INPUT, SDL_LIBUSB_DYNAMIC " found but could not load function."); */ 600 /* ignore error: continue without libusb */ 601 } 602 } 603 #endif /* SDL_LIBUSB_DYNAMIC */ 604 605 #if HAVE_PLATFORM_BACKEND 606 #if __LINUX__ 607 udev_ctx = SDL_UDEV_GetUdevSyms(); 608 #endif /* __LINUX __ */ 609 if (udev_ctx && (err = PLATFORM_hid_init()) < 0) { 610 #ifdef SDL_LIBUSB_DYNAMIC 611 if (libusb_ctx.libhandle) { 612 LIBUSB_hid_exit(); 613 SDL_UnloadObject(libusb_ctx.libhandle); 614 libusb_ctx.libhandle = NULL; 615 } 616 #endif /* SDL_LIBUSB_DYNAMIC */ 617 return err; 618 } 619 #endif /* HAVE_PLATFORM_BACKEND */ 620 621 SDL_hidapi_wasinit = SDL_TRUE; 622 return 0; 623 } 624 625 int HID_API_EXPORT HID_API_CALL hid_exit(void) 626 { 627 int err = 0; 628 629 if (SDL_hidapi_wasinit == SDL_FALSE) { 630 return 0; 631 } 632 SDL_hidapi_wasinit = SDL_FALSE; 633 634 #if HAVE_PLATFORM_BACKEND 635 if (udev_ctx) { 636 err = PLATFORM_hid_exit(); 637 } 638 #endif /* HAVE_PLATFORM_BACKEND */ 639 #ifdef SDL_LIBUSB_DYNAMIC 640 if (libusb_ctx.libhandle) { 641 err |= LIBUSB_hid_exit(); /* Ehhhhh */ 642 SDL_UnloadObject(libusb_ctx.libhandle); 643 libusb_ctx.libhandle = NULL; 644 } 645 #endif /* SDL_LIBUSB_DYNAMIC */ 646 return err; 647 } 648 649 struct hid_device_info HID_API_EXPORT * HID_API_CALL hid_enumerate(unsigned short vendor_id, unsigned short product_id) 650 { 651 #ifdef SDL_LIBUSB_DYNAMIC 652 struct LIBUSB_hid_device_info *usb_devs = NULL; 653 struct LIBUSB_hid_device_info *usb_dev; 654 #endif 655 #if HAVE_DRIVER_BACKEND 656 struct DRIVER_hid_device_info* driver_devs = NULL; 657 struct DRIVER_hid_device_info* driver_dev; 658 #endif 659 #if HAVE_PLATFORM_BACKEND 660 struct PLATFORM_hid_device_info *raw_devs = NULL; 661 struct PLATFORM_hid_device_info *raw_dev; 662 #endif 663 struct hid_device_info *devs = NULL, *last = NULL, *new_dev; 664 665 if (hid_init() != 0) { 666 return NULL; 667 } 668 669 #ifdef SDL_LIBUSB_DYNAMIC 670 if (libusb_ctx.libhandle) { 671 usb_devs = LIBUSB_hid_enumerate(vendor_id, product_id); 672 #ifdef DEBUG_HIDAPI 673 SDL_Log("libusb devices found:"); 674 #endif 675 for (usb_dev = usb_devs; usb_dev; usb_dev = usb_dev->next) { 676 new_dev = (struct hid_device_info*) SDL_malloc(sizeof(struct hid_device_info)); 677 if (!new_dev) { 678 LIBUSB_hid_free_enumeration(usb_devs); 679 hid_free_enumeration(devs); 680 SDL_OutOfMemory(); 681 return NULL; 682 } 683 LIBUSB_CopyHIDDeviceInfo(usb_dev, new_dev); 684 #ifdef DEBUG_HIDAPI 685 SDL_Log(" - %ls %ls 0x%.4hx 0x%.4hx", 686 usb_dev->manufacturer_string, usb_dev->product_string, 687 usb_dev->vendor_id, usb_dev->product_id); 688 #endif 689 690 if (last != NULL) { 691 last->next = new_dev; 692 } else { 693 devs = new_dev; 694 } 695 last = new_dev; 696 } 697 } 698 #endif /* SDL_LIBUSB_DYNAMIC */ 699 700 #ifdef HAVE_DRIVER_BACKEND 701 driver_devs = DRIVER_hid_enumerate(vendor_id, product_id); 702 for (driver_dev = driver_devs; driver_dev; driver_dev = driver_dev->next) { 703 new_dev = (struct hid_device_info*) SDL_malloc(sizeof(struct hid_device_info)); 704 DRIVER_CopyHIDDeviceInfo(driver_dev, new_dev); 705 706 if (last != NULL) { 707 last->next = new_dev; 708 } else { 709 devs = new_dev; 710 } 711 last = new_dev; 712 } 713 #endif /* HAVE_DRIVER_BACKEND */ 714 715 #if HAVE_PLATFORM_BACKEND 716 if (udev_ctx) { 717 raw_devs = PLATFORM_hid_enumerate(vendor_id, product_id); 718 #ifdef DEBUG_HIDAPI 719 SDL_Log("hidraw devices found:"); 720 #endif 721 for (raw_dev = raw_devs; raw_dev; raw_dev = raw_dev->next) { 722 SDL_bool bFound = SDL_FALSE; 723 #ifdef DEBUG_HIDAPI 724 SDL_Log(" - %ls %ls 0x%.4hx 0x%.4hx", 725 raw_dev->manufacturer_string, raw_dev->product_string, 726 raw_dev->vendor_id, raw_dev->product_id); 727 #endif 728 #ifdef SDL_LIBUSB_DYNAMIC 729 for (usb_dev = usb_devs; usb_dev; usb_dev = usb_dev->next) { 730 if (raw_dev->vendor_id == usb_dev->vendor_id && 731 raw_dev->product_id == usb_dev->product_id && 732 (raw_dev->interface_number < 0 || raw_dev->interface_number == usb_dev->interface_number)) { 733 bFound = SDL_TRUE; 734 break; 735 } 736 } 737 #endif 738 #ifdef HAVE_DRIVER_BACKEND 739 for (driver_dev = driver_devs; driver_dev; driver_dev = driver_dev->next) { 740 if (raw_dev->vendor_id == driver_dev->vendor_id && 741 raw_dev->product_id == driver_dev->product_id && 742 (raw_dev->interface_number < 0 || raw_dev->interface_number == driver_dev->interface_number)) { 743 bFound = SDL_TRUE; 744 break; 745 } 746 } 747 #endif 748 if (!bFound) { 749 new_dev = (struct hid_device_info*) SDL_malloc(sizeof(struct hid_device_info)); 750 if (!new_dev) { 751 #ifdef SDL_LIBUSB_DYNAMIC 752 if (libusb_ctx.libhandle) { 753 LIBUSB_hid_free_enumeration(usb_devs); 754 } 755 #endif 756 PLATFORM_hid_free_enumeration(raw_devs); 757 hid_free_enumeration(devs); 758 SDL_OutOfMemory(); 759 return NULL; 760 } 761 PLATFORM_CopyHIDDeviceInfo(raw_dev, new_dev); 762 new_dev->next = NULL; 763 764 if (last != NULL) { 765 last->next = new_dev; 766 } else { 767 devs = new_dev; 768 } 769 last = new_dev; 770 } 771 } 772 PLATFORM_hid_free_enumeration(raw_devs); 773 } 774 #endif /* HAVE_PLATFORM_BACKEND */ 775 776 #ifdef SDL_LIBUSB_DYNAMIC 777 if (libusb_ctx.libhandle) { 778 LIBUSB_hid_free_enumeration(usb_devs); 779 } 780 #endif 781 return devs; 782 } 783 784 void HID_API_EXPORT HID_API_CALL hid_free_enumeration(struct hid_device_info *devs) 785 { 786 while (devs) { 787 struct hid_device_info *next = devs->next; 788 SDL_free(devs->path); 789 SDL_free(devs->serial_number); 790 SDL_free(devs->manufacturer_string); 791 SDL_free(devs->product_string); 792 SDL_free(devs); 793 devs = next; 794 } 795 } 796 797 HID_API_EXPORT hid_device * HID_API_CALL hid_open(unsigned short vendor_id, unsigned short product_id, const wchar_t *serial_number) 798 { 799 hid_device *pDevice = NULL; 800 801 if (hid_init() != 0) { 802 return NULL; 803 } 804 805 #if HAVE_PLATFORM_BACKEND 806 if (udev_ctx && 807 (pDevice = (hid_device*) PLATFORM_hid_open(vendor_id, product_id, serial_number)) != NULL) { 808 809 HIDDeviceWrapper *wrapper = CreateHIDDeviceWrapper(pDevice, &PLATFORM_Backend); 810 return WrapHIDDevice(wrapper); 811 } 812 #endif /* HAVE_PLATFORM_BACKEND */ 813 814 #if HAVE_DRIVER_BACKEND 815 if ((pDevice = (hid_device*) DRIVER_hid_open(vendor_id, product_id, serial_number)) != NULL) { 816 817 HIDDeviceWrapper *wrapper = CreateHIDDeviceWrapper(pDevice, &DRIVER_Backend); 818 return WrapHIDDevice(wrapper); 819 } 820 #endif /* HAVE_DRIVER_BACKEND */ 821 822 #ifdef SDL_LIBUSB_DYNAMIC 823 if (libusb_ctx.libhandle && 824 (pDevice = (hid_device*) LIBUSB_hid_open(vendor_id, product_id, serial_number)) != NULL) { 825 826 HIDDeviceWrapper *wrapper = CreateHIDDeviceWrapper(pDevice, &LIBUSB_Backend); 827 return WrapHIDDevice(wrapper); 828 } 829 #endif /* SDL_LIBUSB_DYNAMIC */ 830 831 return NULL; 832 } 833 834 HID_API_EXPORT hid_device * HID_API_CALL hid_open_path(const char *path, int bExclusive /* = false */) 835 { 836 hid_device *pDevice = NULL; 837 838 if (hid_init() != 0) { 839 return NULL; 840 } 841 842 #if HAVE_PLATFORM_BACKEND 843 if (udev_ctx && 844 (pDevice = (hid_device*) PLATFORM_hid_open_path(path, bExclusive)) != NULL) { 845 846 HIDDeviceWrapper *wrapper = CreateHIDDeviceWrapper(pDevice, &PLATFORM_Backend); 847 return WrapHIDDevice(wrapper); 848 } 849 #endif /* HAVE_PLATFORM_BACKEND */ 850 851 #if HAVE_DRIVER_BACKEND 852 if ((pDevice = (hid_device*) DRIVER_hid_open_path(path, bExclusive)) != NULL) { 853 854 HIDDeviceWrapper *wrapper = CreateHIDDeviceWrapper(pDevice, &DRIVER_Backend); 855 return WrapHIDDevice(wrapper); 856 } 857 #endif /* HAVE_DRIVER_BACKEND */ 858 859 #ifdef SDL_LIBUSB_DYNAMIC 860 if (libusb_ctx.libhandle && 861 (pDevice = (hid_device*) LIBUSB_hid_open_path(path, bExclusive)) != NULL) { 862 863 HIDDeviceWrapper *wrapper = CreateHIDDeviceWrapper(pDevice, &LIBUSB_Backend); 864 return WrapHIDDevice(wrapper); 865 } 866 #endif /* SDL_LIBUSB_DYNAMIC */ 867 868 return NULL; 869 } 870 871 int HID_API_EXPORT HID_API_CALL hid_write(hid_device *device, const unsigned char *data, size_t length) 872 { 873 HIDDeviceWrapper *wrapper = UnwrapHIDDevice(device); 874 return wrapper->backend->hid_write(wrapper->device, data, length); 875 } 876 877 int HID_API_EXPORT HID_API_CALL hid_read_timeout(hid_device *device, unsigned char *data, size_t length, int milliseconds) 878 { 879 HIDDeviceWrapper *wrapper = UnwrapHIDDevice(device); 880 return wrapper->backend->hid_read_timeout(wrapper->device, data, length, milliseconds); 881 } 882 883 int HID_API_EXPORT HID_API_CALL hid_read(hid_device *device, unsigned char *data, size_t length) 884 { 885 HIDDeviceWrapper *wrapper = UnwrapHIDDevice(device); 886 return wrapper->backend->hid_read(wrapper->device, data, length); 887 } 888 889 int HID_API_EXPORT HID_API_CALL hid_set_nonblocking(hid_device *device, int nonblock) 890 { 891 HIDDeviceWrapper *wrapper = UnwrapHIDDevice(device); 892 return wrapper->backend->hid_set_nonblocking(wrapper->device, nonblock); 893 } 894 895 int HID_API_EXPORT HID_API_CALL hid_send_feature_report(hid_device *device, const unsigned char *data, size_t length) 896 { 897 HIDDeviceWrapper *wrapper = UnwrapHIDDevice(device); 898 return wrapper->backend->hid_send_feature_report(wrapper->device, data, length); 899 } 900 901 int HID_API_EXPORT HID_API_CALL hid_get_feature_report(hid_device *device, unsigned char *data, size_t length) 902 { 903 HIDDeviceWrapper *wrapper = UnwrapHIDDevice(device); 904 return wrapper->backend->hid_get_feature_report(wrapper->device, data, length); 905 } 906 907 void HID_API_EXPORT HID_API_CALL hid_close(hid_device *device) 908 { 909 HIDDeviceWrapper *wrapper = UnwrapHIDDevice(device); 910 wrapper->backend->hid_close(wrapper->device); 911 DeleteHIDDeviceWrapper(wrapper); 912 } 913 914 int HID_API_EXPORT_CALL hid_get_manufacturer_string(hid_device *device, wchar_t *string, size_t maxlen) 915 { 916 HIDDeviceWrapper *wrapper = UnwrapHIDDevice(device); 917 return wrapper->backend->hid_get_manufacturer_string(wrapper->device, string, maxlen); 918 } 919 920 int HID_API_EXPORT_CALL hid_get_product_string(hid_device *device, wchar_t *string, size_t maxlen) 921 { 922 HIDDeviceWrapper *wrapper = UnwrapHIDDevice(device); 923 return wrapper->backend->hid_get_product_string(wrapper->device, string, maxlen); 924 } 925 926 int HID_API_EXPORT_CALL hid_get_serial_number_string(hid_device *device, wchar_t *string, size_t maxlen) 927 { 928 HIDDeviceWrapper *wrapper = UnwrapHIDDevice(device); 929 return wrapper->backend->hid_get_serial_number_string(wrapper->device, string, maxlen); 930 } 931 932 int HID_API_EXPORT_CALL hid_get_indexed_string(hid_device *device, int string_index, wchar_t *string, size_t maxlen) 933 { 934 HIDDeviceWrapper *wrapper = UnwrapHIDDevice(device); 935 return wrapper->backend->hid_get_indexed_string(wrapper->device, string_index, string, maxlen); 936 } 937 938 HID_API_EXPORT const wchar_t* HID_API_CALL hid_error(hid_device *device) 939 { 940 HIDDeviceWrapper *wrapper = UnwrapHIDDevice(device); 941 return wrapper->backend->hid_error(wrapper->device); 942 } 943 944 #endif /* SDL_JOYSTICK_HIDAPI */ 945 946 /* vi: set sts=4 ts=4 sw=4 expandtab: */