From 8b3b321c0ec187b494d3378a2b2d5696fa47b94f Mon Sep 17 00:00:00 2001 From: Gergely Nagy Date: Sat, 26 Nov 2016 07:28:53 +0100 Subject: [PATCH 1/8] Use an overridable macroAction function for macro actions Instead of hardcoding the macro actions into the core firmware, use a `macroAction` function that is marked weak. This makes it possible to override the function from Sketches, and implement the handlers there. While there, also made sure that the `macroAction` is always called, with `keyState` argument appropriately set. With this, macro actions can trigger on keyup, or while held, or anytime the implementor wants, not just on keypress. Signed-off-by: Gergely Nagy --- .../KeyboardioFirmware/KeyboardioFirmware.ino | 6 ++++ src/key_defs.h | 12 ++++++- src/key_events.cpp | 34 +++++++++++-------- src/key_events.h | 2 ++ 4 files changed, 39 insertions(+), 15 deletions(-) diff --git a/examples/KeyboardioFirmware/KeyboardioFirmware.ino b/examples/KeyboardioFirmware/KeyboardioFirmware.ino index 0b7c7c60..2b0dc9a6 100644 --- a/examples/KeyboardioFirmware/KeyboardioFirmware.ino +++ b/examples/KeyboardioFirmware/KeyboardioFirmware.ino @@ -39,6 +39,12 @@ static LEDChaseEffect chaseEffect; static LEDNumlock numLockEffect (NUMPAD_KEYMAP); +void macroAction(uint8_t macroIndex, uint8_t keyState) { + if (macroIndex == 1 && key_toggled_on(keyState)) { + Serial.print("Keyboard.IO keyboard driver v0.00"); + } +} + void setup() { Keyboardio.setup(KEYMAP_SIZE); } diff --git a/src/key_defs.h b/src/key_defs.h index 3cce6382..aa4e7032 100644 --- a/src/key_defs.h +++ b/src/key_defs.h @@ -52,7 +52,17 @@ typedef union { #define Key_NoKey (Key){ KEY_FLAGS,0 } #define Key_skip (Key){ KEY_FLAGS,0 } -#define Key_macroKey1 (Key){ KEY_FLAGS|SYNTHETIC|IS_MACRO, 1} +#define M(n) (Key){ KEY_FLAGS|SYNTHETIC|IS_MACRO, n} +#define Key_macroKey1 M(1) +#define Key_macroKey2 M(2) +#define Key_macroKey3 M(3) +#define Key_macroKey4 M(4) +#define Key_macroKey5 M(5) +#define Key_macroKey6 M(6) +#define Key_macroKey7 M(7) +#define Key_macroKey8 M(8) +#define Key_macroKey9 M(9) +#define Key_macroKey10 M(10) #define Key_powerDown (Key) {KEY_FLAGS | SYNTHETIC|IS_SYSCTL,HID_SYSTEM_POWER_DOWN } diff --git a/src/key_events.cpp b/src/key_events.cpp index ba345d1d..9795ce2a 100644 --- a/src/key_events.cpp +++ b/src/key_events.cpp @@ -1,21 +1,27 @@ #include "key_events.h" +__attribute__((weak)) +void +macroAction(uint8_t macroIndex, uint8_t keyState) { +} + void handle_synthetic_key_event(Key mappedKey, uint8_t keyState) { - if (key_toggled_on(keyState)) { - if (mappedKey.flags & IS_CONSUMER) { - ConsumerControl.press(mappedKey.rawKey); - } else if (mappedKey.flags & IS_INTERNAL) { - if (mappedKey.rawKey == LED_TOGGLE) { - LEDControl.next_mode(); - } - } else if (mappedKey.flags & IS_SYSCTL) { - SystemControl.press(mappedKey.rawKey); - } else if (mappedKey.flags & IS_MACRO) { - if (mappedKey.rawKey == 1) { - Serial.print("Keyboard.IO keyboard driver v0.00"); - } - } + if (mappedKey.flags & IS_MACRO) { + macroAction(mappedKey.rawKey, keyState); + return; + } + if (!key_toggled_on(keyState)) + return; + + if (mappedKey.flags & IS_CONSUMER) { + ConsumerControl.press(mappedKey.rawKey); + } else if (mappedKey.flags & IS_INTERNAL) { + if (mappedKey.rawKey == LED_TOGGLE) { + LEDControl.next_mode(); + } + } else if (mappedKey.flags & IS_SYSCTL) { + SystemControl.press(mappedKey.rawKey); } } diff --git a/src/key_events.h b/src/key_events.h index d7128a1b..a8336927 100644 --- a/src/key_events.h +++ b/src/key_events.h @@ -45,6 +45,8 @@ extern const Key keymaps[][ROWS][COLS]; */ void handle_key_event(Key mappedKey, byte row, byte col, uint8_t keyState); +void macroAction(uint8_t macroIndex, uint8_t keyState); + // Internal use void handle_synthetic_key_event( Key mappedKey, uint8_t keyState); void press_key(Key mappedKey); From d2ba853594cde5a6608d14b018370a0655d0fb48 Mon Sep 17 00:00:00 2001 From: Gergely Nagy Date: Sat, 26 Nov 2016 07:40:54 +0100 Subject: [PATCH 2/8] Move all macro handling into separate files Signed-off-by: Gergely Nagy --- src/Macros.cpp | 21 +++++++++++++++++++++ src/Macros.h | 27 +++++++++++++++++++++++++++ src/key_defs.h | 13 ------------- src/key_events.cpp | 10 ---------- src/key_events.h | 3 +-- 5 files changed, 49 insertions(+), 25 deletions(-) create mode 100644 src/Macros.cpp create mode 100644 src/Macros.h diff --git a/src/Macros.cpp b/src/Macros.cpp new file mode 100644 index 00000000..2602dca4 --- /dev/null +++ b/src/Macros.cpp @@ -0,0 +1,21 @@ +#include "Macros.h" +#include "hooks.h" + +__attribute__((weak)) +void +macroAction(uint8_t macroIndex, uint8_t keyState) { +} + +static bool handleMacroEvent(Key mappedKey, byte row, byte col, uint8_t keyState) { + if (!(mappedKey.flags & (SYNTHETIC|IS_MACRO))) + return false; + + macroAction(mappedKey.rawKey, keyState); + return true; +} + +Macros_::Macros_ (void) { + event_handler_hook_add (handleMacroEvent); +} + +Macros_ Macros; diff --git a/src/Macros.h b/src/Macros.h new file mode 100644 index 00000000..12c4e352 --- /dev/null +++ b/src/Macros.h @@ -0,0 +1,27 @@ +#pragma once + +#include +#include "key_defs.h" + +#define IS_MACRO B00000001 + +#define M(n) (Key){ KEY_FLAGS|SYNTHETIC|IS_MACRO, n} +#define Key_macroKey1 M(1) +#define Key_macroKey2 M(2) +#define Key_macroKey3 M(3) +#define Key_macroKey4 M(4) +#define Key_macroKey5 M(5) +#define Key_macroKey6 M(6) +#define Key_macroKey7 M(7) +#define Key_macroKey8 M(8) +#define Key_macroKey9 M(9) +#define Key_macroKey10 M(10) + +void macroAction(uint8_t macroIndex, uint8_t keyState); + +class Macros_ { + public: + Macros_(void); +}; + +extern Macros_ Macros; diff --git a/src/key_defs.h b/src/key_defs.h index aa4e7032..fbcb1ccf 100644 --- a/src/key_defs.h +++ b/src/key_defs.h @@ -22,7 +22,6 @@ typedef union { #define SYNTHETIC B10000000 // we assert that synthetic keys can never have keys held, so we reuse the _HELD bits -#define IS_MACRO B00000001 #define IS_SYSCTL B00000010 #define IS_CONSUMER B00000100 #define IS_INTERNAL B00001000 @@ -52,18 +51,6 @@ typedef union { #define Key_NoKey (Key){ KEY_FLAGS,0 } #define Key_skip (Key){ KEY_FLAGS,0 } -#define M(n) (Key){ KEY_FLAGS|SYNTHETIC|IS_MACRO, n} -#define Key_macroKey1 M(1) -#define Key_macroKey2 M(2) -#define Key_macroKey3 M(3) -#define Key_macroKey4 M(4) -#define Key_macroKey5 M(5) -#define Key_macroKey6 M(6) -#define Key_macroKey7 M(7) -#define Key_macroKey8 M(8) -#define Key_macroKey9 M(9) -#define Key_macroKey10 M(10) - #define Key_powerDown (Key) {KEY_FLAGS | SYNTHETIC|IS_SYSCTL,HID_SYSTEM_POWER_DOWN } #define Key_sleep (Key) {KEY_FLAGS | SYNTHETIC|IS_SYSCTL,HID_SYSTEM_SLEEP } diff --git a/src/key_events.cpp b/src/key_events.cpp index 9795ce2a..ff071c66 100644 --- a/src/key_events.cpp +++ b/src/key_events.cpp @@ -1,16 +1,6 @@ #include "key_events.h" -__attribute__((weak)) -void -macroAction(uint8_t macroIndex, uint8_t keyState) { -} - void handle_synthetic_key_event(Key mappedKey, uint8_t keyState) { - if (mappedKey.flags & IS_MACRO) { - macroAction(mappedKey.rawKey, keyState); - return; - } - if (!key_toggled_on(keyState)) return; diff --git a/src/key_events.h b/src/key_events.h index a8336927..ec917b48 100644 --- a/src/key_events.h +++ b/src/key_events.h @@ -8,6 +8,7 @@ #include "Storage.h" #include "keymap_metadata.h" #include "hooks.h" +#include "Macros.h" //static const Key keymaps[KEYMAPS][ROWS][COLS]; extern uint8_t primary_keymap; @@ -45,8 +46,6 @@ extern const Key keymaps[][ROWS][COLS]; */ void handle_key_event(Key mappedKey, byte row, byte col, uint8_t keyState); -void macroAction(uint8_t macroIndex, uint8_t keyState); - // Internal use void handle_synthetic_key_event( Key mappedKey, uint8_t keyState); void press_key(Key mappedKey); From 516d617cce1da40dfa58e2ce645d3229d7101d32 Mon Sep 17 00:00:00 2001 From: Gergely Nagy Date: Sat, 26 Nov 2016 07:46:07 +0100 Subject: [PATCH 3/8] Move macros to a separate library Signed-off-by: Gergely Nagy --- examples/KeyboardioFirmware/KeyboardioFirmware.ino | 1 + libraries/Keyboardio-Macros/library.properties | 9 +++++++++ .../Keyboardio-Macros/src/Keyboardio-Macros.cpp | 3 +-- .../Keyboardio-Macros/src/Keyboardio-Macros.h | 3 +-- src/key_events.h | 1 - 5 files changed, 12 insertions(+), 5 deletions(-) create mode 100644 libraries/Keyboardio-Macros/library.properties rename src/Macros.cpp => libraries/Keyboardio-Macros/src/Keyboardio-Macros.cpp (91%) rename src/Macros.h => libraries/Keyboardio-Macros/src/Keyboardio-Macros.h (92%) diff --git a/examples/KeyboardioFirmware/KeyboardioFirmware.ino b/examples/KeyboardioFirmware/KeyboardioFirmware.ino index 2b0dc9a6..9bec056d 100644 --- a/examples/KeyboardioFirmware/KeyboardioFirmware.ino +++ b/examples/KeyboardioFirmware/KeyboardioFirmware.ino @@ -5,6 +5,7 @@ #define DEBUG_SERIAL false #include "Keyboardio-MouseKeys.h" +#include "Keyboardio-Macros.h" #include "KeyboardioFirmware.h" #include "generated/keymaps.h" diff --git a/libraries/Keyboardio-Macros/library.properties b/libraries/Keyboardio-Macros/library.properties new file mode 100644 index 00000000..15fbbe7a --- /dev/null +++ b/libraries/Keyboardio-Macros/library.properties @@ -0,0 +1,9 @@ +name=Keyboardio-Macros +version=0.0.1 +author=Jesse Vincent +maintainer=Jesse Vincent +sentence=Macro keys for Keyboardio boards. +paragraph=... +category=Communication +url=https://github.com/keyboardio/KeyboardioFirmware +architectures=avr diff --git a/src/Macros.cpp b/libraries/Keyboardio-Macros/src/Keyboardio-Macros.cpp similarity index 91% rename from src/Macros.cpp rename to libraries/Keyboardio-Macros/src/Keyboardio-Macros.cpp index 2602dca4..b492d8eb 100644 --- a/src/Macros.cpp +++ b/libraries/Keyboardio-Macros/src/Keyboardio-Macros.cpp @@ -1,5 +1,4 @@ -#include "Macros.h" -#include "hooks.h" +#include "Keyboardio-Macros.h" __attribute__((weak)) void diff --git a/src/Macros.h b/libraries/Keyboardio-Macros/src/Keyboardio-Macros.h similarity index 92% rename from src/Macros.h rename to libraries/Keyboardio-Macros/src/Keyboardio-Macros.h index 12c4e352..df209872 100644 --- a/src/Macros.h +++ b/libraries/Keyboardio-Macros/src/Keyboardio-Macros.h @@ -1,7 +1,6 @@ #pragma once -#include -#include "key_defs.h" +#include #define IS_MACRO B00000001 diff --git a/src/key_events.h b/src/key_events.h index ec917b48..d7128a1b 100644 --- a/src/key_events.h +++ b/src/key_events.h @@ -8,7 +8,6 @@ #include "Storage.h" #include "keymap_metadata.h" #include "hooks.h" -#include "Macros.h" //static const Key keymaps[KEYMAPS][ROWS][COLS]; extern uint8_t primary_keymap; From 44f5de357c9ed3458590e5e13402a4c5b2e8921d Mon Sep 17 00:00:00 2001 From: Gergely Nagy Date: Sat, 26 Nov 2016 08:45:29 +0100 Subject: [PATCH 4/8] Implement a way to do simple macros The main thing here is `Macros_::play`, which takes a list of bytes from PROGMEM, and plays a macro. The array is always a command, followed by arguments, and the size of the argument depends on the command: key presses and releases take a 16-bit argument, and the event is injected into the event handler flow. Waiting and interval change take a 8-bit time. Helpers are provided to make it a little bit easier to construct a macro. Of course, the `macroAction` method may do any other side effects, and is not restricted to returning a sequence of commands. Fixes #5. Signed-off-by: Gergely Nagy --- .../KeyboardioFirmware/KeyboardioFirmware.ino | 9 +++- .../src/Keyboardio-Macros.cpp | 47 +++++++++++++++++-- .../Keyboardio-Macros/src/Keyboardio-Macros.h | 19 ++------ .../Keyboardio-Macros/src/MacroKeyDefs.h | 15 ++++++ libraries/Keyboardio-Macros/src/MacroSteps.h | 22 +++++++++ 5 files changed, 94 insertions(+), 18 deletions(-) create mode 100644 libraries/Keyboardio-Macros/src/MacroKeyDefs.h create mode 100644 libraries/Keyboardio-Macros/src/MacroSteps.h diff --git a/examples/KeyboardioFirmware/KeyboardioFirmware.ino b/examples/KeyboardioFirmware/KeyboardioFirmware.ino index 9bec056d..6cf5ebfb 100644 --- a/examples/KeyboardioFirmware/KeyboardioFirmware.ino +++ b/examples/KeyboardioFirmware/KeyboardioFirmware.ino @@ -40,10 +40,17 @@ static LEDChaseEffect chaseEffect; static LEDNumlock numLockEffect (NUMPAD_KEYMAP); -void macroAction(uint8_t macroIndex, uint8_t keyState) { +const macro_t *macroAction(uint8_t macroIndex, uint8_t keyState) { if (macroIndex == 1 && key_toggled_on(keyState)) { Serial.print("Keyboard.IO keyboard driver v0.00"); + return MACRO(I(25), + D(LShift), T(M), U(LShift), T(O), T(D), T(E), T(L), + T(Space), + W(100), + T(0), T(1), + END); } + return MACRO_NONE; } void setup() { diff --git a/libraries/Keyboardio-Macros/src/Keyboardio-Macros.cpp b/libraries/Keyboardio-Macros/src/Keyboardio-Macros.cpp index b492d8eb..0014e07c 100644 --- a/libraries/Keyboardio-Macros/src/Keyboardio-Macros.cpp +++ b/libraries/Keyboardio-Macros/src/Keyboardio-Macros.cpp @@ -1,15 +1,56 @@ #include "Keyboardio-Macros.h" __attribute__((weak)) -void -macroAction(uint8_t macroIndex, uint8_t keyState) { +const macro_t *macroAction(uint8_t macroIndex, uint8_t keyState) { + return MACRO_NONE; +} + +void Macros_::play(const macro_t *macro_p) { + macro_t macro = END; + uint8_t interval = 0; + Key key; + + if (!macro_p) + return; + + while (true) { + switch (macro = pgm_read_byte(macro_p++)) { + case MACRO_ACTION_STEP_INTERVAL: + interval = pgm_read_byte(macro_p++); + break; + case MACRO_ACTION_STEP_WAIT: { + uint8_t wait = pgm_read_byte(macro_p++); + delay(wait); + break; + } + case MACRO_ACTION_STEP_KEYDOWN: + key.flags = pgm_read_byte(macro_p++); + key.rawKey = pgm_read_byte(macro_p++); + handle_key_event(key, 255, 255, IS_PRESSED | INJECTED); + Keyboard.sendReport(); + break; + case MACRO_ACTION_STEP_KEYUP: + key.flags = pgm_read_byte(macro_p++); + key.rawKey = pgm_read_byte(macro_p++); + handle_key_event(key, 255, 255, WAS_PRESSED | INJECTED); + Keyboard.sendReport(); + break; + case END: + default: + return; + } + + delay(interval); + } } static bool handleMacroEvent(Key mappedKey, byte row, byte col, uint8_t keyState) { if (!(mappedKey.flags & (SYNTHETIC|IS_MACRO))) return false; - macroAction(mappedKey.rawKey, keyState); + const macro_t *m = macroAction(mappedKey.rawKey, keyState); + + Macros.play(m); return true; } diff --git a/libraries/Keyboardio-Macros/src/Keyboardio-Macros.h b/libraries/Keyboardio-Macros/src/Keyboardio-Macros.h index df209872..6717ee4e 100644 --- a/libraries/Keyboardio-Macros/src/Keyboardio-Macros.h +++ b/libraries/Keyboardio-Macros/src/Keyboardio-Macros.h @@ -2,25 +2,16 @@ #include -#define IS_MACRO B00000001 +#include "MacroKeyDefs.h" +#include "MacroSteps.h" -#define M(n) (Key){ KEY_FLAGS|SYNTHETIC|IS_MACRO, n} -#define Key_macroKey1 M(1) -#define Key_macroKey2 M(2) -#define Key_macroKey3 M(3) -#define Key_macroKey4 M(4) -#define Key_macroKey5 M(5) -#define Key_macroKey6 M(6) -#define Key_macroKey7 M(7) -#define Key_macroKey8 M(8) -#define Key_macroKey9 M(9) -#define Key_macroKey10 M(10) - -void macroAction(uint8_t macroIndex, uint8_t keyState); +const macro_t *macroAction(uint8_t macroIndex, uint8_t keyState); class Macros_ { public: Macros_(void); + + void play(const macro_t *macro_p); }; extern Macros_ Macros; diff --git a/libraries/Keyboardio-Macros/src/MacroKeyDefs.h b/libraries/Keyboardio-Macros/src/MacroKeyDefs.h new file mode 100644 index 00000000..9efa9481 --- /dev/null +++ b/libraries/Keyboardio-Macros/src/MacroKeyDefs.h @@ -0,0 +1,15 @@ +#pragma once + +#define IS_MACRO B00000001 + +#define M(n) (Key){ KEY_FLAGS|SYNTHETIC|IS_MACRO, n} +#define Key_macroKey1 M(1) +#define Key_macroKey2 M(2) +#define Key_macroKey3 M(3) +#define Key_macroKey4 M(4) +#define Key_macroKey5 M(5) +#define Key_macroKey6 M(6) +#define Key_macroKey7 M(7) +#define Key_macroKey8 M(8) +#define Key_macroKey9 M(9) +#define Key_macroKey10 M(10) diff --git a/libraries/Keyboardio-Macros/src/MacroSteps.h b/libraries/Keyboardio-Macros/src/MacroSteps.h new file mode 100644 index 00000000..c2107c7d --- /dev/null +++ b/libraries/Keyboardio-Macros/src/MacroSteps.h @@ -0,0 +1,22 @@ +#pragma once + +typedef enum { + MACRO_ACTION_END, + + MACRO_ACTION_STEP_INTERVAL, + MACRO_ACTION_STEP_WAIT, + MACRO_ACTION_STEP_KEYDOWN, + MACRO_ACTION_STEP_KEYUP, +} MacroActionStepType; + +typedef uint8_t macro_t; + +#define MACRO_NONE 0 +#define MACRO(...) ({static const macro_t __m[] PROGMEM = { __VA_ARGS__ }; &__m[0]; }) + +#define I(n) MACRO_ACTION_STEP_INTERVAL, n +#define W(n) MACRO_ACTION_STEP_WAIT, n +#define D(k) MACRO_ACTION_STEP_KEYDOWN, (Key_ ## k).raw +#define U(k) MACRO_ACTION_STEP_KEYUP, (Key_ ## k).raw +#define T(k) D(k), U(k) +#define END MACRO_ACTION_END From d767854b8d886c023ada29718a18240a275f16c3 Mon Sep 17 00:00:00 2001 From: Gergely Nagy Date: Sun, 27 Nov 2016 22:35:32 +0100 Subject: [PATCH 5/8] Fix the D and U macro helpers Instead of trying to include an uint16_t in an array of uint8_ts, add the flags and the rawKey separately. Without this, macro playback would not work, because the sequence would be corrupt. Signed-off-by: Gergely Nagy --- libraries/Keyboardio-Macros/src/MacroSteps.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/libraries/Keyboardio-Macros/src/MacroSteps.h b/libraries/Keyboardio-Macros/src/MacroSteps.h index c2107c7d..44318bd4 100644 --- a/libraries/Keyboardio-Macros/src/MacroSteps.h +++ b/libraries/Keyboardio-Macros/src/MacroSteps.h @@ -16,7 +16,7 @@ typedef uint8_t macro_t; #define I(n) MACRO_ACTION_STEP_INTERVAL, n #define W(n) MACRO_ACTION_STEP_WAIT, n -#define D(k) MACRO_ACTION_STEP_KEYDOWN, (Key_ ## k).raw -#define U(k) MACRO_ACTION_STEP_KEYUP, (Key_ ## k).raw +#define D(k) MACRO_ACTION_STEP_KEYDOWN, (Key_ ## k).flags, (Key_ ## k).rawKey +#define U(k) MACRO_ACTION_STEP_KEYUP, (Key_ ## k).flags, (Key_ ## k).rawKey #define T(k) D(k), U(k) #define END MACRO_ACTION_END From 22ebbc6b7a0e1e9bf434ff1b1d3f57841b1eaf9a Mon Sep 17 00:00:00 2001 From: Gergely Nagy Date: Mon, 28 Nov 2016 08:09:19 +0100 Subject: [PATCH 6/8] Macros: dot_a_linkage and static Macros Use dot_a_linkage for the Keyboardio-Macros library, and as a consequence, declare the Macros variable static instead of extern, so that it gets compiled and linked in even when not referenced directly. Signed-off-by: Gergely Nagy --- libraries/Keyboardio-Macros/library.properties | 1 + libraries/Keyboardio-Macros/src/Keyboardio-Macros.cpp | 2 -- libraries/Keyboardio-Macros/src/Keyboardio-Macros.h | 2 +- 3 files changed, 2 insertions(+), 3 deletions(-) diff --git a/libraries/Keyboardio-Macros/library.properties b/libraries/Keyboardio-Macros/library.properties index 15fbbe7a..fb9949be 100644 --- a/libraries/Keyboardio-Macros/library.properties +++ b/libraries/Keyboardio-Macros/library.properties @@ -7,3 +7,4 @@ paragraph=... category=Communication url=https://github.com/keyboardio/KeyboardioFirmware architectures=avr +dot_a_linkage=true diff --git a/libraries/Keyboardio-Macros/src/Keyboardio-Macros.cpp b/libraries/Keyboardio-Macros/src/Keyboardio-Macros.cpp index 0014e07c..1e443793 100644 --- a/libraries/Keyboardio-Macros/src/Keyboardio-Macros.cpp +++ b/libraries/Keyboardio-Macros/src/Keyboardio-Macros.cpp @@ -57,5 +57,3 @@ static bool handleMacroEvent(Key mappedKey, byte row, byte col, uint8_t keyState Macros_::Macros_ (void) { event_handler_hook_add (handleMacroEvent); } - -Macros_ Macros; diff --git a/libraries/Keyboardio-Macros/src/Keyboardio-Macros.h b/libraries/Keyboardio-Macros/src/Keyboardio-Macros.h index 6717ee4e..6773bbb5 100644 --- a/libraries/Keyboardio-Macros/src/Keyboardio-Macros.h +++ b/libraries/Keyboardio-Macros/src/Keyboardio-Macros.h @@ -14,4 +14,4 @@ class Macros_ { void play(const macro_t *macro_p); }; -extern Macros_ Macros; +static Macros_ Macros; From 4aa6e1402140ddec1a9c89d09e3b3ff8e9072829 Mon Sep 17 00:00:00 2001 From: Gergely Nagy Date: Mon, 28 Nov 2016 23:01:55 +0100 Subject: [PATCH 7/8] Add an explicit release event Since macros and other injected keys do not clear the report, we need a way to release keys. The new `release_key` function does just that, similar to how `press_key` does it for key presses. It is called by the default event handler when the `keyState` toggles off, and has the `INJECTED` bit set. The reason behind this is that keys that will need this special treatment will always be injected keys. And those injected keys that do not need this treatment, can be handled by an event handler prior to the default. This should fix the macros not releasing keys issue. Signed-off-by: Gergely Nagy --- src/key_events.cpp | 22 ++++++++++++++++++++++ src/key_events.h | 1 + 2 files changed, 23 insertions(+) diff --git a/src/key_events.cpp b/src/key_events.cpp index ff071c66..e2692f3d 100644 --- a/src/key_events.cpp +++ b/src/key_events.cpp @@ -52,6 +52,8 @@ bool handle_key_event_default(Key mappedKey, byte row, byte col, uint8_t keyStat handle_synthetic_key_event( mappedKey, keyState); } else if (key_is_pressed(keyState)) { press_key(mappedKey); + } else if (key_toggled_off(keyState) && (keyState & INJECTED)) { + release_key(mappedKey); } return true; } @@ -76,6 +78,26 @@ void press_key(Key mappedKey) { } +void release_key(Key mappedKey) { + if (mappedKey.flags & SHIFT_HELD) { + Keyboard.release(Key_LShift.rawKey); + } + if (mappedKey.flags & CTRL_HELD) { + Keyboard.release(Key_LCtrl.rawKey); + } + if (mappedKey.flags & LALT_HELD) { + Keyboard.release(Key_LAlt.rawKey); + } + if (mappedKey.flags & RALT_HELD) { + Keyboard.release(Key_RAlt.rawKey); + } + if (mappedKey.flags & GUI_HELD) { + Keyboard.release(Key_LGUI.rawKey); + } + Keyboard.release(mappedKey.rawKey); +} + + void handle_keymap_key_event(Key keymapEntry, uint8_t keyState) { if (keymapEntry.flags & SWITCH_TO_KEYMAP_MOMENTARY ) { if (key_toggled_on(keyState)) { diff --git a/src/key_events.h b/src/key_events.h index d7128a1b..2bc6d799 100644 --- a/src/key_events.h +++ b/src/key_events.h @@ -48,6 +48,7 @@ void handle_key_event(Key mappedKey, byte row, byte col, uint8_t keyState); // Internal use void handle_synthetic_key_event( Key mappedKey, uint8_t keyState); void press_key(Key mappedKey); +void release_key(Key mappedKey); void handle_keymap_key_event(Key keymapEntry, uint8_t keyState); bool handle_key_event_default(Key mappedKey, byte row, byte col, uint8_t keyState); From 52fdbf773e4522178c96d75975a9bd456c4b903d Mon Sep 17 00:00:00 2001 From: Gergely Nagy Date: Tue, 29 Nov 2016 00:02:05 +0100 Subject: [PATCH 8/8] macros: Do not catch keys not intended for us Keys that have the IS_INTERNAL flag set can also have the same bit set as the IS_MACRO bit, yet, we do not want to handle those as if they were macros. So teach `handleMacroEvent` to skip keys with that bit set. Signed-off-by: Gergely Nagy --- libraries/Keyboardio-Macros/src/Keyboardio-Macros.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libraries/Keyboardio-Macros/src/Keyboardio-Macros.cpp b/libraries/Keyboardio-Macros/src/Keyboardio-Macros.cpp index 1e443793..cb3faeeb 100644 --- a/libraries/Keyboardio-Macros/src/Keyboardio-Macros.cpp +++ b/libraries/Keyboardio-Macros/src/Keyboardio-Macros.cpp @@ -45,7 +45,7 @@ void Macros_::play(const macro_t *macro_p) { } static bool handleMacroEvent(Key mappedKey, byte row, byte col, uint8_t keyState) { - if (!(mappedKey.flags & (SYNTHETIC|IS_MACRO))) + if (!(mappedKey.flags & (SYNTHETIC|IS_MACRO)) || (mappedKey.flags & IS_INTERNAL)) return false; const macro_t *m = macroAction(mappedKey.rawKey, keyState);