diff --git a/cores/arduino/HID.cpp b/cores/arduino/HID.cpp index b508f10..378a157 100644 --- a/cores/arduino/HID.cpp +++ b/cores/arduino/HID.cpp @@ -401,18 +401,32 @@ const uint8_t _asciimap[128] = uint8_t USBPutChar(uint8_t c); +// press() adds the specified key (printing, non-printing, or modifier) +// to the persistent key report and sends the report. Because of the way +// USB HID works, the host acts like the key remains pressed until we +// call release(), releaseAll(), or otherwise clear the report and resend. size_t Keyboard_::press(uint8_t k) { uint8_t i; - k = pgm_read_byte(_asciimap + k); - if (!k) { - setWriteError(); - return 0; - } - if (k & 0x80) { - _keyReport.modifiers |= KEY_MODIFIER_LEFT_SHIFT; - k &= 0x7F; + 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) { + _keyReport.modifiers |= 0x02; // the left shift modifier + k &= 0x7F; + } } + + // Add k to the key report only if it's not already present + // and if there is an empty slot. if (_keyReport.keys[0] != k && _keyReport.keys[1] != k && _keyReport.keys[2] != k && _keyReport.keys[3] != k && _keyReport.keys[4] != k && _keyReport.keys[5] != k) { @@ -432,17 +446,40 @@ size_t Keyboard_::press(uint8_t k) return 1; } +// release() takes the specified key out of the persistent key report and +// sends the report. This tells the OS the key is no longer pressed and that +// it shouldn't be repeated any more. size_t Keyboard_::release(uint8_t k) { + /* uint8_t i; k = pgm_read_byte(_asciimap + k); if (!k) { return 0; } if (k & 0x80) { - _keyReport.modifiers |= KEY_MODIFIER_LEFT_SHIFT; + _keyReport.modifiers |= 0x02; // the left shift modifier k &= 0x7F; } + */ + 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) { + return 0; + } + if (k & 0x80) { + _keyReport.modifiers &= ~(0x02); // the left shift modifier + k &= 0x7F; + } + } + + // Test the key report to see if k is present. Clear it if it exists. for (i=0; i<6; i++) { if (_keyReport.keys[i] == k) { _keyReport.keys[i] = 0x00; @@ -468,6 +505,7 @@ void Keyboard_::releaseAll(void) sendReport(&_keyReport); } +// type() does a press and release of the specified key. size_t Keyboard_::type(uint8_t c) { releaseAll(); diff --git a/cores/arduino/USBAPI.h b/cores/arduino/USBAPI.h index 3f71856..05f7318 100644 --- a/cores/arduino/USBAPI.h +++ b/cores/arduino/USBAPI.h @@ -70,14 +70,42 @@ extern Mouse_ Mouse; //================================================================================ // Keyboard -#define KEY_MODIFIER_LEFT_CTRL 0x01 -#define KEY_MODIFIER_LEFT_SHIFT 0x02 -#define KEY_MODIFIER_LEFT_ALT 0x04 -#define KEY_MODIFIER_LEFT_GUI 0x08 -#define KEY_MODIFIER_RIGHT_CTRL 0x010 -#define KEY_MODIFIER_RIGHT_SHIFT 0x020 -#define KEY_MODIFIER_RIGHT_ALT 0x040 -#define KEY_MODIFIER_RIGHT_GUI 0x080 +#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 +#define KEY_BACKSPACE 0xB2 +#define KEY_TAB 0xB3 +#define KEY_RETURN 0xB0 +#define KEY_ESC 0xB1 +#define KEY_INSERT 0xD1 +#define KEY_DELETE 0xD4 +#define KEY_PAGE_UP 0xD3 +#define KEY_PAGE_DOWN 0xD6 +#define KEY_HOME 0xD2 +#define KEY_END 0xD5 +#define KEY_CAPS_LOCK 0xC1 +#define KEY_F1 0xC2 +#define KEY_F2 0xC3 +#define KEY_F3 0xC4 +#define KEY_F4 0xC5 +#define KEY_F5 0xC6 +#define KEY_F6 0xC7 +#define KEY_F7 0xC8 +#define KEY_F8 0xC9 +#define KEY_F9 0xCA +#define KEY_F10 0xCB +#define KEY_F11 0xCC +#define KEY_F12 0xCD // Low level key report: up to 6 keys and shift, ctrl etc at once typedef struct