Skip to content

Update HIDAPI to match upstream hidapi 0.14.0 #7736

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 36 commits into from
May 26, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
36 commits
Select commit Hold shift + click to select a range
28011e5
Allow declarations after statements
slouken May 24, 2023
a216ec4
Added SDL_wcstol()
slouken May 24, 2023
0d87bb7
Added SDL_swprintf() and SDL_vswprintf()
slouken May 24, 2023
7bbbfb0
Added udev_device_get_syspath() to udev context
slouken May 24, 2023
2378ed1
Fixed build warning on Xcode 14.3
slouken May 25, 2023
ff94d6d
Fixed crash if trying to dump a packet larger than USB_PACKET_LENGTH
slouken May 25, 2023
0bce0fa
Disable HIDAPI libusb support on FreeBSD in CI
slouken May 25, 2023
8aafbbe
Updated hidapi to 0.14.0 release
slouken May 24, 2023
d838e8e
Directly include hidapi.h bundled with the hidapi source code
slouken May 24, 2023
be97686
Fixed compiling hidapi in SDL build environment
slouken May 24, 2023
e0218eb
Fixed building SDL_hidapi.c with new hidapi
slouken May 24, 2023
9e5be34
Added interface_class, interface_subclass, and interface_protocol to …
slouken May 24, 2023
da29eb9
Update the SDL HIDAPI API to match upstream hidapi 0.14.0
slouken May 24, 2023
89f1ebf
Use the bus in the HIDAPI joystick guid now that it's available
slouken May 24, 2023
2cc8cd8
Create wrapper headers for platform specific hidapi modules
slouken May 25, 2023
1ddd0f9
Fixed parameter documentation mismatch
slouken May 24, 2023
a729ba6
Added Android hidapi 0.14.0 support
slouken May 25, 2023
c14ebe7
Added iOS/tvOS hidapi 0.14.0 support
slouken May 25, 2023
e9bad08
hidapi/libusb: use the same logic to get the config descriptor in hid…
slouken May 25, 2023
1d62bf0
hidapi/libusb: use LIBUSB_CALL for the read_callback function
slouken May 25, 2023
9137bf0
hidapi/libusb: maintain in-memory cache of vendor/product strings
slouken May 25, 2023
b9eb0cd
hidapi/libusb: enable support for Xbox 360 and Xbox One controllers
slouken May 25, 2023
a38e723
hidapi/libusb: added quirks for the Sony PS3 controller
slouken May 25, 2023
56b0d76
hidapi/mac: fixed crash on macOS when AirPods are connected
slouken May 25, 2023
3dcfc38
hidapi/mac: Only enumerate IOHIDDevices that are likely to be joysticks
slouken May 25, 2023
80ac619
hidapi/libusb: allow building on Windows, using the SDL C runtime
slouken May 25, 2023
3c3141d
hidapi/windows: allow building on Windows, using the SDL C runtime
slouken May 26, 2023
44753e3
hidapi/windows: avoid enumerating devices that may hang when queried
slouken May 25, 2023
6417f09
hidapi/windows: fix use-after-free SBH corruption due to overlapped R…
slouken May 25, 2023
eb5ec1d
hidapi/windows: do not wait in GetOverlappedResult() in hid_read_time…
slouken May 25, 2023
727512f
hidapi/windows: fixed PS4 controllers over Bluetooth on Windows 7
slouken May 25, 2023
045645e
hidapi/linux: fixed doubled and missing report ID for BLE devices
slouken May 26, 2023
869e2aa
hidapi/linux: retry hid_send_feature_report() if the ioctl() fails wi…
slouken May 26, 2023
d5a28b5
hidapi/linux: fixed crash if uevent info isn't available
slouken May 26, 2023
e6be657
Added SDL_HINT_HIDAPI_IGNORE_DEVICES to specify devices that should b…
slouken May 25, 2023
89027e5
Don't export hidapi functions from SDL
slouken May 26, 2023
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
1 change: 1 addition & 0 deletions .github/workflows/vmactions.yml
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,7 @@ jobs:
cmake -S . -B build -GNinja \
-Wdeprecated -Wdev -Werror \
-DCMAKE_BUILD_TYPE=Release \
-DSDL_HIDAPI_LIBUSB=OFF \
-DSDL_CHECK_REQUIRED_INCLUDES="/usr/local/include" \
-DSDL_CHECK_REQUIRED_LINK_OPTIONS="-L/usr/local/lib"
cmake --build build/ --config Release --verbose -- -j`sysctl -n hw.ncpu`
Expand Down
48 changes: 2 additions & 46 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -570,32 +570,6 @@ if(USE_GCC OR USE_CLANG OR USE_INTELCC OR USE_QCC)
target_compile_options(sdl-global-options INTERFACE "-fno-strict-aliasing")
endif()

