Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
23 commits
Select commit Hold shift + click to select a range
bda7101
Explicitly use non-ARM64 macOS runner
Youw Apr 28, 2024
6c2de30
Switch to macos-13 for Coverity
Youw Apr 28, 2024
4578ea2
Add hid_send_output_report() (#677)
mbcinergy Jun 12, 2024
9fc8b01
hid_send_output_report: bump version to 0.15.0
Youw Aug 2, 2024
d101e5c
macOS: fix hid_send_output_report implementation
Youw Aug 2, 2024
c3c79a7
hidapi: fix "conversion from 'size_t' to 'int', possible loss of data…
madebr Aug 21, 2024
f2e8d41
build(deps): bump actions/download-artifact from 3 to 4 in /.github/w…
dependabot[bot] Sep 6, 2024
ba28d38
Update upload-artifact action to v4 (#693)
Youw Sep 15, 2024
5c4acf8
Windows: return bytes_written if WriteFile returns synchronously (#697)
Megamouse Sep 29, 2024
c15392a
winapi: add hid_winapi_set_write_timeout (#700)
Youw Oct 3, 2024
750bf20
Add missing checks for malloc/calloc/CloseHandle (#702)
Megamouse Oct 3, 2024
ff67c77
Reconstruction logic for padding bytes at the end of Reports (only po…
JoergAtGithub Oct 30, 2024
b26f057
Ensure last_error_str released on macOS (#714)
Youw Jan 14, 2025
c5ee4d3
Fix WinAPI backend compilation as C++ source (#718)
toxieainc Feb 25, 2025
2446b2a
macOS: add option to mimic 1.0.0 compatibility version (#709)
Youw Mar 1, 2025
424d63f
Update docs.yaml (#722)
Youw Mar 2, 2025
122ecb0
Simplify doxygen installation (#723)
Youw Mar 2, 2025
95e6b98
Add hid_read_error (#721)
Youw Mar 11, 2025
0ab6c14
Add missing sanity checks (#727)
Youw Mar 13, 2025
8c9cbf6
Fix CI build on latest Archlinux (#733)
Youw Apr 4, 2025
4da6b89
Update link on Coverity status badge (#738)
Youw May 6, 2025
3425db0
CI: Install awk on Fedora for Autotools (#739)
Youw May 7, 2025
eb0f87d
Merge branch 'master' into connection-callback
k1-801 May 18, 2025
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 4 additions & 4 deletions .github/workflows/builds.yml
Original file line number Diff line number Diff line change
Expand Up @@ -351,7 +351,7 @@ jobs:
Copy-Item "windows\x64\Release\hidapi.dll","windows\x64\Release\hidapi.lib","windows\x64\Release\hidapi.pdb" -Destination "artifacts\x64"
Copy-Item "hidapi\hidapi.h","windows\hidapi_winapi.h" -Destination "artifacts\include"
- name: Upload artifacts
uses: actions/upload-artifact@v3
uses: actions/upload-artifact@v4
with:
name: hidapi-win
path: artifacts/
Expand All @@ -367,7 +367,7 @@ jobs:
with:
path: hidapisrc
- name: Install dependencies
run: sudo dnf install -y autoconf automake libtool mingw64-gcc cmake ninja-build make
run: sudo dnf install -y autoconf automake libtool gawk mingw64-gcc cmake ninja-build make
- name: Configure CMake
run: |
rm -rf build install
Expand Down Expand Up @@ -485,7 +485,7 @@ jobs:
cmake \
-B build/shared_test \
-S hidapisrc/hidtest \
-Dhidapi_ROOT=install/shared-cmake \
-Dhidapi_ROOT=$(pwd)/install/shared-cmake \
-DCMAKE_INSTALL_PREFIX=install/shared_test \
"-DCMAKE_C_FLAGS=${GNU_COMPILE_FLAGS}"
cd build/shared_test
Expand All @@ -495,7 +495,7 @@ jobs:
cmake \
-B build/static_test \
-S hidapisrc/hidtest \
-Dhidapi_ROOT=install/static-cmake \
-Dhidapi_ROOT=$(pwd)/install/static-cmake \
-DCMAKE_INSTALL_PREFIX=install/static_test \
"-DCMAKE_C_FLAGS=${GNU_COMPILE_FLAGS}"
cd build/static_test
Expand Down
12 changes: 6 additions & 6 deletions .github/workflows/checks.yml
Original file line number Diff line number Diff line change
Expand Up @@ -63,15 +63,15 @@ jobs:
cov-build --dir cov-int nmake
Rename-Item ".\cov-int\emit\$(hostname)" hostname
- name: Backup Coverity logs
uses: actions/upload-artifact@v3
uses: actions/upload-artifact@v4
with:
name: coverity-logs-windows
path: build/cov-int
retention-days: 7


coverity-macos:
runs-on: macos-latest
runs-on: macos-13
needs: [coverity-windows]

steps:
Expand All @@ -83,7 +83,7 @@ jobs:
- name: Configure
run: |
cmake -B build -S src -GNinja -DCMAKE_BUILD_TYPE=RelWithDebInfo -DHIDAPI_WITH_TESTS=ON -DHIDAPI_BUILD_HIDTEST=ON -DCMAKE_C_COMPILER=clang
- uses: actions/download-artifact@v3
- uses: actions/download-artifact@v4
with:
name: coverity-logs-windows
path: build/cov-int
Expand Down Expand Up @@ -123,7 +123,7 @@ jobs:
cov-build --dir cov-int --append-log ninja
mv cov-int/emit/$(hostname) cov-int/emit/hostname
- name: Backup Coverity logs
uses: actions/upload-artifact@v3
uses: actions/upload-artifact@v4
with:
name: coverity-logs-windows-macos
path: build/cov-int
Expand All @@ -145,7 +145,7 @@ jobs:
- name: Configure
run: |
cmake -B build -S src -GNinja -DCMAKE_BUILD_TYPE=RelWithDebInfo -DHIDAPI_WITH_TESTS=ON -DHIDAPI_BUILD_HIDTEST=ON -DCMAKE_C_COMPILER=gcc
- uses: actions/download-artifact@v3
- uses: actions/download-artifact@v4
with:
name: coverity-logs-windows-macos
path: build/cov-int
Expand Down Expand Up @@ -191,7 +191,7 @@ jobs:
https://scan.coverity.com/builds?project=hidapi
mv cov-int/emit/$(hostname) cov-int/emit/hostname
- name: Backup Coverity logs
uses: actions/upload-artifact@v3
uses: actions/upload-artifact@v4
with:
name: coverity-logs-windows-macos-linux
path: build/cov-int
Expand Down
28 changes: 8 additions & 20 deletions .github/workflows/docs.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -8,50 +8,38 @@ on:

jobs:
build:
runs-on: ubuntu-latest
runs-on: ubuntu-24.04
steps:
- name: Install Doxygen
run: sudo apt satisfy "doxygen (>= 1.9.6)"

- name: Install Doxygen static libclang deps
run: sudo apt-get install libclang1-12 libclang-cpp12

- name: Install Doxygen from SF binary archives
env:
DOXYGEN_VERSION: '1.9.6'
run: |
mkdir .doxygen && cd .doxygen
curl -L https://sourceforge.net/projects/doxygen/files/rel-$DOXYGEN_VERSION/doxygen-$DOXYGEN_VERSION.linux.bin.tar.gz > doxygen.tar.gz
gunzip doxygen.tar.gz
tar xf doxygen.tar
cd doxygen-$DOXYGEN_VERSION
sudo make install

- uses: actions/checkout@v3
- uses: actions/checkout@v4

- run: doxygen
working-directory: doxygen

- name: Save doxygen docs as artifact
uses: actions/upload-artifact@v3
uses: actions/upload-artifact@v4
with:
name: HIDAPI_doxygen_docs
path: ${{ github.workspace }}/doxygen/html

deploy-docs:
runs-on: ubuntu-latest
runs-on: ubuntu-24.04
needs: [build]
if: github.ref_type == 'branch' && github.ref_name == 'master'
concurrency:
group: "github-pages-deploy"
cancel-in-progress: true
steps:
- name: downlod artifact
uses: actions/download-artifact@v3
uses: actions/download-artifact@v4
with:
name: HIDAPI_doxygen_docs
path: docs

- name: upload to github pages
uses: peaceiris/actions-gh-pages@v3
uses: peaceiris/actions-gh-pages@v4
with:
github_token: ${{ secrets.GITHUB_TOKEN }}
publish_dir: ./docs
Expand Down
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
| `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) |
| `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) |
| `BSD, last build (branch/PR)` | [![builds.sr.ht status](https://builds.sr.ht/~z3ntu/hidapi.svg)](https://builds.sr.ht/~z3ntu/hidapi) |
| `Coverity Scan (last)` | ![Coverity Scan](https://scan.coverity.com/projects/583/badge.svg) |
| `Coverity Scan (last)` | [![Coverity Scan](https://scan.coverity.com/projects/583/badge.svg)](https://scan.coverity.com/projects/hidapi) |

HIDAPI is a multi-platform library which allows an application to interface
with USB and Bluetooth HID-Class devices on Windows, Linux, FreeBSD, and macOS.
Expand Down
2 changes: 1 addition & 1 deletion VERSION
Original file line number Diff line number Diff line change
@@ -1 +1 @@
0.14.0
0.15.0
76 changes: 70 additions & 6 deletions hidapi/hidapi.h
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,7 @@

@ingroup API
*/
#define HID_API_VERSION_MINOR 14
#define HID_API_VERSION_MINOR 15
/** @brief Static/compile-time patch version of the library.

@ingroup API
Expand Down Expand Up @@ -413,9 +413,9 @@ extern "C" {
single report), followed by the report data (16 bytes). In
this example, the length passed in would be 17.

hid_write() will send the data on the first OUT endpoint, if
one exists. If it does not, it will send the data through
the Control Endpoint (Endpoint 0).
hid_write() will send the data on the first interrupt OUT
endpoint, if one exists. If it does not the behaviour is as
@ref hid_send_output_report

@ingroup API
@param dev A device handle returned from hid_open().
Expand Down Expand Up @@ -447,9 +447,11 @@ extern "C" {
@returns
This function returns the actual number of bytes read and
-1 on error.
Call hid_error(dev) to get the failure reason.
Call hid_read_error(dev) to get the failure reason.
If no packet was available to be read within
the timeout period, this function returns 0.

@note This function doesn't change the buffer returned by the hid_error(dev).
*/
int HID_API_EXPORT HID_API_CALL hid_read_timeout(hid_device *dev, unsigned char *data, size_t length, int milliseconds);

Expand All @@ -469,12 +471,40 @@ extern "C" {
@returns
This function returns the actual number of bytes read and
-1 on error.
Call hid_error(dev) to get the failure reason.
Call hid_read_error(dev) to get the failure reason.
If no packet was available to be read and
the handle is in non-blocking mode, this function returns 0.

@note This function doesn't change the buffer returned by the hid_error(dev).
*/
int HID_API_EXPORT HID_API_CALL hid_read(hid_device *dev, unsigned char *data, size_t length);

/** @brief Get a string describing the last error which occurred during hid_read/hid_read_timeout.

Since version 0.15.0, @ref HID_API_VERSION >= HID_API_MAKE_VERSION(0, 15, 0)

This function is intended for logging/debugging purposes.

This function guarantees to never return NULL.
If there was no error in the last call to hid_read/hid_read_error -
the returned string clearly indicates that.

Any HIDAPI function that can explicitly indicate an execution failure
(e.g. by an error code, or by returning NULL) - may set the error string,
to be returned by this function.

Strings returned from hid_read_error() must not be freed by the user,
i.e. owned by HIDAPI library.
Device-specific error string may remain allocated at most until hid_close() is called.

@ingroup API
@param dev A device handle. Shall never be NULL.

@returns
A string describing the hid_read/hid_read_timeout error (if any).
*/
HID_API_EXPORT const wchar_t* HID_API_CALL hid_read_error(hid_device *dev);

/** @brief Set the device handle to be non-blocking.

In non-blocking mode calls to hid_read() will return
Expand Down Expand Up @@ -551,6 +581,40 @@ extern "C" {
*/
int HID_API_EXPORT HID_API_CALL hid_get_feature_report(hid_device *dev, unsigned char *data, size_t length);

/** @brief Send a Output report to the device.

Since version 0.15.0, @ref HID_API_VERSION >= HID_API_MAKE_VERSION(0, 15, 0)

Output reports are sent over the Control endpoint as a
Set_Report transfer. The first byte of @p data[] must
contain the Report ID. For devices which only support a
single report, this must be set to 0x0. The remaining bytes
contain the report data. Since the Report ID is mandatory,
calls to hid_send_output_report() will always contain one
more byte than the report contains. For example, if a hid
report is 16 bytes long, 17 bytes must be passed to
hid_send_output_report(): the Report ID (or 0x0, for
devices which do not use numbered reports), followed by the
report data (16 bytes). In this example, the length passed
in would be 17.

This function sets the return value of hid_error().

@ingroup API
@param dev A device handle returned from hid_open().
@param data The data to send, including the report number as
the first byte.
@param length The length in bytes of the data to send, including
the report number.

@returns
This function returns the actual number of bytes written and
-1 on error.

@see @ref hid_write
*/
int HID_API_EXPORT HID_API_CALL hid_send_output_report(hid_device* dev, const unsigned char* data, size_t length);

/** @brief Get a input report from a HID device.

Since version 0.10.0, @ref HID_API_VERSION >= HID_API_MAKE_VERSION(0, 10, 0)
Expand Down
34 changes: 33 additions & 1 deletion hidtest/test.c
Original file line number Diff line number Diff line change
Expand Up @@ -128,7 +128,11 @@ void print_hid_report_descriptor_from_device(hid_device *device) {
int res = 0;

printf(" Report Descriptor: ");
#if HID_API_VERSION >= HID_API_MAKE_VERSION(0, 14, 0)
res = hid_get_report_descriptor(device, descriptor, sizeof(descriptor));
#else
(void)res;
#endif
if (res < 0) {
printf("error getting: %ls", hid_error(device));
}
Expand Down Expand Up @@ -206,6 +210,10 @@ void test_device(void)
return;
}

#if defined(_WIN32) && HID_API_VERSION >= HID_API_MAKE_VERSION(0, 15, 0)
hid_winapi_set_write_timeout(handle, 5000);
#endif

// Read the Manufacturer String
wstr[0] = 0x0000;
res = hid_get_manufacturer_string(handle, wstr, MAX_STR);
Expand Down Expand Up @@ -249,6 +257,13 @@ void test_device(void)
// Try to read from the device. There should be no
// data here, but execution should not block.
res = hid_read(handle, buf, 17);
if (res < 0) {
#if HID_API_VERSION >= HID_API_MAKE_VERSION(0, 15, 0)
printf("Unable to read from device: %ls\n", hid_read_error(handle));
#else
printf("Unable to read from device: %ls\n", hid_error(handle));
#endif
}

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

memset(buf,0,sizeof(buf));
Expand Down Expand Up @@ -535,6 +550,23 @@ int main(int argc, char* argv[])
(void)argc;
(void)argv;

/* --- HIDAPI R&D: this is just to force the compiler to ensure
each of those functions are implemented (even as a stub)
by each backend. --- */
(void)&hid_open;
(void)&hid_open_path;
(void)&hid_read_timeout;
(void)&hid_get_input_report;
#if HID_API_VERSION >= HID_API_MAKE_VERSION(0, 15, 0)
(void)&hid_send_output_report;
#endif
(void)&hid_get_feature_report;
(void)&hid_send_feature_report;
#if HID_API_VERSION >= HID_API_MAKE_VERSION(0, 14, 0)
(void)&hid_get_report_descriptor;
#endif
/* --- */

if (hid_init())
return -1;

Expand Down
Loading
Loading