Welcome to Macintosh? An iPad disguised as a Mac Plus using real keyboard and mouse from a Mac Plus! pic.twitter.com/bN1KPSsHpZ— Paul Rickards (@paulrickards) October 26, 2020
If you’ve used a Mac in the last decade (or two?) you’ve noticed that the function keys are repurposed to do things like previous/next track, volume, brightness, and more.
Modern Macs deal with this by having a function key map for specific keyboards, so macOS knows that your Macbook internal keyboard has certain keys that map to certain functions. Prior to that they (sensibly) used USB HID usages to define the keys.
Is there a way to mimic this with our own USB device?
USB HID devices (keyboards, mice, game controllers, etc) describe their capabilities to the host using Usage Pages. These are defined in HID Usage Tables 1.12.
There are many, many possibilities available to use and it would have made sense to just use some of the extra keycodes already there, e.g. use F19 for launchpad. But why bother with that when you could make it more complicated and define your very own set of vendor-specific usages?
Thankfully there are a few resources to find out what usages the keys map to. Running
ioreg -l | grep FnFunctionUsageMap
(thanks to this page) shows the map used for an existing keyboard. The first value is the keyboard usage for F1, F2, etc. and the second is the alternate usage. FF01 is the vendor-specific page, 000C is the consumer devices page and is used for volume controls, play/pause, etc.
We can also reference the open source pieces of macOS, the most useful part being AppleHIDUsageTables.h. This shows all of the Apple-specific pages. The file is blank since 10.14. The relevant one for us is the keyboard page, 0xff01. Others are also worth looking into - what’s AppleVendorLisa?
The relevant usages for modern macOS are:
I already had a HID report for the consumer controls so I just added these onto that, here’s part of the HID descriptor as a C array. It defines a report of one byte with each bit corresponding to a specific usage:
0x05, 0x0c, // USAGE_PAGE (Consumer Devices) 0x09, 0x01, // USAGE (consumer control) 0xA1, 0x01, // COLLECTION (Application) 0x85, 0x01, // REPORT ID 1 0x15, 0x00, // Logical min 0x25, 0x01, // Logical max 0x75, 0x01, // Report size (1) 0x95, 0x08, // Report count (8) 0x09, 0xb5, // Usage: next track 0x09, 0xb6, // Usage: prev track 0x09, 0xcd, // Usage: play/pause 0x09, 0xe9, // Usage: vol up 0x09, 0xea, // Usage: vol down 0x06, 0x01, 0xff, // USAGE_PAGE (Vendor-defined, Apple Keyboard) 0x09, 0x21, // Usage: bright down 0x09, 0x20, // Usage: bright up 0x09, 0x04, // Usage: Launchpad 0x81, 0x02, // INPUT data, var, abs 0x0c // End collection
This works… on a Mac. If that’s all you care about then this is fine, but if you plug it into a Windows machine none of them work. Windows doesn’t know what to do with the vendor-specific piece, so it ignores the entire collection. I ended up using one report for the standard consumer controls and a separate report for the Mac-specific ones.
I spent some time tracking down a strange Arduino bug and made a video about it:
I’m back from VCFMW and had a lot of fun! Met a ton of people, sold a few things, and saw some vintage computers that I never thought I’d see. A BeBox, DataRover, and an LMI Lambda LISP machine (whoa).
While there I released a new product or two, one of which is now up on the website. Check out SunUSB, an adapter that lets you use a USB keyboard and mouse on your Sun workstation. It works with Type 5 and should work with Type 4 as well. It might even work with Type 3 if you have the right cable adapter.
It’s the first of the USB-to-vintage adapters with a two layer keymap because the Sun has a bunch of keys that aren’t on a normal USB keyboard. By default you can press right control to switch the function keys to Stop, Again, Props, Undo, Front, Open, Find, Cut, Copy, Paste, Help, and Power.
I’ll have a keymap editor soon(ish) for it that will let you assign your own keys. That will eventually make its way into the other adapters too, so you’ll be able to program the keymap on your IndigoUSB, NeXTUSB, or any future ones. Speaking of future ones, there will be a couple more very soon…
There’s a new firmware for ADB2USB. This version adds improved enumeration, supporting up to 6 ADB devices. If you wanted to use multiple keyboards at once, now you can! More realistically it will support a separate numpad like the Apple Adjustable Keyboard.
There’s also a new dwfw for Windows that can tell you the current version of the firmware you’re running.