Skip to content

Commit 19112a2

Browse files
committed
Merge branch 'master' into connection-callback
2 parents da500c6 + d6b2a97 commit 19112a2

22 files changed

+1005
-178
lines changed

.github/workflows/builds.yml

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -351,7 +351,7 @@ jobs:
351351
Copy-Item "windows\x64\Release\hidapi.dll","windows\x64\Release\hidapi.lib","windows\x64\Release\hidapi.pdb" -Destination "artifacts\x64"
352352
Copy-Item "hidapi\hidapi.h","windows\hidapi_winapi.h" -Destination "artifacts\include"
353353
- name: Upload artifacts
354-
uses: actions/upload-artifact@v3
354+
uses: actions/upload-artifact@v4
355355
with:
356356
name: hidapi-win
357357
path: artifacts/
@@ -367,7 +367,7 @@ jobs:
367367
with:
368368
path: hidapisrc
369369
- name: Install dependencies
370-
run: sudo dnf install -y autoconf automake libtool mingw64-gcc cmake ninja-build make
370+
run: sudo dnf install -y autoconf automake libtool gawk mingw64-gcc cmake ninja-build make
371371
- name: Configure CMake
372372
run: |
373373
rm -rf build install
@@ -485,7 +485,7 @@ jobs:
485485
cmake \
486486
-B build/shared_test \
487487
-S hidapisrc/hidtest \
488-
-Dhidapi_ROOT=install/shared-cmake \
488+
-Dhidapi_ROOT=$(pwd)/install/shared-cmake \
489489
-DCMAKE_INSTALL_PREFIX=install/shared_test \
490490
"-DCMAKE_C_FLAGS=${GNU_COMPILE_FLAGS}"
491491
cd build/shared_test
@@ -495,7 +495,7 @@ jobs:
495495
cmake \
496496
-B build/static_test \
497497
-S hidapisrc/hidtest \
498-
-Dhidapi_ROOT=install/static-cmake \
498+
-Dhidapi_ROOT=$(pwd)/install/static-cmake \
499499
-DCMAKE_INSTALL_PREFIX=install/static_test \
500500
"-DCMAKE_C_FLAGS=${GNU_COMPILE_FLAGS}"
501501
cd build/static_test

.github/workflows/checks.yml

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -63,15 +63,15 @@ jobs:
6363
cov-build --dir cov-int nmake
6464
Rename-Item ".\cov-int\emit\$(hostname)" hostname
6565
- name: Backup Coverity logs
66-
uses: actions/upload-artifact@v3
66+
uses: actions/upload-artifact@v4
6767
with:
6868
name: coverity-logs-windows
6969
path: build/cov-int
7070
retention-days: 7
7171

7272

7373
coverity-macos:
74-
runs-on: macos-latest
74+
runs-on: macos-13
7575
needs: [coverity-windows]
7676

7777
steps:
@@ -83,7 +83,7 @@ jobs:
8383
- name: Configure
8484
run: |
8585
cmake -B build -S src -GNinja -DCMAKE_BUILD_TYPE=RelWithDebInfo -DHIDAPI_WITH_TESTS=ON -DHIDAPI_BUILD_HIDTEST=ON -DCMAKE_C_COMPILER=clang
86-
- uses: actions/download-artifact@v3
86+
- uses: actions/download-artifact@v4
8787
with:
8888
name: coverity-logs-windows
8989
path: build/cov-int
@@ -123,7 +123,7 @@ jobs:
123123
cov-build --dir cov-int --append-log ninja
124124
mv cov-int/emit/$(hostname) cov-int/emit/hostname
125125
- name: Backup Coverity logs
126-
uses: actions/upload-artifact@v3
126+
uses: actions/upload-artifact@v4
127127
with:
128128
name: coverity-logs-windows-macos
129129
path: build/cov-int
@@ -145,7 +145,7 @@ jobs:
145145
- name: Configure
146146
run: |
147147
cmake -B build -S src -GNinja -DCMAKE_BUILD_TYPE=RelWithDebInfo -DHIDAPI_WITH_TESTS=ON -DHIDAPI_BUILD_HIDTEST=ON -DCMAKE_C_COMPILER=gcc
148-
- uses: actions/download-artifact@v3
148+
- uses: actions/download-artifact@v4
149149
with:
150150
name: coverity-logs-windows-macos
151151
path: build/cov-int
@@ -191,7 +191,7 @@ jobs:
191191
https://scan.coverity.com/builds?project=hidapi
192192
mv cov-int/emit/$(hostname) cov-int/emit/hostname
193193
- name: Backup Coverity logs
194-
uses: actions/upload-artifact@v3
194+
uses: actions/upload-artifact@v4
195195
with:
196196
name: coverity-logs-windows-macos-linux
197197
path: build/cov-int

