rb-blink1 0.0.6 → 0.0.7
Sign up to get free protection for your applications and to get access to all the features.
- 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
|