summaryrefslogtreecommitdiff
path: root/contrib/SDL-3.2.8/src/hidapi/libusb/hid.c
diff options
context:
space:
mode:
author3gg <3gg@shellblade.net>2025-12-27 12:03:39 -0800
committer3gg <3gg@shellblade.net>2025-12-27 12:03:39 -0800
commit5a079a2d114f96d4847d1ee305d5b7c16eeec50e (patch)
tree8926ab44f168acf787d8e19608857b3af0f82758 /contrib/SDL-3.2.8/src/hidapi/libusb/hid.c
Initial commit
Diffstat (limited to 'contrib/SDL-3.2.8/src/hidapi/libusb/hid.c')
-rw-r--r--contrib/SDL-3.2.8/src/hidapi/libusb/hid.c2144
1 files changed, 2144 insertions, 0 deletions
diff --git a/contrib/SDL-3.2.8/src/hidapi/libusb/hid.c b/contrib/SDL-3.2.8/src/hidapi/libusb/hid.c
new file mode 100644
index 0000000..f4b1ccb
--- /dev/null
+++ b/contrib/SDL-3.2.8/src/hidapi/libusb/hid.c
@@ -0,0 +1,2144 @@
1/*******************************************************
2 HIDAPI - Multi-Platform library for
3 communication with HID devices.
4
5 Alan Ott
6 Signal 11 Software
7
8 libusb/hidapi Team
9
10 Copyright 2022, All Rights Reserved.
11
12 At the discretion of the user of this library,
13 this software may be licensed under the terms of the
14 GNU General Public License v3, a BSD-Style license, or the
15 original HIDAPI license as outlined in the LICENSE.txt,
16 LICENSE-gpl3.txt, LICENSE-bsd.txt, and LICENSE-orig.txt
17 files located at the root of the source distribution.
18 These files may also be found in the public source
19 code repository located at:
20 https://github.com/libusb/hidapi .
21********************************************************/
22
23#ifndef HIDAPI_USING_SDL_RUNTIME
24#define _GNU_SOURCE /* needed for wcsdup() before glibc 2.10 */
25
26/* C */
27#include <stdio.h>
28#include <string.h>
29#include <stdlib.h>
30#include <ctype.h>
31#include <locale.h>
32#include <errno.h>
33
34/* Unix */
35#include <unistd.h>
36#include <sys/types.h>
37#include <sys/stat.h>
38#include <sys/ioctl.h>
39#include <sys/utsname.h>
40#include <fcntl.h>
41#include <wchar.h>
42
43/* GNU / LibUSB */
44#include <libusb.h>
45#if !defined(__ANDROID__) && !defined(NO_ICONV)
46#include <iconv.h>
47#ifndef ICONV_CONST
48#define ICONV_CONST
49#endif
50#endif
51#endif /* HIDAPI_USING_SDL_RUNTIME */
52
53#include "hidapi_libusb.h"
54
55#ifndef HIDAPI_THREAD_MODEL_INCLUDE
56#define HIDAPI_THREAD_MODEL_INCLUDE "hidapi_thread_pthread.h"
57#endif
58#include HIDAPI_THREAD_MODEL_INCLUDE
59
60#ifdef __cplusplus
61extern "C" {
62#endif
63
64#ifdef DEBUG_PRINTF
65#define LOG(...) fprintf(stderr, __VA_ARGS__)
66#else
67#define LOG(...) do {} while (0)
68#endif
69
70#ifndef __FreeBSD__
71#define DETACH_KERNEL_DRIVER
72#endif
73
74/* Uncomment to enable the retrieval of Usage and Usage Page in
75hid_enumerate(). Warning, on platforms different from FreeBSD
76this is very invasive as it requires the detach
77and re-attach of the kernel driver. See comments inside hid_enumerate().
78libusb HIDAPI programs are encouraged to use the interface number
79instead to differentiate between interfaces on a composite HID device. */
80/*#define INVASIVE_GET_USAGE*/
81
82/* Linked List of input reports received from the device. */
83struct input_report {
84 uint8_t *data;
85 size_t len;
86 struct input_report *next;
87};
88
89
90struct hid_device_ {
91 /* Handle to the actual device. */
92 libusb_device_handle *device_handle;
93
94 /* USB Configuration Number of the device */
95 int config_number;
96 /* The interface number of the HID */
97 int interface;
98 int interface_class;
99 int interface_subclass;
100 int interface_protocol;
101
102 uint16_t report_descriptor_size;
103
104 /* Endpoint information */
105 int input_endpoint;
106 int output_endpoint;
107 int input_ep_max_packet_size;
108
109 /* Indexes of Strings */
110 int manufacturer_index;
111 int product_index;
112 int serial_index;
113 struct hid_device_info* device_info;
114
115 /* Whether blocking reads are used */
116 int blocking; /* boolean */
117
118 /* Read thread objects */
119 hidapi_thread_state thread_state;
120 int shutdown_thread;
121 int transfer_loop_finished;
122 struct libusb_transfer *transfer;
123
124 /* Quirks */
125 int skip_output_report_id;
126 int no_skip_output_report_id;
127 int no_output_reports_on_intr_ep;
128
129 /* List of received input reports. */
130 struct input_report *input_reports;
131
132 /* Was kernel driver detached by libusb */
133#ifdef DETACH_KERNEL_DRIVER
134 int is_driver_detached;
135#endif
136};
137
138static struct hid_api_version api_version = {
139 .major = HID_API_VERSION_MAJOR,
140 .minor = HID_API_VERSION_MINOR,
141 .patch = HID_API_VERSION_PATCH
142};
143
144static libusb_context *usb_context = NULL;
145
146uint16_t get_usb_code_for_current_locale(void);
147static int return_data(hid_device *dev, unsigned char *data, size_t length);
148
149static hid_device *new_hid_device(void)
150{
151 hid_device *dev = (hid_device*) calloc(1, sizeof(hid_device));
152 dev->blocking = 1;
153
154 hidapi_thread_state_init(&dev->thread_state);
155
156 return dev;
157}
158
159static void free_hid_device(hid_device *dev)
160{
161 /* Clean up the thread objects */
162 hidapi_thread_state_destroy(&dev->thread_state);
163
164 hid_free_enumeration(dev->device_info);
165
166 /* Free the device itself */
167 free(dev);
168}
169
170#if 0
171/*TODO: Implement this function on hidapi/libusb.. */
172static void register_error(hid_device *dev, const char *op)
173{
174
175}
176#endif
177
178/* Get bytes from a HID Report Descriptor.
179 Only call with a num_bytes of 0, 1, 2, or 4. */
180static uint32_t get_bytes(uint8_t *rpt, size_t len, size_t num_bytes, size_t cur)
181{
182 /* Return if there aren't enough bytes. */
183 if (cur + num_bytes >= len)
184 return 0;
185
186 if (num_bytes == 0)
187 return 0;
188 else if (num_bytes == 1) {
189 return rpt[cur+1];
190 }
191 else if (num_bytes == 2) {
192 return (rpt[cur+2] * 256 + rpt[cur+1]);
193 }
194 else if (num_bytes == 4) {
195 return (rpt[cur+4] * 0x01000000 +
196 rpt[cur+3] * 0x00010000 +
197 rpt[cur+2] * 0x00000100 +
198 rpt[cur+1] * 0x00000001);
199 }
200 else
201 return 0;
202}
203
204/* Retrieves the device's Usage Page and Usage from the report
205 descriptor. The algorithm is simple, as it just returns the first
206 Usage and Usage Page that it finds in the descriptor.
207 The return value is 0 on success and -1 on failure. */
208static int get_usage(uint8_t *report_descriptor, size_t size,
209 unsigned short *usage_page, unsigned short *usage)
210{
211 unsigned int i = 0;
212 int size_code;
213 int data_len, key_size;
214 int usage_found = 0, usage_page_found = 0;
215
216 while (i < size) {
217 int key = report_descriptor[i];
218 int key_cmd = key & 0xfc;
219
220 //printf("key: %02hhx\n", key);
221
222 if ((key & 0xf0) == 0xf0) {
223 /* This is a Long Item. The next byte contains the
224 length of the data section (value) for this key.
225 See the HID specification, version 1.11, section
226 6.2.2.3, titled "Long Items." */
227 if (i+1 < size)
228 data_len = report_descriptor[i+1];
229 else
230 data_len = 0; /* malformed report */
231 key_size = 3;
232 }
233 else {
234 /* This is a Short Item. The bottom two bits of the
235 key contain the size code for the data section
236 (value) for this key. Refer to the HID
237 specification, version 1.11, section 6.2.2.2,
238 titled "Short Items." */
239 size_code = key & 0x3;
240 switch (size_code) {
241 case 0:
242 case 1:
243 case 2:
244 data_len = size_code;
245 break;
246 case 3:
247 data_len = 4;
248 break;
249 default:
250 /* Can't ever happen since size_code is & 0x3 */
251 data_len = 0;
252 break;
253 }
254 key_size = 1;
255 }
256
257 if (key_cmd == 0x4) {
258 *usage_page = get_bytes(report_descriptor, size, data_len, i);
259 usage_page_found = 1;
260 //printf("Usage Page: %x\n", (uint32_t)*usage_page);
261 }
262 if (key_cmd == 0x8) {
263 if (data_len == 4) { /* Usages 5.5 / Usage Page 6.2.2.7 */
264 *usage_page = get_bytes(report_descriptor, size, 2, i + 2);
265 usage_page_found = 1;
266 *usage = get_bytes(report_descriptor, size, 2, i);
267 usage_found = 1;
268 }
269 else {
270 *usage = get_bytes(report_descriptor, size, data_len, i);
271 usage_found = 1;
272 }
273 //printf("Usage: %x\n", (uint32_t)*usage);
274 }
275
276 if (usage_page_found && usage_found)
277 return 0; /* success */
278
279 /* Skip over this key and it's associated data */
280 i += data_len + key_size;
281 }
282
283 return -1; /* failure */
284}
285
286#if defined(__FreeBSD__) && __FreeBSD__ < 10
287/* The libusb version included in FreeBSD < 10 doesn't have this function. In
288 mainline libusb, it's inlined in libusb.h. This function will bear a striking
289 resemblance to that one, because there's about one way to code it.
290
291 Note that the data parameter is Unicode in UTF-16LE encoding.
292 Return value is the number of bytes in data, or LIBUSB_ERROR_*.
293 */
294static inline int libusb_get_string_descriptor(libusb_device_handle *dev,
295 uint8_t descriptor_index, uint16_t lang_id,
296 unsigned char *data, int length)
297{
298 return libusb_control_transfer(dev,
299 LIBUSB_ENDPOINT_IN | 0x0, /* Endpoint 0 IN */
300 LIBUSB_REQUEST_GET_DESCRIPTOR,
301 (LIBUSB_DT_STRING << 8) | descriptor_index,
302 lang_id, data, (uint16_t) length, 1000);
303}
304
305#endif
306
307
308/* Get the first language the device says it reports. This comes from
309 USB string #0. */
310static uint16_t get_first_language(libusb_device_handle *dev)
311{
312 uint16_t buf[32];
313 int len;
314
315 /* Get the string from libusb. */
316 len = libusb_get_string_descriptor(dev,
317 0x0, /* String ID */
318 0x0, /* Language */
319 (unsigned char*)buf,
320 sizeof(buf));
321 if (len < 4)
322 return 0x0;
323
324 return buf[1]; /* First two bytes are len and descriptor type. */
325}
326
327static int is_language_supported(libusb_device_handle *dev, uint16_t lang)
328{
329 uint16_t buf[32];
330 int len;
331 int i;
332
333 /* Get the string from libusb. */
334 len = libusb_get_string_descriptor(dev,
335 0x0, /* String ID */
336 0x0, /* Language */
337 (unsigned char*)buf,
338 sizeof(buf));
339 if (len < 4)
340 return 0x0;
341
342
343 len /= 2; /* language IDs are two-bytes each. */
344 /* Start at index 1 because there are two bytes of protocol data. */
345 for (i = 1; i < len; i++) {
346 if (buf[i] == lang)
347 return 1;
348 }
349
350 return 0;
351}
352
353
354/* This function returns a newly allocated wide string containing the USB
355 device string numbered by the index. The returned string must be freed
356 by using free(). */
357static wchar_t *get_usb_string(libusb_device_handle *dev, uint8_t idx)
358{
359 char buf[512];
360 int len;
361 wchar_t *str = NULL;
362
363#if !defined(__ANDROID__) && !defined(NO_ICONV) /* we don't use iconv on Android, or when it is explicitly disabled */
364 wchar_t wbuf[256];
365 /* iconv variables */
366 iconv_t ic;
367 size_t inbytes;
368 size_t outbytes;
369 size_t res;
370 ICONV_CONST char *inptr;
371 char *outptr;
372#endif
373
374 /* Determine which language to use. */
375 uint16_t lang;
376 lang = get_usb_code_for_current_locale();
377 if (!is_language_supported(dev, lang))
378 lang = get_first_language(dev);
379
380 /* Get the string from libusb. */
381 len = libusb_get_string_descriptor(dev,
382 idx,
383 lang,
384 (unsigned char*)buf,
385 sizeof(buf));
386 if (len < 2) /* we always skip first 2 bytes */
387 return NULL;
388
389#if defined(__ANDROID__) || defined(NO_ICONV)
390
391 /* Bionic does not have iconv support nor wcsdup() function, so it
392 has to be done manually. The following code will only work for
393 code points that can be represented as a single UTF-16 character,
394 and will incorrectly convert any code points which require more
395 than one UTF-16 character.
396
397 Skip over the first character (2-bytes). */
398 len -= 2;
399 str = (wchar_t*) malloc((len / 2 + 1) * sizeof(wchar_t));
400 int i;
401 for (i = 0; i < len / 2; i++) {
402 str[i] = buf[i * 2 + 2] | (buf[i * 2 + 3] << 8);
403 }
404 str[len / 2] = 0x00000000;
405
406#else
407
408 /* buf does not need to be explicitly NULL-terminated because
409 it is only passed into iconv() which does not need it. */
410
411 /* Initialize iconv. */
412 ic = iconv_open("WCHAR_T", "UTF-16LE");
413 if (ic == (iconv_t)-1) {
414 LOG("iconv_open() failed\n");
415 return NULL;
416 }
417
418 /* Convert to native wchar_t (UTF-32 on glibc/BSD systems).
419 Skip the first character (2-bytes). */
420 inptr = buf+2;
421 inbytes = len-2;
422 outptr = (char*) wbuf;
423 outbytes = sizeof(wbuf);
424 res = iconv(ic, &inptr, &inbytes, &outptr, &outbytes);
425 if (res == (size_t)-1) {
426 LOG("iconv() failed\n");
427 goto err;
428 }
429
430 /* Write the terminating NULL. */
431 wbuf[sizeof(wbuf)/sizeof(wbuf[0])-1] = 0x00000000;
432 if (outbytes >= sizeof(wbuf[0]))
433 *((wchar_t*)outptr) = 0x00000000;
434
435 /* Allocate and copy the string. */
436 str = wcsdup(wbuf);
437
438err:
439 iconv_close(ic);
440
441#endif
442
443 return str;
444}
445
446struct usb_string_cache_entry {
447 uint16_t vid;
448 uint16_t pid;
449 wchar_t *vendor;
450 wchar_t *product;
451};
452
453static struct usb_string_cache_entry *usb_string_cache = NULL;
454static size_t usb_string_cache_size = 0;
455static size_t usb_string_cache_insert_pos = 0;
456
457static int usb_string_cache_grow(void)
458{
459 struct usb_string_cache_entry *new_cache;
460 size_t allocSize;
461 size_t new_cache_size;
462
463 new_cache_size = usb_string_cache_size + 8;
464 allocSize = sizeof(struct usb_string_cache_entry) * new_cache_size;
465 new_cache = (struct usb_string_cache_entry *)realloc(usb_string_cache, allocSize);
466 if (!new_cache)
467 return -1;
468
469 usb_string_cache = new_cache;
470 usb_string_cache_size = new_cache_size;
471
472 return 0;
473}
474
475static void usb_string_cache_destroy(void)
476{
477 size_t i;
478 for (i = 0; i < usb_string_cache_insert_pos; i++) {
479 free(usb_string_cache[i].vendor);
480 free(usb_string_cache[i].product);
481 }
482 free(usb_string_cache);
483
484 usb_string_cache = NULL;
485 usb_string_cache_size = 0;
486 usb_string_cache_insert_pos = 0;
487}
488
489static struct usb_string_cache_entry *usb_string_cache_insert(void)
490{
491 struct usb_string_cache_entry *new_entry = NULL;
492 if (usb_string_cache_insert_pos >= usb_string_cache_size) {
493 if (usb_string_cache_grow() < 0)
494 return NULL;
495 }
496 new_entry = &usb_string_cache[usb_string_cache_insert_pos];
497 usb_string_cache_insert_pos++;
498 return new_entry;
499}
500
501static int usb_string_can_cache(uint16_t vid, uint16_t pid)
502{
503 if (!vid || !pid) {
504 /* We can't cache these, they aren't unique */
505 return 0;
506 }
507
508 if (vid == 0x0f0d && pid == 0x00dc) {
509 /* HORI reuses this VID/PID for many different products */
510 return 0;
511 }
512
513 /* We can cache these strings */
514 return 1;
515}
516
517static const struct usb_string_cache_entry *usb_string_cache_find(struct libusb_device_descriptor *desc, struct libusb_device_handle *handle)
518{
519 struct usb_string_cache_entry *entry = NULL;
520 size_t i;
521
522 /* Search for existing string cache entry */
523 for (i = 0; i < usb_string_cache_insert_pos; i++) {
524 entry = &usb_string_cache[i];
525 if (entry->vid != desc->idVendor)
526 continue;
527 if (entry->pid != desc->idProduct)
528 continue;
529 return entry;
530 }
531
532 /* Not found, create one. */
533 entry = usb_string_cache_insert();
534 if (!entry)
535 return NULL;
536
537 entry->vid = desc->idVendor;
538 entry->pid = desc->idProduct;
539 if (desc->iManufacturer > 0)
540 entry->vendor = get_usb_string(handle, desc->iManufacturer);
541 else
542 entry->vendor = NULL;
543 if (desc->iProduct > 0)
544 entry->product = get_usb_string(handle, desc->iProduct);
545 else
546 entry->product = NULL;
547
548 return entry;
549}
550
551/**
552 Max length of the result: "000-000.000.000.000.000.000.000:000.000" (39 chars).
553 64 is used for simplicity/alignment.
554*/
555static void get_path(char (*result)[64], libusb_device *dev, int config_number, int interface_number)
556{
557 char *str = *result;
558
559 /* Note that USB3 port count limit is 7; use 8 here for alignment */
560 uint8_t port_numbers[8] = {0, 0, 0, 0, 0, 0, 0, 0};
561 int num_ports = libusb_get_port_numbers(dev, port_numbers, 8);
562
563 if (num_ports > 0) {
564 int n = snprintf(str, sizeof("000-000"), "%u-%u", libusb_get_bus_number(dev), port_numbers[0]);
565 for (uint8_t i = 1; i < num_ports; i++) {
566 n += snprintf(&str[n], sizeof(".000"), ".%u", port_numbers[i]);
567 }
568 n += snprintf(&str[n], sizeof(":000.000"), ":%u.%u", (uint8_t)config_number, (uint8_t)interface_number);
569 str[n] = '\0';
570 } else {
571 /* Likely impossible, but check: USB3.0 specs limit number of ports to 7 and buffer size here is 8 */
572 if (num_ports == LIBUSB_ERROR_OVERFLOW) {
573 LOG("make_path() failed. buffer overflow error\n");
574 } else {
575 LOG("make_path() failed. unknown error\n");
576 }
577 str[0] = '\0';
578 }
579}
580
581static char *make_path(libusb_device *dev, int config_number, int interface_number)
582{
583 char str[64];
584 get_path(&str, dev, config_number, interface_number);
585 return strdup(str);
586}
587
588HID_API_EXPORT const struct hid_api_version* HID_API_CALL hid_version(void)
589{
590 return &api_version;
591}
592
593HID_API_EXPORT const char* HID_API_CALL hid_version_str(void)
594{
595 return HID_API_VERSION_STR;
596}
597
598int HID_API_EXPORT hid_init(void)
599{
600 if (!usb_context) {
601 const char *locale;
602
603 /* Init Libusb */
604 if (libusb_init(&usb_context))
605 return -1;
606
607 /* Set the locale if it's not set. */
608 locale = setlocale(LC_CTYPE, NULL);
609 if (!locale)
610 (void) setlocale(LC_CTYPE, "");
611 }
612
613 return 0;
614}
615
616int HID_API_EXPORT hid_exit(void)
617{
618 usb_string_cache_destroy();
619
620 if (usb_context) {
621 libusb_exit(usb_context);
622 usb_context = NULL;
623 }
624
625 return 0;
626}
627
628static int hid_get_report_descriptor_libusb(libusb_device_handle *handle, int interface_num, uint16_t expected_report_descriptor_size, unsigned char *buf, size_t buf_size)
629{
630 unsigned char *tmp = (unsigned char *)malloc(HID_API_MAX_REPORT_DESCRIPTOR_SIZE);
631
632 if (expected_report_descriptor_size > HID_API_MAX_REPORT_DESCRIPTOR_SIZE)
633 expected_report_descriptor_size = HID_API_MAX_REPORT_DESCRIPTOR_SIZE;
634
635 /* Get the HID Report Descriptor.
636 See USB HID Specification, section 7.1.1
637 */
638 int res = libusb_control_transfer(handle, LIBUSB_ENDPOINT_IN|LIBUSB_RECIPIENT_INTERFACE, LIBUSB_REQUEST_GET_DESCRIPTOR, (LIBUSB_DT_REPORT << 8), interface_num, tmp, expected_report_descriptor_size, 5000);
639 if (res >= 0) {
640 if (res > (int)buf_size)
641 res = (int)buf_size;
642
643 memcpy(buf, tmp, (size_t)res);
644 } else {
645 LOG("libusb_control_transfer() for getting the HID Report descriptor failed with %d: %s\n", res, libusb_error_name(res));
646 }
647 free(tmp);
648
649 return res;
650}
651
652/**
653 * Requires an opened device with *claimed interface*.
654 */
655static void fill_device_info_usage(struct hid_device_info *cur_dev, libusb_device_handle *handle, int interface_num, uint16_t expected_report_descriptor_size)
656{
657 unsigned char *hid_report_descriptor = malloc(HID_API_MAX_REPORT_DESCRIPTOR_SIZE);
658 unsigned short page = 0, usage = 0;
659
660 int res = hid_get_report_descriptor_libusb(handle, interface_num, expected_report_descriptor_size, hid_report_descriptor, HID_API_MAX_REPORT_DESCRIPTOR_SIZE);
661 if (res >= 0) {
662 /* Parse the usage and usage page
663 out of the report descriptor. */
664 get_usage(hid_report_descriptor, res, &page, &usage);
665 }
666
667 cur_dev->usage_page = page;
668 cur_dev->usage = usage;
669}
670
671#ifdef INVASIVE_GET_USAGE
672static void invasive_fill_device_info_usage(struct hid_device_info *cur_dev, libusb_device_handle *handle, int interface_num, uint16_t report_descriptor_size)
673{
674 int res = 0;
675
676#ifdef DETACH_KERNEL_DRIVER
677 int detached = 0;
678 /* Usage Page and Usage */
679 res = libusb_kernel_driver_active(handle, interface_num);
680 if (res == 1) {
681 res = libusb_detach_kernel_driver(handle, interface_num);
682 if (res < 0)
683 LOG("Couldn't detach kernel driver, even though a kernel driver was attached.\n");
684 else
685 detached = 1;
686 }
687#endif
688
689 res = libusb_claim_interface(handle, interface_num);
690 if (res >= 0) {
691 fill_device_info_usage(cur_dev, handle, interface_num, report_descriptor_size);
692
693 /* Release the interface */
694 res = libusb_release_interface(handle, interface_num);
695 if (res < 0)
696 LOG("Can't release the interface.\n");
697 }
698 else
699 LOG("Can't claim interface: (%d) %s\n", res, libusb_error_name(res));
700
701#ifdef DETACH_KERNEL_DRIVER
702 /* Re-attach kernel driver if necessary. */
703 if (detached) {
704 res = libusb_attach_kernel_driver(handle, interface_num);
705 if (res < 0)
706 LOG("Couldn't re-attach kernel driver.\n");
707 }
708#endif
709}
710#endif /* INVASIVE_GET_USAGE */
711
712/**
713 * Create and fill up most of hid_device_info fields.
714 * usage_page/usage is not filled up.
715 */
716static struct hid_device_info * create_device_info_for_device(libusb_device *device, libusb_device_handle *handle, struct libusb_device_descriptor *desc, int config_number, int interface_num, int interface_class, int interface_subclass, int interface_protocol)
717{
718 struct hid_device_info *cur_dev = calloc(1, sizeof(struct hid_device_info));
719 if (cur_dev == NULL) {
720 return NULL;
721 }
722
723 /* VID/PID */
724 cur_dev->vendor_id = desc->idVendor;
725 cur_dev->product_id = desc->idProduct;
726
727 cur_dev->release_number = desc->bcdDevice;
728
729 cur_dev->interface_number = interface_num;
730 cur_dev->interface_class = interface_class;
731 cur_dev->interface_subclass = interface_subclass;
732 cur_dev->interface_protocol = interface_protocol;
733
734 cur_dev->bus_type = HID_API_BUS_USB;
735
736 cur_dev->path = make_path(device, config_number, interface_num);
737
738 if (!handle) {
739 return cur_dev;
740 }
741
742 if (desc->iSerialNumber > 0)
743 cur_dev->serial_number = get_usb_string(handle, desc->iSerialNumber);
744
745 /* Manufacturer and Product strings */
746 const struct usb_string_cache_entry *string_cache;
747 if (usb_string_can_cache(desc->idVendor, desc->idProduct) &&
748 (string_cache = usb_string_cache_find(desc, handle)) != NULL) {
749 if (string_cache->vendor) {
750 cur_dev->manufacturer_string = wcsdup(string_cache->vendor);
751 }
752 if (string_cache->product) {
753 cur_dev->product_string = wcsdup(string_cache->product);
754 }
755 } else {
756 if (desc->iManufacturer > 0)
757 cur_dev->manufacturer_string = get_usb_string(handle, desc->iManufacturer);
758 if (desc->iProduct > 0)
759 cur_dev->product_string = get_usb_string(handle, desc->iProduct);
760 }
761
762 return cur_dev;
763}
764
765static uint16_t get_report_descriptor_size_from_interface_descriptors(const struct libusb_interface_descriptor *intf_desc)
766{
767 int i = 0;
768 int found_hid_report_descriptor = 0;
769 uint16_t result = HID_API_MAX_REPORT_DESCRIPTOR_SIZE;
770 const unsigned char *extra = intf_desc->extra;
771 int extra_length = intf_desc->extra_length;
772
773 /*
774 "extra" contains a HID descriptor
775 See section 6.2.1 of HID 1.1 specification.
776 */
777
778 while (extra_length >= 2) { /* Descriptor header: bLength/bDescriptorType */
779 if (extra[1] == LIBUSB_DT_HID) { /* bDescriptorType */
780 if (extra_length < 6) {
781 LOG("Broken HID descriptor: not enough data\n");
782 break;
783 }
784 unsigned char bNumDescriptors = extra[5];
785 if (extra_length < (6 + 3 * bNumDescriptors)) {
786 LOG("Broken HID descriptor: not enough data for Report metadata\n");
787 break;
788 }
789 for (i = 0; i < bNumDescriptors; i++) {
790 if (extra[6 + 3 * i] == LIBUSB_DT_REPORT) {
791 result = (uint16_t)extra[6 + 3 * i + 2] << 8 | extra[6 + 3 * i + 1];
792 found_hid_report_descriptor = 1;
793 break;
794 }
795 }
796
797 if (!found_hid_report_descriptor) {
798 /* We expect to find exactly 1 HID descriptor (LIBUSB_DT_HID)
799 which should contain exactly one HID Report Descriptor metadata (LIBUSB_DT_REPORT). */
800 LOG("Broken HID descriptor: missing Report descriptor\n");
801 }
802 break;
803 }
804
805 if (extra[0] == 0) { /* bLength */
806 LOG("Broken HID Interface descriptors: zero-sized descriptor\n");
807 break;
808 }
809
810 /* Iterate over to the next Descriptor */
811 extra_length -= extra[0];
812 extra += extra[0];
813 }
814
815 return result;
816}
817
818static int is_xbox360(unsigned short vendor_id, const struct libusb_interface_descriptor *intf_desc)
819{
820 static const int xb360_iface_subclass = 93;
821 static const int xb360_iface_protocol = 1; /* Wired */
822 static const int xb360w_iface_protocol = 129; /* Wireless */
823 static const int supported_vendors[] = {
824 0x0079, /* GPD Win 2 */
825 0x044f, /* Thrustmaster */
826 0x045e, /* Microsoft */
827 0x046d, /* Logitech */
828 0x056e, /* Elecom */
829 0x06a3, /* Saitek */
830 0x0738, /* Mad Catz */
831 0x07ff, /* Mad Catz */
832 0x0e6f, /* PDP */
833 0x0f0d, /* Hori */
834 0x1038, /* SteelSeries */
835 0x11c9, /* Nacon */
836 0x12ab, /* Unknown */
837 0x1430, /* RedOctane */
838 0x146b, /* BigBen */
839 0x1532, /* Razer Sabertooth */
840 0x15e4, /* Numark */
841 0x162e, /* Joytech */
842 0x1689, /* Razer Onza */
843 0x1949, /* Lab126, Inc. */
844 0x1bad, /* Harmonix */
845 0x20d6, /* PowerA */
846 0x24c6, /* PowerA */
847 0x2c22, /* Qanba */
848 0x2dc8, /* 8BitDo */
849 0x9886, /* ASTRO Gaming */
850 };
851
852 if (intf_desc->bInterfaceClass == LIBUSB_CLASS_VENDOR_SPEC &&
853 intf_desc->bInterfaceSubClass == xb360_iface_subclass &&
854 (intf_desc->bInterfaceProtocol == xb360_iface_protocol ||
855 intf_desc->bInterfaceProtocol == xb360w_iface_protocol)) {
856 size_t i;
857 for (i = 0; i < sizeof(supported_vendors)/sizeof(supported_vendors[0]); ++i) {
858 if (vendor_id == supported_vendors[i]) {
859 return 1;
860 }
861 }
862 }
863 return 0;
864}
865
866static int is_xboxone(unsigned short vendor_id, const struct libusb_interface_descriptor *intf_desc)
867{
868 static const int xb1_iface_subclass = 71;
869 static const int xb1_iface_protocol = 208;
870 static const int supported_vendors[] = {
871 0x03f0, /* HP */
872 0x044f, /* Thrustmaster */
873 0x045e, /* Microsoft */
874 0x0738, /* Mad Catz */
875 0x0b05, /* ASUS */
876 0x0e6f, /* PDP */
877 0x0f0d, /* Hori */
878 0x10f5, /* Turtle Beach */
879 0x1532, /* Razer Wildcat */
880 0x20d6, /* PowerA */
881 0x24c6, /* PowerA */
882 0x2dc8, /* 8BitDo */
883 0x2e24, /* Hyperkin */
884 0x3537, /* GameSir */
885 };
886
887 if (intf_desc->bInterfaceNumber == 0 &&
888 intf_desc->bInterfaceClass == LIBUSB_CLASS_VENDOR_SPEC &&
889 intf_desc->bInterfaceSubClass == xb1_iface_subclass &&
890 intf_desc->bInterfaceProtocol == xb1_iface_protocol) {
891 size_t i;
892 for (i = 0; i < sizeof(supported_vendors)/sizeof(supported_vendors[0]); ++i) {
893 if (vendor_id == supported_vendors[i]) {
894 return 1;
895 }
896 }
897 }
898 return 0;
899}
900
901static int should_enumerate_interface(unsigned short vendor_id, const struct libusb_interface_descriptor *intf_desc)
902{
903#if 0
904 printf("Checking interface 0x%x %d/%d/%d/%d\n", vendor_id, intf_desc->bInterfaceNumber, intf_desc->bInterfaceClass, intf_desc->bInterfaceSubClass, intf_desc->bInterfaceProtocol);
905#endif
906
907 if (intf_desc->bInterfaceClass == LIBUSB_CLASS_HID)
908 return 1;
909
910 /* Also enumerate Xbox 360 controllers */
911 if (is_xbox360(vendor_id, intf_desc))
912 return 1;
913
914 /* Also enumerate Xbox One controllers */
915 if (is_xboxone(vendor_id, intf_desc))
916 return 1;
917
918 return 0;
919}
920
921struct hid_device_info HID_API_EXPORT *hid_enumerate(unsigned short vendor_id, unsigned short product_id)
922{
923 libusb_device **devs;
924 libusb_device *dev;
925 libusb_device_handle *handle = NULL;
926 ssize_t num_devs;
927 int i = 0;
928
929 struct hid_device_info *root = NULL; /* return object */
930 struct hid_device_info *cur_dev = NULL;
931
932 if(hid_init() < 0)
933 return NULL;
934
935 num_devs = libusb_get_device_list(usb_context, &devs);
936 if (num_devs < 0)
937 return NULL;
938 while ((dev = devs[i++]) != NULL) {
939 struct libusb_device_descriptor desc;
940 struct libusb_config_descriptor *conf_desc = NULL;
941 int j, k;
942
943 int res = libusb_get_device_descriptor(dev, &desc);
944 if (res < 0)
945 continue;
946
947 unsigned short dev_vid = desc.idVendor;
948 unsigned short dev_pid = desc.idProduct;
949
950 if ((vendor_id != 0x0 && vendor_id != dev_vid) ||
951 (product_id != 0x0 && product_id != dev_pid)) {
952 continue;
953 }
954
955#ifdef HIDAPI_IGNORE_DEVICE
956 /* See if there are any devices we should skip in enumeration */
957 if (HIDAPI_IGNORE_DEVICE(HID_API_BUS_USB, dev_vid, dev_pid, 0, 0)) {
958 continue;
959 }
960#endif
961
962 res = libusb_get_active_config_descriptor(dev, &conf_desc);
963 if (res < 0)
964 libusb_get_config_descriptor(dev, 0, &conf_desc);
965 if (conf_desc) {
966 for (j = 0; j < conf_desc->bNumInterfaces; j++) {
967 const struct libusb_interface *intf = &conf_desc->interface[j];
968 for (k = 0; k < intf->num_altsetting; k++) {
969 const struct libusb_interface_descriptor *intf_desc;
970 intf_desc = &intf->altsetting[k];
971 if (should_enumerate_interface(dev_vid, intf_desc)) {
972 struct hid_device_info *tmp;
973
974 res = libusb_open(dev, &handle);
975
976#ifdef __ANDROID__
977 if (handle) {
978 /* There is (a potential) libusb Android backend, in which
979 device descriptor is not accurate up until the device is opened.
980 https://github.com/libusb/libusb/pull/874#discussion_r632801373
981 A workaround is to re-read the descriptor again.
982 Even if it is not going to be accepted into libusb master,
983 having it here won't do any harm, since reading the device descriptor
984 is as cheap as copy 18 bytes of data. */
985 libusb_get_device_descriptor(dev, &desc);
986 }
987#endif
988
989 tmp = create_device_info_for_device(dev, handle, &desc, conf_desc->bConfigurationValue, intf_desc->bInterfaceNumber, intf_desc->bInterfaceClass, intf_desc->bInterfaceSubClass, intf_desc->bInterfaceProtocol);
990 if (tmp) {
991#ifdef INVASIVE_GET_USAGE
992 /* TODO: have a runtime check for this section. */
993
994 /*
995 This section is removed because it is too
996 invasive on the system. Getting a Usage Page
997 and Usage requires parsing the HID Report
998 descriptor. Getting a HID Report descriptor
999 involves claiming the interface. Claiming the
1000 interface involves detaching the kernel driver.
1001 Detaching the kernel driver is hard on the system
1002 because it will unclaim interfaces (if another
1003 app has them claimed) and the re-attachment of
1004 the driver will sometimes change /dev entry names.
1005 It is for these reasons that this section is
1006 optional. For composite devices, use the interface
1007 field in the hid_device_info struct to distinguish
1008 between interfaces. */
1009 if (handle) {
1010 uint16_t report_descriptor_size = get_report_descriptor_size_from_interface_descriptors(intf_desc);
1011
1012 invasive_fill_device_info_usage(tmp, handle, intf_desc->bInterfaceNumber, report_descriptor_size);
1013 }
1014#endif /* INVASIVE_GET_USAGE */
1015
1016 if (cur_dev) {
1017 cur_dev->next = tmp;
1018 }
1019 else {
1020 root = tmp;
1021 }
1022 cur_dev = tmp;
1023 }
1024
1025 if (res >= 0) {
1026 libusb_close(handle);
1027 handle = NULL;
1028 }
1029 break;
1030 }
1031 } /* altsettings */
1032 } /* interfaces */
1033 libusb_free_config_descriptor(conf_desc);
1034 }
1035 }
1036
1037 libusb_free_device_list(devs, 1);
1038
1039 return root;
1040}
1041
1042void HID_API_EXPORT hid_free_enumeration(struct hid_device_info *devs)
1043{
1044 struct hid_device_info *d = devs;
1045 while (d) {
1046 struct hid_device_info *next = d->next;
1047 free(d->path);
1048 free(d->serial_number);
1049 free(d->manufacturer_string);
1050 free(d->product_string);
1051 free(d);
1052 d = next;
1053 }
1054}
1055
1056hid_device * hid_open(unsigned short vendor_id, unsigned short product_id, const wchar_t *serial_number)
1057{
1058 struct hid_device_info *devs, *cur_dev;
1059 const char *path_to_open = NULL;
1060 hid_device *handle = NULL;
1061
1062 devs = hid_enumerate(vendor_id, product_id);
1063 cur_dev = devs;
1064 while (cur_dev) {
1065 if (cur_dev->vendor_id == vendor_id &&
1066 cur_dev->product_id == product_id) {
1067 if (serial_number) {
1068 if (cur_dev->serial_number &&
1069 wcscmp(serial_number, cur_dev->serial_number) == 0) {
1070 path_to_open = cur_dev->path;
1071 break;
1072 }
1073 }
1074 else {
1075 path_to_open = cur_dev->path;
1076 break;
1077 }
1078 }
1079 cur_dev = cur_dev->next;
1080 }
1081
1082 if (path_to_open) {
1083 /* Open the device */
1084 handle = hid_open_path(path_to_open);
1085 }
1086
1087 hid_free_enumeration(devs);
1088
1089 return handle;
1090}
1091
1092static void LIBUSB_CALL read_callback(struct libusb_transfer *transfer)
1093{
1094 hid_device *dev = transfer->user_data;
1095 int res;
1096
1097 if (transfer->status == LIBUSB_TRANSFER_COMPLETED) {
1098
1099 struct input_report *rpt = (struct input_report*) malloc(sizeof(*rpt));
1100 rpt->data = (uint8_t*) malloc(transfer->actual_length);
1101 memcpy(rpt->data, transfer->buffer, transfer->actual_length);
1102 rpt->len = transfer->actual_length;
1103 rpt->next = NULL;
1104
1105 hidapi_thread_mutex_lock(&dev->thread_state);
1106
1107 /* Attach the new report object to the end of the list. */
1108 if (dev->input_reports == NULL) {
1109 /* The list is empty. Put it at the root. */
1110 dev->input_reports = rpt;
1111 hidapi_thread_cond_signal(&dev->thread_state);
1112 }
1113 else {
1114 /* Find the end of the list and attach. */
1115 struct input_report *cur = dev->input_reports;
1116 int num_queued = 0;
1117 while (cur->next != NULL) {
1118 cur = cur->next;
1119 num_queued++;
1120 }
1121 cur->next = rpt;
1122
1123 /* Pop one off if we've reached 30 in the queue. This
1124 way we don't grow forever if the user never reads
1125 anything from the device. */
1126 if (num_queued > 30) {
1127 return_data(dev, NULL, 0);
1128 }
1129 }
1130 hidapi_thread_mutex_unlock(&dev->thread_state);
1131 }
1132 else if (transfer->status == LIBUSB_TRANSFER_CANCELLED) {
1133 dev->shutdown_thread = 1;
1134 }
1135 else if (transfer->status == LIBUSB_TRANSFER_NO_DEVICE) {
1136 dev->shutdown_thread = 1;
1137 }
1138 else if (transfer->status == LIBUSB_TRANSFER_TIMED_OUT) {
1139 //LOG("Timeout (normal)\n");
1140 }
1141 else {
1142 LOG("Unknown transfer code: %d\n", transfer->status);
1143 }
1144
1145 if (dev->shutdown_thread) {
1146 dev->transfer_loop_finished = 1;
1147 return;
1148 }
1149
1150 /* Re-submit the transfer object. */
1151 res = libusb_submit_transfer(transfer);
1152 if (res != 0) {
1153 LOG("Unable to submit URB: (%d) %s\n", res, libusb_error_name(res));
1154 dev->shutdown_thread = 1;
1155 dev->transfer_loop_finished = 1;
1156 }
1157}
1158
1159
1160static void *read_thread(void *param)
1161{
1162 int res;
1163 hid_device *dev = param;
1164 uint8_t *buf;
1165 const size_t length = dev->input_ep_max_packet_size;
1166
1167 /* Set up the transfer object. */
1168 buf = (uint8_t*) malloc(length);
1169 dev->transfer = libusb_alloc_transfer(0);
1170 libusb_fill_interrupt_transfer(dev->transfer,
1171 dev->device_handle,
1172 dev->input_endpoint,
1173 buf,
1174 (int) length,
1175 read_callback,
1176 dev,
1177 5000/*timeout*/);
1178
1179 /* Make the first submission. Further submissions are made
1180 from inside read_callback() */
1181 res = libusb_submit_transfer(dev->transfer);
1182 if(res < 0) {
1183 LOG("libusb_submit_transfer failed: %d %s. Stopping read_thread from running\n", res, libusb_error_name(res));
1184 dev->shutdown_thread = 1;
1185 dev->transfer_loop_finished = 1;
1186 }
1187
1188 /* Notify the main thread that the read thread is up and running. */
1189 hidapi_thread_barrier_wait(&dev->thread_state);
1190
1191 /* Handle all the events. */
1192 while (!dev->shutdown_thread) {
1193 res = libusb_handle_events(usb_context);
1194 if (res < 0) {
1195 /* There was an error. */
1196 LOG("read_thread(): (%d) %s\n", res, libusb_error_name(res));
1197
1198 /* Break out of this loop only on fatal error.*/
1199 if (res != LIBUSB_ERROR_BUSY &&
1200 res != LIBUSB_ERROR_TIMEOUT &&
1201 res != LIBUSB_ERROR_OVERFLOW &&
1202 res != LIBUSB_ERROR_INTERRUPTED) {
1203 dev->shutdown_thread = 1;
1204 break;
1205 }
1206 }
1207 }
1208
1209 /* Cancel any transfer that may be pending. This call will fail
1210 if no transfers are pending, but that's OK. */
1211 libusb_cancel_transfer(dev->transfer);
1212
1213 while (!dev->transfer_loop_finished)
1214 libusb_handle_events_completed(usb_context, &dev->transfer_loop_finished);
1215
1216 /* Now that the read thread is stopping, Wake any threads which are
1217 waiting on data (in hid_read_timeout()). Do this under a mutex to
1218 make sure that a thread which is about to go to sleep waiting on
1219 the condition actually will go to sleep before the condition is
1220 signaled. */
1221 hidapi_thread_mutex_lock(&dev->thread_state);
1222 hidapi_thread_cond_broadcast(&dev->thread_state);
1223 hidapi_thread_mutex_unlock(&dev->thread_state);
1224
1225 /* The dev->transfer->buffer and dev->transfer objects are cleaned up
1226 in hid_close(). They are not cleaned up here because this thread
1227 could end either due to a disconnect or due to a user
1228 call to hid_close(). In both cases the objects can be safely
1229 cleaned up after the call to hidapi_thread_join() (in hid_close()), but
1230 since hid_close() calls libusb_cancel_transfer(), on these objects,
1231 they can not be cleaned up here. */
1232
1233 return NULL;
1234}
1235
1236static void init_xbox360(libusb_device_handle *device_handle, unsigned short idVendor, unsigned short idProduct, const struct libusb_config_descriptor *conf_desc)
1237{
1238 (void)conf_desc;
1239
1240 if ((idVendor == 0x05ac && idProduct == 0x055b) /* Gamesir-G3w */ ||
1241 idVendor == 0x0f0d /* Hori Xbox controllers */) {
1242 unsigned char data[20];
1243
1244 /* The HORIPAD FPS for Nintendo Switch requires this to enable input reports.
1245 This VID/PID is also shared with other HORI controllers, but they all seem
1246 to be fine with this as well.
1247 */
1248 memset(data, 0, sizeof(data));
1249 libusb_control_transfer(device_handle, 0xC1, 0x01, 0x100, 0x0, data, sizeof(data), 100);
1250 }
1251}
1252
1253static void init_xboxone(libusb_device_handle *device_handle, unsigned short idVendor, unsigned short idProduct, const struct libusb_config_descriptor *conf_desc)
1254{
1255 static const int vendor_microsoft = 0x045e;
1256 static const int xb1_iface_subclass = 71;
1257 static const int xb1_iface_protocol = 208;
1258 int j, k, res;
1259
1260 (void)idProduct;
1261
1262 for (j = 0; j < conf_desc->bNumInterfaces; j++) {
1263 const struct libusb_interface *intf = &conf_desc->interface[j];
1264 for (k = 0; k < intf->num_altsetting; k++) {
1265 const struct libusb_interface_descriptor *intf_desc = &intf->altsetting[k];
1266 if (intf_desc->bInterfaceClass == LIBUSB_CLASS_VENDOR_SPEC &&
1267 intf_desc->bInterfaceSubClass == xb1_iface_subclass &&
1268 intf_desc->bInterfaceProtocol == xb1_iface_protocol) {
1269 int bSetAlternateSetting = 0;
1270
1271 /* Newer Microsoft Xbox One controllers have a high speed alternate setting */
1272 if (idVendor == vendor_microsoft &&
1273 intf_desc->bInterfaceNumber == 0 && intf_desc->bAlternateSetting == 1) {
1274 bSetAlternateSetting = 1;
1275 } else if (intf_desc->bInterfaceNumber != 0 && intf_desc->bAlternateSetting == 0) {
1276 bSetAlternateSetting = 1;
1277 }
1278
1279 if (bSetAlternateSetting) {
1280 res = libusb_claim_interface(device_handle, intf_desc->bInterfaceNumber);
1281 if (res < 0) {
1282 LOG("can't claim interface %d: %d\n", intf_desc->bInterfaceNumber, res);
1283 continue;
1284 }
1285
1286 LOG("Setting alternate setting for VID/PID 0x%x/0x%x interface %d to %d\n", idVendor, idProduct, intf_desc->bInterfaceNumber, intf_desc->bAlternateSetting);
1287
1288 res = libusb_set_interface_alt_setting(device_handle, intf_desc->bInterfaceNumber, intf_desc->bAlternateSetting);
1289 if (res < 0) {
1290 LOG("xbox init: can't set alt setting %d: %d\n", intf_desc->bInterfaceNumber, res);
1291 }
1292
1293 libusb_release_interface(device_handle, intf_desc->bInterfaceNumber);
1294 }
1295 }
1296 }
1297 }
1298}
1299
1300static void calculate_device_quirks(hid_device *dev, unsigned short idVendor, unsigned short idProduct)
1301{
1302 static const int VENDOR_SONY = 0x054c;
1303 static const int PRODUCT_PS3_CONTROLLER = 0x0268;
1304 static const int PRODUCT_NAVIGATION_CONTROLLER = 0x042f;
1305
1306 if (idVendor == VENDOR_SONY &&
1307 (idProduct == PRODUCT_PS3_CONTROLLER || idProduct == PRODUCT_NAVIGATION_CONTROLLER)) {
1308 dev->skip_output_report_id = 1;
1309 dev->no_output_reports_on_intr_ep = 1;
1310 }
1311}
1312
1313static int hidapi_initialize_device(hid_device *dev, const struct libusb_interface_descriptor *intf_desc, const struct libusb_config_descriptor *conf_desc)
1314{
1315 int i =0;
1316 int res = 0;
1317 struct libusb_device_descriptor desc;
1318 libusb_get_device_descriptor(libusb_get_device(dev->device_handle), &desc);
1319
1320#ifdef DETACH_KERNEL_DRIVER
1321 /* Detach the kernel driver, but only if the
1322 device is managed by the kernel */
1323 dev->is_driver_detached = 0;
1324 if (libusb_kernel_driver_active(dev->device_handle, intf_desc->bInterfaceNumber) == 1) {
1325 res = libusb_detach_kernel_driver(dev->device_handle, intf_desc->bInterfaceNumber);
1326 if (res < 0) {
1327 LOG("Unable to detach Kernel Driver: (%d) %s\n", res, libusb_error_name(res));
1328 return 0;
1329 }
1330 else {
1331 dev->is_driver_detached = 1;
1332 LOG("Driver successfully detached from kernel.\n");
1333 }
1334 }
1335#endif
1336 res = libusb_claim_interface(dev->device_handle, intf_desc->bInterfaceNumber);
1337 if (res < 0) {
1338 LOG("can't claim interface %d: (%d) %s\n", intf_desc->bInterfaceNumber, res, libusb_error_name(res));
1339
1340#ifdef DETACH_KERNEL_DRIVER
1341 if (dev->is_driver_detached) {
1342 res = libusb_attach_kernel_driver(dev->device_handle, intf_desc->bInterfaceNumber);
1343 if (res < 0)
1344 LOG("Failed to reattach the driver to kernel: (%d) %s\n", res, libusb_error_name(res));
1345 }
1346#endif
1347 return 0;
1348 }
1349
1350 /* Initialize XBox 360 controllers */
1351 if (is_xbox360(desc.idVendor, intf_desc)) {
1352 dev->no_skip_output_report_id = 1;
1353 init_xbox360(dev->device_handle, desc.idVendor, desc.idProduct, conf_desc);
1354 }
1355
1356 /* Initialize XBox One controllers */
1357 if (is_xboxone(desc.idVendor, intf_desc)) {
1358 init_xboxone(dev->device_handle, desc.idVendor, desc.idProduct, conf_desc);
1359 }
1360
1361 /* Store off the string descriptor indexes */
1362 dev->manufacturer_index = desc.iManufacturer;
1363 dev->product_index = desc.iProduct;
1364 dev->serial_index = desc.iSerialNumber;
1365
1366 /* Store off the USB information */
1367 dev->config_number = conf_desc->bConfigurationValue;
1368 dev->interface = intf_desc->bInterfaceNumber;
1369 dev->interface_class = intf_desc->bInterfaceClass;
1370 dev->interface_subclass = intf_desc->bInterfaceSubClass;
1371 dev->interface_protocol = intf_desc->bInterfaceProtocol;
1372
1373 dev->report_descriptor_size = get_report_descriptor_size_from_interface_descriptors(intf_desc);
1374
1375 dev->input_endpoint = 0;
1376 dev->input_ep_max_packet_size = 0;
1377 dev->output_endpoint = 0;
1378
1379 /* Find the INPUT and OUTPUT endpoints. An
1380 OUTPUT endpoint is not required. */
1381 for (i = 0; i < intf_desc->bNumEndpoints; i++) {
1382 const struct libusb_endpoint_descriptor *ep
1383 = &intf_desc->endpoint[i];
1384
1385 /* Determine the type and direction of this
1386 endpoint. */
1387 int is_interrupt =
1388 (ep->bmAttributes & LIBUSB_TRANSFER_TYPE_MASK)
1389 == LIBUSB_TRANSFER_TYPE_INTERRUPT;
1390 int is_output =
1391 (ep->bEndpointAddress & LIBUSB_ENDPOINT_DIR_MASK)
1392 == LIBUSB_ENDPOINT_OUT;
1393 int is_input =
1394 (ep->bEndpointAddress & LIBUSB_ENDPOINT_DIR_MASK)
1395 == LIBUSB_ENDPOINT_IN;
1396
1397 /* Decide whether to use it for input or output. */
1398 if (dev->input_endpoint == 0 &&
1399 is_interrupt && is_input) {
1400 /* Use this endpoint for INPUT */
1401 dev->input_endpoint = ep->bEndpointAddress;
1402 dev->input_ep_max_packet_size = ep->wMaxPacketSize;
1403 }
1404 if (dev->output_endpoint == 0 &&
1405 is_interrupt && is_output) {
1406 /* Use this endpoint for OUTPUT */
1407 dev->output_endpoint = ep->bEndpointAddress;
1408 }
1409 }
1410
1411 calculate_device_quirks(dev, desc.idVendor, desc.idProduct);
1412
1413 hidapi_thread_create(&dev->thread_state, read_thread, dev);
1414
1415 /* Wait here for the read thread to be initialized. */
1416 hidapi_thread_barrier_wait(&dev->thread_state);
1417 return 1;
1418}
1419
1420
1421HID_API_EXPORT hid_device *hid_open_path(const char *path)
1422{
1423 hid_device *dev = NULL;
1424
1425 libusb_device **devs = NULL;
1426 libusb_device *usb_dev = NULL;
1427 int res = 0;
1428 int d = 0;
1429 int good_open = 0;
1430
1431 if(hid_init() < 0)
1432 return NULL;
1433
1434 dev = new_hid_device();
1435
1436 libusb_get_device_list(usb_context, &devs);
1437 while ((usb_dev = devs[d++]) != NULL && !good_open) {
1438 struct libusb_device_descriptor desc;
1439 struct libusb_config_descriptor *conf_desc = NULL;
1440 int j,k;
1441
1442 res = libusb_get_device_descriptor(usb_dev, &desc);
1443 if (res < 0)
1444 continue;
1445
1446 res = libusb_get_active_config_descriptor(usb_dev, &conf_desc);
1447 if (res < 0)
1448 libusb_get_config_descriptor(usb_dev, 0, &conf_desc);
1449 if (!conf_desc)
1450 continue;
1451
1452 for (j = 0; j < conf_desc->bNumInterfaces && !good_open; j++) {
1453 const struct libusb_interface *intf = &conf_desc->interface[j];
1454 for (k = 0; k < intf->num_altsetting && !good_open; k++) {
1455 const struct libusb_interface_descriptor *intf_desc = &intf->altsetting[k];
1456 if (should_enumerate_interface(desc.idVendor, intf_desc)) {
1457 char dev_path[64];
1458 get_path(&dev_path, usb_dev, conf_desc->bConfigurationValue, intf_desc->bInterfaceNumber);
1459 if (!strcmp(dev_path, path)) {
1460 /* Matched Paths. Open this device */
1461
1462 /* OPEN HERE */
1463 res = libusb_open(usb_dev, &dev->device_handle);
1464 if (res < 0) {
1465 LOG("can't open device\n");
1466 break;
1467 }
1468 good_open = hidapi_initialize_device(dev, intf_desc, conf_desc);
1469 if (!good_open)
1470 libusb_close(dev->device_handle);
1471 }
1472 }
1473 }
1474 }
1475 libusb_free_config_descriptor(conf_desc);
1476 }
1477
1478 libusb_free_device_list(devs, 1);
1479
1480 /* If we have a good handle, return it. */
1481 if (good_open) {
1482 return dev;
1483 }
1484 else {
1485 /* Unable to open any devices. */
1486 free_hid_device(dev);
1487 return NULL;
1488 }
1489}
1490
1491
1492HID_API_EXPORT hid_device * HID_API_CALL hid_libusb_wrap_sys_device(intptr_t sys_dev, int interface_num)
1493{
1494/* 0x01000107 is a LIBUSB_API_VERSION for 1.0.23 - version when libusb_wrap_sys_device was introduced */
1495#if (!defined(HIDAPI_TARGET_LIBUSB_API_VERSION) || HIDAPI_TARGET_LIBUSB_API_VERSION >= 0x01000107) && (LIBUSB_API_VERSION >= 0x01000107)
1496 hid_device *dev = NULL;
1497 struct libusb_config_descriptor *conf_desc = NULL;
1498 const struct libusb_interface_descriptor *selected_intf_desc = NULL;
1499 int res = 0;
1500 int j = 0, k = 0;
1501
1502 if(hid_init() < 0)
1503 return NULL;
1504
1505 dev = new_hid_device();
1506
1507 res = libusb_wrap_sys_device(usb_context, sys_dev, &dev->device_handle);
1508 if (res < 0) {
1509 LOG("libusb_wrap_sys_device failed: %d %s\n", res, libusb_error_name(res));
1510 goto err;
1511 }
1512
1513 res = libusb_get_active_config_descriptor(libusb_get_device(dev->device_handle), &conf_desc);
1514 if (res < 0)
1515 libusb_get_config_descriptor(libusb_get_device(dev->device_handle), 0, &conf_desc);
1516
1517 if (!conf_desc) {
1518 LOG("Failed to get configuration descriptor: %d %s\n", res, libusb_error_name(res));
1519 goto err;
1520 }
1521
1522 /* find matching HID interface */
1523 for (j = 0; j < conf_desc->bNumInterfaces && !selected_intf_desc; j++) {
1524 const struct libusb_interface *intf = &conf_desc->interface[j];
1525 for (k = 0; k < intf->num_altsetting; k++) {
1526 const struct libusb_interface_descriptor *intf_desc = &intf->altsetting[k];
1527 if (intf_desc->bInterfaceClass == LIBUSB_CLASS_HID) {
1528 if (interface_num < 0 || interface_num == intf_desc->bInterfaceNumber) {
1529 selected_intf_desc = intf_desc;
1530 break;
1531 }
1532 }
1533 }
1534 }
1535
1536 if (!selected_intf_desc) {
1537 if (interface_num < 0) {
1538 LOG("Sys USB device doesn't contain a HID interface\n");
1539 }
1540 else {
1541 LOG("Sys USB device doesn't contain a HID interface with number %d\n", interface_num);
1542 }
1543 goto err;
1544 }
1545
1546 if (!hidapi_initialize_device(dev, selected_intf_desc, conf_desc))
1547 goto err;
1548
1549 return dev;
1550
1551err:
1552 if (conf_desc)
1553 libusb_free_config_descriptor(conf_desc);
1554 if (dev->device_handle)
1555 libusb_close(dev->device_handle);
1556 free_hid_device(dev);
1557#else
1558 (void)sys_dev;
1559 (void)interface_num;
1560 LOG("libusb_wrap_sys_device is not available\n");
1561#endif
1562 return NULL;
1563}
1564
1565
1566int HID_API_EXPORT hid_write(hid_device *dev, const unsigned char *data, size_t length)
1567{
1568 int res;
1569 int report_number;
1570 int skipped_report_id = 0;
1571
1572 if (!data || (length ==0)) {
1573 return -1;
1574 }
1575
1576 report_number = data[0];
1577
1578 if ((!dev->no_skip_output_report_id && report_number == 0x0) || dev->skip_output_report_id) {
1579 data++;
1580 length--;
1581 skipped_report_id = 1;
1582 }
1583
1584
1585 if (dev->output_endpoint <= 0 || dev->no_output_reports_on_intr_ep) {
1586 /* No interrupt out endpoint. Use the Control Endpoint */
1587 res = libusb_control_transfer(dev->device_handle,
1588 LIBUSB_REQUEST_TYPE_CLASS|LIBUSB_RECIPIENT_INTERFACE|LIBUSB_ENDPOINT_OUT,
1589 0x09/*HID Set_Report*/,
1590 (2/*HID output*/ << 8) | report_number,
1591 dev->interface,
1592 (unsigned char *)data, (uint16_t)length,
1593 1000/*timeout millis*/);
1594
1595 if (res < 0)
1596 return -1;
1597
1598 if (skipped_report_id)
1599 length++;
1600
1601 return (int) length;
1602 }
1603 else {
1604 /* Use the interrupt out endpoint */
1605 int actual_length;
1606 res = libusb_interrupt_transfer(dev->device_handle,
1607 dev->output_endpoint,
1608 (unsigned char*)data,
1609 (int) length,
1610 &actual_length, 1000);
1611
1612 if (res < 0)
1613 return -1;
1614
1615 if (skipped_report_id)
1616 actual_length++;
1617
1618 return actual_length;
1619 }
1620}
1621
1622/* Helper function, to simplify hid_read().
1623 This should be called with dev->mutex locked. */
1624static int return_data(hid_device *dev, unsigned char *data, size_t length)
1625{
1626 /* Copy the data out of the linked list item (rpt) into the
1627 return buffer (data), and delete the liked list item. */
1628 struct input_report *rpt = dev->input_reports;
1629 size_t len = (length < rpt->len)? length: rpt->len;
1630 if (len > 0)
1631 memcpy(data, rpt->data, len);
1632 dev->input_reports = rpt->next;
1633 free(rpt->data);
1634 free(rpt);
1635 return (int) len;
1636}
1637
1638static void cleanup_mutex(void *param)
1639{
1640 hid_device *dev = param;
1641 hidapi_thread_mutex_unlock(&dev->thread_state);
1642}
1643
1644
1645int HID_API_EXPORT hid_read_timeout(hid_device *dev, unsigned char *data, size_t length, int milliseconds)
1646{
1647#if 0
1648 int transferred;
1649 int res = libusb_interrupt_transfer(dev->device_handle, dev->input_endpoint, data, length, &transferred, 5000);
1650 LOG("transferred: %d\n", transferred);
1651 return transferred;
1652#endif
1653 /* by initialising this variable right here, GCC gives a compilation warning/error: */
1654 /* error: variable ‘bytes_read’ might be clobbered by ‘longjmp’ or ‘vfork’ [-Werror=clobbered] */
1655 int bytes_read; /* = -1; */
1656
1657 hidapi_thread_mutex_lock(&dev->thread_state);
1658 hidapi_thread_cleanup_push(cleanup_mutex, dev);
1659
1660 bytes_read = -1;
1661
1662 /* There's an input report queued up. Return it. */
1663 if (dev->input_reports) {
1664 /* Return the first one */
1665 bytes_read = return_data(dev, data, length);
1666 goto ret;
1667 }
1668
1669 if (dev->shutdown_thread) {
1670 /* This means the device has been disconnected.
1671 An error code of -1 should be returned. */
1672 bytes_read = -1;
1673 goto ret;
1674 }
1675
1676 if (milliseconds == -1) {
1677 /* Blocking */
1678 while (!dev->input_reports && !dev->shutdown_thread) {
1679 hidapi_thread_cond_wait(&dev->thread_state);
1680 }
1681 if (dev->input_reports) {
1682 bytes_read = return_data(dev, data, length);
1683 }
1684 }
1685 else if (milliseconds > 0) {
1686 /* Non-blocking, but called with timeout. */
1687 int res;
1688 hidapi_timespec ts;
1689 hidapi_thread_gettime(&ts);
1690 hidapi_thread_addtime(&ts, milliseconds);
1691
1692 while (!dev->input_reports && !dev->shutdown_thread) {
1693 res = hidapi_thread_cond_timedwait(&dev->thread_state, &ts);
1694 if (res == 0) {
1695 if (dev->input_reports) {
1696 bytes_read = return_data(dev, data, length);
1697 break;
1698 }
1699
1700 /* If we're here, there was a spurious wake up
1701 or the read thread was shutdown. Run the
1702 loop again (ie: don't break). */
1703 }
1704 else if (res == HIDAPI_THREAD_TIMED_OUT) {
1705 /* Timed out. */
1706 bytes_read = 0;
1707 break;
1708 }
1709 else {
1710 /* Error. */
1711 bytes_read = -1;
1712 break;
1713 }
1714 }
1715 }
1716 else {
1717 /* Purely non-blocking */
1718 bytes_read = 0;
1719 }
1720
1721ret:
1722 hidapi_thread_mutex_unlock(&dev->thread_state);
1723 hidapi_thread_cleanup_pop(0);
1724
1725 return bytes_read;
1726}
1727
1728int HID_API_EXPORT hid_read(hid_device *dev, unsigned char *data, size_t length)
1729{
1730 return hid_read_timeout(dev, data, length, dev->blocking ? -1 : 0);
1731}
1732
1733int HID_API_EXPORT hid_set_nonblocking(hid_device *dev, int nonblock)
1734{
1735 dev->blocking = !nonblock;
1736
1737 return 0;
1738}
1739
1740
1741int HID_API_EXPORT hid_send_feature_report(hid_device *dev, const unsigned char *data, size_t length)
1742{
1743 int res = -1;
1744 int skipped_report_id = 0;
1745 int report_number = data[0];
1746
1747 if (report_number == 0x0) {
1748 data++;
1749 length--;
1750 skipped_report_id = 1;
1751 }
1752
1753 res = libusb_control_transfer(dev->device_handle,
1754 LIBUSB_REQUEST_TYPE_CLASS|LIBUSB_RECIPIENT_INTERFACE|LIBUSB_ENDPOINT_OUT,
1755 0x09/*HID set_report*/,
1756 (3/*HID feature*/ << 8) | report_number,
1757 dev->interface,
1758 (unsigned char *)data, (uint16_t)length,
1759 1000/*timeout millis*/);
1760
1761 if (res < 0)
1762 return -1;
1763
1764 /* Account for the report ID */
1765 if (skipped_report_id)
1766 length++;
1767
1768 return (int) length;
1769}
1770
1771int HID_API_EXPORT hid_get_feature_report(hid_device *dev, unsigned char *data, size_t length)
1772{
1773 int res = -1;
1774 int skipped_report_id = 0;
1775 int report_number = data[0];
1776
1777 if (report_number == 0x0) {
1778 /* Offset the return buffer by 1, so that the report ID
1779 will remain in byte 0. */
1780 data++;
1781 length--;
1782 skipped_report_id = 1;
1783 }
1784 res = libusb_control_transfer(dev->device_handle,
1785 LIBUSB_REQUEST_TYPE_CLASS|LIBUSB_RECIPIENT_INTERFACE|LIBUSB_ENDPOINT_IN,
1786 0x01/*HID get_report*/,
1787 (3/*HID feature*/ << 8) | report_number,
1788 dev->interface,
1789 (unsigned char *)data, (uint16_t)length,
1790 1000/*timeout millis*/);
1791
1792 if (res < 0)
1793 return -1;
1794
1795 if (skipped_report_id)
1796 res++;
1797
1798 return res;
1799}
1800
1801int HID_API_EXPORT HID_API_CALL hid_get_input_report(hid_device *dev, unsigned char *data, size_t length)
1802{
1803 int res = -1;
1804 int skipped_report_id = 0;
1805 int report_number = data[0];
1806
1807 if (report_number == 0x0) {
1808 /* Offset the return buffer by 1, so that the report ID
1809 will remain in byte 0. */
1810 data++;
1811 length--;
1812 skipped_report_id = 1;
1813 }
1814 res = libusb_control_transfer(dev->device_handle,
1815 LIBUSB_REQUEST_TYPE_CLASS|LIBUSB_RECIPIENT_INTERFACE|LIBUSB_ENDPOINT_IN,
1816 0x01/*HID get_report*/,
1817 (1/*HID Input*/ << 8) | report_number,
1818 dev->interface,
1819 (unsigned char *)data, (uint16_t)length,
1820 1000/*timeout millis*/);
1821
1822 if (res < 0)
1823 return -1;
1824
1825 if (skipped_report_id)
1826 res++;
1827
1828 return res;
1829}
1830
1831void HID_API_EXPORT hid_close(hid_device *dev)
1832{
1833 if (!dev)
1834 return;
1835
1836 /* Cause read_thread() to stop. */
1837 dev->shutdown_thread = 1;
1838 libusb_cancel_transfer(dev->transfer);
1839
1840 /* Wait for read_thread() to end. */
1841 hidapi_thread_join(&dev->thread_state);
1842
1843 /* Clean up the Transfer objects allocated in read_thread(). */
1844 free(dev->transfer->buffer);
1845 dev->transfer->buffer = NULL;
1846 libusb_free_transfer(dev->transfer);
1847
1848 /* release the interface */
1849 libusb_release_interface(dev->device_handle, dev->interface);
1850
1851 /* reattach the kernel driver if it was detached */
1852#ifdef DETACH_KERNEL_DRIVER
1853 if (dev->is_driver_detached) {
1854 int res = libusb_attach_kernel_driver(dev->device_handle, dev->interface);
1855 if (res < 0)
1856 LOG("Failed to reattach the driver to kernel.\n");
1857 }
1858#endif
1859
1860 /* Close the handle */
1861 libusb_close(dev->device_handle);
1862
1863 /* Clear out the queue of received reports. */
1864 hidapi_thread_mutex_lock(&dev->thread_state);
1865 while (dev->input_reports) {
1866 return_data(dev, NULL, 0);
1867 }
1868 hidapi_thread_mutex_unlock(&dev->thread_state);
1869
1870 free_hid_device(dev);
1871}
1872
1873
1874int HID_API_EXPORT_CALL hid_get_manufacturer_string(hid_device *dev, wchar_t *string, size_t maxlen)
1875{
1876 return hid_get_indexed_string(dev, dev->manufacturer_index, string, maxlen);
1877}
1878
1879int HID_API_EXPORT_CALL hid_get_product_string(hid_device *dev, wchar_t *string, size_t maxlen)
1880{
1881 return hid_get_indexed_string(dev, dev->product_index, string, maxlen);
1882}
1883
1884int HID_API_EXPORT_CALL hid_get_serial_number_string(hid_device *dev, wchar_t *string, size_t maxlen)
1885{
1886 return hid_get_indexed_string(dev, dev->serial_index, string, maxlen);
1887}
1888
1889HID_API_EXPORT struct hid_device_info *HID_API_CALL hid_get_device_info(hid_device *dev) {
1890 if (!dev->device_info) {
1891 struct libusb_device_descriptor desc;
1892 libusb_device *usb_device = libusb_get_device(dev->device_handle);
1893 libusb_get_device_descriptor(usb_device, &desc);
1894
1895 dev->device_info = create_device_info_for_device(usb_device, dev->device_handle, &desc, dev->config_number, dev->interface, dev->interface_class, dev->interface_subclass, dev->interface_protocol);
1896 // device error already set by create_device_info_for_device, if any
1897
1898 if (dev->device_info) {
1899 fill_device_info_usage(dev->device_info, dev->device_handle, dev->interface, dev->report_descriptor_size);
1900 }
1901 }
1902
1903 return dev->device_info;
1904}
1905
1906int HID_API_EXPORT_CALL hid_get_indexed_string(hid_device *dev, int string_index, wchar_t *string, size_t maxlen)
1907{
1908 wchar_t *str;
1909
1910 str = get_usb_string(dev->device_handle, string_index);
1911 if (str) {
1912 wcsncpy(string, str, maxlen);
1913 string[maxlen-1] = L'\0';
1914 free(str);
1915 return 0;
1916 }
1917 else
1918 return -1;
1919}
1920
1921
1922int HID_API_EXPORT_CALL hid_get_report_descriptor(hid_device *dev, unsigned char *buf, size_t buf_size)
1923{
1924 return hid_get_report_descriptor_libusb(dev->device_handle, dev->interface, dev->report_descriptor_size, buf, buf_size);
1925}
1926
1927
1928HID_API_EXPORT const wchar_t * HID_API_CALL hid_error(hid_device *dev)
1929{
1930 (void)dev;
1931 return L"hid_error is not implemented yet";
1932}
1933
1934
1935struct lang_map_entry {
1936 const char *name;
1937 const char *string_code;
1938 uint16_t usb_code;
1939};
1940
1941#define LANG(name,code,usb_code) { name, code, usb_code }
1942static struct lang_map_entry lang_map[] = {
1943 LANG("Afrikaans", "af", 0x0436),
1944 LANG("Albanian", "sq", 0x041C),
1945 LANG("Arabic - United Arab Emirates", "ar_ae", 0x3801),
1946 LANG("Arabic - Bahrain", "ar_bh", 0x3C01),
1947 LANG("Arabic - Algeria", "ar_dz", 0x1401),
1948 LANG("Arabic - Egypt", "ar_eg", 0x0C01),
1949 LANG("Arabic - Iraq", "ar_iq", 0x0801),
1950 LANG("Arabic - Jordan", "ar_jo", 0x2C01),
1951 LANG("Arabic - Kuwait", "ar_kw", 0x3401),
1952 LANG("Arabic - Lebanon", "ar_lb", 0x3001),
1953 LANG("Arabic - Libya", "ar_ly", 0x1001),
1954 LANG("Arabic - Morocco", "ar_ma", 0x1801),
1955 LANG("Arabic - Oman", "ar_om", 0x2001),
1956 LANG("Arabic - Qatar", "ar_qa", 0x4001),
1957 LANG("Arabic - Saudi Arabia", "ar_sa", 0x0401),
1958 LANG("Arabic - Syria", "ar_sy", 0x2801),
1959 LANG("Arabic - Tunisia", "ar_tn", 0x1C01),
1960 LANG("Arabic - Yemen", "ar_ye", 0x2401),
1961 LANG("Armenian", "hy", 0x042B),
1962 LANG("Azeri - Latin", "az_az", 0x042C),
1963 LANG("Azeri - Cyrillic", "az_az", 0x082C),
1964 LANG("Basque", "eu", 0x042D),
1965 LANG("Belarusian", "be", 0x0423),
1966 LANG("Bulgarian", "bg", 0x0402),
1967 LANG("Catalan", "ca", 0x0403),
1968 LANG("Chinese - China", "zh_cn", 0x0804),
1969 LANG("Chinese - Hong Kong SAR", "zh_hk", 0x0C04),
1970 LANG("Chinese - Macau SAR", "zh_mo", 0x1404),
1971 LANG("Chinese - Singapore", "zh_sg", 0x1004),
1972 LANG("Chinese - Taiwan", "zh_tw", 0x0404),
1973 LANG("Croatian", "hr", 0x041A),
1974 LANG("Czech", "cs", 0x0405),
1975 LANG("Danish", "da", 0x0406),
1976 LANG("Dutch - Netherlands", "nl_nl", 0x0413),
1977 LANG("Dutch - Belgium", "nl_be", 0x0813),
1978 LANG("English - Australia", "en_au", 0x0C09),
1979 LANG("English - Belize", "en_bz", 0x2809),
1980 LANG("English - Canada", "en_ca", 0x1009),
1981 LANG("English - Caribbean", "en_cb", 0x2409),
1982 LANG("English - Ireland", "en_ie", 0x1809),
1983 LANG("English - Jamaica", "en_jm", 0x2009),
1984 LANG("English - New Zealand", "en_nz", 0x1409),
1985 LANG("English - Philippines", "en_ph", 0x3409),
1986 LANG("English - Southern Africa", "en_za", 0x1C09),
1987 LANG("English - Trinidad", "en_tt", 0x2C09),
1988 LANG("English - Great Britain", "en_gb", 0x0809),
1989 LANG("English - United States", "en_us", 0x0409),
1990 LANG("Estonian", "et", 0x0425),
1991 LANG("Farsi", "fa", 0x0429),
1992 LANG("Finnish", "fi", 0x040B),
1993 LANG("Faroese", "fo", 0x0438),
1994 LANG("French - France", "fr_fr", 0x040C),
1995 LANG("French - Belgium", "fr_be", 0x080C),
1996 LANG("French - Canada", "fr_ca", 0x0C0C),
1997 LANG("French - Luxembourg", "fr_lu", 0x140C),
1998 LANG("French - Switzerland", "fr_ch", 0x100C),
1999 LANG("Gaelic - Ireland", "gd_ie", 0x083C),
2000 LANG("Gaelic - Scotland", "gd", 0x043C),
2001 LANG("German - Germany", "de_de", 0x0407),
2002 LANG("German - Austria", "de_at", 0x0C07),
2003 LANG("German - Liechtenstein", "de_li", 0x1407),
2004 LANG("German - Luxembourg", "de_lu", 0x1007),
2005 LANG("German - Switzerland", "de_ch", 0x0807),
2006 LANG("Greek", "el", 0x0408),
2007 LANG("Hebrew", "he", 0x040D),
2008 LANG("Hindi", "hi", 0x0439),
2009 LANG("Hungarian", "hu", 0x040E),
2010 LANG("Icelandic", "is", 0x040F),
2011 LANG("Indonesian", "id", 0x0421),
2012 LANG("Italian - Italy", "it_it", 0x0410),
2013 LANG("Italian - Switzerland", "it_ch", 0x0810),
2014 LANG("Japanese", "ja", 0x0411),
2015 LANG("Korean", "ko", 0x0412),
2016 LANG("Latvian", "lv", 0x0426),
2017 LANG("Lithuanian", "lt", 0x0427),
2018 LANG("F.Y.R.O. Macedonia", "mk", 0x042F),
2019 LANG("Malay - Malaysia", "ms_my", 0x043E),
2020 LANG("Malay – Brunei", "ms_bn", 0x083E),
2021 LANG("Maltese", "mt", 0x043A),
2022 LANG("Marathi", "mr", 0x044E),
2023 LANG("Norwegian - Bokml", "no_no", 0x0414),
2024 LANG("Norwegian - Nynorsk", "no_no", 0x0814),
2025 LANG("Polish", "pl", 0x0415),
2026 LANG("Portuguese - Portugal", "pt_pt", 0x0816),
2027 LANG("Portuguese - Brazil", "pt_br", 0x0416),
2028 LANG("Raeto-Romance", "rm", 0x0417),
2029 LANG("Romanian - Romania", "ro", 0x0418),
2030 LANG("Romanian - Republic of Moldova", "ro_mo", 0x0818),
2031 LANG("Russian", "ru", 0x0419),
2032 LANG("Russian - Republic of Moldova", "ru_mo", 0x0819),
2033 LANG("Sanskrit", "sa", 0x044F),
2034 LANG("Serbian - Cyrillic", "sr_sp", 0x0C1A),
2035 LANG("Serbian - Latin", "sr_sp", 0x081A),
2036 LANG("Setsuana", "tn", 0x0432),
2037 LANG("Slovenian", "sl", 0x0424),
2038 LANG("Slovak", "sk", 0x041B),
2039 LANG("Sorbian", "sb", 0x042E),
2040 LANG("Spanish - Spain (Traditional)", "es_es", 0x040A),
2041 LANG("Spanish - Argentina", "es_ar", 0x2C0A),
2042 LANG("Spanish - Bolivia", "es_bo", 0x400A),
2043 LANG("Spanish - Chile", "es_cl", 0x340A),
2044 LANG("Spanish - Colombia", "es_co", 0x240A),
2045 LANG("Spanish - Costa Rica", "es_cr", 0x140A),
2046 LANG("Spanish - Dominican Republic", "es_do", 0x1C0A),
2047 LANG("Spanish - Ecuador", "es_ec", 0x300A),
2048 LANG("Spanish - Guatemala", "es_gt", 0x100A),
2049 LANG("Spanish - Honduras", "es_hn", 0x480A),
2050 LANG("Spanish - Mexico", "es_mx", 0x080A),
2051 LANG("Spanish - Nicaragua", "es_ni", 0x4C0A),
2052 LANG("Spanish - Panama", "es_pa", 0x180A),
2053 LANG("Spanish - Peru", "es_pe", 0x280A),
2054 LANG("Spanish - Puerto Rico", "es_pr", 0x500A),
2055 LANG("Spanish - Paraguay", "es_py", 0x3C0A),
2056 LANG("Spanish - El Salvador", "es_sv", 0x440A),
2057 LANG("Spanish - Uruguay", "es_uy", 0x380A),
2058 LANG("Spanish - Venezuela", "es_ve", 0x200A),
2059 LANG("Southern Sotho", "st", 0x0430),
2060 LANG("Swahili", "sw", 0x0441),
2061 LANG("Swedish - Sweden", "sv_se", 0x041D),
2062 LANG("Swedish - Finland", "sv_fi", 0x081D),
2063 LANG("Tamil", "ta", 0x0449),
2064 LANG("Tatar", "tt", 0X0444),
2065 LANG("Thai", "th", 0x041E),
2066 LANG("Turkish", "tr", 0x041F),
2067 LANG("Tsonga", "ts", 0x0431),
2068 LANG("Ukrainian", "uk", 0x0422),
2069 LANG("Urdu", "ur", 0x0420),
2070 LANG("Uzbek - Cyrillic", "uz_uz", 0x0843),
2071 LANG("Uzbek – Latin", "uz_uz", 0x0443),
2072 LANG("Vietnamese", "vi", 0x042A),
2073 LANG("Xhosa", "xh", 0x0434),
2074 LANG("Yiddish", "yi", 0x043D),
2075 LANG("Zulu", "zu", 0x0435),
2076 LANG(NULL, NULL, 0x0),
2077};
2078
2079uint16_t get_usb_code_for_current_locale(void)
2080{
2081 char *locale;
2082 char search_string[64];
2083 char *ptr;
2084 struct lang_map_entry *lang;
2085
2086 /* Get the current locale. */
2087 locale = setlocale(0, NULL);
2088 if (!locale)
2089 return 0x0;
2090
2091 /* Make a copy of the current locale string. */
2092 strncpy(search_string, locale, sizeof(search_string)-1);
2093 search_string[sizeof(search_string)-1] = '\0';
2094
2095 /* Chop off the encoding part, and make it lower case. */
2096 ptr = search_string;
2097 while (*ptr) {
2098 *ptr = tolower(*ptr);
2099 if (*ptr == '.') {
2100 *ptr = '\0';
2101 break;
2102 }
2103 ptr++;
2104 }
2105
2106 /* Find the entry which matches the string code of our locale. */
2107 lang = lang_map;
2108 while (lang->string_code) {
2109 if (!strcmp(lang->string_code, search_string)) {
2110 return lang->usb_code;
2111 }
2112 lang++;
2113 }
2114
2115 /* There was no match. Find with just the language only. */
2116 /* Chop off the variant. Chop it off at the '_'. */
2117 ptr = search_string;
2118 while (*ptr) {
2119 *ptr = tolower(*ptr);
2120 if (*ptr == '_') {
2121 *ptr = '\0';
2122 break;
2123 }
2124 ptr++;
2125 }
2126
2127#if 0 /* TODO: Do we need this? */
2128 /* Find the entry which matches the string code of our language. */
2129 lang = lang_map;
2130 while (lang->string_code) {
2131 if (!strcmp(lang->string_code, search_string)) {
2132 return lang->usb_code;
2133 }
2134 lang++;
2135 }
2136#endif
2137
2138 /* Found nothing. */
2139 return 0x0;
2140}
2141
2142#ifdef __cplusplus
2143}
2144#endif