.github/workflows/docs.yaml

Lines changed: 8 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -8,50 +8,38 @@ on:
88

99
jobs:
1010
build:
11-
runs-on: ubuntu-latest
11+
runs-on: ubuntu-24.04
1212
steps:
13+
- name: Install Doxygen
14+
run: sudo apt satisfy "doxygen (>= 1.9.6)"
1315

14-
- name: Install Doxygen static libclang deps
15-
run: sudo apt-get install libclang1-12 libclang-cpp12
16-
17-
- name: Install Doxygen from SF binary archives
18-
env:
19-
DOXYGEN_VERSION: '1.9.6'
20-
run: |
21-
mkdir .doxygen && cd .doxygen
22-
curl -L https://sourceforge.net/projects/doxygen/files/rel-$DOXYGEN_VERSION/doxygen-$DOXYGEN_VERSION.linux.bin.tar.gz > doxygen.tar.gz
23-
gunzip doxygen.tar.gz
24-
tar xf doxygen.tar
25-
cd doxygen-$DOXYGEN_VERSION
26-
sudo make install
27-
28-
- uses: actions/checkout@v3
16+
- uses: actions/checkout@v4
2917

3018
- run: doxygen
3119
working-directory: doxygen
3220

3321
- name: Save doxygen docs as artifact
34-
uses: actions/upload-artifact@v3
22+
uses: actions/upload-artifact@v4
3523
with:
3624
name: HIDAPI_doxygen_docs
3725
path: ${{ github.workspace }}/doxygen/html
3826

3927
deploy-docs:
40-
runs-on: ubuntu-latest
28+
runs-on: ubuntu-24.04
4129
needs: [build]
4230
if: github.ref_type == 'branch' && github.ref_name == 'master'
4331
concurrency:
4432
group: "github-pages-deploy"
4533
cancel-in-progress: true
4634
steps:
4735
- name: downlod artifact
48-
uses: actions/download-artifact@v3
36+
uses: actions/download-artifact@v4
4937
with:
5038
name: HIDAPI_doxygen_docs
5139
path: docs
5240

5341
- name: upload to github pages
54-
uses: peaceiris/actions-gh-pages@v3
42+
uses: peaceiris/actions-gh-pages@v4
5543
with:
5644
github_token: ${{ secrets.GITHUB_TOKEN }}
5745
publish_dir: ./docs