# command-line option ‘-Wdeclaration-after-statement’ is valid for C/ObjC but not for C++
check_c_compiler_flag(-Wdeclaration-after-statement HAVE_GCC_WDECLARATION_AFTER_STATEMENT)
if(HAVE_GCC_WDECLARATION_AFTER_STATEMENT)
if(SDL_WERROR)
check_c_compiler_flag(-Werror=declaration-after-statement HAVE_GCC_WERROR_DECLARATION_AFTER_STATEMENT)
if(HAVE_GCC_WERROR_DECLARATION_AFTER_STATEMENT)
if(CMAKE_VERSION VERSION_LESS 3.3)
target_compile_options(sdl-global-options INTERFACE "-Werror=declaration-after-statement")
else()
target_compile_options(sdl-global-options INTERFACE "$<$<COMPILE_LANGUAGE:C>:-Werror=declaration-after-statement>")
if(CMAKE_OBJC_COMPILER)
target_compile_options(sdl-global-options INTERFACE "$<$<COMPILE_LANGUAGE:OBJC>:-Werror=declaration-after-statement>")
endif()
endif()
endif()
endif()
if(CMAKE_VERSION VERSION_LESS 3.3)
target_compile_options(sdl-global-options INTERFACE "-Wdeclaration-after-statement")
else()
target_compile_options(sdl-global-options INTERFACE "$<$<COMPILE_LANGUAGE:C>:-Wdeclaration-after-statement>")
if(CMAKE_OBJC_COMPILER)
target_compile_options(sdl-global-options INTERFACE "$<$<COMPILE_LANGUAGE:OBJC>:-Wdeclaration-after-statement>")
endif()
endif()
endif()

