On Mac OS X 10.8.x (Mountain Lion), if a device is connected, opened, then
closed, then unplugged, subsequent calls to hid_enumerate() will still
list the device (even though it's been unplugged). If the device is
plugged in again, a second instance will show up in the list and often it
will be impossible to open either. Github user TamToucan figured out that
in hid_enumerate() if a call is made to IOHIDManagerSetDeviceMatching()
before the call to IOHIDManagerCopyDevices() that this will clear the
problem.
Thanks to TamToucan for figuring this out.
Passing product_id=0 will match any product of a given vendor. This patch
makes it also possible to use vendor_id=0 to match any vendor for a given
product id.
Windows code added to Ludovic's patch by Alan Ott.
Using locations makes the path the same for each run of a HIDAPI based
program. This is useful for opening devices which don't have a serial
number, and where multiple devices of the same type are attached to the
system at once.
This references pull request #78.
There were errors regarding the length of strings in conversion from CFString
to wchar_t.
Thanks to github user nikolajsheller for pointing this out in pull request #80.
Use kIOHIDOptionsTypeSeizeDevice instead of kIOHIDOptionsTypeNone to
avoid interferences with other applications trying to use the HID device
at the same time.
Remove device_list, which was used to match up IOHIDDeviceRef's and
hid_device's in the device removal callback. This was needed because the
removal callback was attached to the whole IOHIDManager, instead of
individual IOHIDDevices.
Instead attach the removal callback to each IOHIDDevice individually,
and have a pointer to the device's hid_device passed to the callback.
This adds the familiar autotools build system and associated documentation
for Linux, FreeBSD, Mac, MinGW, and Cygwin. The old Makefiles have been
kept, and where appropriate have been renamed Makefile-manual.
Thanks to Peter Stuge, Ludovic Rousseau, Xiaofan Chen, Alex Dupre, and
Segher Boessenkool for providing testing, review, and suggestions, and to
Ludovic Rousseau for providing patches which contributed to this commit.
get_serial_number()
get_manufacturer_string()
get_product_string()
This is to match the documentation in the header file, returning 0 on
success and -1 on error.
Fix the problem where hid_enumerate() will crash if any of the HID devices
attached to the system are opened in exclusive mode (using
kIOHIDOptionsTypeSeizeDevice from IOHIDManagerOpen()). According to reports,
some Logitech devices have software which opens devices in exclusive mode,
causing HIDAPI-based programs to crash on systems where these Logitech
devices (and their accompanying software) are installed.
The fix is simple enough. IOHIDManagerOpen() does not need to be called from
HIDAPI, contrary to the examples in Apple's Technical Note TN2187. From
examining the IOHIDManager source[1], it appears that "opening" the
IOHIDManager (not the IOHIDDevice) causes IOHIDManager to try to open all
matching devices connected to the system, failing if even one device cannot
be opened. (Calling IOHIDManagerOpen() does indeed call IOHIDDeviceOpen()
for every matching connected device and for every future matching connected
device as well). HIDAPI of course tries to match all devices (by passing
NULL to IOHIDManagerSetDeviceMatching()), hence the issue.
Empirical evidence first suggested that IOHIDManagerOpen() did not actually
need to be called, and examination of the source[1] seems to confirm that it
only gets in the way.
Many thanks to Brendan Shanks, Bill Good, Github user darthrake, and Vitali
Lovich for pointing this out and participating in the information gathering,
debugging, and discussion.
[1] http://opensource.apple.com/source/IOKitUser/IOKitUser-502/hid.subproj/IOHIDManager.c
Signed-off-by: Alan Ott <alan@signal11.us>
Surrounding application may not be using a run loop (or may not have
given it a chance to run). Process any outstanding events (this does
imply that hid_enumerate will take about at least 1ms to process).
The previous mac/hid.c implementation was kind of problematic. It worked
fine on 10.5, but on 10.7 I have gotten reports of really weird stuff
happening, such as the report callback being called with invalid context
data.
The problem was, the callback's don't get removed from the callback list
when you call IOHIDDeviceClose() in 10.7 like they used to. This means that
the report callback must be unregistered at hid_close() time. Further the
unregister will not work unless you pass _exactly_ the same parameters into
IOHIDDeviceRegisterInputReportCallback() that were passed in the first time
(with the exception of the function being NULL). Thanks Apple for your
stellar documentation and commitment to backwards compatibility.
Further, with the previous implementation, the OS only seemed to buffer
up 4 reports in between calls to CFRunLoopRun*(), causing the potential
for reports to get lost. The new method, being on a separate thread,
will now buffer up to a configurable 30 reports.
The interface number is added to the hid_device_info struct. Since the
Linux/libusb implementation can't put the Usage and Usage Page in the
hid_device_info struct because it requires detaching the kernel driver, the
interface number is added instead so that users with composite HID devices
can differentiate between the interfaces on the device.
Functions with no arguments should use void
hid.c:51: warning: function declaration isn’t a prototype
hid.c:210: warning: function declaration isn’t a prototype
Signed-off-by: Alan Ott <alan@signal11.us>