38 #include <sys/types.h> 41 #include <sys/ioctl.h> 42 #include <sys/utsname.h> 52 #include "../fcdhid/hidapi.h" 59 #define LOG(...) fprintf(stderr, __VA_ARGS__) 61 #define LOG(...) do {} while (0) 65 #define DETACH_KERNEL_DRIVER 124 static libusb_context *usb_context = NULL;
127 static int return_data(
hid_device *dev,
unsigned char *
data,
size_t length);
134 pthread_mutex_init(&dev->
mutex, NULL);
135 pthread_cond_init(&dev->
condition, NULL);
136 pthread_barrier_init(&dev->
barrier, NULL, 2);
144 pthread_barrier_destroy(&dev->
barrier);
146 pthread_mutex_destroy(&dev->
mutex);
154 static void register_error(
hid_device *device,
const char *op)
160 #ifdef INVASIVE_GET_USAGE 166 if (cur + num_bytes >= len)
171 else if (num_bytes == 1) {
174 else if (num_bytes == 2) {
175 return (rpt[cur+2] * 256 + rpt[cur+1]);
177 else if (num_bytes == 4) {
178 return (rpt[cur+4] * 0x01000000 +
179 rpt[cur+3] * 0x00010000 +
180 rpt[cur+2] * 0x00000100 +
181 rpt[cur+1] * 0x00000001);
191 static int get_usage(
uint8_t *report_descriptor,
size_t size,
192 unsigned short *usage_page,
unsigned short *usage)
196 int data_len, key_size;
197 int usage_found = 0, usage_page_found = 0;
200 int key = report_descriptor[
i];
201 int key_cmd = key & 0xfc;
205 if ((key & 0xf0) == 0xf0) {
211 data_len = report_descriptor[i+1];
222 size_code = key & 0x3;
227 data_len = size_code;
240 if (key_cmd == 0x4) {
241 *usage_page = get_bytes(report_descriptor, size, data_len, i);
242 usage_page_found = 1;
245 if (key_cmd == 0x8) {
246 *usage = get_bytes(report_descriptor, size, data_len, i);
251 if (usage_page_found && usage_found)
255 i += data_len + key_size;
270 static inline int libusb_get_string_descriptor(libusb_device_handle *dev,
272 unsigned char *
data,
int length)
274 return libusb_control_transfer(dev,
275 LIBUSB_ENDPOINT_IN | 0x0,
276 LIBUSB_REQUEST_GET_DESCRIPTOR,
277 (LIBUSB_DT_STRING << 8) | descriptor_index,
278 lang_id, data, (
uint16_t) length, 1000);
286 static uint16_t get_first_language(libusb_device_handle *dev)
292 len = libusb_get_string_descriptor(dev,
303 static int is_language_supported(libusb_device_handle *dev,
uint16_t lang)
310 len = libusb_get_string_descriptor(dev,
321 for (i = 1; i <
len; i++) {
333 static wchar_t *get_usb_string(libusb_device_handle *dev,
uint8_t idx)
355 if (!is_language_supported(dev, lang))
356 lang = get_first_language(dev);
359 len = libusb_get_string_descriptor(dev,
371 ic = iconv_open(
"WCHAR_T",
"UTF-16LE");
372 if (ic == (iconv_t)-1) {
373 LOG(
"iconv_open() failed\n");
381 outptr = (
char*) wbuf;
382 outbytes =
sizeof(wbuf);
383 res = iconv(ic, &inptr, &inbytes, &outptr, &outbytes);
384 if (res == (
size_t)-1) {
385 LOG(
"iconv() failed\n");
390 wbuf[
sizeof(wbuf)/
sizeof(wbuf[0])-1] = 0x00000000;
391 if (outbytes >=
sizeof(wbuf[0]))
392 *((
wchar_t*)outptr) = 0x00000000;
403 static char *make_path(libusb_device *dev,
int interface_number)
406 snprintf(str,
sizeof(str),
"%04x:%04x:%02x",
407 libusb_get_bus_number(dev),
408 libusb_get_device_address(dev),
410 str[
sizeof(str)-1] =
'\0';
422 if (libusb_init(&usb_context))
426 locale = setlocale(LC_CTYPE, NULL);
428 setlocale(LC_CTYPE,
"");
437 libusb_exit(usb_context);
446 libusb_device **devs;
448 libusb_device_handle *handle;
458 num_devs = libusb_get_device_list(usb_context, &devs);
461 while ((dev = devs[i++]) != NULL) {
462 struct libusb_device_descriptor desc;
463 struct libusb_config_descriptor *conf_desc = NULL;
465 int interface_num = 0;
467 int res = libusb_get_device_descriptor(dev, &desc);
468 unsigned short dev_vid = desc.idVendor;
469 unsigned short dev_pid = desc.idProduct;
471 res = libusb_get_active_config_descriptor(dev, &conf_desc);
473 libusb_get_config_descriptor(dev, 0, &conf_desc);
475 for (j = 0; j < conf_desc->bNumInterfaces; j++) {
476 const struct libusb_interface *intf = &conf_desc->interface[j];
477 for (k = 0; k < intf->num_altsetting; k++) {
478 const struct libusb_interface_descriptor *intf_desc;
479 intf_desc = &intf->altsetting[k];
480 if (intf_desc->bInterfaceClass == LIBUSB_CLASS_HID) {
481 interface_num = intf_desc->bInterfaceNumber;
484 if ((vendor_id == 0x0 || vendor_id == dev_vid) &&
485 (product_id == 0x0 || product_id == dev_pid)) {
499 cur_dev->
next = NULL;
500 cur_dev->
path = make_path(dev, interface_num);
502 res = libusb_open(dev, &handle);
506 if (desc.iSerialNumber > 0)
508 get_usb_string(handle, desc.iSerialNumber);
511 if (desc.iManufacturer > 0)
513 get_usb_string(handle, desc.iManufacturer);
514 if (desc.iProduct > 0)
516 get_usb_string(handle, desc.iProduct);
518 #ifdef INVASIVE_GET_USAGE 535 unsigned char data[256];
536 #ifdef DETACH_KERNEL_DRIVER 539 res = libusb_kernel_driver_active(handle, interface_num);
541 res = libusb_detach_kernel_driver(handle, interface_num);
543 LOG(
"Couldn't detach kernel driver, even though a kernel driver was attached.");
548 res = libusb_claim_interface(handle, interface_num);
551 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);
553 unsigned short page=0, usage=0;
556 get_usage(data, res, &page, &usage);
561 LOG(
"libusb_control_transfer() for getting the HID report failed with %d\n", res);
564 res = libusb_release_interface(handle, interface_num);
566 LOG(
"Can't release the interface.\n");
569 LOG(
"Can't claim interface %d\n", res);
570 #ifdef DETACH_KERNEL_DRIVER 573 res = libusb_attach_kernel_driver(handle, interface_num);
575 LOG(
"Couldn't re-attach kernel driver.\n");
581 libusb_close(handle);
596 libusb_free_config_descriptor(conf_desc);
600 libusb_free_device_list(devs, 1);
622 const char *path_to_open = NULL;
632 path_to_open = cur_dev->
path;
637 path_to_open = cur_dev->
path;
641 cur_dev = cur_dev->
next;
654 static void read_callback(
struct libusb_transfer *transfer)
659 if (transfer->status == LIBUSB_TRANSFER_COMPLETED) {
662 rpt->
data = malloc(transfer->actual_length);
663 memcpy(rpt->
data, transfer->buffer, transfer->actual_length);
664 rpt->
len = transfer->actual_length;
667 pthread_mutex_lock(&dev->
mutex);
679 while (cur->
next != NULL) {
688 if (num_queued > 30) {
689 return_data(dev, NULL, 0);
692 pthread_mutex_unlock(&dev->
mutex);
694 else if (transfer->status == LIBUSB_TRANSFER_CANCELLED) {
699 else if (transfer->status == LIBUSB_TRANSFER_NO_DEVICE) {
704 else if (transfer->status == LIBUSB_TRANSFER_TIMED_OUT) {
708 LOG(
"Unknown transfer code: %d\n", transfer->status);
712 res = libusb_submit_transfer(transfer);
714 LOG(
"Unable to submit URB. libusb error code: %d\n", res);
721 static void *read_thread(
void *param)
728 buf = malloc(length);
729 dev->
transfer = libusb_alloc_transfer(0);
730 libusb_fill_interrupt_transfer(dev->
transfer,
741 libusb_submit_transfer(dev->
transfer);
744 pthread_barrier_wait(&dev->
barrier);
749 res = libusb_handle_events(usb_context);
752 LOG(
"read_thread(): libusb reports error # %d\n", res);
755 if (res != LIBUSB_ERROR_BUSY &&
756 res != LIBUSB_ERROR_TIMEOUT &&
757 res != LIBUSB_ERROR_OVERFLOW &&
758 res != LIBUSB_ERROR_INTERRUPTED) {
766 libusb_cancel_transfer(dev->
transfer);
769 libusb_handle_events_completed(usb_context, &dev->
cancelled);
776 pthread_mutex_lock(&dev->
mutex);
778 pthread_mutex_unlock(&dev->
mutex);
796 libusb_device **devs;
797 libusb_device *usb_dev;
805 dev = new_hid_device();
807 libusb_get_device_list(usb_context, &devs);
808 while ((usb_dev = devs[d++]) != NULL) {
809 struct libusb_device_descriptor desc;
810 struct libusb_config_descriptor *conf_desc = NULL;
812 libusb_get_device_descriptor(usb_dev, &desc);
814 if (libusb_get_active_config_descriptor(usb_dev, &conf_desc) < 0)
816 for (j = 0; j < conf_desc->bNumInterfaces; j++) {
817 const struct libusb_interface *intf = &conf_desc->interface[j];
818 for (k = 0; k < intf->num_altsetting; k++) {
819 const struct libusb_interface_descriptor *intf_desc;
820 intf_desc = &intf->altsetting[k];
821 if (intf_desc->bInterfaceClass == LIBUSB_CLASS_HID) {
822 char *dev_path = make_path(usb_dev, intf_desc->bInterfaceNumber);
823 if (!strcmp(dev_path, path)) {
829 LOG(
"can't open device\n");
834 #ifdef DETACH_KERNEL_DRIVER 837 if (libusb_kernel_driver_active(dev->
device_handle, intf_desc->bInterfaceNumber) == 1) {
838 res = libusb_detach_kernel_driver(dev->
device_handle, intf_desc->bInterfaceNumber);
841 LOG(
"Unable to detach Kernel Driver\n");
848 res = libusb_claim_interface(dev->
device_handle, intf_desc->bInterfaceNumber);
850 LOG(
"can't claim interface %d: %d\n", intf_desc->bInterfaceNumber, res);
863 dev->
interface = intf_desc->bInterfaceNumber;
867 for (i = 0; i < intf_desc->bNumEndpoints; i++) {
868 const struct libusb_endpoint_descriptor *ep
869 = &intf_desc->endpoint[
i];
874 (ep->bmAttributes & LIBUSB_TRANSFER_TYPE_MASK)
875 == LIBUSB_TRANSFER_TYPE_INTERRUPT;
877 (ep->bEndpointAddress & LIBUSB_ENDPOINT_DIR_MASK)
878 == LIBUSB_ENDPOINT_OUT;
880 (ep->bEndpointAddress & LIBUSB_ENDPOINT_DIR_MASK)
881 == LIBUSB_ENDPOINT_IN;
885 is_interrupt && is_input) {
891 is_interrupt && is_output) {
897 pthread_create(&dev->
thread, NULL, read_thread, dev);
900 pthread_barrier_wait(&dev->
barrier);
907 libusb_free_config_descriptor(conf_desc);
911 libusb_free_device_list(devs, 1);
919 free_hid_device(dev);
928 int report_number = data[0];
929 int skipped_report_id = 0;
931 if (report_number == 0x0) {
934 skipped_report_id = 1;
941 LIBUSB_REQUEST_TYPE_CLASS|LIBUSB_RECIPIENT_INTERFACE|LIBUSB_ENDPOINT_OUT,
943 (2 << 8) | report_number,
945 (
unsigned char *)data, length,
951 if (skipped_report_id)
961 (
unsigned char*)data,
963 &actual_length, 1000);
968 if (skipped_report_id)
971 return actual_length;
977 static int return_data(
hid_device *dev,
unsigned char *data,
size_t length)
982 size_t len = (length < rpt->
len)? length: rpt->
len;
984 memcpy(data, rpt->
data, len);
991 static void cleanup_mutex(
void *param)
994 pthread_mutex_unlock(&dev->
mutex);
1000 int bytes_read = -1;
1005 LOG(
"transferred: %d\n", transferred);
1009 pthread_mutex_lock(&dev->
mutex);
1010 pthread_cleanup_push(&cleanup_mutex, dev);
1015 bytes_read = return_data(dev, data, length);
1026 if (milliseconds == -1) {
1032 bytes_read = return_data(dev, data, length);
1035 else if (milliseconds > 0) {
1039 clock_gettime(CLOCK_REALTIME, &ts);
1040 ts.tv_sec += milliseconds / 1000;
1041 ts.tv_nsec += (milliseconds % 1000) * 1000000;
1042 if (ts.tv_nsec >= 1000000000L) {
1044 ts.tv_nsec -= 1000000000L;
1051 bytes_read = return_data(dev, data, length);
1059 else if (res == ETIMEDOUT) {
1077 pthread_mutex_unlock(&dev->
mutex);
1078 pthread_cleanup_pop(0);
1099 int skipped_report_id = 0;
1100 int report_number = data[0];
1102 if (report_number == 0x0) {
1105 skipped_report_id = 1;
1109 LIBUSB_REQUEST_TYPE_CLASS|LIBUSB_RECIPIENT_INTERFACE|LIBUSB_ENDPOINT_OUT,
1111 (3 << 8) | report_number,
1113 (
unsigned char *)data, length,
1120 if (skipped_report_id)
1129 int skipped_report_id = 0;
1130 int report_number = data[0];
1132 if (report_number == 0x0) {
1137 skipped_report_id = 1;
1140 LIBUSB_REQUEST_TYPE_CLASS|LIBUSB_RECIPIENT_INTERFACE|LIBUSB_ENDPOINT_IN,
1142 (3 << 8) | report_number,
1144 (
unsigned char *)data, length,
1150 if (skipped_report_id)
1164 libusb_cancel_transfer(dev->
transfer);
1167 pthread_join(dev->
thread, NULL);
1171 libusb_free_transfer(dev->
transfer);
1180 pthread_mutex_lock(&dev->
mutex);
1182 return_data(dev, NULL, 0);
1184 pthread_mutex_unlock(&dev->
mutex);
1186 free_hid_device(dev);
1211 wcsncpy(
string, str, maxlen);
1212 string[maxlen-1] = L
'\0';
1233 #define LANG(name,code,usb_code) { name, code, usb_code } 1235 LANG(
"Afrikaans",
"af", 0x0436),
1236 LANG(
"Albanian",
"sq", 0x041C),
1237 LANG(
"Arabic - United Arab Emirates",
"ar_ae", 0x3801),
1238 LANG(
"Arabic - Bahrain",
"ar_bh", 0x3C01),
1239 LANG(
"Arabic - Algeria",
"ar_dz", 0x1401),
1240 LANG(
"Arabic - Egypt",
"ar_eg", 0x0C01),
1241 LANG(
"Arabic - Iraq",
"ar_iq", 0x0801),
1242 LANG(
"Arabic - Jordan",
"ar_jo", 0x2C01),
1243 LANG(
"Arabic - Kuwait",
"ar_kw", 0x3401),
1244 LANG(
"Arabic - Lebanon",
"ar_lb", 0x3001),
1245 LANG(
"Arabic - Libya",
"ar_ly", 0x1001),
1246 LANG(
"Arabic - Morocco",
"ar_ma", 0x1801),
1247 LANG(
"Arabic - Oman",
"ar_om", 0x2001),
1248 LANG(
"Arabic - Qatar",
"ar_qa", 0x4001),
1249 LANG(
"Arabic - Saudi Arabia",
"ar_sa", 0x0401),
1250 LANG(
"Arabic - Syria",
"ar_sy", 0x2801),
1251 LANG(
"Arabic - Tunisia",
"ar_tn", 0x1C01),
1252 LANG(
"Arabic - Yemen",
"ar_ye", 0x2401),
1253 LANG(
"Armenian",
"hy", 0x042B),
1254 LANG(
"Azeri - Latin",
"az_az", 0x042C),
1255 LANG(
"Azeri - Cyrillic",
"az_az", 0x082C),
1256 LANG(
"Basque",
"eu", 0x042D),
1257 LANG(
"Belarusian",
"be", 0x0423),
1258 LANG(
"Bulgarian",
"bg", 0x0402),
1259 LANG(
"Catalan",
"ca", 0x0403),
1260 LANG(
"Chinese - China",
"zh_cn", 0x0804),
1261 LANG(
"Chinese - Hong Kong SAR",
"zh_hk", 0x0C04),
1262 LANG(
"Chinese - Macau SAR",
"zh_mo", 0x1404),
1263 LANG(
"Chinese - Singapore",
"zh_sg", 0x1004),
1264 LANG(
"Chinese - Taiwan",
"zh_tw", 0x0404),
1265 LANG(
"Croatian",
"hr", 0x041A),
1266 LANG(
"Czech",
"cs", 0x0405),
1267 LANG(
"Danish",
"da", 0x0406),
1268 LANG(
"Dutch - Netherlands",
"nl_nl", 0x0413),
1269 LANG(
"Dutch - Belgium",
"nl_be", 0x0813),
1270 LANG(
"English - Australia",
"en_au", 0x0C09),
1271 LANG(
"English - Belize",
"en_bz", 0x2809),
1272 LANG(
"English - Canada",
"en_ca", 0x1009),
1273 LANG(
"English - Caribbean",
"en_cb", 0x2409),
1274 LANG(
"English - Ireland",
"en_ie", 0x1809),
1275 LANG(
"English - Jamaica",
"en_jm", 0x2009),
1276 LANG(
"English - New Zealand",
"en_nz", 0x1409),
1277 LANG(
"English - Phillippines",
"en_ph", 0x3409),
1278 LANG(
"English - Southern Africa",
"en_za", 0x1C09),
1279 LANG(
"English - Trinidad",
"en_tt", 0x2C09),
1280 LANG(
"English - Great Britain",
"en_gb", 0x0809),
1281 LANG(
"English - United States",
"en_us", 0x0409),
1282 LANG(
"Estonian",
"et", 0x0425),
1283 LANG(
"Farsi",
"fa", 0x0429),
1284 LANG(
"Finnish",
"fi", 0x040B),
1285 LANG(
"Faroese",
"fo", 0x0438),
1286 LANG(
"French - France",
"fr_fr", 0x040C),
1287 LANG(
"French - Belgium",
"fr_be", 0x080C),
1288 LANG(
"French - Canada",
"fr_ca", 0x0C0C),
1289 LANG(
"French - Luxembourg",
"fr_lu", 0x140C),
1290 LANG(
"French - Switzerland",
"fr_ch", 0x100C),
1291 LANG(
"Gaelic - Ireland",
"gd_ie", 0x083C),
1292 LANG(
"Gaelic - Scotland",
"gd", 0x043C),
1293 LANG(
"German - Germany",
"de_de", 0x0407),
1294 LANG(
"German - Austria",
"de_at", 0x0C07),
1295 LANG(
"German - Liechtenstein",
"de_li", 0x1407),
1296 LANG(
"German - Luxembourg",
"de_lu", 0x1007),
1297 LANG(
"German - Switzerland",
"de_ch", 0x0807),
1298 LANG(
"Greek",
"el", 0x0408),
1299 LANG(
"Hebrew",
"he", 0x040D),
1300 LANG(
"Hindi",
"hi", 0x0439),
1301 LANG(
"Hungarian",
"hu", 0x040E),
1302 LANG(
"Icelandic",
"is", 0x040F),
1303 LANG(
"Indonesian",
"id", 0x0421),
1304 LANG(
"Italian - Italy",
"it_it", 0x0410),
1305 LANG(
"Italian - Switzerland",
"it_ch", 0x0810),
1306 LANG(
"Japanese",
"ja", 0x0411),
1307 LANG(
"Korean",
"ko", 0x0412),
1308 LANG(
"Latvian",
"lv", 0x0426),
1309 LANG(
"Lithuanian",
"lt", 0x0427),
1310 LANG(
"F.Y.R.O. Macedonia",
"mk", 0x042F),
1311 LANG(
"Malay - Malaysia",
"ms_my", 0x043E),
1312 LANG(
"Malay – Brunei",
"ms_bn", 0x083E),
1313 LANG(
"Maltese",
"mt", 0x043A),
1314 LANG(
"Marathi",
"mr", 0x044E),
1315 LANG(
"Norwegian - Bokml",
"no_no", 0x0414),
1316 LANG(
"Norwegian - Nynorsk",
"no_no", 0x0814),
1317 LANG(
"Polish",
"pl", 0x0415),
1318 LANG(
"Portuguese - Portugal",
"pt_pt", 0x0816),
1319 LANG(
"Portuguese - Brazil",
"pt_br", 0x0416),
1320 LANG(
"Raeto-Romance",
"rm", 0x0417),
1321 LANG(
"Romanian - Romania",
"ro", 0x0418),
1322 LANG(
"Romanian - Republic of Moldova",
"ro_mo", 0x0818),
1323 LANG(
"Russian",
"ru", 0x0419),
1324 LANG(
"Russian - Republic of Moldova",
"ru_mo", 0x0819),
1325 LANG(
"Sanskrit",
"sa", 0x044F),
1326 LANG(
"Serbian - Cyrillic",
"sr_sp", 0x0C1A),
1327 LANG(
"Serbian - Latin",
"sr_sp", 0x081A),
1328 LANG(
"Setsuana",
"tn", 0x0432),
1329 LANG(
"Slovenian",
"sl", 0x0424),
1330 LANG(
"Slovak",
"sk", 0x041B),
1331 LANG(
"Sorbian",
"sb", 0x042E),
1332 LANG(
"Spanish - Spain (Traditional)",
"es_es", 0x040A),
1333 LANG(
"Spanish - Argentina",
"es_ar", 0x2C0A),
1334 LANG(
"Spanish - Bolivia",
"es_bo", 0x400A),
1335 LANG(
"Spanish - Chile",
"es_cl", 0x340A),
1336 LANG(
"Spanish - Colombia",
"es_co", 0x240A),
1337 LANG(
"Spanish - Costa Rica",
"es_cr", 0x140A),
1338 LANG(
"Spanish - Dominican Republic",
"es_do", 0x1C0A),
1339 LANG(
"Spanish - Ecuador",
"es_ec", 0x300A),
1340 LANG(
"Spanish - Guatemala",
"es_gt", 0x100A),
1341 LANG(
"Spanish - Honduras",
"es_hn", 0x480A),
1342 LANG(
"Spanish - Mexico",
"es_mx", 0x080A),
1343 LANG(
"Spanish - Nicaragua",
"es_ni", 0x4C0A),
1344 LANG(
"Spanish - Panama",
"es_pa", 0x180A),
1345 LANG(
"Spanish - Peru",
"es_pe", 0x280A),
1346 LANG(
"Spanish - Puerto Rico",
"es_pr", 0x500A),
1347 LANG(
"Spanish - Paraguay",
"es_py", 0x3C0A),
1348 LANG(
"Spanish - El Salvador",
"es_sv", 0x440A),
1349 LANG(
"Spanish - Uruguay",
"es_uy", 0x380A),
1350 LANG(
"Spanish - Venezuela",
"es_ve", 0x200A),
1351 LANG(
"Southern Sotho",
"st", 0x0430),
1352 LANG(
"Swahili",
"sw", 0x0441),
1353 LANG(
"Swedish - Sweden",
"sv_se", 0x041D),
1354 LANG(
"Swedish - Finland",
"sv_fi", 0x081D),
1355 LANG(
"Tamil",
"ta", 0x0449),
1356 LANG(
"Tatar",
"tt", 0X0444),
1357 LANG(
"Thai",
"th", 0x041E),
1358 LANG(
"Turkish",
"tr", 0x041F),
1359 LANG(
"Tsonga",
"ts", 0x0431),
1360 LANG(
"Ukrainian",
"uk", 0x0422),
1361 LANG(
"Urdu",
"ur", 0x0420),
1362 LANG(
"Uzbek - Cyrillic",
"uz_uz", 0x0843),
1363 LANG(
"Uzbek – Latin",
"uz_uz", 0x0443),
1364 LANG(
"Vietnamese",
"vi", 0x042A),
1365 LANG(
"Xhosa",
"xh", 0x0434),
1366 LANG(
"Yiddish",
"yi", 0x043D),
1367 LANG(
"Zulu",
"zu", 0x0435),
1368 LANG(NULL, NULL, 0x0),
1374 char search_string[64];
1379 locale = setlocale(0, NULL);
1384 strncpy(search_string, locale,
sizeof(search_string));
1385 search_string[
sizeof(search_string)-1] =
'\0';
1388 ptr = search_string;
1390 *ptr = tolower(*ptr);
1409 ptr = search_string;
1411 *ptr = tolower(*ptr);
hid_device * hid_open(unsigned short vendor_id, unsigned short product_id, const wchar_t *serial_number)
Open a HID device using a Vendor ID (VID), Product ID (PID) and optionally a serial number...
int HID_API_EXPORT_CALL hid_get_serial_number_string(hid_device *dev, wchar_t *string, size_t maxlen)
Get The Serial Number String from a HID device.
#define LANG(name, code, usb_code)
int HID_API_EXPORT hid_send_feature_report(hid_device *dev, const unsigned char *data, size_t length)
Send a Feature report to the device.
wchar_t * manufacturer_string
struct input_report * input_reports
void HID_API_EXPORT hid_close(hid_device *dev)
Close a HID device.
int HID_API_EXPORT hid_exit(void)
Finalize the HIDAPI library.
int HID_API_EXPORT hid_read(hid_device *dev, unsigned char *data, size_t length)
Read an Input report from a HID device.
struct libusb_transfer * transfer
struct hid_device_info * next
int HID_API_EXPORT_CALL hid_get_product_string(hid_device *dev, wchar_t *string, size_t maxlen)
Get The Product String from a HID device.
unsigned short product_id
int HID_API_EXPORT hid_get_feature_report(hid_device *dev, unsigned char *data, size_t length)
Get a feature report from a HID device.
libusb_device_handle * device_handle
hid_device *HID_API_EXPORT hid_open_path(const char *path)
Open a HID device by its path name.
uint16_t get_usb_code_for_current_locale(void)
int input_ep_max_packet_size
pthread_barrier_t barrier
struct hid_device_info HID_API_EXPORT * hid_enumerate(unsigned short vendor_id, unsigned short product_id)
Enumerate the HID Devices.
HID_API_EXPORT const wchar_t *HID_API_CALL hid_error(hid_device *dev)
Get a string describing the last error which occurred.
int HID_API_EXPORT_CALL hid_get_manufacturer_string(hid_device *dev, wchar_t *string, size_t maxlen)
Get The Manufacturer String from a HID device.
int HID_API_EXPORT hid_init(void)
Initialize the HIDAPI library.
int HID_API_EXPORT hid_read_timeout(hid_device *dev, unsigned char *data, size_t length, int milliseconds)
Read an Input report from a HID device with timeout.
int HID_API_EXPORT_CALL hid_get_indexed_string(hid_device *dev, int string_index, wchar_t *string, size_t maxlen)
Get a string from a HID device, based on its string index.
#define HID_API_EXPORT_CALL
unsigned short usage_page
void HID_API_EXPORT hid_free_enumeration(struct hid_device_info *devs)
Free an enumeration Linked List.
int HID_API_EXPORT hid_write(hid_device *dev, const unsigned char *data, size_t length)
Write an Output report to a HID device.
unsigned short release_number
int HID_API_EXPORT hid_set_nonblocking(hid_device *dev, int nonblock)
Set the device handle to be non-blocking.