Added Consumer Keys to Keyboard API

This commit is contained in:
NicoHood 2015-10-24 11:10:42 +02:00
parent 2e7b5607f7
commit 60a30c1cdb
5 changed files with 100 additions and 15 deletions

View file

@ -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

View file

@ -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);

View file

@ -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)

View file

@ -27,6 +27,7 @@ THE SOFTWARE.
#include <Arduino.h>
#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;

View file

@ -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
}