rb-blink1 0.0.6 → 0.0.7
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/ext/blink1/blink1-lib.c +106 -74
- data/ext/blink1/blink1-lib.h +9 -7
- data/ext/blink1/blink1.c +15 -0
- data/ext/blink1/hid.c.libusb +108 -109
- data/ext/blink1/hid.c.mac +115 -160
- data/ext/blink1/hid.c.windows +115 -112
- data/ext/blink1/hidapi.h +3 -2
- data/ext/blink1/osccal.h +7 -7
- data/ext/blink1/usbconfig.h +3 -3
- data/lib/blink1.rb +5 -5
- data/lib/blink1/version.rb +1 -1
- data/spec/blink1_spec.rb +11 -3
- data/spec/spec_helper.rb +7 -1
- metadata +2 -2
data/ext/blink1/blink1.c
CHANGED
@@ -230,6 +230,20 @@ static VALUE rb_blink1_fadeToRGB(VALUE self, VALUE fadeMillis, VALUE r, VALUE g,
|
|
230
230
|
return INT2NUM(blink1_fadeToRGB(ins->dev, FIX2UINT(fadeMillis), FIX2UINT(r), FIX2UINT(g), FIX2UINT(b)));
|
231
231
|
}
|
232
232
|
|
233
|
+
/**
|
234
|
+
* :call-seq:
|
235
|
+
* <span class="name">fade_to_rgbn</span> <span class="arguments">(fade_millis, r, g, b, n) -> integer</span>
|
236
|
+
*
|
237
|
+
* Fade a specific (blink(1) mk2) LED LED color to RGB in +fade_millis+.
|
238
|
+
*
|
239
|
+
* Return the actual number of bytes written and -1 on error.
|
240
|
+
*/
|
241
|
+
static VALUE rb_blink1_fadeToRGBN(VALUE self, VALUE fadeMillis, VALUE r, VALUE g, VALUE b, VALUE n) {
|
242
|
+
struct Blink1Instance *ins;
|
243
|
+
Data_Get_Struct(self, struct Blink1Instance, ins);
|
244
|
+
return INT2NUM(blink1_fadeToRGBN(ins->dev, FIX2UINT(fadeMillis), FIX2UINT(r), FIX2UINT(g), FIX2UINT(b), FIX2UINT(n)));
|
245
|
+
}
|
246
|
+
|
233
247
|
/**
|
234
248
|
* :call-seq:
|
235
249
|
* <span class="name">set_rgb</span> <span class="arguments">(r, g, b) -> integer</span>
|
@@ -404,6 +418,7 @@ void Init_blink1() {
|
|
404
418
|
rb_define_method(klass, "close", rb_blink1_close, 0);
|
405
419
|
rb_define_method(klass, "version", rb_blink1_getVersion, 0);
|
406
420
|
rb_define_method(klass, "fade_to_rgb", rb_blink1_fadeToRGB, 4);
|
421
|
+
rb_define_method(klass, "fade_to_rgbn", rb_blink1_fadeToRGBN, 5);
|
407
422
|
rb_define_method(klass, "set_rgb", rb_blink1_setRGB, 3);
|
408
423
|
rb_define_method(klass, "eeread", rb_blink1_eeread, 1);
|
409
424
|
rb_define_method(klass, "eewrite", rb_blink1_eewrite, 2);
|
data/ext/blink1/hid.c.libusb
CHANGED
@@ -11,7 +11,7 @@
|
|
11
11
|
FreeBSD Version - 11/1/2011
|
12
12
|
|
13
13
|
Copyright 2009, All Rights Reserved.
|
14
|
-
|
14
|
+
|
15
15
|
At the discretion of the user of this library,
|
16
16
|
this software may be licensed under the terms of the
|
17
17
|
GNU Public License v3, a BSD-Style license, or the
|
@@ -23,7 +23,7 @@
|
|
23
23
|
http://github.com/signal11/hidapi .
|
24
24
|
********************************************************/
|
25
25
|
|
26
|
-
#define _GNU_SOURCE
|
26
|
+
#define _GNU_SOURCE /* needed for wcsdup() before glibc 2.10 */
|
27
27
|
|
28
28
|
/* C */
|
29
29
|
#include <stdio.h>
|
@@ -82,23 +82,23 @@ struct input_report {
|
|
82
82
|
struct hid_device_ {
|
83
83
|
/* Handle to the actual device. */
|
84
84
|
libusb_device_handle *device_handle;
|
85
|
-
|
85
|
+
|
86
86
|
/* Endpoint information */
|
87
87
|
int input_endpoint;
|
88
88
|
int output_endpoint;
|
89
89
|
int input_ep_max_packet_size;
|
90
90
|
|
91
|
-
/* The interface number of the HID */
|
91
|
+
/* The interface number of the HID */
|
92
92
|
int interface;
|
93
|
-
|
93
|
+
|
94
94
|
/* Indexes of Strings */
|
95
95
|
int manufacturer_index;
|
96
96
|
int product_index;
|
97
97
|
int serial_index;
|
98
|
-
|
98
|
+
|
99
99
|
/* Whether blocking reads are used */
|
100
100
|
int blocking; /* boolean */
|
101
|
-
|
101
|
+
|
102
102
|
/* Read thread objects */
|
103
103
|
pthread_t thread;
|
104
104
|
pthread_mutex_t mutex; /* Protects input_reports */
|
@@ -120,11 +120,11 @@ static hid_device *new_hid_device(void)
|
|
120
120
|
{
|
121
121
|
hid_device *dev = calloc(1, sizeof(hid_device));
|
122
122
|
dev->blocking = 1;
|
123
|
-
|
123
|
+
|
124
124
|
pthread_mutex_init(&dev->mutex, NULL);
|
125
125
|
pthread_cond_init(&dev->condition, NULL);
|
126
126
|
pthread_barrier_init(&dev->barrier, NULL, 2);
|
127
|
-
|
127
|
+
|
128
128
|
return dev;
|
129
129
|
}
|
130
130
|
|
@@ -140,7 +140,7 @@ static void free_hid_device(hid_device *dev)
|
|
140
140
|
}
|
141
141
|
|
142
142
|
#if 0
|
143
|
-
|
143
|
+
/*TODO: Implement this funciton on hidapi/libusb.. */
|
144
144
|
static void register_error(hid_device *device, const char *op)
|
145
145
|
{
|
146
146
|
|
@@ -181,17 +181,17 @@ static uint32_t get_bytes(uint8_t *rpt, size_t len, size_t num_bytes, size_t cur
|
|
181
181
|
static int get_usage(uint8_t *report_descriptor, size_t size,
|
182
182
|
unsigned short *usage_page, unsigned short *usage)
|
183
183
|
{
|
184
|
-
int i = 0;
|
184
|
+
unsigned int i = 0;
|
185
185
|
int size_code;
|
186
186
|
int data_len, key_size;
|
187
187
|
int usage_found = 0, usage_page_found = 0;
|
188
|
-
|
188
|
+
|
189
189
|
while (i < size) {
|
190
190
|
int key = report_descriptor[i];
|
191
191
|
int key_cmd = key & 0xfc;
|
192
192
|
|
193
193
|
//printf("key: %02hhx\n", key);
|
194
|
-
|
194
|
+
|
195
195
|
if ((key & 0xf0) == 0xf0) {
|
196
196
|
/* This is a Long Item. The next byte contains the
|
197
197
|
length of the data section (value) for this key.
|
@@ -226,7 +226,7 @@ static int get_usage(uint8_t *report_descriptor, size_t size,
|
|
226
226
|
};
|
227
227
|
key_size = 1;
|
228
228
|
}
|
229
|
-
|
229
|
+
|
230
230
|
if (key_cmd == 0x4) {
|
231
231
|
*usage_page = get_bytes(report_descriptor, size, data_len, i);
|
232
232
|
usage_page_found = 1;
|
@@ -240,14 +240,14 @@ static int get_usage(uint8_t *report_descriptor, size_t size,
|
|
240
240
|
|
241
241
|
if (usage_page_found && usage_found)
|
242
242
|
return 0; /* success */
|
243
|
-
|
243
|
+
|
244
244
|
/* Skip over this key and it's associated data */
|
245
245
|
i += data_len + key_size;
|
246
246
|
}
|
247
|
-
|
247
|
+
|
248
248
|
return -1; /* failure */
|
249
249
|
}
|
250
|
-
#endif
|
250
|
+
#endif /* INVASIVE_GET_USAGE */
|
251
251
|
|
252
252
|
#ifdef __FreeBSD__
|
253
253
|
/* The FreeBSD version of libusb doesn't have this funciton. In mainline
|
@@ -277,7 +277,7 @@ static uint16_t get_first_language(libusb_device_handle *dev)
|
|
277
277
|
{
|
278
278
|
uint16_t buf[32];
|
279
279
|
int len;
|
280
|
-
|
280
|
+
|
281
281
|
/* Get the string from libusb. */
|
282
282
|
len = libusb_get_string_descriptor(dev,
|
283
283
|
0x0, /* String ID */
|
@@ -286,8 +286,8 @@ static uint16_t get_first_language(libusb_device_handle *dev)
|
|
286
286
|
sizeof(buf));
|
287
287
|
if (len < 4)
|
288
288
|
return 0x0;
|
289
|
-
|
290
|
-
return buf[1];
|
289
|
+
|
290
|
+
return buf[1]; /* First two bytes are len and descriptor type. */
|
291
291
|
}
|
292
292
|
|
293
293
|
static int is_language_supported(libusb_device_handle *dev, uint16_t lang)
|
@@ -295,7 +295,7 @@ static int is_language_supported(libusb_device_handle *dev, uint16_t lang)
|
|
295
295
|
uint16_t buf[32];
|
296
296
|
int len;
|
297
297
|
int i;
|
298
|
-
|
298
|
+
|
299
299
|
/* Get the string from libusb. */
|
300
300
|
len = libusb_get_string_descriptor(dev,
|
301
301
|
0x0, /* String ID */
|
@@ -304,8 +304,8 @@ static int is_language_supported(libusb_device_handle *dev, uint16_t lang)
|
|
304
304
|
sizeof(buf));
|
305
305
|
if (len < 4)
|
306
306
|
return 0x0;
|
307
|
-
|
308
|
-
|
307
|
+
|
308
|
+
|
309
309
|
len /= 2; /* language IDs are two-bytes each. */
|
310
310
|
/* Start at index 1 because there are two bytes of protocol data. */
|
311
311
|
for (i = 1; i < len; i++) {
|
@@ -344,7 +344,7 @@ static wchar_t *get_usb_string(libusb_device_handle *dev, uint8_t idx)
|
|
344
344
|
lang = get_usb_code_for_current_locale();
|
345
345
|
if (!is_language_supported(dev, lang))
|
346
346
|
lang = get_first_language(dev);
|
347
|
-
|
347
|
+
|
348
348
|
/* Get the string from libusb. */
|
349
349
|
len = libusb_get_string_descriptor(dev,
|
350
350
|
idx,
|
@@ -353,17 +353,17 @@ static wchar_t *get_usb_string(libusb_device_handle *dev, uint8_t idx)
|
|
353
353
|
sizeof(buf));
|
354
354
|
if (len < 0)
|
355
355
|
return NULL;
|
356
|
-
|
356
|
+
|
357
357
|
/* buf does not need to be explicitly NULL-terminated because
|
358
358
|
it is only passed into iconv() which does not need it. */
|
359
|
-
|
359
|
+
|
360
360
|
/* Initialize iconv. */
|
361
361
|
ic = iconv_open("WCHAR_T", "UTF-16LE");
|
362
362
|
if (ic == (iconv_t)-1) {
|
363
363
|
LOG("iconv_open() failed\n");
|
364
364
|
return NULL;
|
365
365
|
}
|
366
|
-
|
366
|
+
|
367
367
|
/* Convert to native wchar_t (UTF-32 on glibc/BSD systems).
|
368
368
|
Skip the first character (2-bytes). */
|
369
369
|
inptr = buf+2;
|
@@ -380,13 +380,13 @@ static wchar_t *get_usb_string(libusb_device_handle *dev, uint8_t idx)
|
|
380
380
|
wbuf[sizeof(wbuf)/sizeof(wbuf[0])-1] = 0x00000000;
|
381
381
|
if (outbytes >= sizeof(wbuf[0]))
|
382
382
|
*((wchar_t*)outptr) = 0x00000000;
|
383
|
-
|
383
|
+
|
384
384
|
/* Allocate and copy the string. */
|
385
385
|
str = wcsdup(wbuf);
|
386
386
|
|
387
387
|
err:
|
388
388
|
iconv_close(ic);
|
389
|
-
|
389
|
+
|
390
390
|
return str;
|
391
391
|
}
|
392
392
|
|
@@ -398,7 +398,7 @@ static char *make_path(libusb_device *dev, int interface_number)
|
|
398
398
|
libusb_get_device_address(dev),
|
399
399
|
interface_number);
|
400
400
|
str[sizeof(str)-1] = '\0';
|
401
|
-
|
401
|
+
|
402
402
|
return strdup(str);
|
403
403
|
}
|
404
404
|
|
@@ -438,11 +438,12 @@ struct hid_device_info HID_API_EXPORT *hid_enumerate(unsigned short vendor_id,
|
|
438
438
|
libusb_device_handle *handle;
|
439
439
|
ssize_t num_devs;
|
440
440
|
int i = 0;
|
441
|
-
|
442
|
-
struct hid_device_info *root = NULL;
|
441
|
+
|
442
|
+
struct hid_device_info *root = NULL; /* return object */
|
443
443
|
struct hid_device_info *cur_dev = NULL;
|
444
|
-
|
445
|
-
hid_init()
|
444
|
+
|
445
|
+
if(hid_init() < 0)
|
446
|
+
return NULL;
|
446
447
|
|
447
448
|
num_devs = libusb_get_device_list(usb_context, &devs);
|
448
449
|
if (num_devs < 0)
|
@@ -456,10 +457,6 @@ struct hid_device_info HID_API_EXPORT *hid_enumerate(unsigned short vendor_id,
|
|
456
457
|
int res = libusb_get_device_descriptor(dev, &desc);
|
457
458
|
unsigned short dev_vid = desc.idVendor;
|
458
459
|
unsigned short dev_pid = desc.idProduct;
|
459
|
-
|
460
|
-
/* HID's are defined at the interface level. */
|
461
|
-
if (desc.bDeviceClass != LIBUSB_CLASS_PER_INTERFACE)
|
462
|
-
continue;
|
463
460
|
|
464
461
|
res = libusb_get_active_config_descriptor(dev, &conf_desc);
|
465
462
|
if (res < 0)
|
@@ -474,8 +471,8 @@ struct hid_device_info HID_API_EXPORT *hid_enumerate(unsigned short vendor_id,
|
|
474
471
|
interface_num = intf_desc->bInterfaceNumber;
|
475
472
|
|
476
473
|
/* Check the VID/PID against the arguments */
|
477
|
-
if ((vendor_id == 0x0
|
478
|
-
(
|
474
|
+
if ((vendor_id == 0x0 || vendor_id == dev_vid) &&
|
475
|
+
(product_id == 0x0 || product_id == dev_pid)) {
|
479
476
|
struct hid_device_info *tmp;
|
480
477
|
|
481
478
|
/* VID/PID match. Create the record. */
|
@@ -487,11 +484,11 @@ struct hid_device_info HID_API_EXPORT *hid_enumerate(unsigned short vendor_id,
|
|
487
484
|
root = tmp;
|
488
485
|
}
|
489
486
|
cur_dev = tmp;
|
490
|
-
|
487
|
+
|
491
488
|
/* Fill out the record */
|
492
489
|
cur_dev->next = NULL;
|
493
490
|
cur_dev->path = make_path(dev, interface_num);
|
494
|
-
|
491
|
+
|
495
492
|
res = libusb_open(dev, &handle);
|
496
493
|
|
497
494
|
if (res >= 0) {
|
@@ -509,6 +506,7 @@ struct hid_device_info HID_API_EXPORT *hid_enumerate(unsigned short vendor_id,
|
|
509
506
|
get_usb_string(handle, desc.iProduct);
|
510
507
|
|
511
508
|
#ifdef INVASIVE_GET_USAGE
|
509
|
+
{
|
512
510
|
/*
|
513
511
|
This section is removed because it is too
|
514
512
|
invasive on the system. Getting a Usage Page
|
@@ -567,8 +565,8 @@ struct hid_device_info HID_API_EXPORT *hid_enumerate(unsigned short vendor_id,
|
|
567
565
|
LOG("Couldn't re-attach kernel driver.\n");
|
568
566
|
}
|
569
567
|
#endif
|
570
|
-
|
571
|
-
#endif
|
568
|
+
}
|
569
|
+
#endif /* INVASIVE_GET_USAGE */
|
572
570
|
|
573
571
|
libusb_close(handle);
|
574
572
|
}
|
@@ -578,7 +576,7 @@ struct hid_device_info HID_API_EXPORT *hid_enumerate(unsigned short vendor_id,
|
|
578
576
|
|
579
577
|
/* Release Number */
|
580
578
|
cur_dev->release_number = desc.bcdDevice;
|
581
|
-
|
579
|
+
|
582
580
|
/* Interface Number */
|
583
581
|
cur_dev->interface_number = interface_num;
|
584
582
|
}
|
@@ -613,7 +611,7 @@ hid_device * hid_open(unsigned short vendor_id, unsigned short product_id, const
|
|
613
611
|
struct hid_device_info *devs, *cur_dev;
|
614
612
|
const char *path_to_open = NULL;
|
615
613
|
hid_device *handle = NULL;
|
616
|
-
|
614
|
+
|
617
615
|
devs = hid_enumerate(vendor_id, product_id);
|
618
616
|
cur_dev = devs;
|
619
617
|
while (cur_dev) {
|
@@ -639,7 +637,7 @@ hid_device * hid_open(unsigned short vendor_id, unsigned short product_id, const
|
|
639
637
|
}
|
640
638
|
|
641
639
|
hid_free_enumeration(devs);
|
642
|
-
|
640
|
+
|
643
641
|
return handle;
|
644
642
|
}
|
645
643
|
|
@@ -647,7 +645,7 @@ static void read_callback(struct libusb_transfer *transfer)
|
|
647
645
|
{
|
648
646
|
hid_device *dev = transfer->user_data;
|
649
647
|
int res;
|
650
|
-
|
648
|
+
|
651
649
|
if (transfer->status == LIBUSB_TRANSFER_COMPLETED) {
|
652
650
|
|
653
651
|
struct input_report *rpt = malloc(sizeof(*rpt));
|
@@ -673,13 +671,13 @@ static void read_callback(struct libusb_transfer *transfer)
|
|
673
671
|
num_queued++;
|
674
672
|
}
|
675
673
|
cur->next = rpt;
|
676
|
-
|
674
|
+
|
677
675
|
/* Pop one off if we've reached 30 in the queue. This
|
678
676
|
way we don't grow forever if the user never reads
|
679
677
|
anything from the device. */
|
680
678
|
if (num_queued > 30) {
|
681
679
|
return_data(dev, NULL, 0);
|
682
|
-
}
|
680
|
+
}
|
683
681
|
}
|
684
682
|
pthread_mutex_unlock(&dev->mutex);
|
685
683
|
}
|
@@ -697,7 +695,7 @@ static void read_callback(struct libusb_transfer *transfer)
|
|
697
695
|
else {
|
698
696
|
LOG("Unknown transfer code: %d\n", transfer->status);
|
699
697
|
}
|
700
|
-
|
698
|
+
|
701
699
|
/* Re-submit the transfer object. */
|
702
700
|
res = libusb_submit_transfer(transfer);
|
703
701
|
if (res != 0) {
|
@@ -724,14 +722,14 @@ static void *read_thread(void *param)
|
|
724
722
|
read_callback,
|
725
723
|
dev,
|
726
724
|
5000/*timeout*/);
|
727
|
-
|
725
|
+
|
728
726
|
/* Make the first submission. Further submissions are made
|
729
727
|
from inside read_callback() */
|
730
728
|
libusb_submit_transfer(dev->transfer);
|
731
729
|
|
732
|
-
|
730
|
+
/* Notify the main thread that the read thread is up and running. */
|
733
731
|
pthread_barrier_wait(&dev->barrier);
|
734
|
-
|
732
|
+
|
735
733
|
/* Handle all the events. */
|
736
734
|
while (!dev->shutdown_thread) {
|
737
735
|
int res;
|
@@ -749,14 +747,14 @@ static void *read_thread(void *param)
|
|
749
747
|
}
|
750
748
|
}
|
751
749
|
}
|
752
|
-
|
750
|
+
|
753
751
|
/* Cancel any transfer that may be pending. This call will fail
|
754
752
|
if no transfers are pending, but that's OK. */
|
755
753
|
if (libusb_cancel_transfer(dev->transfer) == 0) {
|
756
754
|
/* The transfer was cancelled, so wait for its completion. */
|
757
755
|
libusb_handle_events(usb_context);
|
758
756
|
}
|
759
|
-
|
757
|
+
|
760
758
|
/* Now that the read thread is stopping, Wake any threads which are
|
761
759
|
waiting on data (in hid_read_timeout()). Do this under a mutex to
|
762
760
|
make sure that a thread which is about to go to sleep waiting on
|
@@ -773,7 +771,7 @@ static void *read_thread(void *param)
|
|
773
771
|
cleaned up after the call to pthread_join() (in hid_close()), but
|
774
772
|
since hid_close() calls libusb_cancel_transfer(), on these objects,
|
775
773
|
they can not be cleaned up here. */
|
776
|
-
|
774
|
+
|
777
775
|
return NULL;
|
778
776
|
}
|
779
777
|
|
@@ -782,18 +780,18 @@ hid_device * HID_API_EXPORT hid_open_path(const char *path)
|
|
782
780
|
{
|
783
781
|
hid_device *dev = NULL;
|
784
782
|
|
785
|
-
dev = new_hid_device();
|
786
|
-
|
787
783
|
libusb_device **devs;
|
788
784
|
libusb_device *usb_dev;
|
789
|
-
ssize_t num_devs;
|
790
785
|
int res;
|
791
786
|
int d = 0;
|
792
787
|
int good_open = 0;
|
793
|
-
|
794
|
-
hid_init();
|
795
788
|
|
796
|
-
|
789
|
+
dev = new_hid_device();
|
790
|
+
|
791
|
+
if(hid_init() < 0)
|
792
|
+
return NULL;
|
793
|
+
|
794
|
+
libusb_get_device_list(usb_context, &devs);
|
797
795
|
while ((usb_dev = devs[d++]) != NULL) {
|
798
796
|
struct libusb_device_descriptor desc;
|
799
797
|
struct libusb_config_descriptor *conf_desc = NULL;
|
@@ -812,12 +810,12 @@ hid_device * HID_API_EXPORT hid_open_path(const char *path)
|
|
812
810
|
if (!strcmp(dev_path, path)) {
|
813
811
|
/* Matched Paths. Open this device */
|
814
812
|
|
815
|
-
|
813
|
+
/* OPEN HERE */
|
816
814
|
res = libusb_open(usb_dev, &dev->device_handle);
|
817
815
|
if (res < 0) {
|
818
816
|
LOG("can't open device\n");
|
819
817
|
free(dev_path);
|
820
|
-
|
818
|
+
break;
|
821
819
|
}
|
822
820
|
good_open = 1;
|
823
821
|
#ifdef DETACH_KERNEL_DRIVER
|
@@ -850,7 +848,7 @@ hid_device * HID_API_EXPORT hid_open_path(const char *path)
|
|
850
848
|
|
851
849
|
/* Store off the interface number */
|
852
850
|
dev->interface = intf_desc->bInterfaceNumber;
|
853
|
-
|
851
|
+
|
854
852
|
/* Find the INPUT and OUTPUT endpoints. An
|
855
853
|
OUTPUT endpoint is not required. */
|
856
854
|
for (i = 0; i < intf_desc->bNumEndpoints; i++) {
|
@@ -862,10 +860,10 @@ hid_device * HID_API_EXPORT hid_open_path(const char *path)
|
|
862
860
|
int is_interrupt =
|
863
861
|
(ep->bmAttributes & LIBUSB_TRANSFER_TYPE_MASK)
|
864
862
|
== LIBUSB_TRANSFER_TYPE_INTERRUPT;
|
865
|
-
int is_output =
|
863
|
+
int is_output =
|
866
864
|
(ep->bEndpointAddress & LIBUSB_ENDPOINT_DIR_MASK)
|
867
865
|
== LIBUSB_ENDPOINT_OUT;
|
868
|
-
int is_input =
|
866
|
+
int is_input =
|
869
867
|
(ep->bEndpointAddress & LIBUSB_ENDPOINT_DIR_MASK)
|
870
868
|
== LIBUSB_ENDPOINT_IN;
|
871
869
|
|
@@ -882,12 +880,12 @@ hid_device * HID_API_EXPORT hid_open_path(const char *path)
|
|
882
880
|
dev->output_endpoint = ep->bEndpointAddress;
|
883
881
|
}
|
884
882
|
}
|
885
|
-
|
883
|
+
|
886
884
|
pthread_create(&dev->thread, NULL, read_thread, dev);
|
887
|
-
|
888
|
-
|
885
|
+
|
886
|
+
/* Wait here for the read thread to be initialized. */
|
889
887
|
pthread_barrier_wait(&dev->barrier);
|
890
|
-
|
888
|
+
|
891
889
|
}
|
892
890
|
free(dev_path);
|
893
891
|
}
|
@@ -898,13 +896,13 @@ hid_device * HID_API_EXPORT hid_open_path(const char *path)
|
|
898
896
|
}
|
899
897
|
|
900
898
|
libusb_free_device_list(devs, 1);
|
901
|
-
|
902
|
-
|
899
|
+
|
900
|
+
/* If we have a good handle, return it. */
|
903
901
|
if (good_open) {
|
904
902
|
return dev;
|
905
903
|
}
|
906
904
|
else {
|
907
|
-
|
905
|
+
/* Unable to open any devices. */
|
908
906
|
free_hid_device(dev);
|
909
907
|
return NULL;
|
910
908
|
}
|
@@ -933,13 +931,13 @@ int HID_API_EXPORT hid_write(hid_device *dev, const unsigned char *data, size_t
|
|
933
931
|
dev->interface,
|
934
932
|
(unsigned char *)data, length,
|
935
933
|
1000/*timeout millis*/);
|
936
|
-
|
934
|
+
|
937
935
|
if (res < 0)
|
938
936
|
return -1;
|
939
|
-
|
937
|
+
|
940
938
|
if (skipped_report_id)
|
941
939
|
length++;
|
942
|
-
|
940
|
+
|
943
941
|
return length;
|
944
942
|
}
|
945
943
|
else {
|
@@ -950,13 +948,13 @@ int HID_API_EXPORT hid_write(hid_device *dev, const unsigned char *data, size_t
|
|
950
948
|
(unsigned char*)data,
|
951
949
|
length,
|
952
950
|
&actual_length, 1000);
|
953
|
-
|
951
|
+
|
954
952
|
if (res < 0)
|
955
953
|
return -1;
|
956
|
-
|
954
|
+
|
957
955
|
if (skipped_report_id)
|
958
956
|
actual_length++;
|
959
|
-
|
957
|
+
|
960
958
|
return actual_length;
|
961
959
|
}
|
962
960
|
}
|
@@ -1004,14 +1002,14 @@ int HID_API_EXPORT hid_read_timeout(hid_device *dev, unsigned char *data, size_t
|
|
1004
1002
|
bytes_read = return_data(dev, data, length);
|
1005
1003
|
goto ret;
|
1006
1004
|
}
|
1007
|
-
|
1005
|
+
|
1008
1006
|
if (dev->shutdown_thread) {
|
1009
1007
|
/* This means the device has been disconnected.
|
1010
1008
|
An error code of -1 should be returned. */
|
1011
1009
|
bytes_read = -1;
|
1012
1010
|
goto ret;
|
1013
1011
|
}
|
1014
|
-
|
1012
|
+
|
1015
1013
|
if (milliseconds == -1) {
|
1016
1014
|
/* Blocking */
|
1017
1015
|
while (!dev->input_reports && !dev->shutdown_thread) {
|
@@ -1032,7 +1030,7 @@ int HID_API_EXPORT hid_read_timeout(hid_device *dev, unsigned char *data, size_t
|
|
1032
1030
|
ts.tv_sec++;
|
1033
1031
|
ts.tv_nsec -= 1000000000L;
|
1034
1032
|
}
|
1035
|
-
|
1033
|
+
|
1036
1034
|
while (!dev->input_reports && !dev->shutdown_thread) {
|
1037
1035
|
res = pthread_cond_timedwait(&dev->condition, &dev->mutex, &ts);
|
1038
1036
|
if (res == 0) {
|
@@ -1040,7 +1038,7 @@ int HID_API_EXPORT hid_read_timeout(hid_device *dev, unsigned char *data, size_t
|
|
1040
1038
|
bytes_read = return_data(dev, data, length);
|
1041
1039
|
break;
|
1042
1040
|
}
|
1043
|
-
|
1041
|
+
|
1044
1042
|
/* If we're here, there was a spurious wake up
|
1045
1043
|
or the read thread was shutdown. Run the
|
1046
1044
|
loop again (ie: don't break). */
|
@@ -1077,7 +1075,7 @@ int HID_API_EXPORT hid_read(hid_device *dev, unsigned char *data, size_t length)
|
|
1077
1075
|
int HID_API_EXPORT hid_set_nonblocking(hid_device *dev, int nonblock)
|
1078
1076
|
{
|
1079
1077
|
dev->blocking = !nonblock;
|
1080
|
-
|
1078
|
+
|
1081
1079
|
return 0;
|
1082
1080
|
}
|
1083
1081
|
|
@@ -1101,14 +1099,14 @@ int HID_API_EXPORT hid_send_feature_report(hid_device *dev, const unsigned char
|
|
1101
1099
|
dev->interface,
|
1102
1100
|
(unsigned char *)data, length,
|
1103
1101
|
1000/*timeout millis*/);
|
1104
|
-
|
1102
|
+
|
1105
1103
|
if (res < 0)
|
1106
1104
|
return -1;
|
1107
|
-
|
1105
|
+
|
1108
1106
|
/* Account for the report ID */
|
1109
1107
|
if (skipped_report_id)
|
1110
1108
|
length++;
|
1111
|
-
|
1109
|
+
|
1112
1110
|
return length;
|
1113
1111
|
}
|
1114
1112
|
|
@@ -1132,13 +1130,13 @@ int HID_API_EXPORT hid_get_feature_report(hid_device *dev, unsigned char *data,
|
|
1132
1130
|
dev->interface,
|
1133
1131
|
(unsigned char *)data, length,
|
1134
1132
|
1000/*timeout millis*/);
|
1135
|
-
|
1133
|
+
|
1136
1134
|
if (res < 0)
|
1137
1135
|
return -1;
|
1138
1136
|
|
1139
1137
|
if (skipped_report_id)
|
1140
1138
|
res++;
|
1141
|
-
|
1139
|
+
|
1142
1140
|
return res;
|
1143
1141
|
}
|
1144
1142
|
|
@@ -1147,31 +1145,31 @@ void HID_API_EXPORT hid_close(hid_device *dev)
|
|
1147
1145
|
{
|
1148
1146
|
if (!dev)
|
1149
1147
|
return;
|
1150
|
-
|
1148
|
+
|
1151
1149
|
/* Cause read_thread() to stop. */
|
1152
1150
|
dev->shutdown_thread = 1;
|
1153
1151
|
libusb_cancel_transfer(dev->transfer);
|
1154
1152
|
|
1155
1153
|
/* Wait for read_thread() to end. */
|
1156
1154
|
pthread_join(dev->thread, NULL);
|
1157
|
-
|
1155
|
+
|
1158
1156
|
/* Clean up the Transfer objects allocated in read_thread(). */
|
1159
1157
|
free(dev->transfer->buffer);
|
1160
1158
|
libusb_free_transfer(dev->transfer);
|
1161
|
-
|
1159
|
+
|
1162
1160
|
/* release the interface */
|
1163
1161
|
libusb_release_interface(dev->device_handle, dev->interface);
|
1164
|
-
|
1162
|
+
|
1165
1163
|
/* Close the handle */
|
1166
1164
|
libusb_close(dev->device_handle);
|
1167
|
-
|
1165
|
+
|
1168
1166
|
/* Clear out the queue of received reports. */
|
1169
1167
|
pthread_mutex_lock(&dev->mutex);
|
1170
1168
|
while (dev->input_reports) {
|
1171
1169
|
return_data(dev, NULL, 0);
|
1172
1170
|
}
|
1173
1171
|
pthread_mutex_unlock(&dev->mutex);
|
1174
|
-
|
1172
|
+
|
1175
1173
|
free_hid_device(dev);
|
1176
1174
|
}
|
1177
1175
|
|
@@ -1354,7 +1352,7 @@ static struct lang_map_entry lang_map[] = {
|
|
1354
1352
|
LANG("Xhosa", "xh", 0x0434),
|
1355
1353
|
LANG("Yiddish", "yi", 0x043D),
|
1356
1354
|
LANG("Zulu", "zu", 0x0435),
|
1357
|
-
LANG(NULL, NULL, 0x0),
|
1355
|
+
LANG(NULL, NULL, 0x0),
|
1358
1356
|
};
|
1359
1357
|
|
1360
1358
|
uint16_t get_usb_code_for_current_locale(void)
|
@@ -1362,16 +1360,17 @@ uint16_t get_usb_code_for_current_locale(void)
|
|
1362
1360
|
char *locale;
|
1363
1361
|
char search_string[64];
|
1364
1362
|
char *ptr;
|
1365
|
-
|
1363
|
+
struct lang_map_entry *lang;
|
1364
|
+
|
1366
1365
|
/* Get the current locale. */
|
1367
1366
|
locale = setlocale(0, NULL);
|
1368
1367
|
if (!locale)
|
1369
1368
|
return 0x0;
|
1370
|
-
|
1369
|
+
|
1371
1370
|
/* Make a copy of the current locale string. */
|
1372
1371
|
strncpy(search_string, locale, sizeof(search_string));
|
1373
1372
|
search_string[sizeof(search_string)-1] = '\0';
|
1374
|
-
|
1373
|
+
|
1375
1374
|
/* Chop off the encoding part, and make it lower case. */
|
1376
1375
|
ptr = search_string;
|
1377
1376
|
while (*ptr) {
|
@@ -1384,14 +1383,14 @@ uint16_t get_usb_code_for_current_locale(void)
|
|
1384
1383
|
}
|
1385
1384
|
|
1386
1385
|
/* Find the entry which matches the string code of our locale. */
|
1387
|
-
|
1386
|
+
lang = lang_map;
|
1388
1387
|
while (lang->string_code) {
|
1389
1388
|
if (!strcmp(lang->string_code, search_string)) {
|
1390
1389
|
return lang->usb_code;
|
1391
|
-
}
|
1390
|
+
}
|
1392
1391
|
lang++;
|
1393
1392
|
}
|
1394
|
-
|
1393
|
+
|
1395
1394
|
/* There was no match. Find with just the language only. */
|
1396
1395
|
/* Chop off the variant. Chop it off at the '_'. */
|
1397
1396
|
ptr = search_string;
|
@@ -1403,22 +1402,22 @@ uint16_t get_usb_code_for_current_locale(void)
|
|
1403
1402
|
}
|
1404
1403
|
ptr++;
|
1405
1404
|
}
|
1406
|
-
|
1407
|
-
#if 0
|
1405
|
+
|
1406
|
+
#if 0 /* TODO: Do we need this? */
|
1408
1407
|
/* Find the entry which matches the string code of our language. */
|
1409
1408
|
lang = lang_map;
|
1410
1409
|
while (lang->string_code) {
|
1411
1410
|
if (!strcmp(lang->string_code, search_string)) {
|
1412
1411
|
return lang->usb_code;
|
1413
|
-
}
|
1412
|
+
}
|
1414
1413
|
lang++;
|
1415
1414
|
}
|
1416
1415
|
#endif
|
1417
|
-
|
1416
|
+
|
1418
1417
|
/* Found nothing. */
|
1419
1418
|
return 0x0;
|
1420
1419
|
}
|
1421
1420
|
|
1422
1421
|
#ifdef __cplusplus
|
1423
1422
|
}
|
1424
|
-
#endif
|
1423
|
+
#endif
|