I'm looking to do the same thing - I've made progress, but still can't get it to work.
If you take a look at the hardware/arduino/cores/arduino/USBAPI.h file, it lists out some #defines for button presses:
#define KEY_LEFT_CTRL 0x80
#define KEY_LEFT_SHIFT 0x81
#define KEY_LEFT_ALT 0x82
#define KEY_LEFT_GUI 0x83
#define KEY_RIGHT_CTRL 0x84
#define KEY_RIGHT_SHIFT 0x85
#define KEY_RIGHT_ALT 0x86
#define KEY_RIGHT_GUI 0x87
#define KEY_UP_ARROW 0xDA
#define KEY_DOWN_ARROW 0xD9
#define KEY_LEFT_ARROW 0xD8
#define KEY_RIGHT_ARROW 0xD7
If you compare this to the USB specification (USB HID usage table), you'll find they don't match:
0x4E Keyboard PageDown
0x4F Keyboard RightArrow
0x50 Keyboard LeftArrow
0x51 Keyboard DownArrow
0x52 Keyboard UpArrow
0xE0 Keyboard LeftControl
0xE1 Keyboard LeftShift
0xE2 Keyboard LeftAlt
0xE3 Keyboard Left GUI
0xE4 Keyboard RightControl
0xE5 Keyboard RightShift
0xE6 Keyboard RightAlt
0xE7 Keyboard Right GUI
If you take a look in hardware/arduino/cores/arduino/HID.cpp file, in the 'press' function, you see this:
size_t Keyboard_::press(uint8_t k)
{
uint8_t i;
if (k >= 136) { // it's a non-printing key (not a modifier)
k = k - 136;
} else if (k >= 128) { // it's a modifier key
_keyReport.modifiers |= (1<<(k-128));
k = 0;
} else { // it's a printing key
k = pgm_read_byte(_asciimap + k);
if (!k) {
setWriteError();
return 0;
}
if (k & 0x80) { // it's a capital letter or other character reached with shift
_keyReport.modifiers |= 0x02; // the left shift modifier
k &= 0x7F;
}
}
My first gripe - As a programmer, mixing decimal notation and hex notation is a huge pain. 136=0x88 - which is means that the "KEY_LEFT_CTRL" block of #defines will be caught there. They call these 'Modifiers'. 128=0x80 - anything that falls below this is a standard ASCII key, and they look it up to find the HID code.
The reason they do this is so you can do something like "Keyboard.print("A")" and it'll press the 'A' key. Very helpful for printing text, very NOT helpful if you want to press any old key on the keyboard.
What we want to do is press these keys:
0x7F Keyboard Mute
0x80 Keyboard Volume Up
0x81 Keyboard Volume Down
But if the code is going to subtract 136 (0x88) from them, it is literally impossible to get it to work (with the current 'press' code). Essentially you're limited to only printing the first 256-136 = 120 keys - from 0x00->0x78. JUST SHORT of what we need!
Since that is the case - I went ahead and made some new functions. I made a press_direct and release_direct, which don't do any fiddling with the numbers, they just send it out as-is. I tested my code by passing in the real HID values for letters, and it printed them as expected. Unfortunately - the volume up/down/mute functions STILL don't work!! :0
According to some sources, Windows just doesn't implement the functions in this way. So if the application your sending the keys to will read them, it'll work, but Windows won't pick it up directly. Linux and OS X will apparently work fine.