-
Notifications
You must be signed in to change notification settings - Fork 449
Description
Problem
Sending feature reports or output reports and receiving responses is currently well-supported by hidapi.
However, to handle input reports from a device, e.g. to track scroll-wheel-movement, the user has to create a dedicated thread and then poll the device using hid_read().
This is bad in particular on macOS because it already provides a callback-based interface that notifies the user whenever the device issues an input report – IOHIDDeviceRegisterInputReportCallback().
In fact, the macOS implementation of hid_read() is built on top of IOHIDDeviceRegisterInputReportCallback().
That means, when building a callback-system on top of hidapi, on macOS, the control-flow will end up looking something like this:
USB interrupt
-> CFRunLoop
-> IOHIDDeviceRegisterInputReportCallback() callback
-> input_reports queue
-> hid_read()
-> User's polling loop
-> User's callback
We're essentially turning an asynchronous API into a synchronous one, and then turning it back into an asynchronous one through polling.
It seems suboptimal.
Proposal
Therefore I propose a dedicated API for receiving input reports via a callback:
int hid_register_input_report_callback(
hid_device *dev,
void (*callback)(unsigned char *data, size_t length, void *user_data),
void *user_data
);
int hid_unregister_input_report_callback(hid_device *dev);To control which thread the callbacks arrive on, you'd need additional interfaces. For macOS, it could look like this:
void hid_darwin_set_run_loop(hid_device *dev, CFRunLoopRef run_loop);If the thread is left unspecified, the API could spawn its own internal thread to monitor the device and deliver callbacks.
Benefits
With this API, the control-flow on macOS would be much simplified:
Instead of:
USB interrupt
-> CFRunLoop
-> IOHIDDeviceRegisterInputReportCallback() callback
-> input_reports queue
-> hid_read()
-> User's polling loop
-> User's callback
It would be:
USB interrupt
-> CFRunLoop
-> IOHIDDeviceRegisterInputReportCallback() callback
-> hid_register_input_report_callback() callback
Therefore, it should be more efficient.
It would also allow users on macOS to easily have the input reports be delivered on their program's main thread (by simply setting the runLoop to CFRunLoopGetMain()), thereby preventing the need to create and coordinate multiple threads, and potentially making their program less error-prone.
The existing synchronous APIs such as hid_read() could stay exactly as they are.
What about Linux and Windows?
My experience is with macOS, but I think on Linux and Windows, a callback-based API like this would also make hidapi more easy-to-use and efficient for the use cases we discussed, such as tracking scroll-wheel-movement.
As I said, I don't know much about Linux and Windows development, so the specific APIs might have to be adjusted.
Thank you for your time and for maintaining hidapi. It really seems like an exceptional library, and I hope to adopt it in my projects.
Metadata
Metadata
Assignees
Labels
Type
Projects
Status