APIs for Human Input Devices

This site is a joint effort with David Merrill and Olaf Matthes. as part of our [hidio] project.

Here we comment on the various APIs that we have considered during the development of this work. We do not cover APIs that are defunct, such as Apple Input Sprockets and the Windows Joystick API. The APIs in this section are broken down by the operating system they support.

Apple

Apple HID Manager

HID Manager is the standard USB HID API on Mac OS X. It also includes Apple Desktop Bus (ADB) devices like PowerBook keyboards and trackpads. It is very close to the USB HID API and therefore also relatively close to the Windows Driver Development Kit (DDK) HID API. Since it is quite low level, programming with this API is relatively complicated. Understand C pointers well before diving in!

Apple HID Utilities

HID Utilities is an easy-to-use layer on top of HID Manager. It is provided as free software which can be used or modified. Using it is much easier than HID Manager, but it is designed with a very specific application type in mind, so it can limit flexibility. Also, building the device list can be quite heavy, which may cause audio to skip or other undesirable effects. Internally, it uses a number of global variables, which means that multiple instances of [hidio] connected to the same device will steal events from each other.

Linux

Linux input.h

The Linux Input Subsystem, represented by input.h, is a very clean and simple API that unifies a number of APIs: USB HID, PS/2, Wacom, serial mice, ADB, and more. It is quite different from USB HID, including a custom event scheme that can occasionally cause difficulties with more obscure devices. While there is not much documentation, the C header is quite readable and enough to get most things working without much trouble. It has become the standard method for handling input devices in the vast majority of GNU/Linux distributions.

Linux HID (aka hiddev)

Linux's HID API, known as hiddev after the kernel module, is similar to Windows DDK HID and Apple HID Manager since they all closely follow the USB HID API. It provides access only to USB HID devices (i.e. no PS/2, serial, etc). It is useful for a programmer that already knows USB HID and wants to stick to something familiar. Most GNU/Linux distributions will not use the hiddev kernel module by default, so the user will have to set up that module in order to use software based on hiddev.

Microsoft Windows

Windows Driver Development Kit HID

The Windows DDK HID API is like the Apple HID Manager in that is a complicated, low-level API that closely mirrors USB HID. A program can access more or less every device, both input and output, except for the keyboard and mouse, which Microsoft has deliberately blocked from this API. Unlike the other APIs covered so far, the nature of the reading mechanism makes it quite difficult to use without having a thread dedicated to reading events from the queue. While at first glance it may seem necessary to purchase Microsoft's Driver Development Kit in order to use this API, it is possible to use it with the free MinGW tools.

In Windows, notifications of device plug and unplug events are sent to a window handle, so in order to receive them the hidio object needs it's own (invisible) window which can then receive the notifications. In the current implementation the object automatically rebuilds the device list when it receive such a notification. Additionally, in case a device is currently open it checks whether the device is still connected or got removed.

DirectInput

Microsoft's DirectInput API provides a relatively straightforward interface, but at the expense of flexibility. It has limited support for the USB HID device types and mainly aimed at the most popular gaming devices; in USB HID-speak, it only supports the `Generic Desktop Page'. It does provide access to the mouse and keyboard data, but not as individual devices. If there are multiple mice or keyboards attached, then all of the data is lumped into one virtual device. It does support Force Feedback, but not any other output type. Like Linux input.h, it has its own simplified event scheme, and also automatically scales some of the incoming data, which can be problematic.

Windows Raw Input

Raw Input is a new API as of Windows XP that was provided in response to developers' desire to get raw access to the keyboard and mouse. It is the only way to get raw data from mice and keyboards on Windows. With Raw Input, it is possible to get the input events for any USB HID device, but output is not supported at all. For this reason, we have not explored Raw Input deeply yet, but we will probably use it in order to fully support keyboards and mice on Windows.

Cross-platform

libhid

libhid is a free, cross-platform library built on top of libusb, another free, cross-platform library. It is the cleanest direct representation of the USB HID API. It fully supports USB HID, including input, output, and feature reports. The downside is that is does not support Windows without great difficulty on the part of the user because of its reliance on libusb. While some people have gotten it working with libusb on Windows, there are a number of unresolved issues on Windows that prevents it from being usable for most people.

libSDL

libSDL is a free, cross-platform API much in the spirit of Microsoft's DirectInput. It also suffers from some of the same benefits and problems. It covers many platforms and it easier than USB HID-based APIs. But like DirectInput, libSDL automatically scales values, is limited to supporting only the most common device types, and it lumps all mice together, or all keyboards together.

Device-specific APIs

A number of HIDs have their own specific APIs even though they are closely related to the USB HID specification. Two examples are Wacom graphics tablets and the P5 Glove. Both of these are USB devices that are designed for human input. Both provide similar interfaces to the USB HID API, but the manufacturers decided to use custom APIs instead. On some platforms, it is possible to get some data from them using the standard API. In order to fully utilize these devices, the device-specific API must be used. Wacom support has been integrated into Linux input.h, so this is not necessary on GNU/Linux, and tablets are fully supported by [hidio] on that platform. For devices that have custom APIs, we have chosen to create patches in Pd and Max/MSP that provide a similar interface to the [joystick], [gamepad], etc., and to use different objects internally to communicate with the device. It should also be possible to use this same approach to support MIDI-based devices like the Kaoss Pad.


$Id: apis.html,v 1.4 2007/04/14 19:15:24 hans Exp $