README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@
55
| `Linux/macOS/Windows (master)` | [![GitHub Builds](https://github.com/libusb/hidapi/actions/workflows/builds.yml/badge.svg?branch=master)](https://github.com/libusb/hidapi/actions/workflows/builds.yml?query=branch%3Amaster) |
66
| `Windows (master)` | [![Build status](https://ci.appveyor.com/api/projects/status/xfmr5fo8w0re8ded/branch/master?svg=true)](https://ci.appveyor.com/project/libusb/hidapi/branch/master) |
77
| `BSD, last build (branch/PR)` | [![builds.sr.ht status](https://builds.sr.ht/~z3ntu/hidapi.svg)](https://builds.sr.ht/~z3ntu/hidapi) |
8-
| `Coverity Scan (last)` | ![Coverity Scan](https://scan.coverity.com/projects/583/badge.svg) |
8+
| `Coverity Scan (last)` | [![Coverity Scan](https://scan.coverity.com/projects/583/badge.svg)](https://scan.coverity.com/projects/hidapi) |
99

1010
HIDAPI is a multi-platform library which allows an application to interface
1111
with USB and Bluetooth HID-Class devices on Windows, Linux, FreeBSD, and macOS.

VERSION

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
0.14.0
1+
0.15.0

hidapi/hidapi.h

Lines changed: 66 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -52,7 +52,7 @@
5252
5353
@ingroup API
5454
*/
55-
#define HID_API_VERSION_MINOR 14
55+
#define HID_API_VERSION_MINOR 15
5656
/** @brief Static/compile-time patch version of the library.
5757
5858
@ingroup API
@@ -413,9 +413,9 @@ extern "C" {
413413
single report), followed by the report data (16 bytes). In
414414
this example, the length passed in would be 17.
415415
416-
hid_write() will send the data on the first OUT endpoint, if
417-
one exists. If it does not, it will send the data through
418-
the Control Endpoint (Endpoint 0).
416+
hid_write() will send the data on the first interrupt OUT
417+
endpoint, if one exists. If it does not the behaviour is as
418+
@ref hid_send_output_report
419419
420420
@ingroup API
421421
@param dev A device handle returned from hid_open().
@@ -447,9 +447,11 @@ extern "C" {
447447
@returns
448448
This function returns the actual number of bytes read and
449449
-1 on error.
450-
Call hid_error(dev) to get the failure reason.
450+
Call hid_read_error(dev) to get the failure reason.
451451
If no packet was available to be read within
452452
the timeout period, this function returns 0.
453+
454+
@note This function doesn't change the buffer returned by the hid_error(dev).
453455
*/
454456
int HID_API_EXPORT HID_API_CALL hid_read_timeout(hid_device *dev, unsigned char *data, size_t length, int milliseconds);
455457

@@ -469,12 +471,36 @@ extern "C" {
469471
@returns
470472
This function returns the actual number of bytes read and
471473
-1 on error.
472-
Call hid_error(dev) to get the failure reason.
474+
Call hid_read_error(dev) to get the failure reason.
473475
If no packet was available to be read and
474476
the handle is in non-blocking mode, this function returns 0.
477+
478+
@note This function doesn't change the buffer returned by the hid_error(dev).
475479
*/
476480
int HID_API_EXPORT HID_API_CALL hid_read(hid_device *dev, unsigned char *data, size_t length);
477481

482+
/** @brief Get a string describing the last error which occurred during hid_read/hid_read_timeout.
483+
484+
Since version 0.15.0, @ref HID_API_VERSION >= HID_API_MAKE_VERSION(0, 15, 0)
485+
486+
This function is intended for logging/debugging purposes.
487+
488+
This function guarantees to never return NULL for a valid @ref dev.
489+
If there was no error in the last call to hid_read/hid_read_error -
490+
the returned string clearly indicates that.
491+
492+
Strings returned from hid_read_error() must not be freed by the user,
493+
i.e. owned by HIDAPI library.
494+
Device-specific error string may remain allocated at most until hid_close() is called.
495+
496+
@ingroup API
497+
@param dev A device handle. Shall never be NULL.
498+
499+
@returns
500+
A string describing the hid_read/hid_read_timeout error (if any).
501+
*/
502+
HID_API_EXPORT const wchar_t* HID_API_CALL hid_read_error(hid_device *dev);
503+
478504
/** @brief Set the device handle to be non-blocking.
479505
480506
In non-blocking mode calls to hid_read() will return
@@ -551,6 +577,40 @@ extern "C" {
551577
*/
552578
int HID_API_EXPORT HID_API_CALL hid_get_feature_report(hid_device *dev, unsigned char *data, size_t length);
553579

580+
/** @brief Send a Output report to the device.
581+
582+
Since version 0.15.0, @ref HID_API_VERSION >= HID_API_MAKE_VERSION(0, 15, 0)
583+
584+
Output reports are sent over the Control endpoint as a
585+
Set_Report transfer. The first byte of @p data[] must
586+
contain the Report ID. For devices which only support a
587+
single report, this must be set to 0x0. The remaining bytes
588+
contain the report data. Since the Report ID is mandatory,
589+
calls to hid_send_output_report() will always contain one
590+
more byte than the report contains. For example, if a hid
591+
report is 16 bytes long, 17 bytes must be passed to
592+
hid_send_output_report(): the Report ID (or 0x0, for
593+
devices which do not use numbered reports), followed by the
594+
report data (16 bytes). In this example, the length passed
595+
in would be 17.
596+
597+
This function sets the return value of hid_error().
598+
599+
@ingroup API
600+
@param dev A device handle returned from hid_open().
601+
@param data The data to send, including the report number as
602+
the first byte.
603+
@param length The length in bytes of the data to send, including
604+
the report number.
605+
606+
@returns
607+
This function returns the actual number of bytes written and
608+
-1 on error.
609+
610+
@see @ref hid_write
611+
*/
612+
int HID_API_EXPORT HID_API_CALL hid_send_output_report(hid_device* dev, const unsigned char* data, size_t length);
613+
554614
/** @brief Get a input report from a HID device.
555615
556616
Since version 0.10.0, @ref HID_API_VERSION >= HID_API_MAKE_VERSION(0, 10, 0)

hidtest/test.c

Lines changed: 37 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -128,7 +128,11 @@ void print_hid_report_descriptor_from_device(hid_device *device) {
128128
int res = 0;
129129

130130
printf(" Report Descriptor: ");
131+
#if HID_API_VERSION >= HID_API_MAKE_VERSION(0, 14, 0)
131132
res = hid_get_report_descriptor(device, descriptor, sizeof(descriptor));
133+
#else
134+
(void)res;
135+
#endif
132136
if (res < 0) {
133137
printf("error getting: %ls", hid_error(device));
134138
}
@@ -206,6 +210,10 @@ void test_device(void)
206210
return;
207211
}
208212

213+
#if defined(_WIN32) && HID_API_VERSION >= HID_API_MAKE_VERSION(0, 15, 0)
214+
hid_winapi_set_write_timeout(handle, 5000);
215+
#endif
216+
209217
// Read the Manufacturer String
210218
wstr[0] = 0x0000;
211219
res = hid_get_manufacturer_string(handle, wstr, MAX_STR);
@@ -249,6 +257,13 @@ void test_device(void)
249257
// Try to read from the device. There should be no
250258
// data here, but execution should not block.
251259
res = hid_read(handle, buf, 17);
260+
if (res < 0) {
261+
#if HID_API_VERSION >= HID_API_MAKE_VERSION(0, 15, 0)
262+
printf("Unable to read from device: %ls\n", hid_read_error(handle));
263+
#else
264+
printf("Unable to read from device: %ls\n", hid_error(handle));
265+
#endif
266+
}
252267

253268
// Send a Feature Report to the device
254269
buf[0] = 0x2;
@@ -258,7 +273,7 @@ void test_device(void)
258273
buf[4] = 0x00;
259274
res = hid_send_feature_report(handle, buf, 17);
260275
if (res < 0) {
261-
printf("Unable to send a feature report.\n");
276+
printf("Unable to send a feature report: %ls\n", hid_error(handle));
262277
}
263278

264279
memset(buf,0,sizeof(buf));
@@ -511,11 +526,11 @@ void interactive_loop(void)
511526
test_device();
512527
break;
513528
case '4':
514-
test_hotplug_deadlocks();
515-
break;
529+
test_hotplug_deadlocks();
530+
break;
516531
case 'Q':
517-
printf("Quitting.\n");
518-
return;
532+
printf("Quitting.\n");
533+
return;
519534
default:
520535
printf("Command not recognized\n");
521536
break;
@@ -535,6 +550,23 @@ int main(int argc, char* argv[])
535550
(void)argc;
536551
(void)argv;
537552

553+
/* --- HIDAPI R&D: this is just to force the compiler to ensure
554+
each of those functions are implemented (even as a stub)
555+
by each backend. --- */
556+
(void)&hid_open;
557+
(void)&hid_open_path;
558+
(void)&hid_read_timeout;
559+
(void)&hid_get_input_report;
560+
#if HID_API_VERSION >= HID_API_MAKE_VERSION(0, 15, 0)
561+
(void)&hid_send_output_report;
562+
#endif
563+
(void)&hid_get_feature_report;
564+
(void)&hid_send_feature_report;
565+
#if HID_API_VERSION >= HID_API_MAKE_VERSION(0, 14, 0)
566+
(void)&hid_get_report_descriptor;
567+
#endif
568+
/* --- */
569+
538570
if (hid_init())
539571
return -1;
540572

0 commit comments

Comments
 (0)