20150221 - Great Example of Horrible API Interface Design


Linux gamepad support (via /dev/input/event) is one of the best examples of horrible interface design that I can remember. It should serve as a reminder of "how not to do it".

(1.) Sparsely Segmented IDs
Every large gap in a sequence of IDs say for input event codes has an associated increase in complexity for the developer: results in special branching, etc.

(2.) Mix of Same Buttons With Different and Similar IDs on Different Devices
There is a dead obvious common mapping between XBOX and PLAYSTATION controllers which should be used for common IDs. When instead the devices have subsets of different IDs for the same buttons, this results in angry developers.

(3.) The Same IDs Getting Used for Different Buttons on Different Devices
Another example of the same disease: creating extra complexity for the developer. The point of a interface is to reduce complexity. When the app needs to special case the device, right the app is now writing the driver too.

(4.) Using Base 10 Numbering Without Leading Zeros
Talking about the ordering of "event#" in "/dev/input/event" file names. Instead of something dead simple for a program like just "/dev/input/event##" where "##" is a hex number with a leading zero when under 0x10, lets instead make it base ten and require the developer to special case numbers under 10 (remove the leading zero). Fail.

(5.) Keeping Information Used Together On Unaligned Memory
For example, "struct input_id { __u16 bustype; __u16 vendor; __u16 product; __u16 version; };", it should be dead obvious that many developers would want to load "{vendor, product}" as a 32-bit value.

(6.) Providing No Good Way to Know if a Device is a Gamepad
The logic of the interface seems to be that developers need to keep an up-to-date {vendor, product} table for all current and future gamepads, this way they can write all the special case per device code required, or alternatively an even worse option of using a string table by device name.

(7.) Resorting To User-Space Daemons to Translate
Fantastic idea. First lets add extra latency to input. Second lets make it so that applications which handle the native /dev/input/event(s) manually now see duplications of the same device as some other kind of device, but with no obvious way to know the device was duplicated? Third lets push the problem to the user, creating another thing which needs to be configured by an expert and can easly go wrong.

Suggestions on How to Fix This Mess
Add INPUT_PROP_GAMEPAD so devs instantly know if the device is a "gamepad" or not. Any device which has the INPUT_PROP_GAMEPAD property uses a standard common set of contiguous input event codes.