From 4c2b9e8e55ea28ce340b55f74c2a50694ea93791 Mon Sep 17 00:00:00 2001 From: Gergely Nagy Date: Thu, 8 Jun 2017 11:24:59 +0200 Subject: [PATCH] Add a way to type ASCII strings, as if pressing keys Adds a `Macros.type()` method, which expects a string in PROGMEM, iterates through it, and simulates key presses. It converts ASCII codes to Key codes during the process. Assumes an US QWERTY layout on the host, supports all printable chars, and a few control codes too. Signed-off-by: Gergely Nagy --- src/Kaleidoscope-Macros.cpp | 97 +++++++++++++++++++++++++++++++++++++ src/Kaleidoscope-Macros.h | 1 + 2 files changed, 98 insertions(+) diff --git a/src/Kaleidoscope-Macros.cpp b/src/Kaleidoscope-Macros.cpp index 6680c30f..7688b1ba 100644 --- a/src/Kaleidoscope-Macros.cpp +++ b/src/Kaleidoscope-Macros.cpp @@ -71,6 +71,103 @@ void Macros_::play(const macro_t *macro_p) { delay(interval); } } +static const Key ascii_to_key_map[] PROGMEM = { + // 0x21 - 0x30 + LSHIFT(Key_1), + LSHIFT(Key_Quote), + LSHIFT(Key_3), + LSHIFT(Key_4), + LSHIFT(Key_5), + LSHIFT(Key_7), + Key_Quote, + LSHIFT(Key_9), + LSHIFT(Key_0), + LSHIFT(Key_8), + LSHIFT(Key_Equals), + Key_Comma, + Key_Minus, + Key_Period, + Key_Slash, + Key_0, + + // 0x3a ... 0x40 + LSHIFT(Key_Semicolon), + Key_Semicolon, + LSHIFT(Key_Comma), + Key_Equals, + LSHIFT(Key_Period), + LSHIFT(Key_Slash), + LSHIFT(Key_2), + + // 0x5b ... 0x5f + Key_LeftBracket, + Key_Backslash, + Key_RightBracket, + LSHIFT(Key_6), + LSHIFT(Key_Minus), + Key_Backtick, + + // 0x7b ... 0x7e + LSHIFT(Key_LeftBracket), + LSHIFT(Key_Backslash), + LSHIFT(Key_RightBracket), + LSHIFT(Key_Backtick), +}; + +void Macros_::type(const char *string) { + while (true) { + uint8_t ascii_code = pgm_read_byte(string++); + if (!ascii_code) + break; + + Key key = Key_NoKey; + + switch (ascii_code) { + case 0x08 ... 0x09: + key.keyCode = Key_Backspace.keyCode + ascii_code - 0x08; + break; + case 0x0A: + key.keyCode = Key_Enter.keyCode; + break; + case 0x1B: + key.keyCode = Key_Escape.keyCode; + break; + case 0x20: + key.keyCode = Key_Spacebar.keyCode; + break; + case 0x21 ... 0x30: + key.raw = pgm_read_word(&ascii_to_key_map[ascii_code - 0x21]); + break; + case 0x31 ... 0x39: + key.keyCode = Key_1.keyCode + ascii_code - 0x31; + break; + case 0x3A ... 0x40: + key.raw = pgm_read_word(&ascii_to_key_map[ascii_code - 0x3A + 16]); + break; + case 0x41 ... 0x5A: + key.flags = SHIFT_HELD; + key.keyCode = Key_A.keyCode + ascii_code - 0x41; + break; + case 0x5B ... 0x5F: + key.raw = pgm_read_word(&ascii_to_key_map[ascii_code - 0x5B + 23]); + break; + case 0x61 ... 0x7A: + key.keyCode = Key_A.keyCode + ascii_code - 0x61; + break; + case 0x7B ... 0x7E: + key.raw = pgm_read_word(&ascii_to_key_map[ascii_code - 0x7B + 29]); + break; + } + + if (key.raw == Key_NoKey.raw) + continue; + + handle_keyswitch_event(key, UNKNOWN_KEYSWITCH_LOCATION, IS_PRESSED | INJECTED); + Keyboard.sendReport(); + handle_keyswitch_event(key, UNKNOWN_KEYSWITCH_LOCATION, WAS_PRESSED | INJECTED); + Keyboard.sendReport(); + } +} static Key handleMacroEvent(Key mappedKey, byte row, byte col, uint8_t keyState) { if (mappedKey.flags != (SYNTHETIC | IS_MACRO)) diff --git a/src/Kaleidoscope-Macros.h b/src/Kaleidoscope-Macros.h index eddaef23..92b14fd9 100644 --- a/src/Kaleidoscope-Macros.h +++ b/src/Kaleidoscope-Macros.h @@ -14,6 +14,7 @@ class Macros_ : public KaleidoscopePlugin { void begin(void) final; void play(const macro_t *macro_p); + void type(const char *string); static byte row, col; };