41 #include <sys/types.h> 43 #include <sys/ioctl.h> 44 #include <sys/utsname.h> 50 #include <libusb-1.0/libusb.h> 53 #include "../fcdhid/hidapi.h" 60 #define LOG(...) fprintf(stderr, __VA_ARGS__) 62 #define LOG(...) do {} while (0) 66 #define DETACH_KERNEL_DRIVER 87 libusb_device_handle *device_handle;
92 int input_ep_max_packet_size;
98 int manufacturer_index;
107 pthread_mutex_t mutex;
108 pthread_cond_t condition;
109 pthread_barrier_t barrier;
112 struct libusb_transfer *transfer;
118 static libusb_context *usb_context = NULL;
121 static int return_data(
hid_device *dev,
unsigned char *
data,
size_t length);
128 pthread_mutex_init(&dev->
mutex, NULL);
129 pthread_cond_init(&dev->
condition, NULL);
130 pthread_barrier_init(&dev->
barrier, NULL, 2);
138 pthread_barrier_destroy(&dev->
barrier);
140 pthread_mutex_destroy(&dev->
mutex);
148 static void register_error(
hid_device *device,
const char *op)
154 #ifdef INVASIVE_GET_USAGE 160 if (cur + num_bytes >= len)
165 else if (num_bytes == 1) {
168 else if (num_bytes == 2) {
169 return (rpt[cur+2] * 256 + rpt[cur+1]);
171 else if (num_bytes == 4) {
172 return (rpt[cur+4] * 0x01000000 +
173 rpt[cur+3] * 0x00010000 +
174 rpt[cur+2] * 0x00000100 +
175 rpt[cur+1] * 0x00000001);
185 static int get_usage(
uint8_t *report_descriptor,
size_t size,
186 unsigned short *usage_page,
unsigned short *usage)
190 int data_len, key_size;
191 int usage_found = 0, usage_page_found = 0;
194 int key = report_descriptor[
i];
195 int key_cmd = key & 0xfc;
199 if ((key & 0xf0) == 0xf0) {
205 data_len = report_descriptor[i+1];
216 size_code = key & 0x3;
221 data_len = size_code;
234 if (key_cmd == 0x4) {
235 *usage_page = get_bytes(report_descriptor, size, data_len, i);
236 usage_page_found = 1;
239 if (key_cmd == 0x8) {
240 *usage = get_bytes(report_descriptor, size, data_len, i);
245 if (usage_page_found && usage_found)
249 i += data_len + key_size;
264 static inline int libusb_get_string_descriptor(libusb_device_handle *dev,
266 unsigned char *data,
int length)
268 return libusb_control_transfer(dev,
269 LIBUSB_ENDPOINT_IN | 0x0,
270 LIBUSB_REQUEST_GET_DESCRIPTOR,
271 (LIBUSB_DT_STRING << 8) | descriptor_index,
272 lang_id, data, (
uint16_t) length, 1000);
280 static uint16_t get_first_language(libusb_device_handle *dev)
286 len = libusb_get_string_descriptor(dev,
297 static int is_language_supported(libusb_device_handle *dev,
uint16_t lang)
304 len = libusb_get_string_descriptor(dev,
315 for (i = 1; i <
len; i++) {
327 static wchar_t *get_usb_string(libusb_device_handle *dev,
uint8_t idx)
349 if (!is_language_supported(dev, lang))
350 lang = get_first_language(dev);
353 len = libusb_get_string_descriptor(dev,
365 ic = iconv_open(
"WCHAR_T",
"UTF-16LE");
366 if (ic == (iconv_t)-1) {
367 LOG(
"iconv_open() failed\n");
375 outptr = (
char*) wbuf;
376 outbytes =
sizeof(wbuf);
377 res = iconv(ic, &inptr, &inbytes, &outptr, &outbytes);
378 if (res == (
size_t)-1) {
379 LOG(
"iconv() failed\n");
384 wbuf[
sizeof(wbuf)/
sizeof(wbuf[0])-1] = 0x00000000;
385 if (outbytes >=
sizeof(wbuf[0]))
386 *((
wchar_t*)outptr) = 0x00000000;
397 static char *make_path(libusb_device *dev,
int interface_number)
400 snprintf(str,
sizeof(str),
"%04x:%04x:%02x",
401 libusb_get_bus_number(dev),
402 libusb_get_device_address(dev),
404 str[
sizeof(str)-1] =
'\0';
416 if (libusb_init(&usb_context))
420 locale = setlocale(LC_CTYPE, NULL);
422 setlocale(LC_CTYPE,
"");
431 libusb_exit(usb_context);
440 libusb_device **devs;
442 libusb_device_handle *handle;
452 num_devs = libusb_get_device_list(usb_context, &devs);
455 while ((dev = devs[i++]) != NULL) {
456 struct libusb_device_descriptor desc;
457 struct libusb_config_descriptor *conf_desc = NULL;
459 int interface_num = 0;
461 int res = libusb_get_device_descriptor(dev, &desc);
462 unsigned short dev_vid = desc.idVendor;
463 unsigned short dev_pid = desc.idProduct;
465 res = libusb_get_active_config_descriptor(dev, &conf_desc);
467 libusb_get_config_descriptor(dev, 0, &conf_desc);
469 for (j = 0; j < conf_desc->bNumInterfaces; j++) {
470 const struct libusb_interface *intf = &conf_desc->interface[j];
471 for (k = 0; k < intf->num_altsetting; k++) {
472 const struct libusb_interface_descriptor *intf_desc;
473 intf_desc = &intf->altsetting[k];
474 if (intf_desc->bInterfaceClass == LIBUSB_CLASS_HID) {
475 interface_num = intf_desc->bInterfaceNumber;
478 if ((vendor_id == 0x0 || vendor_id == dev_vid) &&
479 (product_id == 0x0 || product_id == dev_pid)) {
493 cur_dev->
next = NULL;
494 cur_dev->
path = make_path(dev, interface_num);
496 res = libusb_open(dev, &handle);
500 if (desc.iSerialNumber > 0)
502 get_usb_string(handle, desc.iSerialNumber);
505 if (desc.iManufacturer > 0)
507 get_usb_string(handle, desc.iManufacturer);
508 if (desc.iProduct > 0)
510 get_usb_string(handle, desc.iProduct);
512 #ifdef INVASIVE_GET_USAGE 529 unsigned char data[256];
530 #ifdef DETACH_KERNEL_DRIVER 533 res = libusb_kernel_driver_active(handle, interface_num);
535 res = libusb_detach_kernel_driver(handle, interface_num);
537 LOG(
"Couldn't detach kernel driver, even though a kernel driver was attached.");
542 res = libusb_claim_interface(handle, interface_num);
545 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);
547 unsigned short page=0, usage=0;
550 get_usage(data, res, &page, &usage);
555 LOG(
"libusb_control_transfer() for getting the HID report failed with %d\n", res);
558 res = libusb_release_interface(handle, interface_num);
560 LOG(
"Can't release the interface.\n");
563 LOG(
"Can't claim interface %d\n", res);
564 #ifdef DETACH_KERNEL_DRIVER 567 res = libusb_attach_kernel_driver(handle, interface_num);
569 LOG(
"Couldn't re-attach kernel driver.\n");
575 libusb_close(handle);
590 libusb_free_config_descriptor(conf_desc);
594 libusb_free_device_list(devs, 1);
616 const char *path_to_open = NULL;
626 path_to_open = cur_dev->
path;
631 path_to_open = cur_dev->
path;
635 cur_dev = cur_dev->
next;
648 static void read_callback(
struct libusb_transfer *transfer)
653 if (transfer->status == LIBUSB_TRANSFER_COMPLETED) {
656 rpt->
data = (
unsigned char *)malloc(transfer->actual_length);
657 memcpy(rpt->
data, transfer->buffer, transfer->actual_length);
658 rpt->
len = transfer->actual_length;
661 pthread_mutex_lock(&dev->
mutex);
673 while (cur->
next != NULL) {
682 if (num_queued > 30) {
683 return_data(dev, NULL, 0);
686 pthread_mutex_unlock(&dev->
mutex);
688 else if (transfer->status == LIBUSB_TRANSFER_CANCELLED) {
693 else if (transfer->status == LIBUSB_TRANSFER_NO_DEVICE) {
698 else if (transfer->status == LIBUSB_TRANSFER_TIMED_OUT) {
702 LOG(
"Unknown transfer code: %d\n", transfer->status);
706 res = libusb_submit_transfer(transfer);
708 LOG(
"Unable to submit URB. libusb error code: %d\n", res);
715 static void *read_thread(
void *param)
722 buf = (
unsigned char *)malloc(length);
723 dev->
transfer = libusb_alloc_transfer(0);
724 libusb_fill_interrupt_transfer(dev->
transfer,
735 libusb_submit_transfer(dev->
transfer);
738 pthread_barrier_wait(&dev->
barrier);
743 res = libusb_handle_events(usb_context);
746 LOG(
"read_thread(): libusb reports error # %d\n", res);
749 if (res != LIBUSB_ERROR_BUSY &&
750 res != LIBUSB_ERROR_TIMEOUT &&
751 res != LIBUSB_ERROR_OVERFLOW &&
752 res != LIBUSB_ERROR_INTERRUPTED) {
760 libusb_cancel_transfer(dev->
transfer);
763 libusb_handle_events_completed(usb_context, &dev->
cancelled);
770 pthread_mutex_lock(&dev->
mutex);
772 pthread_mutex_unlock(&dev->
mutex);
790 libusb_device **devs;
791 libusb_device *usb_dev;
799 dev = new_hid_device();
801 libusb_get_device_list(usb_context, &devs);
802 while ((usb_dev = devs[d++]) != NULL) {
803 struct libusb_device_descriptor desc;
804 struct libusb_config_descriptor *conf_desc = NULL;
806 libusb_get_device_descriptor(usb_dev, &desc);
808 if (libusb_get_active_config_descriptor(usb_dev, &conf_desc) < 0)
810 for (j = 0; j < conf_desc->bNumInterfaces; j++) {
811 const struct libusb_interface *intf = &conf_desc->interface[j];
812 for (k = 0; k < intf->num_altsetting; k++) {
813 const struct libusb_interface_descriptor *intf_desc;
814 intf_desc = &intf->altsetting[k];
815 if (intf_desc->bInterfaceClass == LIBUSB_CLASS_HID) {
816 char *dev_path = make_path(usb_dev, intf_desc->bInterfaceNumber);
817 if (!strcmp(dev_path, path)) {
823 LOG(
"can't open device\n");
828 #ifdef DETACH_KERNEL_DRIVER 831 if (libusb_kernel_driver_active(dev->
device_handle, intf_desc->bInterfaceNumber) == 1) {
832 res = libusb_detach_kernel_driver(dev->
device_handle, intf_desc->bInterfaceNumber);
835 LOG(
"Unable to detach Kernel Driver\n");
842 res = libusb_claim_interface(dev->
device_handle, intf_desc->bInterfaceNumber);
844 LOG(
"can't claim interface %d: %d\n", intf_desc->bInterfaceNumber, res);
857 dev->
interface = intf_desc->bInterfaceNumber;
861 for (i = 0; i < intf_desc->bNumEndpoints; i++) {
862 const struct libusb_endpoint_descriptor *ep
863 = &intf_desc->endpoint[
i];
868 (ep->bmAttributes & LIBUSB_TRANSFER_TYPE_MASK)
869 == LIBUSB_TRANSFER_TYPE_INTERRUPT;
871 (ep->bEndpointAddress & LIBUSB_ENDPOINT_DIR_MASK)
872 == LIBUSB_ENDPOINT_OUT;
874 (ep->bEndpointAddress & LIBUSB_ENDPOINT_DIR_MASK)
875 == LIBUSB_ENDPOINT_IN;
879 is_interrupt && is_input) {
885 is_interrupt && is_output) {
891 pthread_create(&dev->
thread, NULL, read_thread, dev);
894 pthread_barrier_wait(&dev->
barrier);
901 libusb_free_config_descriptor(conf_desc);
905 libusb_free_device_list(devs, 1);
913 free_hid_device(dev);
922 int report_number = data[0];
923 int skipped_report_id = 0;
925 if (report_number == 0x0) {
928 skipped_report_id = 1;
935 LIBUSB_REQUEST_TYPE_CLASS|LIBUSB_RECIPIENT_INTERFACE|LIBUSB_ENDPOINT_OUT,
937 (2 << 8) | report_number,
939 (
unsigned char *)data, length,
945 if (skipped_report_id)
955 (
unsigned char*)data,
957 &actual_length, 1000);
962 if (skipped_report_id)
965 return actual_length;
971 static int return_data(
hid_device *dev,
unsigned char *data,
size_t length)
976 size_t len = (length < rpt->
len)? length: rpt->
len;
978 memcpy(data, rpt->
data, len);
985 static void cleanup_mutex(
void *param)
988 pthread_mutex_unlock(&dev->
mutex);
999 LOG(
"transferred: %d\n", transferred);
1003 pthread_mutex_lock(&dev->
mutex);
1004 pthread_cleanup_push(&cleanup_mutex, dev);
1009 bytes_read = return_data(dev, data, length);
1020 if (milliseconds == -1) {
1026 bytes_read = return_data(dev, data, length);
1029 else if (milliseconds > 0) {
1033 clock_gettime(CLOCK_REALTIME, &ts);
1034 ts.tv_sec += milliseconds / 1000;
1035 ts.tv_nsec += (milliseconds % 1000) * 1000000;
1036 if (ts.tv_nsec >= 1000000000L) {
1038 ts.tv_nsec -= 1000000000L;
1045 bytes_read = return_data(dev, data, length);
1053 else if (res == ETIMEDOUT) {
1071 pthread_mutex_unlock(&dev->
mutex);
1072 pthread_cleanup_pop(0);
1093 int skipped_report_id = 0;
1094 int report_number = data[0];
1096 if (report_number == 0x0) {
1099 skipped_report_id = 1;
1103 LIBUSB_REQUEST_TYPE_CLASS|LIBUSB_RECIPIENT_INTERFACE|LIBUSB_ENDPOINT_OUT,
1105 (3 << 8) | report_number,
1107 (
unsigned char *)data, length,
1114 if (skipped_report_id)
1123 int skipped_report_id = 0;
1124 int report_number = data[0];
1126 if (report_number == 0x0) {
1131 skipped_report_id = 1;
1134 LIBUSB_REQUEST_TYPE_CLASS|LIBUSB_RECIPIENT_INTERFACE|LIBUSB_ENDPOINT_IN,
1136 (3 << 8) | report_number,
1138 (
unsigned char *)data, length,
1144 if (skipped_report_id)
1158 libusb_cancel_transfer(dev->
transfer);
1161 pthread_join(dev->
thread, NULL);
1165 libusb_free_transfer(dev->
transfer);
1174 pthread_mutex_lock(&dev->
mutex);
1176 return_data(dev, NULL, 0);
1178 pthread_mutex_unlock(&dev->
mutex);
1180 free_hid_device(dev);
1205 wcsncpy(
string, str, maxlen);
1206 string[maxlen-1] = L
'\0';
1223 const char *string_code;
1227 #define LANG(name,code,usb_code) { name, code, usb_code } 1229 LANG(
"Afrikaans",
"af", 0x0436),
1230 LANG(
"Albanian",
"sq", 0x041C),
1231 LANG(
"Arabic - United Arab Emirates",
"ar_ae", 0x3801),
1232 LANG(
"Arabic - Bahrain",
"ar_bh", 0x3C01),
1233 LANG(
"Arabic - Algeria",
"ar_dz", 0x1401),
1234 LANG(
"Arabic - Egypt",
"ar_eg", 0x0C01),
1235 LANG(
"Arabic - Iraq",
"ar_iq", 0x0801),
1236 LANG(
"Arabic - Jordan",
"ar_jo", 0x2C01),
1237 LANG(
"Arabic - Kuwait",
"ar_kw", 0x3401),
1238 LANG(
"Arabic - Lebanon",
"ar_lb", 0x3001),
1239 LANG(
"Arabic - Libya",
"ar_ly", 0x1001),
1240 LANG(
"Arabic - Morocco",
"ar_ma", 0x1801),
1241 LANG(
"Arabic - Oman",
"ar_om", 0x2001),
1242 LANG(
"Arabic - Qatar",
"ar_qa", 0x4001),
1243 LANG(
"Arabic - Saudi Arabia",
"ar_sa", 0x0401),
1244 LANG(
"Arabic - Syria",
"ar_sy", 0x2801),
1245 LANG(
"Arabic - Tunisia",
"ar_tn", 0x1C01),
1246 LANG(
"Arabic - Yemen",
"ar_ye", 0x2401),
1247 LANG(
"Armenian",
"hy", 0x042B),
1248 LANG(
"Azeri - Latin",
"az_az", 0x042C),
1249 LANG(
"Azeri - Cyrillic",
"az_az", 0x082C),
1250 LANG(
"Basque",
"eu", 0x042D),
1251 LANG(
"Belarusian",
"be", 0x0423),
1252 LANG(
"Bulgarian",
"bg", 0x0402),
1253 LANG(
"Catalan",
"ca", 0x0403),
1254 LANG(
"Chinese - China",
"zh_cn", 0x0804),
1255 LANG(
"Chinese - Hong Kong SAR",
"zh_hk", 0x0C04),
1256 LANG(
"Chinese - Macau SAR",
"zh_mo", 0x1404),
1257 LANG(
"Chinese - Singapore",
"zh_sg", 0x1004),
1258 LANG(
"Chinese - Taiwan",
"zh_tw", 0x0404),
1259 LANG(
"Croatian",
"hr", 0x041A),
1260 LANG(
"Czech",
"cs", 0x0405),
1261 LANG(
"Danish",
"da", 0x0406),
1262 LANG(
"Dutch - Netherlands",
"nl_nl", 0x0413),
1263 LANG(
"Dutch - Belgium",
"nl_be", 0x0813),
1264 LANG(
"English - Australia",
"en_au", 0x0C09),
1265 LANG(
"English - Belize",
"en_bz", 0x2809),
1266 LANG(
"English - Canada",
"en_ca", 0x1009),
1267 LANG(
"English - Caribbean",
"en_cb", 0x2409),
1268 LANG(
"English - Ireland",
"en_ie", 0x1809),
1269 LANG(
"English - Jamaica",
"en_jm", 0x2009),
1270 LANG(
"English - New Zealand",
"en_nz", 0x1409),
1271 LANG(
"English - Phillippines",
"en_ph", 0x3409),
1272 LANG(
"English - Southern Africa",
"en_za", 0x1C09),
1273 LANG(
"English - Trinidad",
"en_tt", 0x2C09),
1274 LANG(
"English - Great Britain",
"en_gb", 0x0809),
1275 LANG(
"English - United States",
"en_us", 0x0409),
1276 LANG(
"Estonian",
"et", 0x0425),
1277 LANG(
"Farsi",
"fa", 0x0429),
1278 LANG(
"Finnish",
"fi", 0x040B),
1279 LANG(
"Faroese",
"fo", 0x0438),
1280 LANG(
"French - France",
"fr_fr", 0x040C),
1281 LANG(
"French - Belgium",
"fr_be", 0x080C),
1282 LANG(
"French - Canada",
"fr_ca", 0x0C0C),
1283 LANG(
"French - Luxembourg",
"fr_lu", 0x140C),
1284 LANG(
"French - Switzerland",
"fr_ch", 0x100C),
1285 LANG(
"Gaelic - Ireland",
"gd_ie", 0x083C),
1286 LANG(
"Gaelic - Scotland",
"gd", 0x043C),
1287 LANG(
"German - Germany",
"de_de", 0x0407),
1288 LANG(
"German - Austria",
"de_at", 0x0C07),
1289 LANG(
"German - Liechtenstein",
"de_li", 0x1407),
1290 LANG(
"German - Luxembourg",
"de_lu", 0x1007),
1291 LANG(
"German - Switzerland",
"de_ch", 0x0807),
1292 LANG(
"Greek",
"el", 0x0408),
1293 LANG(
"Hebrew",
"he", 0x040D),
1294 LANG(
"Hindi",
"hi", 0x0439),
1295 LANG(
"Hungarian",
"hu", 0x040E),
1296 LANG(
"Icelandic",
"is", 0x040F),
1297 LANG(
"Indonesian",
"id", 0x0421),
1298 LANG(
"Italian - Italy",
"it_it", 0x0410),
1299 LANG(
"Italian - Switzerland",
"it_ch", 0x0810),
1300 LANG(
"Japanese",
"ja", 0x0411),
1301 LANG(
"Korean",
"ko", 0x0412),
1302 LANG(
"Latvian",
"lv", 0x0426),
1303 LANG(
"Lithuanian",
"lt", 0x0427),
1304 LANG(
"F.Y.R.O. Macedonia",
"mk", 0x042F),
1305 LANG(
"Malay - Malaysia",
"ms_my", 0x043E),
1306 LANG(
"Malay – Brunei",
"ms_bn", 0x083E),
1307 LANG(
"Maltese",
"mt", 0x043A),
1308 LANG(
"Marathi",
"mr", 0x044E),
1309 LANG(
"Norwegian - Bokml",
"no_no", 0x0414),
1310 LANG(
"Norwegian - Nynorsk",
"no_no", 0x0814),
1311 LANG(
"Polish",
"pl", 0x0415),
1312 LANG(
"Portuguese - Portugal",
"pt_pt", 0x0816),
1313 LANG(
"Portuguese - Brazil",
"pt_br", 0x0416),
1314 LANG(
"Raeto-Romance",
"rm", 0x0417),
1315 LANG(
"Romanian - Romania",
"ro", 0x0418),
1316 LANG(
"Romanian - Republic of Moldova",
"ro_mo", 0x0818),
1317 LANG(
"Russian",
"ru", 0x0419),
1318 LANG(
"Russian - Republic of Moldova",
"ru_mo", 0x0819),
1319 LANG(
"Sanskrit",
"sa", 0x044F),
1320 LANG(
"Serbian - Cyrillic",
"sr_sp", 0x0C1A),
1321 LANG(
"Serbian - Latin",
"sr_sp", 0x081A),
1322 LANG(
"Setsuana",
"tn", 0x0432),
1323 LANG(
"Slovenian",
"sl", 0x0424),
1324 LANG(
"Slovak",
"sk", 0x041B),
1325 LANG(
"Sorbian",
"sb", 0x042E),
1326 LANG(
"Spanish - Spain (Traditional)",
"es_es", 0x040A),
1327 LANG(
"Spanish - Argentina",
"es_ar", 0x2C0A),
1328 LANG(
"Spanish - Bolivia",
"es_bo", 0x400A),
1329 LANG(
"Spanish - Chile",
"es_cl", 0x340A),
1330 LANG(
"Spanish - Colombia",
"es_co", 0x240A),
1331 LANG(
"Spanish - Costa Rica",
"es_cr", 0x140A),
1332 LANG(
"Spanish - Dominican Republic",
"es_do", 0x1C0A),
1333 LANG(
"Spanish - Ecuador",
"es_ec", 0x300A),
1334 LANG(
"Spanish - Guatemala",
"es_gt", 0x100A),
1335 LANG(
"Spanish - Honduras",
"es_hn", 0x480A),
1336 LANG(
"Spanish - Mexico",
"es_mx", 0x080A),
1337 LANG(
"Spanish - Nicaragua",
"es_ni", 0x4C0A),
1338 LANG(
"Spanish - Panama",
"es_pa", 0x180A),
1339 LANG(
"Spanish - Peru",
"es_pe", 0x280A),
1340 LANG(
"Spanish - Puerto Rico",
"es_pr", 0x500A),
1341 LANG(
"Spanish - Paraguay",
"es_py", 0x3C0A),
1342 LANG(
"Spanish - El Salvador",
"es_sv", 0x440A),
1343 LANG(
"Spanish - Uruguay",
"es_uy", 0x380A),
1344 LANG(
"Spanish - Venezuela",
"es_ve", 0x200A),
1345 LANG(
"Southern Sotho",
"st", 0x0430),
1346 LANG(
"Swahili",
"sw", 0x0441),
1347 LANG(
"Swedish - Sweden",
"sv_se", 0x041D),
1348 LANG(
"Swedish - Finland",
"sv_fi", 0x081D),
1349 LANG(
"Tamil",
"ta", 0x0449),
1350 LANG(
"Tatar",
"tt", 0X0444),
1351 LANG(
"Thai",
"th", 0x041E),
1352 LANG(
"Turkish",
"tr", 0x041F),
1353 LANG(
"Tsonga",
"ts", 0x0431),
1354 LANG(
"Ukrainian",
"uk", 0x0422),
1355 LANG(
"Urdu",
"ur", 0x0420),
1356 LANG(
"Uzbek - Cyrillic",
"uz_uz", 0x0843),
1357 LANG(
"Uzbek – Latin",
"uz_uz", 0x0443),
1358 LANG(
"Vietnamese",
"vi", 0x042A),
1359 LANG(
"Xhosa",
"xh", 0x0434),
1360 LANG(
"Yiddish",
"yi", 0x043D),
1361 LANG(
"Zulu",
"zu", 0x0435),
1362 LANG(NULL, NULL, 0x0),
1368 char search_string[64];
1373 locale = setlocale(0, NULL);
1378 strncpy(search_string, locale,
sizeof(search_string));
1379 search_string[
sizeof(search_string)-1] =
'\0';
1382 ptr = search_string;
1384 *ptr = tolower(*ptr);
1403 ptr = search_string;
1405 *ptr = tolower(*ptr);
1432 #endif // _HIDAPI_H_ 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.
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.
uint16_t get_usb_code_for_current_locale(void)
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.
#define LANG(name, code, usb_code)
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.