HID Usage is property of a HID top-level-collection, not of a HID device #453
Labels
No labels
3rdparty
Android
API
Author does not respond
bsd
bug
build system/CI
ci-virtual-device
CMake
Contributions Welcome
Core
dependencies
device-specific
documentation
don't_merge
duplicate
enhancement
Example
Haiku
hidraw
hotplug
info required
invalid
libusb
macOS
Misc
Not an issue
question
Release
Test
Test GUI
Windows
wontfix
No milestone
No assignees
1 participant
Notifications
Due date
No due date set.
Dependencies
No dependencies set
Reference
gh-libusb/hidapi#453
Loading…
Reference in a new issue
No description provided.
Delete branch "%!s()"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
The HID standard doesn't define a Usage for an whole HID device. These property belongs to a top level collection.
From USB HID spec 1.11 page 34:

Sure, that is true.
But to "fix" it right, we would have to introduce a breaking API change -
hid_device_infoshould contain some kind of collection of usage_page/usage pages, instead of a single one. That way the API/behavior will be uniform on all platforms.Current approach (with duplicating the devices) is more about having the functionality and keep full backward compatibility.
I'd say, to make it "right" - is something we should consider for V1.
@Youw
Just a minor thing, you change the title of this issue to "a HID" from "an HID", but actually I think it is more correct to use "an HID".
Ref: https://www.pristineword.com/grammar-an-h/
So the question here is what is the correct pronounce of a HID - is it 'an (aitch i di)', or as a single word - 'a (hid)'.
Maybe I'm biased by my cultural environment (english in not my native), but I always pronounce it as 'a hid'.
I see, I always pronouce it as H-I-D, but I am not a native English speaker either...
Got some interesting argument from my colleague:

MS documentation refers to HID as "a HID":
and multiple other occurrences.
Or, we could just introduce a separate structure called something in the lines of
hid_device_collectionorhid_top_level_devicethat represents the top-level collection (a single physical device)and can contain multiple. Then we introduce a functionhid_device_info'shid_enumerate_collections()that makes them. Problem solved.The structure would be basically a copy of
hid_device_infowith no usage_page and on Windows it's path field would be empty. On other systems it would be able to be opened by path, if necessary.Might interfere with the current hotplug implementation, though. On Windows each of them gets a separate event and there isn't much we can do.
UPD:
hid_free_collectionwould also be needed.UPD2: found a solution on how to merge them on Windows, but it might degrade the performance.
UPD3: if we really care about performance, we can avoid writing the
hid_device_info's into the collection structure and instead have a separate functionhid_enumerate_collection_devices()that retrieves allhid_device_info's for one on request. This will save some time on Linux and on MacOS, where this data is retrieved for each collection from a single source on every enumeration. On Windows it would have to be assembled from multiple endpoints that aren't connected with one another.I could make a simplified implementation if it sounds like a good idea to you.
If you imply having a single "virtual" device on HIDAPI level that would agregate all top level collections as reported by WinAPI - I'm against that idea.
That would complicate the backend implementation.
I'd be happier to see a hid_device_info with a list of available collections (usaga/usage_page pairs) where on most systems there would be a list of available pairs, and on Windows there would be multiple devices with a list contain a single element.
I'm more into having as simpler wrapper/implementation over what OS provides as possible.
I'm not sure this is a good idea.
I'd expect hidapi to abstract platform specific details so the applications using hidapi become multi-platform (ignoring smaller quirks) - isn't that the whole point of it?
I don't think it'd be wise to expect the application to handle more than one API behaviour (depending on backend).
With such API design I don't really see the benefit of using hidapi over just using the native functions in each application (or using another hid library), because the burden of "fixing" the interface behaviour would have to be part of the application anyway (which is probably more work than interfacing with the platforms hid interface).
By using native functions over hidapi you'd at least be able to know the quirks at time of writing, whereas with hidapi you'd have to speculatively fix all possible behaviour quirks of each backend - hidapi would be useless.
The existing API and platform specific behaviour appears to already cause issues which breaks cross-platform support.
OpenRGB does
hid_enumerateand calls a detector function for each device, trying to recombine different usage pages / usages into the same device again.That code was written for some platform where each report in the top-level collection is returned as separate devices, but for me (on Linux) I only seem to receive the report of the top-level collection - so it doesn't work depending on the backend.
Likewise, I was also surprised that OpenRGB has to copy internal hidapi functions to parse the report descriptors. I understand that hidapi hasn't reach v1 yet, but if it doesn't actually expose functions to work with found hid devices and wouldn't even abstract/fix platform specific behaviour, then I'm not sure why anyone should consider hidapi - the application seems to have to do all the work anyway and hidapi merely acts as reference code.