mirror of
https://github.com/RPCS3/hidapi.git
synced 2026-01-31 01:25:21 +01:00
Added support for Get Input Report (#59)
- Get Input Report supported on linux/libusb, mac and windows; - linux/hidraw doesn't support it on kernel level;
This commit is contained in:
committed by
Ihor Dutchak
parent
7e91963917
commit
083223e779
@@ -334,6 +334,31 @@ extern "C" {
|
||||
*/
|
||||
int HID_API_EXPORT HID_API_CALL hid_get_feature_report(hid_device *dev, unsigned char *data, size_t length);
|
||||
|
||||
/** @brief Get a input report from a HID device.
|
||||
|
||||
Set the first byte of @p data[] to the Report ID of the
|
||||
report to be read. Make sure to allow space for this
|
||||
extra byte in @p data[]. Upon return, the first byte will
|
||||
still contain the Report ID, and the report data will
|
||||
start in data[1].
|
||||
|
||||
@ingroup API
|
||||
@param device A device handle returned from hid_open().
|
||||
@param data A buffer to put the read data into, including
|
||||
the Report ID. Set the first byte of @p data[] to the
|
||||
Report ID of the report to be read, or set it to zero
|
||||
if your device does not use numbered reports.
|
||||
@param length The number of bytes to read, including an
|
||||
extra byte for the report ID. The buffer can be longer
|
||||
than the actual report.
|
||||
|
||||
@returns
|
||||
This function returns the number of bytes read plus
|
||||
one for the report ID (which is still in the first
|
||||
byte), or -1 on error.
|
||||
*/
|
||||
int HID_API_EXPORT HID_API_CALL hid_get_input_report(hid_device *dev, unsigned char *data, size_t length);
|
||||
|
||||
/** @brief Close a HID device.
|
||||
|
||||
This function sets the return value of hid_error().
|
||||
|
||||
29
libusb/hid.c
29
libusb/hid.c
@@ -1237,6 +1237,35 @@ int HID_API_EXPORT hid_get_feature_report(hid_device *dev, unsigned char *data,
|
||||
return res;
|
||||
}
|
||||
|
||||
int HID_API_EXPORT HID_API_CALL hid_get_input_report(hid_device *dev, unsigned char *data, size_t length)
|
||||
{
|
||||
int res = -1;
|
||||
int skipped_report_id = 0;
|
||||
int report_number = data[0];
|
||||
|
||||
if (report_number == 0x0) {
|
||||
/* Offset the return buffer by 1, so that the report ID
|
||||
will remain in byte 0. */
|
||||
data++;
|
||||
length--;
|
||||
skipped_report_id = 1;
|
||||
}
|
||||
res = libusb_control_transfer(dev->device_handle,
|
||||
LIBUSB_REQUEST_TYPE_CLASS|LIBUSB_RECIPIENT_INTERFACE|LIBUSB_ENDPOINT_IN,
|
||||
0x01/*HID get_report*/,
|
||||
(1/*HID Input*/ << 8) | report_number,
|
||||
dev->interface,
|
||||
(unsigned char *)data, length,
|
||||
1000/*timeout millis*/);
|
||||
|
||||
if (res < 0)
|
||||
return -1;
|
||||
|
||||
if (skipped_report_id)
|
||||
res++;
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
void HID_API_EXPORT hid_close(hid_device *dev)
|
||||
{
|
||||
|
||||
@@ -790,6 +790,11 @@ int HID_API_EXPORT hid_get_feature_report(hid_device *dev, unsigned char *data,
|
||||
return res;
|
||||
}
|
||||
|
||||
// Not supported by Linux HidRaw yet
|
||||
int HID_API_EXPORT HID_API_CALL hid_get_input_report(hid_device *dev, unsigned char *data, size_t length)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
void HID_API_EXPORT hid_close(hid_device *dev)
|
||||
{
|
||||
|
||||
@@ -983,6 +983,11 @@ int HID_API_EXPORT hid_get_feature_report(hid_device *dev, unsigned char *data,
|
||||
return get_report(dev, kIOHIDReportTypeFeature, data, length);
|
||||
}
|
||||
|
||||
int HID_API_EXPORT HID_API_CALL hid_get_input_report(hid_device *dev, unsigned char *data, size_t length)
|
||||
{
|
||||
return get_report(dev, kIOHIDReportTypeInput, data, length);
|
||||
}
|
||||
|
||||
void HID_API_EXPORT hid_close(hid_device *dev)
|
||||
{
|
||||
if (!dev)
|
||||
|
||||
@@ -14,4 +14,5 @@ EXPORTS
|
||||
hid_open_path @12
|
||||
hid_send_feature_report @13
|
||||
hid_get_feature_report @14
|
||||
hid_get_input_report @15
|
||||
|
||||
@@ -55,6 +55,7 @@ extern "C" {
|
||||
#define HID_OUT_CTL_CODE(id) \
|
||||
CTL_CODE(FILE_DEVICE_KEYBOARD, (id), METHOD_OUT_DIRECT, FILE_ANY_ACCESS)
|
||||
#define IOCTL_HID_GET_FEATURE HID_OUT_CTL_CODE(100)
|
||||
#define IOCTL_HID_GET_INPUT_REPORT HID_OUT_CTL_CODE(104)
|
||||
|
||||
#ifdef __cplusplus
|
||||
} /* extern "C" */
|
||||
@@ -109,6 +110,7 @@ extern "C" {
|
||||
typedef BOOLEAN (__stdcall *HidD_GetProductString_)(HANDLE handle, PVOID buffer, ULONG buffer_len);
|
||||
typedef BOOLEAN (__stdcall *HidD_SetFeature_)(HANDLE handle, PVOID data, ULONG length);
|
||||
typedef BOOLEAN (__stdcall *HidD_GetFeature_)(HANDLE handle, PVOID data, ULONG length);
|
||||
typedef BOOLEAN (__stdcall *HidD_GetInputReport_)(HANDLE handle, PVOID data, ULONG length);
|
||||
typedef BOOLEAN (__stdcall *HidD_GetIndexedString_)(HANDLE handle, ULONG string_index, PVOID buffer, ULONG buffer_len);
|
||||
typedef BOOLEAN (__stdcall *HidD_GetPreparsedData_)(HANDLE handle, PHIDP_PREPARSED_DATA *preparsed_data);
|
||||
typedef BOOLEAN (__stdcall *HidD_FreePreparsedData_)(PHIDP_PREPARSED_DATA preparsed_data);
|
||||
@@ -121,6 +123,7 @@ extern "C" {
|
||||
static HidD_GetProductString_ HidD_GetProductString;
|
||||
static HidD_SetFeature_ HidD_SetFeature;
|
||||
static HidD_GetFeature_ HidD_GetFeature;
|
||||
static HidD_GetInputReport_ HidD_GetInputReport;
|
||||
static HidD_GetIndexedString_ HidD_GetIndexedString;
|
||||
static HidD_GetPreparsedData_ HidD_GetPreparsedData;
|
||||
static HidD_FreePreparsedData_ HidD_FreePreparsedData;
|
||||
@@ -211,6 +214,7 @@ static int lookup_functions()
|
||||
RESOLVE(HidD_GetProductString);
|
||||
RESOLVE(HidD_SetFeature);
|
||||
RESOLVE(HidD_GetFeature);
|
||||
RESOLVE(HidD_GetInputReport);
|
||||
RESOLVE(HidD_GetIndexedString);
|
||||
RESOLVE(HidD_GetPreparsedData);
|
||||
RESOLVE(HidD_FreePreparsedData);
|
||||
@@ -821,6 +825,55 @@ int HID_API_EXPORT HID_API_CALL hid_get_feature_report(hid_device *dev, unsigned
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
int HID_API_EXPORT HID_API_CALL hid_get_input_report(hid_device *dev, unsigned char *data, size_t length)
|
||||
{
|
||||
#if 0
|
||||
BOOL res;
|
||||
res = HidD_GetInputReport(dev->device_handle, data, length);
|
||||
if (!res) {
|
||||
register_error(dev, "HidD_GetInputReport");
|
||||
return -1;
|
||||
}
|
||||
return length;
|
||||
#else
|
||||
DWORD bytes_returned;
|
||||
|
||||
OVERLAPPED ol;
|
||||
memset(&ol, 0, sizeof(ol));
|
||||
|
||||
BOOL res = DeviceIoControl(dev->device_handle,
|
||||
IOCTL_HID_GET_INPUT_REPORT,
|
||||
data, length,
|
||||
data, length,
|
||||
&bytes_returned, &ol);
|
||||
|
||||
if (!res) {
|
||||
if (GetLastError() != ERROR_IO_PENDING) {
|
||||
/* DeviceIoControl() failed. Return error. */
|
||||
register_error(dev, "Send Input Report DeviceIoControl");
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
/* Wait here until the write is done. This makes
|
||||
hid_get_feature_report() synchronous. */
|
||||
res = GetOverlappedResult(dev->device_handle, &ol, &bytes_returned, TRUE/*wait*/);
|
||||
if (!res) {
|
||||
/* The operation failed. */
|
||||
register_error(dev, "Send Input Report GetOverLappedResult");
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* bytes_returned does not include the first byte which contains the
|
||||
report ID. The data buffer actually contains one more byte than
|
||||
bytes_returned. */
|
||||
bytes_returned++;
|
||||
|
||||
return bytes_returned;
|
||||
#endif
|
||||
}
|
||||
|
||||
void HID_API_EXPORT HID_API_CALL hid_close(hid_device *dev)
|
||||
{
|
||||
if (!dev)
|
||||
|
||||
Reference in New Issue
Block a user