Host Computer's Awareness of Layer Keys

User avatar
Muirium
µ

13 May 2013, 18:48

This is specifically about the Mac, but this may be a general topic as both USB and Bluetooth keyboards are interchangeable between platforms, of course.

These screenshots are from the built in "Keyboard Viewer" utility, using Apple's standard compact Bluetooth keyboard.

Layout map for the unmodified keyboard layer.
Standard Layer.tiff
Standard Layer.tiff (92.12 KiB) Viewed 5551 times
This is what happens when you hold Option: the Mac's equivalent of Alt.
Option Layer.tiff
Option Layer.tiff (93.56 KiB) Viewed 5551 times
The orange highlights are "dead keys" which switch you into another mode each. Hitting u, for instance, puts you into ümläüts. e accesses ácúté áccénts. Etc.

But this one's the interesting one. This is with the function key pressed.
Function Layer.tiff
Function Layer.tiff (92.43 KiB) Viewed 5551 times
As far as OS X's concerned, function is just like shift or control etc. It can "see" the key. Function isn't a "state" hidden inside the keyboard, it's exposed to the host.

Note: Fn+1 does not = F1 etc. It's already set aside to handle the cursor keys and a few other odds and ends. In fact, you can assign Fn+1 as a keyboard shortcut for whatever command you like as a user. The OS sees both keys pressed together.

I bumped into this since I'm wanting to design my own keyboard layout for use with the Mac. Do I need to have my own second flavour of function key to access my custom layer? I honestly don't know.

If anyone has an HHKB or another Mac friendly keyboard with its own custom function layer, I'd love to see what Keyboard Viewer shows up for you. Go into System Preferences > Language & Text > Input Sources and check the box called Keyboard & Character Viewer at the top of the list. That'll toggle it on and off in the Input Menu available across the whole system. My screenshots may look a little different, I took them just now on my old iMac G4 running Leopard, with the built in "Grab" utility.

User avatar
Muirium
µ

13 May 2013, 19:28

Ne0phyte reports the HHKB conceals its function key state from the host. It's used entirely within the keyboard's own logic. Quite the opposite of Apple's.

alfa147x

13 May 2013, 20:48

Muirium wrote:Ne0phyte reports the HHKB conceals its function key state from the host. It's used entirely within the keyboard's own logic. Quite the opposite of Apple's.
I feel like most boards do that. I'll have to try my MiniLa and see if it does or doesn't.

User avatar
Muirium
µ

13 May 2013, 20:56

If you're on Mounain Lion, double tap function and see if voice recognition gets activated (same style UI as on iPad). Pretty sure that's the default shortcut. If the keyboard doesn't send an event for the Fn key, OS X will have no idea that anything happened.

What does Keyboard Viewer's layout map look like for your Filco, I wonder? As far as I know, keyboards don't have any way to report their physical layout to the host, beyond their make and model name. So I presume Keyboard Viewer shows something generic.

Findecanor

13 May 2013, 21:27

What happens when you use a Fn key combo on a Mac keyboard plugged into a PC or Linux machine?

User avatar
Muirium
µ

13 May 2013, 21:34

Good question. My Bluetooth keyboard's no good on the old PCs I have to hand. And the other Apple keyboards I have are all built into laptops.

I expect Function does still show up on the host. But as what?

User avatar
Daniel

13 May 2013, 22:58

The Fn key on a Matias Tactile Pro Keyboard (FK302) does not produce any keycode under Linux (tested with xev)

User avatar
matt3o
-[°_°]-

14 May 2013, 00:13

The FN of the original Apple keyboard does not produce any result on xev on Mac either, so I suspect FN on the bluetooth kb on Mac does some sort of firmware voodoo (Apple likes to do things weird :P ).

User avatar
hasu

15 May 2013, 07:19

From souce code, I guess they use their own vendor usage page for those keys, they may use kHIDUsage_AppleVendorKeyboard_Function or kHIDUsage_AV_TopCase_KeyboardFn usage.
http://www.opensource.apple.com/source/ ... geTables.h

