Generalize handling of extension devices

Since my request for discussion of this topic on the mailing list was not as fruitful as I hoped, I figured it would be best to just whip up a basic implementation of a more flexible EXT handling.

This has no fancy plugin-like interface and I am not sure we need that. The downside is that the application is completely responsible for interpreting the unprocessed data that it is handed by the lib. It would probably be nice to wrap this in some kind of EXT module of the lib, at least for the offical extension devices (currently only Sharp Shooter and Racing Wheel, at the moment of writing).
No, I didn't check if the struct ends up at the same size as before, that's perfect. Of course, a zero-size array doesn't make too much sense.