Keyboard - Fn keys customization
================================
This document describes observations with the K800 keyboard which features
customizable Fn keys and a HID++ 1.0 protocol. Its observations may apply to
other HID++ 1.0 keyboards too.

See registers.txt for HID++ details. Important knowledge from that file:
- Setting Notifications flags makes the keyboard emit different HID reports that
  can be captured by the software to generate custom events.
- The functionality Fx and Fn + Fx can be swapped (e.g. pressing F1 generates a
  "Web" event, Fn + F1 generates the regular "F1" event).


The Consumer Control (3) and System Control (4) descriptors have the following
descriptors:
  INPUT(3)[INPUT]
    Field(0)
      Application(Consumer.0001)
      Usage(652)
        Consumer.0001
        Consumer.0002
        ... (a lot Consumer.xxxx omitted) ...
        Consumer.028b
        Consumer.028c
      Logical Minimum(1)
      Logical Maximum(652)
      Report Size(16)
      Report Count(2)
      Report Offset(0)
      Flags( Array Absolute )
  INPUT(4)[INPUT]
    Field(0)
      Application(GenericDesktop.SystemControl)
      Usage(3)
        GenericDesktop.SystemSleep
        GenericDesktop.SystemPowerDown
        GenericDesktop.SystemWakeUp
      Logical Minimum(1)
      Logical Maximum(3)
      Report Size(2)
      Report Count(1)
      Report Offset(0)
      Flags( Array Absolute NoPreferredState NullState )

/* At most two simultaneous key presses can be registered. If a button is not
 * pressed, the value for that "button" is 00 00. The HID layer keeps a state of
 * which keys are pressed, reports simply change that state.
 * 
 * 92 01  00 00 - Pressed "Calculator" (0192)
 * 92 01  b5 00 - Pressed "Forward" (00b5)
 * b5 00  00 00 - Released "Calculator" (0192 has gone)
 * 00 00  00 00 - Released "Forward" (00b5 has gone)
 */
struct consumer_control_data {
	uint16_t button1;
	uint16_t button2;
}

/* The button is a number in the range 1 - 3 (0 means released)
 */
struct system_control_data {
	char button : 2; /* two right-most bits, Big Endian */
};

The 20 ix yy dd.. ... messages below are described as follows:
- 20: Report ID for Logitech Vendor DJ collection (messages are not processed by
  the hid-logitech-dj driver but are passed through to the HID layer.)
- yy: descriptor type (system control, consumer control, keyboard, etc.)
- dd..: data, length is dependent on descriptor type.
- Remaining bytes is garbage/padding and can be ignored (confirmed by Nestor
  from Logitech).


The following describes what events are generated when a certain flag is toggled
	in the notification register 00.
flag 1, bit 1 - controls "System Control" events?
Format:
	(disabled bit) 20 ix 04  XX ... (other 11 bytes is padding)
	(enabled  bit) 10 ix 04  XX 00 00 00
Values for XX:
- 01: Sleep Button (Fn + F8)


flag 1, bit 0 - controls "Consumer Control" events?
Format:
	(disabled bit) 20 ix 03  XX xx YY yy ... (other 8 bytes is padding)
	(enabled  bit) 10 ix 03  XX xx YY yy
XX xx and YY yy are two buttons that are pressed according to the keyboard (see
also struct consumer_control_data above).
Known keys (XX xx are shown as xxXX):
- 0223: Web (Fn + F1)
- 018a: Email (Fn + F2)
- 0221: Search (Fn + F3)
- 0183: Music (Fn + F9)
- 00b6: Previous (Fn + F10)
- 00cd: Play/Pause (Fn + F10)
- 00b5: Next (Fn + F10)
- 00e2: Mute
- 00ea: Volume down
- 00e9: Volume up
- 0192: Calculator
- 102c: "Fn" button
Note: when Fn keys are not swapped, pressing Fn + F1 will still generate 102c:
              vv vv-------- Fn (102c)
    10 ix 03  2c 10 23 02
                    ^^ ^^-- Web (0223)

Remaining unmappable keys:
- Application Switcher (Fn + F4)
- Illumination brightnesss down (Fn + F5)
- Illumination brightnesss up (Fn + F6)
- Battery status (Fn + F7)
