hid.c (44603B)
1 /******************************************************* 2 HIDAPI - Multi-Platform library for 3 communication with HID devices. 4 5 Alan Ott 6 Signal 11 Software 7 8 8/22/2009 9 Linux Version - 6/2/2010 10 Libusb Version - 8/13/2010 11 FreeBSD Version - 11/1/2011 12 13 Copyright 2009, All Rights Reserved. 14 15 At the discretion of the user of this library, 16 this software may be licensed under the terms of the 17 GNU General Public License v3, a BSD-Style license, or the 18 original HIDAPI license as outlined in the LICENSE.txt, 19 LICENSE-gpl3.txt, LICENSE-bsd.txt, and LICENSE-orig.txt 20 files located at the root of the source distribution. 21 These files may also be found in the public source 22 code repository located at: 23 https://github.com/libusb/hidapi . 24 ********************************************************/ 25 26 /* This file is heavily modified from the original libusb.c, for portability. 27 * Last upstream update was from July 25, 2019, Git commit 93dca807. 28 */ 29 30 #include "../../SDL_internal.h" 31 #include "SDL_thread.h" 32 #include "SDL_mutex.h" 33 34 #ifdef SDL_JOYSTICK_HIDAPI 35 36 #include <libusb.h> 37 #include <locale.h> /* setlocale */ 38 39 #include "hidapi.h" 40 41 #ifdef NAMESPACE 42 namespace NAMESPACE 43 { 44 #endif 45 46 /* Barrier implementation because Android/Bionic don't have pthread_barrier. 47 This implementation came from Brent Priddy and was posted on 48 StackOverflow. It is used with his permission. */ 49 50 typedef struct _SDL_ThreadBarrier 51 { 52 SDL_mutex *mutex; 53 SDL_cond *cond; 54 Uint32 count; 55 Uint32 trip_count; 56 } SDL_ThreadBarrier; 57 58 static int SDL_CreateThreadBarrier(SDL_ThreadBarrier *barrier, Uint32 count) 59 { 60 if (barrier == NULL) { 61 return SDL_SetError("barrier must be non-NULL"); 62 } 63 if (count == 0) { 64 return SDL_SetError("count must be > 0"); 65 } 66 67 barrier->mutex = SDL_CreateMutex(); 68 if (barrier->mutex == NULL) { 69 return -1; /* Error set by CreateMutex */ 70 } 71 barrier->cond = SDL_CreateCond(); 72 if (barrier->cond == NULL) { 73 return -1; /* Error set by CreateCond */ 74 } 75 76 barrier->trip_count = count; 77 barrier->count = 0; 78 79 return 0; 80 } 81 82 static void SDL_DestroyThreadBarrier(SDL_ThreadBarrier *barrier) 83 { 84 SDL_DestroyCond(barrier->cond); 85 SDL_DestroyMutex(barrier->mutex); 86 } 87 88 static int SDL_WaitThreadBarrier(SDL_ThreadBarrier *barrier) 89 { 90 SDL_LockMutex(barrier->mutex); 91 barrier->count += 1; 92 if (barrier->count >= barrier->trip_count) { 93 barrier->count = 0; 94 SDL_CondBroadcast(barrier->cond); 95 SDL_UnlockMutex(barrier->mutex); 96 return 1; 97 } 98 SDL_CondWait(barrier->cond, barrier->mutex); 99 SDL_UnlockMutex(barrier->mutex); 100 return 0; 101 } 102 103 #if defined(__cplusplus) && !defined(NAMESPACE) 104 extern "C" { 105 #endif 106 107 #ifdef DEBUG_PRINTF 108 #define LOG(...) fprintf(stderr, __VA_ARGS__) 109 #else 110 #define LOG(...) do {} while (0) 111 #endif 112 113 #ifndef __FreeBSD__ 114 #define DETACH_KERNEL_DRIVER 115 #endif 116 117 /* Uncomment to enable the retrieval of Usage and Usage Page in 118 hid_enumerate(). Warning, on platforms different from FreeBSD 119 this is very invasive as it requires the detach 120 and re-attach of the kernel driver. See comments inside hid_enumerate(). 121 libusb HIDAPI programs are encouraged to use the interface number 122 instead to differentiate between interfaces on a composite HID device. */ 123 /*#define INVASIVE_GET_USAGE*/ 124 125 /* Linked List of input reports received from the device. */ 126 struct input_report { 127 uint8_t *data; 128 size_t len; 129 struct input_report *next; 130 }; 131 132 133 struct hid_device_ { 134 /* Handle to the actual device. */ 135 libusb_device_handle *device_handle; 136 137 /* Endpoint information */ 138 int input_endpoint; 139 int output_endpoint; 140 int input_ep_max_packet_size; 141 142 /* The interface number of the HID */ 143 int interface; 144 int detached_driver; 145 146 /* Indexes of Strings */ 147 int manufacturer_index; 148 int product_index; 149 int serial_index; 150 151 /* Whether blocking reads are used */ 152 int blocking; /* boolean */ 153 154 /* Read thread objects */ 155 SDL_Thread *thread; 156 SDL_mutex *mutex; /* Protects input_reports */ 157 SDL_cond *condition; 158 SDL_ThreadBarrier barrier; /* Ensures correct startup sequence */ 159 int shutdown_thread; 160 int cancelled; 161 struct libusb_transfer *transfer; 162 163 /* List of received input reports. */ 164 struct input_report *input_reports; 165 }; 166 167 static libusb_context *usb_context = NULL; 168 169 uint16_t get_usb_code_for_current_locale(void); 170 static int return_data(hid_device *dev, unsigned char *data, size_t length); 171 172 static hid_device *new_hid_device(void) 173 { 174 hid_device *dev = (hid_device*) calloc(1, sizeof(hid_device)); 175 dev->blocking = 1; 176 177 dev->mutex = SDL_CreateMutex(); 178 dev->condition = SDL_CreateCond(); 179 SDL_CreateThreadBarrier(&dev->barrier, 2); 180 181 return dev; 182 } 183 184 static void free_hid_device(hid_device *dev) 185 { 186 /* Clean up the thread objects */ 187 SDL_DestroyThreadBarrier(&dev->barrier); 188 SDL_DestroyCond(dev->condition); 189 SDL_DestroyMutex(dev->mutex); 190 191 /* Free the device itself */ 192 free(dev); 193 } 194 195 #if 0 196 /*TODO: Implement this function on hidapi/libusb.. */ 197 static void register_error(hid_device *dev, const char *op) 198 { 199 200 } 201 #endif 202 203 #ifdef INVASIVE_GET_USAGE 204 /* Get bytes from a HID Report Descriptor. 205 Only call with a num_bytes of 0, 1, 2, or 4. */ 206 static uint32_t get_bytes(uint8_t *rpt, size_t len, size_t num_bytes, size_t cur) 207 { 208 /* Return if there aren't enough bytes. */ 209 if (cur + num_bytes >= len) 210 return 0; 211 212 if (num_bytes == 0) 213 return 0; 214 else if (num_bytes == 1) { 215 return rpt[cur+1]; 216 } 217 else if (num_bytes == 2) { 218 return (rpt[cur+2] * 256 + rpt[cur+1]); 219 } 220 else if (num_bytes == 4) { 221 return (rpt[cur+4] * 0x01000000 + 222 rpt[cur+3] * 0x00010000 + 223 rpt[cur+2] * 0x00000100 + 224 rpt[cur+1] * 0x00000001); 225 } 226 else 227 return 0; 228 } 229 230 /* Retrieves the device's Usage Page and Usage from the report 231 descriptor. The algorithm is simple, as it just returns the first 232 Usage and Usage Page that it finds in the descriptor. 233 The return value is 0 on success and -1 on failure. */ 234 static int get_usage(uint8_t *report_descriptor, size_t size, 235 unsigned short *usage_page, unsigned short *usage) 236 { 237 unsigned int i = 0; 238 int size_code; 239 int data_len, key_size; 240 int usage_found = 0, usage_page_found = 0; 241 242 while (i < size) { 243 int key = report_descriptor[i]; 244 int key_cmd = key & 0xfc; 245 246 //printf("key: %02hhx\n", key); 247 248 if ((key & 0xf0) == 0xf0) { 249 /* This is a Long Item. The next byte contains the 250 length of the data section (value) for this key. 251 See the HID specification, version 1.11, section 252 6.2.2.3, titled "Long Items." */ 253 if (i+1 < size) 254 data_len = report_descriptor[i+1]; 255 else 256 data_len = 0; /* malformed report */ 257 key_size = 3; 258 } 259 else { 260 /* This is a Short Item. The bottom two bits of the 261 key contain the size code for the data section 262 (value) for this key. Refer to the HID 263 specification, version 1.11, section 6.2.2.2, 264 titled "Short Items." */ 265 size_code = key & 0x3; 266 switch (size_code) { 267 case 0: 268 case 1: 269 case 2: 270 data_len = size_code; 271 break; 272 case 3: 273 data_len = 4; 274 break; 275 default: 276 /* Can't ever happen since size_code is & 0x3 */ 277 data_len = 0; 278 break; 279 }; 280 key_size = 1; 281 } 282 283 if (key_cmd == 0x4) { 284 *usage_page = get_bytes(report_descriptor, size, data_len, i); 285 usage_page_found = 1; 286 //printf("Usage Page: %x\n", (uint32_t)*usage_page); 287 } 288 if (key_cmd == 0x8) { 289 *usage = get_bytes(report_descriptor, size, data_len, i); 290 usage_found = 1; 291 //printf("Usage: %x\n", (uint32_t)*usage); 292 } 293 294 if (usage_page_found && usage_found) 295 return 0; /* success */ 296 297 /* Skip over this key and it's associated data */ 298 i += data_len + key_size; 299 } 300 301 return -1; /* failure */ 302 } 303 #endif /* INVASIVE_GET_USAGE */ 304 305 #if defined(__FreeBSD__) && __FreeBSD__ < 10 306 /* The libusb version included in FreeBSD < 10 doesn't have this function. In 307 mainline libusb, it's inlined in libusb.h. This function will bear a striking 308 resemblance to that one, because there's about one way to code it. 309 310 Note that the data parameter is Unicode in UTF-16LE encoding. 311 Return value is the number of bytes in data, or LIBUSB_ERROR_*. 312 */ 313 static inline int libusb_get_string_descriptor(libusb_device_handle *dev, 314 uint8_t descriptor_index, uint16_t lang_id, 315 unsigned char *data, int length) 316 { 317 return libusb_control_transfer(dev, 318 LIBUSB_ENDPOINT_IN | 0x0, /* Endpoint 0 IN */ 319 LIBUSB_REQUEST_GET_DESCRIPTOR, 320 (LIBUSB_DT_STRING << 8) | descriptor_index, 321 lang_id, data, (uint16_t) length, 1000); 322 } 323 324 #endif 325 326 327 /* Get the first language the device says it reports. This comes from 328 USB string #0. */ 329 static uint16_t get_first_language(libusb_device_handle *dev) 330 { 331 uint16_t buf[32]; 332 int len; 333 334 /* Get the string from libusb. */ 335 len = libusb_get_string_descriptor(dev, 336 0x0, /* String ID */ 337 0x0, /* Language */ 338 (unsigned char*)buf, 339 sizeof(buf)); 340 if (len < 4) 341 return 0x0; 342 343 return buf[1]; /* First two bytes are len and descriptor type. */ 344 } 345 346 static int is_language_supported(libusb_device_handle *dev, uint16_t lang) 347 { 348 uint16_t buf[32]; 349 int len; 350 int i; 351 352 /* Get the string from libusb. */ 353 len = libusb_get_string_descriptor(dev, 354 0x0, /* String ID */ 355 0x0, /* Language */ 356 (unsigned char*)buf, 357 sizeof(buf)); 358 if (len < 4) 359 return 0x0; 360 361 362 len /= 2; /* language IDs are two-bytes each. */ 363 /* Start at index 1 because there are two bytes of protocol data. */ 364 for (i = 1; i < len; i++) { 365 if (buf[i] == lang) 366 return 1; 367 } 368 369 return 0; 370 } 371 372 373 /* This function returns a newly allocated wide string containing the USB 374 device string numbered by the index. The returned string must be freed 375 by using free(). */ 376 static wchar_t *get_usb_string(libusb_device_handle *dev, uint8_t idx) 377 { 378 char buf[512]; 379 int len; 380 wchar_t *str = NULL; 381 382 wchar_t wbuf[256]; 383 SDL_iconv_t ic; 384 size_t inbytes; 385 size_t outbytes; 386 size_t res; 387 const char *inptr; 388 char *outptr; 389 390 /* Determine which language to use. */ 391 uint16_t lang; 392 lang = get_usb_code_for_current_locale(); 393 if (!is_language_supported(dev, lang)) 394 lang = get_first_language(dev); 395 396 /* Get the string from libusb. */ 397 len = libusb_get_string_descriptor(dev, 398 idx, 399 lang, 400 (unsigned char*)buf, 401 sizeof(buf)); 402 if (len < 0) 403 return NULL; 404 405 /* buf does not need to be explicitly NULL-terminated because 406 it is only passed into iconv() which does not need it. */ 407 408 /* Initialize iconv. */ 409 ic = SDL_iconv_open("WCHAR_T", "UTF-16LE"); 410 if (ic == (SDL_iconv_t)-1) { 411 LOG("SDL_iconv_open() failed\n"); 412 return NULL; 413 } 414 415 /* Convert to native wchar_t (UTF-32 on glibc/BSD systems). 416 Skip the first character (2-bytes). */ 417 inptr = buf+2; 418 inbytes = len-2; 419 outptr = (char*) wbuf; 420 outbytes = sizeof(wbuf); 421 res = SDL_iconv(ic, &inptr, &inbytes, &outptr, &outbytes); 422 if (res == (size_t)-1) { 423 LOG("SDL_iconv() failed\n"); 424 goto err; 425 } 426 427 /* Write the terminating NULL. */ 428 wbuf[sizeof(wbuf)/sizeof(wbuf[0])-1] = 0x00000000; 429 if (outbytes >= sizeof(wbuf[0])) 430 *((wchar_t*)outptr) = 0x00000000; 431 432 /* Allocate and copy the string. */ 433 str = wcsdup(wbuf); 434 435 err: 436 SDL_iconv_close(ic); 437 438 return str; 439 } 440 441 static char *make_path(libusb_device *dev, int interface_number) 442 { 443 char str[64]; 444 snprintf(str, sizeof(str), "%04x:%04x:%02x", 445 libusb_get_bus_number(dev), 446 libusb_get_device_address(dev), 447 interface_number); 448 str[sizeof(str)-1] = '\0'; 449 450 return strdup(str); 451 } 452 453 454 int HID_API_EXPORT hid_init(void) 455 { 456 if (!usb_context) { 457 const char *locale; 458 459 /* Init Libusb */ 460 if (libusb_init(&usb_context)) 461 return -1; 462 463 /* Set the locale if it's not set. */ 464 locale = setlocale(LC_CTYPE, NULL); 465 if (!locale) 466 setlocale(LC_CTYPE, ""); 467 } 468 469 return 0; 470 } 471 472 int HID_API_EXPORT hid_exit(void) 473 { 474 if (usb_context) { 475 libusb_exit(usb_context); 476 usb_context = NULL; 477 } 478 479 return 0; 480 } 481 482 static int is_xbox360(unsigned short vendor_id, const struct libusb_interface_descriptor *intf_desc) 483 { 484 static const int XB360_IFACE_SUBCLASS = 93; 485 static const int XB360_IFACE_PROTOCOL = 1; /* Wired */ 486 static const int XB360W_IFACE_PROTOCOL = 129; /* Wireless */ 487 static const int SUPPORTED_VENDORS[] = { 488 0x0079, /* GPD Win 2 */ 489 0x044f, /* Thrustmaster */ 490 0x045e, /* Microsoft */ 491 0x046d, /* Logitech */ 492 0x056e, /* Elecom */ 493 0x06a3, /* Saitek */ 494 0x0738, /* Mad Catz */ 495 0x07ff, /* Mad Catz */ 496 0x0e6f, /* PDP */ 497 0x0f0d, /* Hori */ 498 0x1038, /* SteelSeries */ 499 0x11c9, /* Nacon */ 500 0x12ab, /* Unknown */ 501 0x1430, /* RedOctane */ 502 0x146b, /* BigBen */ 503 0x1532, /* Razer Sabertooth */ 504 0x15e4, /* Numark */ 505 0x162e, /* Joytech */ 506 0x1689, /* Razer Onza */ 507 0x1bad, /* Harmonix */ 508 0x24c6, /* PowerA */ 509 }; 510 511 if (intf_desc->bInterfaceClass == LIBUSB_CLASS_VENDOR_SPEC && 512 intf_desc->bInterfaceSubClass == XB360_IFACE_SUBCLASS && 513 (intf_desc->bInterfaceProtocol == XB360_IFACE_PROTOCOL || 514 intf_desc->bInterfaceProtocol == XB360W_IFACE_PROTOCOL)) { 515 int i; 516 for (i = 0; i < sizeof(SUPPORTED_VENDORS)/sizeof(SUPPORTED_VENDORS[0]); ++i) { 517 if (vendor_id == SUPPORTED_VENDORS[i]) { 518 return 1; 519 } 520 } 521 } 522 return 0; 523 } 524 525 static int is_xboxone(unsigned short vendor_id, const struct libusb_interface_descriptor *intf_desc) 526 { 527 static const int XB1_IFACE_SUBCLASS = 71; 528 static const int XB1_IFACE_PROTOCOL = 208; 529 static const int SUPPORTED_VENDORS[] = { 530 0x045e, /* Microsoft */ 531 0x0738, /* Mad Catz */ 532 0x0e6f, /* PDP */ 533 0x0f0d, /* Hori */ 534 0x1532, /* Razer Wildcat */ 535 0x24c6, /* PowerA */ 536 0x2e24, /* Hyperkin */ 537 }; 538 539 if (intf_desc->bInterfaceNumber == 0 && 540 intf_desc->bInterfaceClass == LIBUSB_CLASS_VENDOR_SPEC && 541 intf_desc->bInterfaceSubClass == XB1_IFACE_SUBCLASS && 542 intf_desc->bInterfaceProtocol == XB1_IFACE_PROTOCOL) { 543 int i; 544 for (i = 0; i < sizeof(SUPPORTED_VENDORS)/sizeof(SUPPORTED_VENDORS[0]); ++i) { 545 if (vendor_id == SUPPORTED_VENDORS[i]) { 546 return 1; 547 } 548 } 549 } 550 return 0; 551 } 552 553 static int should_enumerate_interface(unsigned short vendor_id, const struct libusb_interface_descriptor *intf_desc) 554 { 555 if (intf_desc->bInterfaceClass == LIBUSB_CLASS_HID) 556 return 1; 557 558 /* Also enumerate Xbox 360 controllers */ 559 if (is_xbox360(vendor_id, intf_desc)) 560 return 1; 561 562 /* Also enumerate Xbox One controllers */ 563 if (is_xboxone(vendor_id, intf_desc)) 564 return 1; 565 566 return 0; 567 } 568 569 struct hid_device_info HID_API_EXPORT *hid_enumerate(unsigned short vendor_id, unsigned short product_id) 570 { 571 libusb_device **devs; 572 libusb_device *dev; 573 libusb_device_handle *handle; 574 ssize_t num_devs; 575 int i = 0; 576 577 struct hid_device_info *root = NULL; /* return object */ 578 struct hid_device_info *cur_dev = NULL; 579 580 if(hid_init() < 0) 581 return NULL; 582 583 num_devs = libusb_get_device_list(usb_context, &devs); 584 if (num_devs < 0) 585 return NULL; 586 while ((dev = devs[i++]) != NULL) { 587 struct libusb_device_descriptor desc; 588 struct libusb_config_descriptor *conf_desc = NULL; 589 int j, k; 590 int interface_num = 0; 591 592 int res = libusb_get_device_descriptor(dev, &desc); 593 unsigned short dev_vid = desc.idVendor; 594 unsigned short dev_pid = desc.idProduct; 595 596 res = libusb_get_active_config_descriptor(dev, &conf_desc); 597 if (res < 0) 598 libusb_get_config_descriptor(dev, 0, &conf_desc); 599 if (conf_desc) { 600 for (j = 0; j < conf_desc->bNumInterfaces; j++) { 601 const struct libusb_interface *intf = &conf_desc->interface[j]; 602 for (k = 0; k < intf->num_altsetting; k++) { 603 const struct libusb_interface_descriptor *intf_desc; 604 intf_desc = &intf->altsetting[k]; 605 if (should_enumerate_interface(dev_vid, intf_desc)) { 606 interface_num = intf_desc->bInterfaceNumber; 607 608 /* Check the VID/PID against the arguments */ 609 if ((vendor_id == 0x0 || vendor_id == dev_vid) && 610 (product_id == 0x0 || product_id == dev_pid)) { 611 res = libusb_open(dev, &handle); 612 613 if (res >= 0) { 614 struct hid_device_info *tmp; 615 616 /* VID/PID match. Create the record. */ 617 tmp = (struct hid_device_info*) calloc(1, sizeof(struct hid_device_info)); 618 if (cur_dev) { 619 cur_dev->next = tmp; 620 } 621 else { 622 root = tmp; 623 } 624 cur_dev = tmp; 625 626 /* Fill out the record */ 627 cur_dev->next = NULL; 628 cur_dev->path = make_path(dev, interface_num); 629 630 /* Serial Number */ 631 if (desc.iSerialNumber > 0) 632 cur_dev->serial_number = 633 get_usb_string(handle, desc.iSerialNumber); 634 635 /* Manufacturer and Product strings */ 636 if (desc.iManufacturer > 0) 637 cur_dev->manufacturer_string = 638 get_usb_string(handle, desc.iManufacturer); 639 if (desc.iProduct > 0) 640 cur_dev->product_string = 641 get_usb_string(handle, desc.iProduct); 642 643 #ifdef INVASIVE_GET_USAGE 644 { 645 /* 646 This section is removed because it is too 647 invasive on the system. Getting a Usage Page 648 and Usage requires parsing the HID Report 649 descriptor. Getting a HID Report descriptor 650 involves claiming the interface. Claiming the 651 interface involves detaching the kernel driver. 652 Detaching the kernel driver is hard on the system 653 because it will unclaim interfaces (if another 654 app has them claimed) and the re-attachment of 655 the driver will sometimes change /dev entry names. 656 It is for these reasons that this section is 657 #if 0. For composite devices, use the interface 658 field in the hid_device_info struct to distinguish 659 between interfaces. */ 660 unsigned char data[256]; 661 #ifdef DETACH_KERNEL_DRIVER 662 int detached = 0; 663 /* Usage Page and Usage */ 664 res = libusb_kernel_driver_active(handle, interface_num); 665 if (res == 1) { 666 res = libusb_detach_kernel_driver(handle, interface_num); 667 if (res < 0) 668 LOG("Couldn't detach kernel driver, even though a kernel driver was attached."); 669 else 670 detached = 1; 671 } 672 #endif 673 res = libusb_claim_interface(handle, interface_num); 674 if (res >= 0) { 675 /* Get the HID Report Descriptor. */ 676 res = libusb_control_transfer(handle, LIBUSB_ENDPOINT_IN|LIBUSB_RECIPIENT_INTERFACE, LIBUSB_REQUEST_GET_DESCRIPTOR, (LIBUSB_DT_REPORT << 8)|interface_num, 0, data, sizeof(data), 5000); 677 if (res >= 0) { 678 unsigned short page=0, usage=0; 679 /* Parse the usage and usage page 680 out of the report descriptor. */ 681 get_usage(data, res, &page, &usage); 682 cur_dev->usage_page = page; 683 cur_dev->usage = usage; 684 } 685 else 686 LOG("libusb_control_transfer() for getting the HID report failed with %d\n", res); 687 688 /* Release the interface */ 689 res = libusb_release_interface(handle, interface_num); 690 if (res < 0) 691 LOG("Can't release the interface.\n"); 692 } 693 else 694 LOG("Can't claim interface %d\n", res); 695 #ifdef DETACH_KERNEL_DRIVER 696 /* Re-attach kernel driver if necessary. */ 697 if (detached) { 698 res = libusb_attach_kernel_driver(handle, interface_num); 699 if (res < 0) 700 LOG("Couldn't re-attach kernel driver.\n"); 701 } 702 #endif 703 } 704 #endif /* INVASIVE_GET_USAGE */ 705 706 libusb_close(handle); 707 708 /* VID/PID */ 709 cur_dev->vendor_id = dev_vid; 710 cur_dev->product_id = dev_pid; 711 712 /* Release Number */ 713 cur_dev->release_number = desc.bcdDevice; 714 715 /* Interface Number */ 716 cur_dev->interface_number = interface_num; 717 cur_dev->interface_class = intf_desc->bInterfaceClass; 718 cur_dev->interface_subclass = intf_desc->bInterfaceSubClass; 719 cur_dev->interface_protocol = intf_desc->bInterfaceProtocol; 720 721 } else 722 LOG("Can't open device 0x%.4x/0x%.4x during enumeration: %d\n", dev_vid, dev_pid, res); 723 } 724 } 725 } /* altsettings */ 726 } /* interfaces */ 727 libusb_free_config_descriptor(conf_desc); 728 } 729 } 730 731 libusb_free_device_list(devs, 1); 732 733 return root; 734 } 735 736 void HID_API_EXPORT hid_free_enumeration(struct hid_device_info *devs) 737 { 738 struct hid_device_info *d = devs; 739 while (d) { 740 struct hid_device_info *next = d->next; 741 free(d->path); 742 free(d->serial_number); 743 free(d->manufacturer_string); 744 free(d->product_string); 745 free(d); 746 d = next; 747 } 748 } 749 750 hid_device * hid_open(unsigned short vendor_id, unsigned short product_id, const wchar_t *serial_number) 751 { 752 struct hid_device_info *devs, *cur_dev; 753 const char *path_to_open = NULL; 754 hid_device *handle = NULL; 755 756 devs = hid_enumerate(vendor_id, product_id); 757 cur_dev = devs; 758 while (cur_dev) { 759 if (cur_dev->vendor_id == vendor_id && 760 cur_dev->product_id == product_id) { 761 if (serial_number) { 762 if (cur_dev->serial_number && 763 wcscmp(serial_number, cur_dev->serial_number) == 0) { 764 path_to_open = cur_dev->path; 765 break; 766 } 767 } 768 else { 769 path_to_open = cur_dev->path; 770 break; 771 } 772 } 773 cur_dev = cur_dev->next; 774 } 775 776 if (path_to_open) { 777 /* Open the device */ 778 handle = hid_open_path(path_to_open, 0); 779 } 780 781 hid_free_enumeration(devs); 782 783 return handle; 784 } 785 786 static void LIBUSB_CALL read_callback(struct libusb_transfer *transfer) 787 { 788 hid_device *dev = (hid_device *)transfer->user_data; 789 int res; 790 791 if (transfer->status == LIBUSB_TRANSFER_COMPLETED) { 792 793 struct input_report *rpt = (struct input_report*) malloc(sizeof(*rpt)); 794 rpt->data = (uint8_t*) malloc(transfer->actual_length); 795 memcpy(rpt->data, transfer->buffer, transfer->actual_length); 796 rpt->len = transfer->actual_length; 797 rpt->next = NULL; 798 799 SDL_LockMutex(dev->mutex); 800 801 /* Attach the new report object to the end of the list. */ 802 if (dev->input_reports == NULL) { 803 /* The list is empty. Put it at the root. */ 804 dev->input_reports = rpt; 805 SDL_CondSignal(dev->condition); 806 } 807 else { 808 /* Find the end of the list and attach. */ 809 struct input_report *cur = dev->input_reports; 810 int num_queued = 0; 811 while (cur->next != NULL) { 812 cur = cur->next; 813 num_queued++; 814 } 815 cur->next = rpt; 816 817 /* Pop one off if we've reached 30 in the queue. This 818 way we don't grow forever if the user never reads 819 anything from the device. */ 820 if (num_queued > 30) { 821 return_data(dev, NULL, 0); 822 } 823 } 824 SDL_UnlockMutex(dev->mutex); 825 } 826 else if (transfer->status == LIBUSB_TRANSFER_CANCELLED) { 827 dev->shutdown_thread = 1; 828 dev->cancelled = 1; 829 return; 830 } 831 else if (transfer->status == LIBUSB_TRANSFER_NO_DEVICE) { 832 dev->shutdown_thread = 1; 833 dev->cancelled = 1; 834 return; 835 } 836 else if (transfer->status == LIBUSB_TRANSFER_TIMED_OUT) { 837 //LOG("Timeout (normal)\n"); 838 } 839 else { 840 LOG("Unknown transfer code: %d\n", transfer->status); 841 } 842 843 /* Re-submit the transfer object. */ 844 res = libusb_submit_transfer(transfer); 845 if (res != 0) { 846 LOG("Unable to submit URB. libusb error code: %d\n", res); 847 dev->shutdown_thread = 1; 848 dev->cancelled = 1; 849 } 850 } 851 852 853 static int read_thread(void *param) 854 { 855 hid_device *dev = (hid_device *)param; 856 uint8_t *buf; 857 const size_t length = dev->input_ep_max_packet_size; 858 859 /* Set up the transfer object. */ 860 buf = (uint8_t*) malloc(length); 861 dev->transfer = libusb_alloc_transfer(0); 862 libusb_fill_interrupt_transfer(dev->transfer, 863 dev->device_handle, 864 dev->input_endpoint, 865 buf, 866 length, 867 read_callback, 868 dev, 869 5000/*timeout*/); 870 871 /* Make the first submission. Further submissions are made 872 from inside read_callback() */ 873 libusb_submit_transfer(dev->transfer); 874 875 /* Notify the main thread that the read thread is up and running. */ 876 SDL_WaitThreadBarrier(&dev->barrier); 877 878 /* Handle all the events. */ 879 while (!dev->shutdown_thread) { 880 int res; 881 res = libusb_handle_events(usb_context); 882 if (res < 0) { 883 /* There was an error. */ 884 LOG("read_thread(): libusb reports error # %d\n", res); 885 886 /* Break out of this loop only on fatal error.*/ 887 if (res != LIBUSB_ERROR_BUSY && 888 res != LIBUSB_ERROR_TIMEOUT && 889 res != LIBUSB_ERROR_OVERFLOW && 890 res != LIBUSB_ERROR_INTERRUPTED) { 891 break; 892 } 893 } 894 } 895 896 /* Cancel any transfer that may be pending. This call will fail 897 if no transfers are pending, but that's OK. */ 898 libusb_cancel_transfer(dev->transfer); 899 900 while (!dev->cancelled) 901 libusb_handle_events_completed(usb_context, &dev->cancelled); 902 903 /* Now that the read thread is stopping, Wake any threads which are 904 waiting on data (in hid_read_timeout()). Do this under a mutex to 905 make sure that a thread which is about to go to sleep waiting on 906 the condition actually will go to sleep before the condition is 907 signaled. */ 908 SDL_LockMutex(dev->mutex); 909 SDL_CondBroadcast(dev->condition); 910 SDL_UnlockMutex(dev->mutex); 911 912 /* The dev->transfer->buffer and dev->transfer objects are cleaned up 913 in hid_close(). They are not cleaned up here because this thread 914 could end either due to a disconnect or due to a user 915 call to hid_close(). In both cases the objects can be safely 916 cleaned up after the call to pthread_join() (in hid_close()), but 917 since hid_close() calls libusb_cancel_transfer(), on these objects, 918 they can not be cleaned up here. */ 919 920 return 0; 921 } 922 923 static void init_xboxone(libusb_device_handle *device_handle, struct libusb_config_descriptor *conf_desc) 924 { 925 static const int XB1_IFACE_SUBCLASS = 71; 926 static const int XB1_IFACE_PROTOCOL = 208; 927 int j, k, res; 928 929 for (j = 0; j < conf_desc->bNumInterfaces; j++) { 930 const struct libusb_interface *intf = &conf_desc->interface[j]; 931 for (k = 0; k < intf->num_altsetting; k++) { 932 const struct libusb_interface_descriptor *intf_desc; 933 intf_desc = &intf->altsetting[k]; 934 935 if (intf_desc->bInterfaceNumber != 0 && 936 intf_desc->bAlternateSetting == 0 && 937 intf_desc->bInterfaceClass == LIBUSB_CLASS_VENDOR_SPEC && 938 intf_desc->bInterfaceSubClass == XB1_IFACE_SUBCLASS && 939 intf_desc->bInterfaceProtocol == XB1_IFACE_PROTOCOL) { 940 res = libusb_claim_interface(device_handle, intf_desc->bInterfaceNumber); 941 if (res < 0) { 942 LOG("can't claim interface %d: %d\n", intf_desc->bInterfaceNumber, res); 943 continue; 944 } 945 946 res = libusb_set_interface_alt_setting(device_handle, intf_desc->bInterfaceNumber, intf_desc->bAlternateSetting); 947 if (res < 0) { 948 LOG("xbox init: can't set alt setting %d: %d\n", intf_desc->bInterfaceNumber, res); 949 } 950 951 libusb_release_interface(device_handle, intf_desc->bInterfaceNumber); 952 } 953 } 954 } 955 } 956 957 hid_device * HID_API_EXPORT hid_open_path(const char *path, int bExclusive) 958 { 959 hid_device *dev = NULL; 960 961 libusb_device **devs; 962 libusb_device *usb_dev; 963 int res; 964 int d = 0; 965 int good_open = 0; 966 967 if(hid_init() < 0) 968 return NULL; 969 970 dev = new_hid_device(); 971 972 libusb_get_device_list(usb_context, &devs); 973 while ((usb_dev = devs[d++]) != NULL) { 974 struct libusb_device_descriptor desc; 975 struct libusb_config_descriptor *conf_desc = NULL; 976 int i,j,k; 977 978 libusb_get_device_descriptor(usb_dev, &desc); 979 980 res = libusb_get_active_config_descriptor(usb_dev, &conf_desc); 981 if (res < 0) 982 libusb_get_config_descriptor(usb_dev, 0, &conf_desc); 983 if (!conf_desc) 984 continue; 985 for (j = 0; j < conf_desc->bNumInterfaces && !good_open; j++) { 986 const struct libusb_interface *intf = &conf_desc->interface[j]; 987 for (k = 0; k < intf->num_altsetting && !good_open; k++) { 988 const struct libusb_interface_descriptor *intf_desc; 989 intf_desc = &intf->altsetting[k]; 990 if (should_enumerate_interface(desc.idVendor, intf_desc)) { 991 char *dev_path = make_path(usb_dev, intf_desc->bInterfaceNumber); 992 if (!strcmp(dev_path, path)) { 993 int detached_driver = 0; 994 995 /* Matched Paths. Open this device */ 996 997 /* OPEN HERE */ 998 res = libusb_open(usb_dev, &dev->device_handle); 999 if (res < 0) { 1000 LOG("can't open device\n"); 1001 free(dev_path); 1002 break; 1003 } 1004 good_open = 1; 1005 1006 #ifdef DETACH_KERNEL_DRIVER 1007 /* Detach the kernel driver, but only if the 1008 device is managed by the kernel */ 1009 if (libusb_kernel_driver_active(dev->device_handle, intf_desc->bInterfaceNumber) == 1) { 1010 res = libusb_detach_kernel_driver(dev->device_handle, intf_desc->bInterfaceNumber); 1011 if (res < 0) { 1012 libusb_close(dev->device_handle); 1013 LOG("Unable to detach Kernel Driver\n"); 1014 free(dev_path); 1015 good_open = 0; 1016 break; 1017 } 1018 detached_driver = 1; 1019 } 1020 #endif 1021 1022 res = libusb_claim_interface(dev->device_handle, intf_desc->bInterfaceNumber); 1023 if (res < 0) { 1024 LOG("can't claim interface %d: %d\n", intf_desc->bInterfaceNumber, res); 1025 free(dev_path); 1026 libusb_close(dev->device_handle); 1027 good_open = 0; 1028 break; 1029 } 1030 1031 /* Initialize XBox One controllers */ 1032 if (is_xboxone(desc.idVendor, intf_desc)) { 1033 init_xboxone(dev->device_handle, conf_desc); 1034 } 1035 1036 /* Store off the string descriptor indexes */ 1037 dev->manufacturer_index = desc.iManufacturer; 1038 dev->product_index = desc.iProduct; 1039 dev->serial_index = desc.iSerialNumber; 1040 1041 /* Store off the interface number */ 1042 dev->interface = intf_desc->bInterfaceNumber; 1043 dev->detached_driver = detached_driver; 1044 1045 /* Find the INPUT and OUTPUT endpoints. An 1046 OUTPUT endpoint is not required. */ 1047 for (i = 0; i < intf_desc->bNumEndpoints; i++) { 1048 const struct libusb_endpoint_descriptor *ep 1049 = &intf_desc->endpoint[i]; 1050 1051 /* Determine the type and direction of this 1052 endpoint. */ 1053 int is_interrupt = 1054 (ep->bmAttributes & LIBUSB_TRANSFER_TYPE_MASK) 1055 == LIBUSB_TRANSFER_TYPE_INTERRUPT; 1056 int is_output = 1057 (ep->bEndpointAddress & LIBUSB_ENDPOINT_DIR_MASK) 1058 == LIBUSB_ENDPOINT_OUT; 1059 int is_input = 1060 (ep->bEndpointAddress & LIBUSB_ENDPOINT_DIR_MASK) 1061 == LIBUSB_ENDPOINT_IN; 1062 1063 /* Decide whether to use it for input or output. */ 1064 if (dev->input_endpoint == 0 && 1065 is_interrupt && is_input) { 1066 /* Use this endpoint for INPUT */ 1067 dev->input_endpoint = ep->bEndpointAddress; 1068 dev->input_ep_max_packet_size = ep->wMaxPacketSize; 1069 } 1070 if (dev->output_endpoint == 0 && 1071 is_interrupt && is_output) { 1072 /* Use this endpoint for OUTPUT */ 1073 dev->output_endpoint = ep->bEndpointAddress; 1074 } 1075 } 1076 1077 dev->thread = SDL_CreateThread(read_thread, NULL, dev); 1078 1079 /* Wait here for the read thread to be initialized. */ 1080 SDL_WaitThreadBarrier(&dev->barrier); 1081 1082 } 1083 free(dev_path); 1084 } 1085 } 1086 } 1087 libusb_free_config_descriptor(conf_desc); 1088 1089 } 1090 1091 libusb_free_device_list(devs, 1); 1092 1093 /* If we have a good handle, return it. */ 1094 if (good_open) { 1095 return dev; 1096 } 1097 else { 1098 /* Unable to open any devices. */ 1099 free_hid_device(dev); 1100 return NULL; 1101 } 1102 } 1103 1104 1105 int HID_API_EXPORT hid_write(hid_device *dev, const unsigned char *data, size_t length) 1106 { 1107 int res; 1108 1109 if (dev->output_endpoint <= 0) { 1110 int report_number = data[0]; 1111 int skipped_report_id = 0; 1112 1113 if (report_number == 0x0) { 1114 data++; 1115 length--; 1116 skipped_report_id = 1; 1117 } 1118 1119 /* No interrupt out endpoint. Use the Control Endpoint */ 1120 res = libusb_control_transfer(dev->device_handle, 1121 LIBUSB_REQUEST_TYPE_CLASS|LIBUSB_RECIPIENT_INTERFACE|LIBUSB_ENDPOINT_OUT, 1122 0x09/*HID Set_Report*/, 1123 (2/*HID output*/ << 8) | report_number, 1124 dev->interface, 1125 (unsigned char *)data, length, 1126 1000/*timeout millis*/); 1127 1128 if (res < 0) 1129 return -1; 1130 1131 if (skipped_report_id) 1132 length++; 1133 1134 return length; 1135 } 1136 else { 1137 /* Use the interrupt out endpoint */ 1138 int actual_length; 1139 res = libusb_interrupt_transfer(dev->device_handle, 1140 dev->output_endpoint, 1141 (unsigned char*)data, 1142 length, 1143 &actual_length, 1000); 1144 1145 if (res < 0) 1146 return -1; 1147 1148 return actual_length; 1149 } 1150 } 1151 1152 /* Helper function, to simplify hid_read(). 1153 This should be called with dev->mutex locked. */ 1154 static int return_data(hid_device *dev, unsigned char *data, size_t length) 1155 { 1156 /* Copy the data out of the linked list item (rpt) into the 1157 return buffer (data), and delete the liked list item. */ 1158 struct input_report *rpt = dev->input_reports; 1159 size_t len = (length < rpt->len)? length: rpt->len; 1160 if (data && len > 0) 1161 memcpy(data, rpt->data, len); 1162 dev->input_reports = rpt->next; 1163 free(rpt->data); 1164 free(rpt); 1165 return len; 1166 } 1167 1168 #if 0 /* TODO: pthread_cleanup SDL? */ 1169 static void cleanup_mutex(void *param) 1170 { 1171 hid_device *dev = (hid_device *)param; 1172 SDL_UnlockMutex(dev->mutex); 1173 } 1174 #endif 1175 1176 1177 int HID_API_EXPORT hid_read_timeout(hid_device *dev, unsigned char *data, size_t length, int milliseconds) 1178 { 1179 int bytes_read = -1; 1180 1181 #if 0 1182 int transferred; 1183 int res = libusb_interrupt_transfer(dev->device_handle, dev->input_endpoint, data, length, &transferred, 5000); 1184 LOG("transferred: %d\n", transferred); 1185 return transferred; 1186 #endif 1187 1188 SDL_LockMutex(dev->mutex); 1189 /* TODO: pthread_cleanup SDL? */ 1190 1191 /* There's an input report queued up. Return it. */ 1192 if (dev->input_reports) { 1193 /* Return the first one */ 1194 bytes_read = return_data(dev, data, length); 1195 goto ret; 1196 } 1197 1198 if (dev->shutdown_thread) { 1199 /* This means the device has been disconnected. 1200 An error code of -1 should be returned. */ 1201 bytes_read = -1; 1202 goto ret; 1203 } 1204 1205 if (milliseconds == -1) { 1206 /* Blocking */ 1207 while (!dev->input_reports && !dev->shutdown_thread) { 1208 SDL_CondWait(dev->condition, dev->mutex); 1209 } 1210 if (dev->input_reports) { 1211 bytes_read = return_data(dev, data, length); 1212 } 1213 } 1214 else if (milliseconds > 0) { 1215 /* Non-blocking, but called with timeout. */ 1216 int res; 1217 1218 while (!dev->input_reports && !dev->shutdown_thread) { 1219 res = SDL_CondWaitTimeout(dev->condition, dev->mutex, milliseconds); 1220 if (res == 0) { 1221 if (dev->input_reports) { 1222 bytes_read = return_data(dev, data, length); 1223 break; 1224 } 1225 1226 /* If we're here, there was a spurious wake up 1227 or the read thread was shutdown. Run the 1228 loop again (ie: don't break). */ 1229 } 1230 else if (res == SDL_MUTEX_TIMEDOUT) { 1231 /* Timed out. */ 1232 bytes_read = 0; 1233 break; 1234 } 1235 else { 1236 /* Error. */ 1237 bytes_read = -1; 1238 break; 1239 } 1240 } 1241 } 1242 else { 1243 /* Purely non-blocking */ 1244 bytes_read = 0; 1245 } 1246 1247 ret: 1248 SDL_UnlockMutex(dev->mutex); 1249 /* TODO: pthread_cleanup SDL? */ 1250 1251 return bytes_read; 1252 } 1253 1254 int HID_API_EXPORT hid_read(hid_device *dev, unsigned char *data, size_t length) 1255 { 1256 return hid_read_timeout(dev, data, length, dev->blocking ? -1 : 0); 1257 } 1258 1259 int HID_API_EXPORT hid_set_nonblocking(hid_device *dev, int nonblock) 1260 { 1261 dev->blocking = !nonblock; 1262 1263 return 0; 1264 } 1265 1266 1267 int HID_API_EXPORT hid_send_feature_report(hid_device *dev, const unsigned char *data, size_t length) 1268 { 1269 int res = -1; 1270 int skipped_report_id = 0; 1271 int report_number = data[0]; 1272 1273 if (report_number == 0x0) { 1274 data++; 1275 length--; 1276 skipped_report_id = 1; 1277 } 1278 1279 res = libusb_control_transfer(dev->device_handle, 1280 LIBUSB_REQUEST_TYPE_CLASS|LIBUSB_RECIPIENT_INTERFACE|LIBUSB_ENDPOINT_OUT, 1281 0x09/*HID set_report*/, 1282 (3/*HID feature*/ << 8) | report_number, 1283 dev->interface, 1284 (unsigned char *)data, length, 1285 1000/*timeout millis*/); 1286 1287 if (res < 0) 1288 return -1; 1289 1290 /* Account for the report ID */ 1291 if (skipped_report_id) 1292 length++; 1293 1294 return length; 1295 } 1296 1297 int HID_API_EXPORT hid_get_feature_report(hid_device *dev, unsigned char *data, size_t length) 1298 { 1299 int res = -1; 1300 int skipped_report_id = 0; 1301 int report_number = data[0]; 1302 1303 if (report_number == 0x0) { 1304 /* Offset the return buffer by 1, so that the report ID 1305 will remain in byte 0. */ 1306 data++; 1307 length--; 1308 skipped_report_id = 1; 1309 } 1310 res = libusb_control_transfer(dev->device_handle, 1311 LIBUSB_REQUEST_TYPE_CLASS|LIBUSB_RECIPIENT_INTERFACE|LIBUSB_ENDPOINT_IN, 1312 0x01/*HID get_report*/, 1313 (3/*HID feature*/ << 8) | report_number, 1314 dev->interface, 1315 (unsigned char *)data, length, 1316 1000/*timeout millis*/); 1317 1318 if (res < 0) 1319 return -1; 1320 1321 if (skipped_report_id) 1322 res++; 1323 1324 return res; 1325 } 1326 1327 1328 void HID_API_EXPORT hid_close(hid_device *dev) 1329 { 1330 int status; 1331 1332 if (!dev) 1333 return; 1334 1335 /* Cause read_thread() to stop. */ 1336 dev->shutdown_thread = 1; 1337 libusb_cancel_transfer(dev->transfer); 1338 1339 /* Wait for read_thread() to end. */ 1340 SDL_WaitThread(dev->thread, &status); 1341 1342 /* Clean up the Transfer objects allocated in read_thread(). */ 1343 free(dev->transfer->buffer); 1344 libusb_free_transfer(dev->transfer); 1345 1346 /* release the interface */ 1347 libusb_release_interface(dev->device_handle, dev->interface); 1348 1349 #ifdef DETACH_KERNEL_DRIVER 1350 /* Re-attach kernel driver if necessary. */ 1351 if (dev->detached_driver) { 1352 int res = libusb_attach_kernel_driver(dev->device_handle, dev->interface); 1353 if (res < 0) 1354 LOG("Couldn't re-attach kernel driver.\n"); 1355 } 1356 #endif 1357 1358 /* Close the handle */ 1359 libusb_close(dev->device_handle); 1360 1361 /* Clear out the queue of received reports. */ 1362 SDL_LockMutex(dev->mutex); 1363 while (dev->input_reports) { 1364 return_data(dev, NULL, 0); 1365 } 1366 SDL_UnlockMutex(dev->mutex); 1367 1368 free_hid_device(dev); 1369 } 1370 1371 1372 int HID_API_EXPORT_CALL hid_get_manufacturer_string(hid_device *dev, wchar_t *string, size_t maxlen) 1373 { 1374 return hid_get_indexed_string(dev, dev->manufacturer_index, string, maxlen); 1375 } 1376 1377 int HID_API_EXPORT_CALL hid_get_product_string(hid_device *dev, wchar_t *string, size_t maxlen) 1378 { 1379 return hid_get_indexed_string(dev, dev->product_index, string, maxlen); 1380 } 1381 1382 int HID_API_EXPORT_CALL hid_get_serial_number_string(hid_device *dev, wchar_t *string, size_t maxlen) 1383 { 1384 return hid_get_indexed_string(dev, dev->serial_index, string, maxlen); 1385 } 1386 1387 int HID_API_EXPORT_CALL hid_get_indexed_string(hid_device *dev, int string_index, wchar_t *string, size_t maxlen) 1388 { 1389 wchar_t *str; 1390 1391 str = get_usb_string(dev->device_handle, string_index); 1392 if (str) { 1393 wcsncpy(string, str, maxlen); 1394 string[maxlen-1] = L'\0'; 1395 free(str); 1396 return 0; 1397 } 1398 else 1399 return -1; 1400 } 1401 1402 1403 HID_API_EXPORT const wchar_t * HID_API_CALL hid_error(hid_device *dev) 1404 { 1405 return NULL; 1406 } 1407 1408 1409 struct lang_map_entry { 1410 const char *name; 1411 const char *string_code; 1412 uint16_t usb_code; 1413 }; 1414 1415 #define LANG(name,code,usb_code) { name, code, usb_code } 1416 static struct lang_map_entry lang_map[] = { 1417 LANG("Afrikaans", "af", 0x0436), 1418 LANG("Albanian", "sq", 0x041C), 1419 LANG("Arabic - United Arab Emirates", "ar_ae", 0x3801), 1420 LANG("Arabic - Bahrain", "ar_bh", 0x3C01), 1421 LANG("Arabic - Algeria", "ar_dz", 0x1401), 1422 LANG("Arabic - Egypt", "ar_eg", 0x0C01), 1423 LANG("Arabic - Iraq", "ar_iq", 0x0801), 1424 LANG("Arabic - Jordan", "ar_jo", 0x2C01), 1425 LANG("Arabic - Kuwait", "ar_kw", 0x3401), 1426 LANG("Arabic - Lebanon", "ar_lb", 0x3001), 1427 LANG("Arabic - Libya", "ar_ly", 0x1001), 1428 LANG("Arabic - Morocco", "ar_ma", 0x1801), 1429 LANG("Arabic - Oman", "ar_om", 0x2001), 1430 LANG("Arabic - Qatar", "ar_qa", 0x4001), 1431 LANG("Arabic - Saudi Arabia", "ar_sa", 0x0401), 1432 LANG("Arabic - Syria", "ar_sy", 0x2801), 1433 LANG("Arabic - Tunisia", "ar_tn", 0x1C01), 1434 LANG("Arabic - Yemen", "ar_ye", 0x2401), 1435 LANG("Armenian", "hy", 0x042B), 1436 LANG("Azeri - Latin", "az_az", 0x042C), 1437 LANG("Azeri - Cyrillic", "az_az", 0x082C), 1438 LANG("Basque", "eu", 0x042D), 1439 LANG("Belarusian", "be", 0x0423), 1440 LANG("Bulgarian", "bg", 0x0402), 1441 LANG("Catalan", "ca", 0x0403), 1442 LANG("Chinese - China", "zh_cn", 0x0804), 1443 LANG("Chinese - Hong Kong SAR", "zh_hk", 0x0C04), 1444 LANG("Chinese - Macau SAR", "zh_mo", 0x1404), 1445 LANG("Chinese - Singapore", "zh_sg", 0x1004), 1446 LANG("Chinese - Taiwan", "zh_tw", 0x0404), 1447 LANG("Croatian", "hr", 0x041A), 1448 LANG("Czech", "cs", 0x0405), 1449 LANG("Danish", "da", 0x0406), 1450 LANG("Dutch - Netherlands", "nl_nl", 0x0413), 1451 LANG("Dutch - Belgium", "nl_be", 0x0813), 1452 LANG("English - Australia", "en_au", 0x0C09), 1453 LANG("English - Belize", "en_bz", 0x2809), 1454 LANG("English - Canada", "en_ca", 0x1009), 1455 LANG("English - Caribbean", "en_cb", 0x2409), 1456 LANG("English - Ireland", "en_ie", 0x1809), 1457 LANG("English - Jamaica", "en_jm", 0x2009), 1458 LANG("English - New Zealand", "en_nz", 0x1409), 1459 LANG("English - Philippines", "en_ph", 0x3409), 1460 LANG("English - Southern Africa", "en_za", 0x1C09), 1461 LANG("English - Trinidad", "en_tt", 0x2C09), 1462 LANG("English - Great Britain", "en_gb", 0x0809), 1463 LANG("English - United States", "en_us", 0x0409), 1464 LANG("Estonian", "et", 0x0425), 1465 LANG("Farsi", "fa", 0x0429), 1466 LANG("Finnish", "fi", 0x040B), 1467 LANG("Faroese", "fo", 0x0438), 1468 LANG("French - France", "fr_fr", 0x040C), 1469 LANG("French - Belgium", "fr_be", 0x080C), 1470 LANG("French - Canada", "fr_ca", 0x0C0C), 1471 LANG("French - Luxembourg", "fr_lu", 0x140C), 1472 LANG("French - Switzerland", "fr_ch", 0x100C), 1473 LANG("Gaelic - Ireland", "gd_ie", 0x083C), 1474 LANG("Gaelic - Scotland", "gd", 0x043C), 1475 LANG("German - Germany", "de_de", 0x0407), 1476 LANG("German - Austria", "de_at", 0x0C07), 1477 LANG("German - Liechtenstein", "de_li", 0x1407), 1478 LANG("German - Luxembourg", "de_lu", 0x1007), 1479 LANG("German - Switzerland", "de_ch", 0x0807), 1480 LANG("Greek", "el", 0x0408), 1481 LANG("Hebrew", "he", 0x040D), 1482 LANG("Hindi", "hi", 0x0439), 1483 LANG("Hungarian", "hu", 0x040E), 1484 LANG("Icelandic", "is", 0x040F), 1485 LANG("Indonesian", "id", 0x0421), 1486 LANG("Italian - Italy", "it_it", 0x0410), 1487 LANG("Italian - Switzerland", "it_ch", 0x0810), 1488 LANG("Japanese", "ja", 0x0411), 1489 LANG("Korean", "ko", 0x0412), 1490 LANG("Latvian", "lv", 0x0426), 1491 LANG("Lithuanian", "lt", 0x0427), 1492 LANG("F.Y.R.O. Macedonia", "mk", 0x042F), 1493 LANG("Malay - Malaysia", "ms_my", 0x043E), 1494 LANG("Malay ??? Brunei", "ms_bn", 0x083E), 1495 LANG("Maltese", "mt", 0x043A), 1496 LANG("Marathi", "mr", 0x044E), 1497 LANG("Norwegian - Bokml", "no_no", 0x0414), 1498 LANG("Norwegian - Nynorsk", "no_no", 0x0814), 1499 LANG("Polish", "pl", 0x0415), 1500 LANG("Portuguese - Portugal", "pt_pt", 0x0816), 1501 LANG("Portuguese - Brazil", "pt_br", 0x0416), 1502 LANG("Raeto-Romance", "rm", 0x0417), 1503 LANG("Romanian - Romania", "ro", 0x0418), 1504 LANG("Romanian - Republic of Moldova", "ro_mo", 0x0818), 1505 LANG("Russian", "ru", 0x0419), 1506 LANG("Russian - Republic of Moldova", "ru_mo", 0x0819), 1507 LANG("Sanskrit", "sa", 0x044F), 1508 LANG("Serbian - Cyrillic", "sr_sp", 0x0C1A), 1509 LANG("Serbian - Latin", "sr_sp", 0x081A), 1510 LANG("Setsuana", "tn", 0x0432), 1511 LANG("Slovenian", "sl", 0x0424), 1512 LANG("Slovak", "sk", 0x041B), 1513 LANG("Sorbian", "sb", 0x042E), 1514 LANG("Spanish - Spain (Traditional)", "es_es", 0x040A), 1515 LANG("Spanish - Argentina", "es_ar", 0x2C0A), 1516 LANG("Spanish - Bolivia", "es_bo", 0x400A), 1517 LANG("Spanish - Chile", "es_cl", 0x340A), 1518 LANG("Spanish - Colombia", "es_co", 0x240A), 1519 LANG("Spanish - Costa Rica", "es_cr", 0x140A), 1520 LANG("Spanish - Dominican Republic", "es_do", 0x1C0A), 1521 LANG("Spanish - Ecuador", "es_ec", 0x300A), 1522 LANG("Spanish - Guatemala", "es_gt", 0x100A), 1523 LANG("Spanish - Honduras", "es_hn", 0x480A), 1524 LANG("Spanish - Mexico", "es_mx", 0x080A), 1525 LANG("Spanish - Nicaragua", "es_ni", 0x4C0A), 1526 LANG("Spanish - Panama", "es_pa", 0x180A), 1527 LANG("Spanish - Peru", "es_pe", 0x280A), 1528 LANG("Spanish - Puerto Rico", "es_pr", 0x500A), 1529 LANG("Spanish - Paraguay", "es_py", 0x3C0A), 1530 LANG("Spanish - El Salvador", "es_sv", 0x440A), 1531 LANG("Spanish - Uruguay", "es_uy", 0x380A), 1532 LANG("Spanish - Venezuela", "es_ve", 0x200A), 1533 LANG("Southern Sotho", "st", 0x0430), 1534 LANG("Swahili", "sw", 0x0441), 1535 LANG("Swedish - Sweden", "sv_se", 0x041D), 1536 LANG("Swedish - Finland", "sv_fi", 0x081D), 1537 LANG("Tamil", "ta", 0x0449), 1538 LANG("Tatar", "tt", 0X0444), 1539 LANG("Thai", "th", 0x041E), 1540 LANG("Turkish", "tr", 0x041F), 1541 LANG("Tsonga", "ts", 0x0431), 1542 LANG("Ukrainian", "uk", 0x0422), 1543 LANG("Urdu", "ur", 0x0420), 1544 LANG("Uzbek - Cyrillic", "uz_uz", 0x0843), 1545 LANG("Uzbek ??? Latin", "uz_uz", 0x0443), 1546 LANG("Vietnamese", "vi", 0x042A), 1547 LANG("Xhosa", "xh", 0x0434), 1548 LANG("Yiddish", "yi", 0x043D), 1549 LANG("Zulu", "zu", 0x0435), 1550 LANG(NULL, NULL, 0x0), 1551 }; 1552 1553 uint16_t get_usb_code_for_current_locale(void) 1554 { 1555 char *locale; 1556 char search_string[64]; 1557 char *ptr; 1558 struct lang_map_entry *lang; 1559 1560 /* Get the current locale. */ 1561 locale = setlocale(0, NULL); 1562 if (!locale) 1563 return 0x0; 1564 1565 /* Make a copy of the current locale string. */ 1566 strncpy(search_string, locale, sizeof(search_string)); 1567 search_string[sizeof(search_string)-1] = '\0'; 1568 1569 /* Chop off the encoding part, and make it lower case. */ 1570 ptr = search_string; 1571 while (*ptr) { 1572 *ptr = tolower(*ptr); 1573 if (*ptr == '.') { 1574 *ptr = '\0'; 1575 break; 1576 } 1577 ptr++; 1578 } 1579 1580 /* Find the entry which matches the string code of our locale. */ 1581 lang = lang_map; 1582 while (lang->string_code) { 1583 if (!strcmp(lang->string_code, search_string)) { 1584 return lang->usb_code; 1585 } 1586 lang++; 1587 } 1588 1589 /* There was no match. Find with just the language only. */ 1590 /* Chop off the variant. Chop it off at the '_'. */ 1591 ptr = search_string; 1592 while (*ptr) { 1593 *ptr = tolower(*ptr); 1594 if (*ptr == '_') { 1595 *ptr = '\0'; 1596 break; 1597 } 1598 ptr++; 1599 } 1600 1601 #if 0 /* TODO: Do we need this? */ 1602 /* Find the entry which matches the string code of our language. */ 1603 lang = lang_map; 1604 while (lang->string_code) { 1605 if (!strcmp(lang->string_code, search_string)) { 1606 return lang->usb_code; 1607 } 1608 lang++; 1609 } 1610 #endif 1611 1612 /* Found nothing. */ 1613 return 0x0; 1614 } 1615 1616 #if defined(__cplusplus) && !defined(NAMESPACE) 1617 } 1618 #endif 1619 1620 #ifdef NAMESPACE 1621 } 1622 #endif 1623 1624 #endif /* SDL_JOYSTICK_HIDAPI */