diff --git a/Readme.md b/Readme.md index dfaa9b6..71037aa 100644 --- a/Readme.md +++ b/Readme.md @@ -91,8 +91,6 @@ Version History * Added a few key definitions * Uses .alinkage custom IDE option * Added BootKeyboard support (BIOS compatibility) -* KEY_MENU switched to KEY_APPLICATION -* KEY_RETURN is not KEY_ENTER anymore! 2.3 Release (never released) * Updated Libraries diff --git a/examples/ImprovedKeyboard/ImprovedKeyboard.ino b/examples/ImprovedKeyboard/ImprovedKeyboard.ino index 23fb0fa..37bcf3e 100644 --- a/examples/ImprovedKeyboard/ImprovedKeyboard.ino +++ b/examples/ImprovedKeyboard/ImprovedKeyboard.ino @@ -38,9 +38,26 @@ void loop() { // Write single keys, do not use a number here! //Keyboard.write(KEY_ENTER); + // If you really wish to press a RAW keycode without the name use this: //Keyboard.write(KeyboardKeycode(40)); + // Use (a limited number of) consumer keys. + // Only works with the lower 255 keys and on linux only. + //Keyboard.write(MEDIA_PLAY_PAUSE); + + // Linux also supports several system function via consumer report. + //Keyboard.write(CONSUMER_POWER); + //Keyboard.write(CONSUMER_SLEEP); + + // You can also use some special keyboard keys on linux. + //Keyboard.write(KEY_POWER); + //Keyboard.write(KEY_F13); + + // You can wakeup you PC from sleep. + // This might be not supported on all hardware, but on all OS types. + //Keyboard.wakeupHost(); + // Simple debounce delay(300); digitalWrite(pinLed, LOW); diff --git a/src/HID-APIs/ImprovedKeylayouts.h b/src/HID-APIs/ImprovedKeylayouts.h index 7574a8d..1c9c5a3 100644 --- a/src/HID-APIs/ImprovedKeylayouts.h +++ b/src/HID-APIs/ImprovedKeylayouts.h @@ -133,6 +133,7 @@ enum KeyboardKeycode : uint8_t { KEYPAD_SUBTRACT = 0x56, KEYPAD_ADD = 0x57, KEYPAD_ENTER = 0x59, + KEY_RETURN = 0x59, // Alias KEYPAD_1 = 0x59, KEYPAD_2 = 0x5A, KEYPAD_3 = 0x5B, @@ -146,6 +147,7 @@ enum KeyboardKeycode : uint8_t { KEYPAD_DOT = 0x63, KEY_NON_US = 0x64, KEY_APPLICATION = 0x65, // Context menu/right click + KEY_MENU = 0x65, // Alias // Most of the following keys will only work with Linux or not at all. // F13+ keys are mostly used for laptop functions like ECO key. @@ -165,7 +167,7 @@ enum KeyboardKeycode : uint8_t { KEY_F24 = 0x73, // Disabled (Ubuntu) KEY_EXECUTE = 0x74, // Open (Ubuntu) KEY_HELP = 0x75, // Help (Ubuntu) - KEY_MENU = 0x76, // Disabled (Ubuntu) + KEY_MENU2 = 0x76, // Disabled (Ubuntu) KEY_SELECT = 0x77, // Disabled (Ubuntu) KEY_STOP = 0x78, // Cancel (Ubuntu) KEY_AGAIN = 0x79, // Redo (Ubuntu) @@ -206,7 +208,7 @@ enum KeyboardKeycode : uint8_t { KEY_CANCEL = 0x9B, // Disabled (Ubuntu) KEY_CLEAR = 0x9C, // Delete (Ubuntu) KEY_PRIOR = 0x9D, // Disabled (Ubuntu) - KEY_RETURN = 0x9E, // Disabled (Ubuntu), Do not confuse this with KEY_ENTER + KEY_RETURN2 = 0x9E, // Disabled (Ubuntu), Do not confuse this with KEY_ENTER KEY_SEPARATOR = 0x9F, // Disabled (Ubuntu) KEY_OUT = 0xA0, // Disabled (Ubuntu) KEY_OPER = 0xA1, // Disabled (Ubuntu) diff --git a/src/HID-APIs/KeyboardAPI.h b/src/HID-APIs/KeyboardAPI.h index 6a8df49..1c6f5e3 100644 --- a/src/HID-APIs/KeyboardAPI.h +++ b/src/HID-APIs/KeyboardAPI.h @@ -27,6 +27,7 @@ THE SOFTWARE. #include #include "HID-Settings.h" #include "ImprovedKeylayouts.h" +#include "ConsumerAPI.h" typedef union{ // Low level key report: up to 6 keys and shift, ctrl etc at once @@ -36,46 +37,45 @@ typedef union{ struct{ uint8_t modifiers; uint8_t reserved; - uint8_t keys[6]; + KeyboardKeycode keys[6]; }; } HID_KeyboardReport_Data_t; class KeyboardAPI : public Print { public: -//TODO nkro compatiblity, merge them inline void begin(void); inline void end(void); inline size_t write(uint8_t k); inline size_t write(KeyboardKeycode k); inline size_t write(KeyboardModifier k); + inline size_t write(ConsumerKeycode k); inline size_t press(uint8_t k); inline size_t press(KeyboardKeycode k); inline size_t press(KeyboardModifier k); + inline size_t press(ConsumerKeycode k); inline size_t release(uint8_t k); inline size_t release(KeyboardKeycode k); inline size_t release(KeyboardModifier k); + inline size_t release(ConsumerKeycode k); inline size_t add(uint8_t k); inline size_t add(KeyboardKeycode k); inline size_t add(KeyboardModifier k); + inline size_t add(ConsumerKeycode k); inline size_t remove(uint8_t k); inline size_t remove(KeyboardKeycode k); inline size_t remove(KeyboardModifier k); - - // TODO media, system - inline void setMedia(uint8_t m){ - _keyReport.reserved = m; - send_now(); - } + inline size_t remove(ConsumerKeycode k); inline void releaseAll(void); inline void removeAll(void); inline void send_now(void); + inline void wakeupHost(void); // Sending is public in the base class for advanced users. virtual void SendReport(void* data, int length) = 0; diff --git a/src/HID-APIs/KeyboardAPI.hpp b/src/HID-APIs/KeyboardAPI.hpp index fba968d..6486133 100644 --- a/src/HID-APIs/KeyboardAPI.hpp +++ b/src/HID-APIs/KeyboardAPI.hpp @@ -36,7 +36,6 @@ void KeyboardAPI::end(void) } -// TODO template?? size_t KeyboardAPI::write(uint8_t k) { // Press and release key (if press was successfull) @@ -70,6 +69,17 @@ size_t KeyboardAPI::write(KeyboardModifier k) } +size_t KeyboardAPI::write(ConsumerKeycode k) +{ + // Press and release key (if press was successfull) + auto ret = press(k); + if(ret){ + release(k); + } + return ret; +} + + size_t KeyboardAPI::press(uint8_t k) { // Press key and send report to host @@ -103,6 +113,17 @@ size_t KeyboardAPI::press(KeyboardModifier k) } +size_t KeyboardAPI::press(ConsumerKeycode k) +{ + // Press key and send report to host + auto ret = add(k); + if(ret){ + send_now(); + } + return ret; +} + + size_t KeyboardAPI::add(uint8_t k) { // Ignore invalid input @@ -131,7 +152,7 @@ size_t KeyboardAPI::add(KeyboardKeycode k) { // Is key already in the list or did we found an empty slot? auto key = _keyReport.keys[i]; - if (key == uint8_t(k) || key == 0) { + if (key == uint8_t(k) || key == KEY_RESERVED) { _keyReport.keys[i] = k; return 1; } @@ -151,6 +172,21 @@ size_t KeyboardAPI::add(KeyboardModifier k) } +size_t KeyboardAPI::add(ConsumerKeycode k) +{ + if(k > 0xFF){ + // No 2 byte keys are supported + setWriteError(); + return 0; + } + + // Place the key inside the reserved keyreport position. + // This does not work on Windows. + _keyReport.reserved = k; + return 1; +} + + size_t KeyboardAPI::release(uint8_t k) { // Release key and send report to host @@ -184,6 +220,17 @@ size_t KeyboardAPI::release(KeyboardModifier k) } +size_t KeyboardAPI::release(ConsumerKeycode k) +{ + // Release key and send report to host + auto ret = remove(k); + if(ret){ + send_now(); + } + return ret; +} + + size_t KeyboardAPI::remove(uint8_t k) { // Ignore invalid input @@ -208,7 +255,7 @@ size_t KeyboardAPI::remove(KeyboardKeycode k) // Test the key report to see if k is present. Clear it if it exists. for (uint8_t i = 0; i < 6; i++) { if (_keyReport.keys[i] == k) { - _keyReport.keys[i] = 0x00; + _keyReport.keys[i] = KEY_RESERVED; return 1; } } @@ -232,6 +279,20 @@ size_t KeyboardAPI::remove(KeyboardModifier k) } +size_t KeyboardAPI::remove(ConsumerKeycode k) +{ + if(k > 0xFF){ + // No 2 byte keys are supported + return 0; + } + + // Always release the key, to make it simpler releasing a consumer key + // without releasing all other normal keyboard keys. + _keyReport.reserved = HID_CONSUMER_UNASSIGNED; + return 1; +} + + void KeyboardAPI::releaseAll(void) { // Release all keys @@ -252,3 +313,10 @@ void KeyboardAPI::send_now(void){ } +void KeyboardAPI::wakeupHost(void){ +#ifdef USBCON + USBDevice.wakeupHost(); +#endif +} + +