check_c_compiler_flag(-Wdocumentation HAVE_GCC_WDOCUMENTATION)
if(HAVE_GCC_WDOCUMENTATION)
if(SDL_WERROR)
Expand Down Expand Up @@ -1132,16 +1106,7 @@ if(SDL_LIBC)
set(${_HAVE_H} 1)
endforeach()
set(HAVE_SIGNAL_H 1)
foreach(_FN
malloc calloc realloc free bsearch qsort abs memset memcpy memmove memcmp
wcslen _wcsdup wcsdup wcsstr wcscmp wcsncmp _wcsicmp _wcsnicmp
strlen _strrev _strupr _strlwr strchr strrchr strstr itoa _ltoa
_ultoa strtol strtoul strtoll strtod atoi atof strcmp strncmp
_stricmp _strnicmp sscanf
acos acosf asin asinf atan atanf atan2 atan2f ceil ceilf
copysign copysignf cos cosf exp expf fabs fabsf floor floorf fmod fmodf
log logf log10 log10f lround lroundf modf modff pow powf round roundf
scalbn scalbnf sin sinf sqrt sqrtf tan tanf trunc truncf)
foreach(_FN abs acos acosf asin asinf atan atan2 atan2f atanf atof atoi bsearch calloc ceil ceilf copysign copysignf cos cosf exp expf fabs fabsf floor floorf fmod fmodf free itoa log log10 log10f logf lround lroundf _ltoa malloc memcmp memcpy memmove memset modf modff pow powf qsort realloc round roundf scalbn scalbnf sin sinf sqrt sqrtf sscanf strchr strcmp _stricmp strlen _strlwr strncmp _strnicmp strrchr _strrev strstr strtod strtol strtoll strtoul _strupr tan tanf trunc truncf _ultoa wcscmp _wcsdup wcsdup _wcsicmp wcslen wcsncmp _wcsnicmp wcsstr wcstol)
string(TOUPPER ${_FN} _UPPER)
set(HAVE_${_UPPER} 1)
endforeach()
Expand Down Expand Up @@ -1185,16 +1150,7 @@ if(SDL_LIBC)
check_c_source_compiles("#include <sys/types.h>
#include <sys/mman.h>
int main(void) { return 0; }" HAVE_MPROTECT)
foreach(_FN
strtod malloc calloc realloc free getenv setenv putenv unsetenv
bsearch qsort abs bcopy memset memcpy memmove memcmp strlen strlcpy strlcat
_strrev _strupr _strlwr index rindex strchr strrchr strstr strtok_r
itoa _ltoa _uitoa _ultoa strtol strtoul _i64toa _ui64toa strtoll strtoull
atoi atof strcmp strncmp _stricmp strcasecmp _strnicmp strncasecmp strcasestr
wcscmp _wcsdup wcsdup wcslcat wcslcpy wcslen wcsncmp wcsstr
wcscasecmp _wcsicmp wcsncasecmp _wcsnicmp
sscanf vsscanf vsnprintf fopen64 fseeko fseeko64 _Exit
)
foreach(_FN abs atof atoi bcopy bsearch calloc _Exit fopen64 free fseeko fseeko64 getenv _i64toa index itoa _ltoa malloc memcmp memcpy memmove memset putenv qsort realloc rindex setenv sscanf strcasecmp strcasestr strchr strcmp _stricmp strlcat strlcpy strlen _strlwr strncasecmp strncmp _strnicmp strrchr _strrev strstr strtod strtok_r strtol strtoll strtoul strtoull _strupr _ui64toa _uitoa _ultoa unsetenv vsnprintf vsscanf wcscasecmp wcscmp _wcsdup wcsdup _wcsicmp wcslcat wcslcpy wcslen wcsncasecmp wcsncmp _wcsnicmp wcsstr wcstol)
string(TOUPPER ${_FN} _UPPER)
set(LIBC_HAS_VAR "LIBC_HAS_${_UPPER}")
check_symbol_exists("${_FN}" "${STDC_HEADER_NAMES}" ${LIBC_HAS_VAR})
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,9 +13,8 @@ interface HIDDevice
public String getProductName();
public UsbDevice getDevice();
public boolean open();
public int sendFeatureReport(byte[] report);
public int sendOutputReport(byte[] report);
public boolean getFeatureReport(byte[] report);
public int writeReport(byte[] report, boolean feature);
public boolean readReport(byte[] report, boolean feature);
public void setFrozen(boolean frozen);
public void close();
public void shutdown();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -457,7 +457,7 @@ public void onCharacteristicRead(BluetoothGatt gatt, BluetoothGattCharacteristic
//Log.v(TAG, "onCharacteristicRead status=" + status + " uuid=" + characteristic.getUuid());

if (characteristic.getUuid().equals(reportCharacteristic) && !mFrozen) {
mManager.HIDDeviceFeatureReport(getId(), characteristic.getValue());
mManager.HIDDeviceReportResponse(getId(), characteristic.getValue());
}

finishCurrentGattOperation();
Expand Down Expand Up @@ -575,50 +575,45 @@ public boolean open() {
}

@Override
public int sendFeatureReport(byte[] report) {
public int writeReport(byte[] report, boolean feature) {
if (!isRegistered()) {
Log.e(TAG, "Attempted sendFeatureReport before Steam Controller is registered!");
Log.e(TAG, "Attempted writeReport before Steam Controller is registered!");
if (mIsConnected) {
probeService(this);
}
return -1;
}

// We need to skip the first byte, as that doesn't go over the air
byte[] actual_report = Arrays.copyOfRange(report, 1, report.length - 1);
//Log.v(TAG, "sendFeatureReport " + HexDump.dumpHexString(actual_report));
writeCharacteristic(reportCharacteristic, actual_report);
return report.length;
}

@Override
public int sendOutputReport(byte[] report) {
if (!isRegistered()) {
Log.e(TAG, "Attempted sendOutputReport before Steam Controller is registered!");
if (mIsConnected) {
probeService(this);
}
return -1;
if (feature) {
// We need to skip the first byte, as that doesn't go over the air
byte[] actual_report = Arrays.copyOfRange(report, 1, report.length - 1);
//Log.v(TAG, "writeFeatureReport " + HexDump.dumpHexString(actual_report));
writeCharacteristic(reportCharacteristic, actual_report);
return report.length;
} else {
//Log.v(TAG, "writeOutputReport " + HexDump.dumpHexString(report));
writeCharacteristic(reportCharacteristic, report);
return report.length;
}

//Log.v(TAG, "sendFeatureReport " + HexDump.dumpHexString(report));
writeCharacteristic(reportCharacteristic, report);
return report.length;
}

@Override
public boolean getFeatureReport(byte[] report) {
public boolean readReport(byte[] report, boolean feature) {
if (!isRegistered()) {
Log.e(TAG, "Attempted getFeatureReport before Steam Controller is registered!");
Log.e(TAG, "Attempted readReport before Steam Controller is registered!");
if (mIsConnected) {
probeService(this);
}
return false;
}

//Log.v(TAG, "getFeatureReport");
readCharacteristic(reportCharacteristic);
return true;
if (feature) {
readCharacteristic(reportCharacteristic);
return true;
} else {
// Not implemented
return false;
}
}

@Override
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -599,51 +599,34 @@ public boolean openDevice(int deviceID) {
return false;
}

public int sendOutputReport(int deviceID, byte[] report) {
public int writeReport(int deviceID, byte[] report, boolean feature) {
try {
//Log.v(TAG, "sendOutputReport deviceID=" + deviceID + " length=" + report.length);
//Log.v(TAG, "writeReport deviceID=" + deviceID + " length=" + report.length);
HIDDevice device;
device = getDevice(deviceID);
if (device == null) {
HIDDeviceDisconnected(deviceID);
return -1;
}

return device.sendOutputReport(report);
return device.writeReport(report, feature);
} catch (Exception e) {
Log.e(TAG, "Got exception: " + Log.getStackTraceString(e));
}
return -1;
}

public int sendFeatureReport(int deviceID, byte[] report) {
public boolean readReport(int deviceID, byte[] report, boolean feature) {
try {
//Log.v(TAG, "sendFeatureReport deviceID=" + deviceID + " length=" + report.length);
HIDDevice device;
device = getDevice(deviceID);
if (device == null) {
HIDDeviceDisconnected(deviceID);
return -1;
}

return device.sendFeatureReport(report);
} catch (Exception e) {
Log.e(TAG, "Got exception: " + Log.getStackTraceString(e));
}
return -1;
}

public boolean getFeatureReport(int deviceID, byte[] report) {
try {
//Log.v(TAG, "getFeatureReport deviceID=" + deviceID);
//Log.v(TAG, "readReport deviceID=" + deviceID);
HIDDevice device;
device = getDevice(deviceID);
if (device == null) {
HIDDeviceDisconnected(deviceID);
return false;
}

return device.getFeatureReport(report);
return device.readReport(report, feature);
} catch (Exception e) {
Log.e(TAG, "Got exception: " + Log.getStackTraceString(e));
}
Expand Down Expand Up @@ -680,5 +663,5 @@ public void closeDevice(int deviceID) {
native void HIDDeviceDisconnected(int deviceID);

native void HIDDeviceInputReport(int deviceID, byte[] report);
native void HIDDeviceFeatureReport(int deviceID, byte[] report);
native void HIDDeviceReportResponse(int deviceID, byte[] report);
}
77 changes: 38 additions & 39 deletions android-project/app/src/main/java/org/libsdl/app/HIDDeviceUSB.java
Original file line number Diff line number Diff line change
Expand Up @@ -153,49 +153,48 @@ public boolean open() {
}

@Override
public int sendFeatureReport(byte[] report) {
int res = -1;
int offset = 0;
int length = report.length;
boolean skipped_report_id = false;
byte report_number = report[0];

if (report_number == 0x0) {
++offset;
--length;
skipped_report_id = true;
}

res = mConnection.controlTransfer(
UsbConstants.USB_TYPE_CLASS | 0x01 /*RECIPIENT_INTERFACE*/ | UsbConstants.USB_DIR_OUT,
0x09/*HID set_report*/,
(3/*HID feature*/ << 8) | report_number,
mInterface,
report, offset, length,
1000/*timeout millis*/);

if (res < 0) {
Log.w(TAG, "sendFeatureReport() returned " + res + " on device " + getDeviceName());
return -1;
}
public int writeReport(byte[] report, boolean feature) {
if (feature) {
int res = -1;
int offset = 0;
int length = report.length;
boolean skipped_report_id = false;
byte report_number = report[0];

if (report_number == 0x0) {
++offset;
--length;
skipped_report_id = true;
}

if (skipped_report_id) {
++length;
}
return length;
}
res = mConnection.controlTransfer(
UsbConstants.USB_TYPE_CLASS | 0x01 /*RECIPIENT_INTERFACE*/ | UsbConstants.USB_DIR_OUT,
0x09/*HID set_report*/,
(3/*HID feature*/ << 8) | report_number,
mInterface,
report, offset, length,
1000/*timeout millis*/);

if (res < 0) {
Log.w(TAG, "writeFeatureReport() returned " + res + " on device " + getDeviceName());
return -1;
}

@Override
public int sendOutputReport(byte[] report) {
int r = mConnection.bulkTransfer(mOutputEndpoint, report, report.length, 1000);
if (r != report.length) {
Log.w(TAG, "sendOutputReport() returned " + r + " on device " + getDeviceName());
if (skipped_report_id) {
++length;
}
return length;
} else {
int res = mConnection.bulkTransfer(mOutputEndpoint, report, report.length, 1000);
if (res != report.length) {
Log.w(TAG, "writeOutputReport() returned " + res + " on device " + getDeviceName());
}
return res;
}
return r;
}

@Override
public boolean getFeatureReport(byte[] report) {
public boolean readReport(byte[] report, boolean feature) {
int res = -1;
int offset = 0;
int length = report.length;
Expand All @@ -213,7 +212,7 @@ public boolean getFeatureReport(byte[] report) {
res = mConnection.controlTransfer(
UsbConstants.USB_TYPE_CLASS | 0x01 /*RECIPIENT_INTERFACE*/ | UsbConstants.USB_DIR_IN,
0x01/*HID get_report*/,
(3/*HID feature*/ << 8) | report_number,
((feature ? 3/*HID feature*/ : 1/*HID Input*/) << 8) | report_number,
mInterface,
report, offset, length,
1000/*timeout millis*/);
Expand All @@ -234,7 +233,7 @@ public boolean getFeatureReport(byte[] report) {
} else {
data = Arrays.copyOfRange(report, 0, res);
}
mManager.HIDDeviceFeatureReport(mDeviceId, data);
mManager.HIDDeviceReportResponse(mDeviceId, data);

return true;
}
Expand Down
Loading