I'm building a macro keyboard and one of the functions I'm trying to implement is Ctrl+Shift+R, but in the definitions, only one modifier exists in the fixed 8 byte string. How do I implement additional modifiers?
USB keyboards almost always have a HID Report Descriptor that defines each inbound keyboard report as follows:
Bit: 7 6 5 4 3 2 1 0
+---+---+---+---+---+---+---+---+
Byte 0 | RG| RA| RS| RC| LG| LA| LS| LC| Modifier bits (LC=Left Control, LS= Left Shift, etc)
+---+---+---+---+---+---+---+---+
Byte 1 | Reserved byte |
+---+---+---+---+---+---+---+---+
Byte 2 | Key 1 |
+---+---+---+---+---+---+---+---+
Byte 3 | Key 2 |
+---+---+---+---+---+---+---+---+
Byte 4 | Key 3 |
+---+---+---+---+---+---+---+---+
Byte 5 | Key 4 |
+---+---+---+---+---+---+---+---+
Byte 6 | Key 5 |
+---+---+---+---+---+---+---+---+
Byte 7 | Key 6 |
+---+---+---+---+---+---+---+---+
Each modifier key is represented as a single bit in byte 0. To indicate that multiple modifier keys are pressed you would "or" the values together. You could code something like:
#define MOD_LEFT_CONTROL 0b00000001
#define MOD_LEFT_SHIFT 0b00000010
#define MOD_LEFT_ALT 0b00000100
.
.
#define KEY_R 0x15
.
.
modifiers = MOD_LEFT_CONTROL | MOD_LEFT_SHIFT;
reserved = 0;
key[0] = KEY_R;
It is possible to define a HID Report Descriptor that allows modifier key usages to be included in the 6-byte key array but there is usually no need to do that - and the above scheme uses less space anyway.