And I found some magic numbers and hard code of special care for their own keyboard :p If you want to send FN key to OSX from your DIY keyboard you'll need to emulate Apple vendor ID.

If someone can snag HID descriptor of apple keyboard it must be very useful to discuss.

User avatar
Muirium
µ

15 May 2013, 14:25

I can try, as I borrowed the USB version of my compact Apple keyboard. It can indeed also "see" its fn key.
Et tu USB.tiff
Et tu USB.tiff (55.39 KiB) Viewed 5419 times
Here's the basics as reported by System Information:
Keyboard Hub:

Product ID: 0x1005
Vendor ID: 0x05ac (Apple Inc.)
Version: 96.15
Serial Number: 000000000000
Speed: Up to 480 Mb/sec
Manufacturer: Apple Inc.
Location ID: 0x1d130000 / 4
Current Available (mA): 500
Current Required (mA): 300

Apple Keyboard:

Product ID: 0x021e
Vendor ID: 0x05ac (Apple Inc.)
Version: 0.70
Speed: Up to 1.5 Mb/sec
Manufacturer: Apple Inc.
Location ID: 0x1d132000 / 11
Current Available (mA): 100
Current Required (mA): 20
(The USB keyboard's built in hub is enough to put it over the iPad camera connection kit's stingy current limit, so it doesn't show up without a powered hub. But I digress.)

Googling on HID Descriptor doesn't get me anything I can understand how to do, though. (Interesting Stack Overflow articles about writing custom HID drivers and such!)

I do have IORegistryExplorer though. A useful tool for diagnosing (unsupported / flashed firmware) graphics cards among other things. It has entries for all connected USB devices. Here's an XML dump of its output from OS X 10.8 with said keyboard connected (and my Bluetooth keyboard) as well as the usual bunch of other things hooked into this system.
Both Keyboards Connected.zip
(470.83 KiB) Downloaded 210 times
Just on the off-chance it has the info you are looking for. If you're after something completely different, do tell me.

User avatar
hasu

16 May 2013, 03:09

Thanks, that ioreg file seems to include descriptors and i'm looking into them.
I should use more precise word, report descriptor for that. I'll let you know if I find interesting thing.

User avatar
hasu

16 May 2013, 08:36

Apple keyboard has two interfaces one for keyboard and another for standard media keys(not includes Apple specific).
As expected first one uses usage page 0xff(kHIDPage_AppleVendorTopCase) and usage 0x03(kHIDUsage_AV_TopCase_KeyboardFn) to send Fn key. and Interestingly Apple keyboard seems to be 5KRO!!! hahaha.

I think If you write proper driver for windows or linux you will see Fn event. Or you can emulate Apple keyboard behavior with your DIY keyboard to send Fn to OSX but it is a bit of hassle.

Is there third-party keyboard which can send Fn event without vendor driver as Apple do? I guess no keyboard like that exist in the market because OSX keyboard driver do special only for Apple keyboard. With this magic Apple can makes their own keyboard the most useful for Mac in the market, I suspect.

Code: Select all

Apple Keyboard
VID 0x05ac 1452
PID 0x021e 542
 
Interface 0
$ echo BQEJBqEBBQcZ4CnnFQAlAXUBlQiBApUBdQiBAQUIGQEpBZUFdQGRApUBdQORAQUHGQAq/wCVBXUIFQAm/wCBAAX/CQN1CJUBgQLA | base64 -d | hidrd-convert -o code
0x05, 0x01,         /*  Usage Page (Desktop),               */
0x09, 0x06,         /*  Usage (Keyboard),                   */
0xA1, 0x01,         /*  Collection (Application),           */
0x05, 0x07,         /*      Usage Page (Keyboard),          */
0x19, 0xE0,         /*      Usage Minimum (KB Leftcontrol), */
0x29, 0xE7,         /*      Usage Maximum (KB Right GUI),   */
0x15, 0x00,         /*      Logical Minimum (0),            */
0x25, 0x01,         /*      Logical Maximum (1),            */
0x75, 0x01,         /*      Report Size (1),                */
0x95, 0x08,         /*      Report Count (8),               */
0x81, 0x02,         /*      Input (Variable),               */
0x95, 0x01,         /*      Report Count (1),               */
0x75, 0x08,         /*      Report Size (8),                */
0x81, 0x01,         /*      Input (Constant),               */
0x05, 0x08,         /*      Usage Page (LED),               */
0x19, 0x01,         /*      Usage Minimum (01h),            */
0x29, 0x05,         /*      Usage Maximum (05h),            */
0x95, 0x05,         /*      Report Count (5),               */
0x75, 0x01,         /*      Report Size (1),                */
0x91, 0x02,         /*      Output (Variable),              */
0x95, 0x01,         /*      Report Count (1),               */
0x75, 0x03,         /*      Report Size (3),                */
0x91, 0x01,         /*      Output (Constant),              */
0x05, 0x07,         /*      Usage Page (Keyboard),          */
0x19, 0x00,         /*      Usage Minimum (None),           */
0x2A, 0xFF, 0x00,   /*      Usage Maximum (FFh),            */
0x95, 0x05,         /*      Report Count (5),               */
0x75, 0x08,         /*      Report Size (8),                */
0x15, 0x00,         /*      Logical Minimum (0),            */
0x26, 0xFF, 0x00,   /*      Logical Maximum (255),          */
0x81, 0x00,         /*      Input,                          */
0x05, 0xFF,         /*      Usage Page (FFh),               */
0x09, 0x03,         /*      Usage (03h),                    */
0x75, 0x08,         /*      Report Size (8),                */
0x95, 0x01,         /*      Report Count (1),               */
0x81, 0x02,         /*      Input (Variable),               */
0xC0                /*  End Collection                      */

Interface 1
$ echo BQwJAaEBBQx1AZUBFQAlAQnNgQYJtYECCbaBAgm4gQYJ4oEGCeqBAgnpgQKBAcA= | base64 -d | hidrd-convert -o code
0x05, 0x0C, /*  Usage Page (Consumer),              */
0x09, 0x01, /*  Usage (Consumer Control),           */
0xA1, 0x01, /*  Collection (Application),           */
0x05, 0x0C, /*      Usage Page (Consumer),          */
0x75, 0x01, /*      Report Size (1),                */
0x95, 0x01, /*      Report Count (1),               */
0x15, 0x00, /*      Logical Minimum (0),            */
0x25, 0x01, /*      Logical Maximum (1),            */
0x09, 0xCD, /*      Usage (Play Pause),             */
0x81, 0x06, /*      Input (Variable, Relative),     */
0x09, 0xB5, /*      Usage (Scan Next Track),        */
0x81, 0x02, /*      Input (Variable),               */
0x09, 0xB6, /*      Usage (Scan Previous Track),    */
0x81, 0x02, /*      Input (Variable),               */
0x09, 0xB8, /*      Usage (Eject),                  */
0x81, 0x06, /*      Input (Variable, Relative),     */
0x09, 0xE2, /*      Usage (Mute),                   */
0x81, 0x06, /*      Input (Variable, Relative),     */
0x09, 0xEA, /*      Usage (Volume Dec),             */
0x81, 0x02, /*      Input (Variable),               */
0x09, 0xE9, /*      Usage (Volume Inc),             */
0x81, 0x02, /*      Input (Variable),               */
0x81, 0x01, /*      Input (Constant),               */
0xC0        /*  End Collection                      */

Another keyboard's VID broadcom 0x0a5c, it may be bluetooth keyboard(with mouse?) which has broadcom bt chip. Nothing interesting.

Code: Select all

Broadcom keyboard/mouse bluetooth?
VID: 0x0a5c 2652        Broadcom
PID: 0x4502 17666
$ echo BQEJBqEBhQEFCBkBKQMVACUBdQGVA5EClQWRAQUHGeAp55UIgQJ1CJUBgQEZACmRJv8AlQaBAMA= | base64 -d | hidrd-convert -o code            
0x05, 0x01,         /*  Usage Page (Desktop),               */
0x09, 0x06,         /*  Usage (Keyboard),                   */
0xA1, 0x01,         /*  Collection (Application),           */
0x85, 0x01,         /*      Report ID (1),                  */
0x05, 0x08,         /*      Usage Page (LED),               */
0x19, 0x01,         /*      Usage Minimum (01h),            */
0x29, 0x03,         /*      Usage Maximum (03h),            */
0x15, 0x00,         /*      Logical Minimum (0),            */
0x25, 0x01,         /*      Logical Maximum (1),            */
0x75, 0x01,         /*      Report Size (1),                */
0x95, 0x03,         /*      Report Count (3),               */
0x91, 0x02,         /*      Output (Variable),              */
0x95, 0x05,         /*      Report Count (5),               */
0x91, 0x01,         /*      Output (Constant),              */
0x05, 0x07,         /*      Usage Page (Keyboard),          */
0x19, 0xE0,         /*      Usage Minimum (KB Leftcontrol), */
0x29, 0xE7,         /*      Usage Maximum (KB Right GUI),   */
0x95, 0x08,         /*      Report Count (8),               */
0x81, 0x02,         /*      Input (Variable),               */
0x75, 0x08,         /*      Report Size (8),                */
0x95, 0x01,         /*      Report Count (1),               */
0x81, 0x01,         /*      Input (Constant),               */
0x19, 0x00,         /*      Usage Minimum (None),           */
0x29, 0x91,         /*      Usage Maximum (KB LANG2),       */
0x26, 0xFF, 0x00,   /*      Logical Maximum (255),          */
0x95, 0x06,         /*      Report Count (6),               */
0x81, 0x00,         /*      Input,                          */
0xC0                /*  End Collection                      */

$ echo BQEJAqEBhQIJAaEABQkZASkDFQAlAXUBlQOBApUBdQWBAQUBCTAJMRWBJX91CJUCgQbAwAUMCQGhAYV/BgD/dQiVAxUAJv8AGkD8KkL8sQKFfpUbGkT8Kl78sQKFfXUBlQolARpf/Cpo/IEClQaBAcA= | base64 -d | hidrd-convert -o code                                                                   
0x05, 0x01,         /*  Usage Page (Desktop),               */
0x09, 0x02,         /*  Usage (Mouse),                      */
0xA1, 0x01,         /*  Collection (Application),           */
0x85, 0x02,         /*      Report ID (2),                  */
0x09, 0x01,         /*      Usage (Pointer),                */
0xA1, 0x00,         /*      Collection (Physical),          */
0x05, 0x09,         /*          Usage Page (Button),        */
0x19, 0x01,         /*          Usage Minimum (01h),        */
0x29, 0x03,         /*          Usage Maximum (03h),        */
0x15, 0x00,         /*          Logical Minimum (0),        */
0x25, 0x01,         /*          Logical Maximum (1),        */
0x75, 0x01,         /*          Report Size (1),            */
0x95, 0x03,         /*          Report Count (3),           */
0x81, 0x02,         /*          Input (Variable),           */
0x95, 0x01,         /*          Report Count (1),           */
0x75, 0x05,         /*          Report Size (5),            */
0x81, 0x01,         /*          Input (Constant),           */
0x05, 0x01,         /*          Usage Page (Desktop),       */
0x09, 0x30,         /*          Usage (X),                  */
0x09, 0x31,         /*          Usage (Y),                  */
0x15, 0x81,         /*          Logical Minimum (-127),     */
0x25, 0x7F,         /*          Logical Maximum (127),      */
0x75, 0x08,         /*          Report Size (8),            */
0x95, 0x02,         /*          Report Count (2),           */
0x81, 0x06,         /*          Input (Variable, Relative), */
0xC0,               /*      End Collection,                 */
0xC0,               /*  End Collection,                     */
0x05, 0x0C,         /*  Usage Page (Consumer),              */
0x09, 0x01,         /*  Usage (Consumer Control),           */
0xA1, 0x01,         /*  Collection (Application),           */
0x85, 0x7F,         /*      Report ID (127),                */
0x06, 0x00, 0xFF,   /*      Usage Page (FF00h),             */  Vendor defined
0x75, 0x08,         /*      Report Size (8),                */
0x95, 0x03,         /*      Report Count (3),               */
0x15, 0x00,         /*      Logical Minimum (0),            */
0x26, 0xFF, 0x00,   /*      Logical Maximum (255),          */
0x1A, 0x40, 0xFC,   /*      Usage Minimum (FC40h),          */
0x2A, 0x42, 0xFC,   /*      Usage Maximum (FC42h),          */
0xB1, 0x02,         /*      Feature (Variable),             */
0x85, 0x7E,         /*      Report ID (126),                */
0x95, 0x1B,         /*      Report Count (27),              */
0x1A, 0x44, 0xFC,   /*      Usage Minimum (FC44h),          */
0x2A, 0x5E, 0xFC,   /*      Usage Maximum (FC5Eh),          */
0xB1, 0x02,         /*      Feature (Variable),             */
0x85, 0x7D,         /*      Report ID (125),                */
0x75, 0x01,         /*      Report Size (1),                */
0x95, 0x0A,         /*      Report Count (10),              */
0x25, 0x01,         /*      Logical Maximum (1),            */
0x1A, 0x5F, 0xFC,   /*      Usage Minimum (FC5Fh),          */
0x2A, 0x68, 0xFC,   /*      Usage Maximum (FC68h),          */
0x81, 0x02,         /*      Input (Variable),               */
0x95, 0x06,         /*      Report Count (6),               */
0x81, 0x01,         /*      Input (Constant),               */
0xC0                /*  End Collection                      */

User avatar
Muirium
µ

16 May 2013, 09:11

Thanks hasu. I'm thinking I may go the way everyone else does and forget all about a computer visible Fn. It's a key with particular appeal on 60% keyboards, but I think it would be easier to work around it in my design than to emulate Apple's own identity. 5 vs. 6 KRO included.

I use the key almost exclusively for Page Up/Down and Home/End; adding it to the arrow keys. So I could always make a layer for that!

Apple has a Windows driver for its keyboards included in Boot Camp. (The optional Windows boot mode and downloadable driver bundle for Intel Macs.) But the last install disc and license I have is for Windows 2000 Professional! Kind of fell off the train a while back. Needless to say: incompatible.

Does the Bluetooth keyboard do it any differently to the wired one? I had both hooked up on purpose, for comparison. Bluetooth is the way I want to go with my own designs when I can!

alfa147x

16 May 2013, 21:33

Muirium wrote:Thanks hasu. I'm thinking I may go the way everyone else does and forget all about a computer visible Fn. It's a key with particular appeal on 60% keyboards, but I think it would be easier to work around it in my design than to emulate Apple's own identity. 5 vs. 6 KRO included.

I use the key almost exclusively for Page Up/Down and Home/End; adding it to the arrow keys. So I could always make a layer for that!

Apple has a Windows driver for its keyboards included in Boot Camp. (The optional Windows boot mode and downloadable driver bundle for Intel Macs.) But the last install disc and license I have is for Windows 2000 Professional! Kind of fell off the train a while back. Needless to say: incompatible.

Does the Bluetooth keyboard do it any differently to the wired one? I had both hooked up on purpose, for comparison. Bluetooth is the way I want to go with my own designs when I can!
Download latest Boot Camp update:
http://support.apple.com/kb/DL1638

It will have the latest drivers.
Look in: \BootCamp5.0.5033\BootCamp\Drivers\Apple

Post Reply

Return to “Workshop”