From 7adf80dacc8f5cd71b544405a91391c4bec5c336 Mon Sep 17 00:00:00 2001 From: Gergely Nagy Date: Fri, 25 Nov 2016 09:12:46 +0100 Subject: [PATCH] Layer handling reworked Instead of having a primary and a temporary layer, store the state of at most 32 layers in a bitfield. These can be individually turned on and off, and key lookup starts from the top, and goes downwards until the default layer to find a non-transparent key. This allows one to reuse a partially transparent layer: set the default, and the transparent parts will be reused. The numpad layer was updated accordingly. Having an interface to the layer switching things also makes it easier to build other behaviour on top of these. As part of the rework, layer handling was moved to a separate file, and into its own, full-blown handler. Furthermore, we now use a single bit for all keymap events. Signed-off-by: Gergely Nagy --- .../KeyboardioFirmware/generated/keymaps.h | 70 +++++------ .../KeyboardioFirmware/layouts/generic_fn2 | 4 +- examples/KeyboardioFirmware/layouts/numpad | 8 +- src/KeyboardioFirmware.cpp | 3 +- src/KeyboardioFirmware.h | 4 +- src/LED-Numlock.cpp | 49 ++++---- src/key_defs.h | 28 +++-- src/key_events.cpp | 46 +------ src/key_events.h | 5 - src/layers.cpp | 113 ++++++++++++++++++ src/layers.h | 30 +++++ 11 files changed, 231 insertions(+), 129 deletions(-) create mode 100644 src/layers.cpp create mode 100644 src/layers.h diff --git a/examples/KeyboardioFirmware/generated/keymaps.h b/examples/KeyboardioFirmware/generated/keymaps.h index f37292ab..4cec1b3c 100644 --- a/examples/KeyboardioFirmware/generated/keymaps.h +++ b/examples/KeyboardioFirmware/generated/keymaps.h @@ -1,13 +1,8 @@ -#define KEYMAP_GENERIC_FN2_MOO { /* Generated keymap for GENERIC_FN2_MOO */ {Key_skip, Key_F1, Key_F2, Key_F3, Key_F4, Key_F5, Key_NoKey, Key_LCtrl, Key_RCtrl, Key_NoKey, Key_F6, Key_F7, Key_F8, Key_F9, Key_Keymap0, Key_skip},\ - {Key_Tab, Key_mouseBtnM, Key_mouseUp, Key_skip, Key_mouseWarpNW, Key_mouseWarpNE, Key_NoKey, Key_mouseBtnL, Key_mouseBtnR, Key_NoKey, Key_playPause, Key_LCurlyBracket, Key_RCurlyBracket, Key_LEFT_PAREN, Key_RIGHT_PAREN, Key_sleep},\ - {Key_Home, Key_mouseL, Key_mouseDn, Key_mouseR, Key_mouseWarpSW, Key_mouseWarpSE, Key_nextTrack, Key_LShift, Key_RShift, Key_Delete, Key_LArrow, Key_DnArrow, Key_UpArrow, Key_RArrow, Key_F11, Key_F12},\ - {Key_End, Key_Z, Key_X, Key_C, Key_V, Key_mouseWarpEnd, Key_skip, Key_LGUI, Key_RAlt, Key_skip, Key_volumeDown, Key_volumeUp, Key_LSquareBracket, Key_RSquareBracket, Key_Backslash, Key_Pipe},\ -}, -#define KEYMAP_WORKMAN { /* Generated keymap for WORKMAN */ {Key_skip, Key_1, Key_2, Key_3, Key_4, Key_5, Key_skip, Key_skip, Key_6, Key_7, Key_8, Key_9, Key_0, Key_skip},\ - {Key_Backtick, Key_Q, Key_D, Key_R, Key_W, Key_B, Key_skip, Key_skip, Key_J, Key_F, Key_U, Key_P, Key_Semicolon, Key_Equals},\ - {Key_PageUp, Key_A, Key_S, Key_H, Key_T, Key_G, Key_Tab, Key_Return, Key_Y, Key_N, Key_E, Key_O, Key_I, Key_Quote},\ - {Key_PageDn, Key_Z, Key_X, Key_M, Key_C, Key_V, Key_Esc, Key_Keymap0, Key_K, Key_L, Key_Comma, Key_Period, Key_Slash, Key_Minus},\ - {Key_LGUI, Key_Backspace, Key_LShift, Key_LCtrl, Key_KeymapNext_Momentary, Key_skip, Key_skip, Key_skip, Key_skip, Key_KeymapNext_Momentary, Key_RCtrl, Key_RShift, Key_Space, Key_RAlt},\ +#define KEYMAP_COLEMAK { /* Generated keymap for COLEMAK */ {Key_skip, Key_1, Key_2, Key_3, Key_4, Key_5, Key_skip, Key_skip, Key_6, Key_7, Key_8, Key_9, Key_0, Key_skip},\ + {Key_Backtick, Key_Q, Key_W, Key_F, Key_P, Key_G, Key_skip, Key_skip, Key_J, Key_L, Key_U, Key_Y, Key_Semicolon, Key_Equals},\ + {Key_PageUp, Key_A, Key_R, Key_S, Key_T, Key_D, Key_Tab, Key_Return, Key_H, Key_N, Key_E, Key_I, Key_O, Key_Quote},\ + {Key_PageDn, Key_Z, Key_X, Key_C, Key_V, Key_B, Key_Esc, Key_Keymap2, Key_K, Key_M, Key_Comma, Key_Period, Key_Slash, Key_Minus},\ + {Key_LCtrl, Key_Backspace, Key_LShift, Key_LGUI, Key_KeymapNext_Momentary, Key_skip, Key_skip, Key_skip, Key_skip, Key_KeymapNext_Momentary, Key_RAlt, Key_RShift, Key_Space, Key_RCtrl},\ }, #define KEYMAP_DVORAK { /* Generated keymap for DVORAK */ {Key_skip, Key_1, Key_2, Key_3, Key_4, Key_5, Key_skip, Key_skip, Key_6, Key_7, Key_8, Key_9, Key_0, Key_skip},\ {Key_Backtick, Key_Quote, Key_Comma, Key_Period, Key_P, Key_Y, Key_skip, Key_skip, Key_F, Key_G, Key_C, Key_R, Key_L, Key_Slash},\ @@ -15,45 +10,50 @@ {Key_PageDn, Key_Semicolon, Key_Q, Key_J, Key_K, Key_X, Key_Esc, Key_Keymap2, Key_B, Key_M, Key_W, Key_V, Key_Z, Key_Equals},\ {Key_LCtrl, Key_Backspace, Key_LShift, Key_LGUI, Key_KeymapNext_Momentary, Key_skip, Key_skip, Key_skip, Key_skip, Key_KeymapNext_Momentary, Key_RAlt, Key_RShift, Key_Space, Key_RCtrl},\ }, -#define KEYMAP_NUMPAD { /* Generated keymap for NUMPAD */ {Key_LEDEffectNext, Key_1, Key_2, Key_3, Key_4, Key_5, Key_skip, Key_LCtrl, Key_RCtrl, Key_skip, Key_6, Key_Keypad7, Key_Keypad8, Key_Keypad9, Key_KeypadMinus, Key_Keymap0},\ - {Key_Backtick, Key_Q, Key_W, Key_E, Key_R, Key_T, Key_Keymap1_Momentary, Key_Backspace, Key_Space, Key_Keymap1_Momentary, Key_Y, Key_Keypad4, Key_Keypad5, Key_Keypad6, Key_KeypadPlus, Key_Equals},\ - {Key_PageUp, Key_A, Key_S, Key_D, Key_F, Key_G, Key_Tab, Key_LGUI, Key_RAlt, Key_Return, Key_H, Key_Keypad1, Key_Keypad2, Key_Keypad3, Key_Equals, Key_Quote},\ - {Key_PageDn, Key_Z, Key_X, Key_C, Key_V, Key_B, Key_Esc, Key_LShift, Key_RShift, Key_skip, Key_N, Key_Keypad0, Key_KeypadDot, Key_KeypadMultiply, Key_KeypadSlash, Key_Enter},\ +#define KEYMAP_GENERIC_FN2 { /* Generated keymap for GENERIC_FN2 */ {Key_skip, Key_F1, Key_F2, Key_F3, Key_F4, Key_F5, Key_NoKey, Key_LCtrl, Key_RCtrl, Key_NoKey, Key_F6, Key_F7, Key_F8, Key_F9, Key_Trans, Key_skip},\ + {Key_Tab, Key_mouseBtnM, Key_mouseUp, Key_skip, Key_mouseWarpNW, Key_mouseWarpNE, Key_NoKey, Key_mouseBtnL, Key_mouseBtnR, Key_NoKey, Key_playPause, Key_LCurlyBracket, Key_RCurlyBracket, Key_LSquareBracket, Key_RSquareBracket, Key_sleep},\ + {Key_Home, Key_mouseL, Key_mouseDn, Key_mouseR, Key_mouseWarpSW, Key_mouseWarpSE, Key_nextTrack, Key_LGUI, Key_RAlt, Key_Delete, Key_LArrow, Key_DnArrow, Key_UpArrow, Key_RArrow, Key_F11, Key_F12},\ + {Key_End, Key_Z, Key_X, Key_C, Key_V, Key_mouseWarpEnd, Key_Trans, Key_LShift, Key_RShift, Key_Trans, Key_volumeDown, Key_volumeUp, Key_BacklightDn, Key_BacklightUp, Key_Backslash, Key_Pipe},\ +}, +#define KEYMAP_GENERIC_FN2_MOO { /* Generated keymap for GENERIC_FN2_MOO */ {Key_skip, Key_F1, Key_F2, Key_F3, Key_F4, Key_F5, Key_NoKey, Key_LCtrl, Key_RCtrl, Key_NoKey, Key_F6, Key_F7, Key_F8, Key_F9, Key_Keymap0, Key_skip},\ + {Key_Tab, Key_mouseBtnM, Key_mouseUp, Key_skip, Key_mouseWarpNW, Key_mouseWarpNE, Key_NoKey, Key_mouseBtnL, Key_mouseBtnR, Key_NoKey, Key_playPause, Key_LCurlyBracket, Key_RCurlyBracket, Key_LEFT_PAREN, Key_RIGHT_PAREN, Key_sleep},\ + {Key_Home, Key_mouseL, Key_mouseDn, Key_mouseR, Key_mouseWarpSW, Key_mouseWarpSE, Key_nextTrack, Key_LShift, Key_RShift, Key_Delete, Key_LArrow, Key_DnArrow, Key_UpArrow, Key_RArrow, Key_F11, Key_F12},\ + {Key_End, Key_Z, Key_X, Key_C, Key_V, Key_mouseWarpEnd, Key_skip, Key_LGUI, Key_RAlt, Key_skip, Key_volumeDown, Key_volumeUp, Key_LSquareBracket, Key_RSquareBracket, Key_Backslash, Key_Pipe},\ +}, +#define KEYMAP_MALTRON { /* Generated keymap for MALTRON */ {Key_skip, Key_1, Key_2, Key_3, Key_4, Key_5, Key_skip, Key_skip, Key_6, Key_7, Key_8, Key_9, Key_0, Key_skip},\ + {Key_Backtick, Key_Q, Key_P, Key_Y, Key_C, Key_B, Key_skip, Key_skip, Key_V, Key_M, Key_U, Key_Z, Key_L, Key_Equals},\ + {Key_PageUp, Key_A, Key_N, Key_I, Key_S, Key_F, Key_Tab, Key_Return, Key_D, Key_T, Key_H, Key_O, Key_R, Key_Quote},\ + {Key_PageDn, Key_Comma, Key_Period, Key_J, Key_G, Key_Slash, Key_Esc, Key_Keymap2, Key_Semicolon, Key_W, Key_K, Key_Minus, Key_X, Key_LSquareBracket},\ + {Key_LGUI, Key_E, Key_LShift, Key_Backspace, Key_KeymapNext_Momentary, Key_skip, Key_skip, Key_skip, Key_skip, Key_KeymapNext_Momentary, Key_RCtrl, Key_RShift, Key_Space, Key_RAlt},\ +}, +#define KEYMAP_NUMPAD { /* Generated keymap for NUMPAD */ {Key_Trans, Key_Trans, Key_Trans, Key_Trans, Key_Trans, Key_Trans, Key_Trans, Key_Trans, Key_Trans, Key_Trans, Key_Trans, Key_Keypad7, Key_Keypad8, Key_Keypad9, Key_KeypadMinus, Key_Trans},\ + {Key_Trans, Key_Trans, Key_Trans, Key_Trans, Key_Trans, Key_Trans, Key_Keymap1_Momentary, Key_Trans, Key_Trans, Key_Keymap1_Momentary, Key_Trans, Key_Keypad4, Key_Keypad5, Key_Keypad6, Key_KeypadPlus, Key_Trans},\ + {Key_Trans, Key_Trans, Key_Trans, Key_Trans, Key_Trans, Key_Trans, Key_Trans, Key_Trans, Key_Trans, Key_Trans, Key_Trans, Key_Keypad1, Key_Keypad2, Key_Keypad3, Key_Equals, Key_Quote},\ + {Key_Trans, Key_Trans, Key_Trans, Key_Trans, Key_Trans, Key_Trans, Key_Trans, Key_Trans, Key_Trans, Key_Trans, Key_Trans, Key_Keypad0, Key_KeypadDot, Key_KeypadMultiply, Key_KeypadSlash, Key_Enter},\ }, #define KEYMAP_QWERTY { /* Generated keymap for QWERTY */ {Key_LEDEffectNext, Key_1, Key_2, Key_3, Key_4, Key_5, Key_LEDEffectNext, Key_LCtrl, Key_RCtrl, Key_skip, Key_6, Key_7, Key_8, Key_9, Key_0, Key_Keymap2},\ {Key_Backtick, Key_Q, Key_W, Key_E, Key_R, Key_T, Key_Tab, Key_Backspace, Key_Space, Key_Enter, Key_Y, Key_U, Key_I, Key_O, Key_P, Key_Equals},\ {Key_PageUp, Key_A, Key_S, Key_D, Key_F, Key_G, Key_Esc, Key_LGUI, Key_RAlt, Key_skip, Key_H, Key_J, Key_K, Key_L, Key_Semicolon, Key_Quote},\ {Key_PageDn, Key_Z, Key_X, Key_C, Key_V, Key_B, Key_KeymapNext_Momentary, Key_LShift, Key_RShift, Key_KeymapNext_Momentary, Key_N, Key_M, Key_Comma, Key_Period, Key_Slash, Key_Minus},\ }, -#define KEYMAP_COLEMAK { /* Generated keymap for COLEMAK */ {Key_skip, Key_1, Key_2, Key_3, Key_4, Key_5, Key_skip, Key_skip, Key_6, Key_7, Key_8, Key_9, Key_0, Key_skip},\ - {Key_Backtick, Key_Q, Key_W, Key_F, Key_P, Key_G, Key_skip, Key_skip, Key_J, Key_L, Key_U, Key_Y, Key_Semicolon, Key_Equals},\ - {Key_PageUp, Key_A, Key_R, Key_S, Key_T, Key_D, Key_Tab, Key_Return, Key_H, Key_N, Key_E, Key_I, Key_O, Key_Quote},\ - {Key_PageDn, Key_Z, Key_X, Key_C, Key_V, Key_B, Key_Esc, Key_Keymap2, Key_K, Key_M, Key_Comma, Key_Period, Key_Slash, Key_Minus},\ - {Key_LCtrl, Key_Backspace, Key_LShift, Key_LGUI, Key_KeymapNext_Momentary, Key_skip, Key_skip, Key_skip, Key_skip, Key_KeymapNext_Momentary, Key_RAlt, Key_RShift, Key_Space, Key_RCtrl},\ -}, -#define KEYMAP_QWERTY_PIERS { /* Generated keymap for QWERTY_PIERS */ {Key_skip, Key_1, Key_2, Key_3, Key_4, Key_5, Key_skip, Key_LCtrl, Key_RCtrl, Key_skip, Key_6, Key_7, Key_8, Key_9, Key_0, Key_skip},\ - {Key_Backtick, Key_Q, Key_W, Key_E, Key_R, Key_T, Key_KeymapNext_Momentary, Key_Backspace, Key_Space, Key_KeymapNext_Momentary, Key_Y, Key_U, Key_I, Key_O, Key_P, Key_Equals},\ - {Key_PageUp, Key_A, Key_S, Key_D, Key_F, Key_G, Key_Tab, Key_LGUI, Key_RAlt, Key_Return, Key_H, Key_J, Key_K, Key_L, Key_Semicolon, Key_Quote},\ - {Key_PageDn, Key_Z, Key_X, Key_C, Key_V, Key_B, Key_Esc, Key_RShift, Key_RShift, Key_skip, Key_N, Key_M, Key_Comma, Key_Period, Key_Slash, Key_Minus},\ -}, #define KEYMAP_QWERTY_ALT_CMD { /* Generated keymap for QWERTY_ALT_CMD */ {Key_LEDEffectNext, Key_1, Key_2, Key_3, Key_4, Key_5, Key_skip, Key_LCtrl, Key_RCtrl, Key_skip, Key_6, Key_7, Key_8, Key_9, Key_0, Key_Keymap2},\ {Key_Backtick, Key_Q, Key_W, Key_E, Key_R, Key_T, Key_KeymapNext_Momentary, Key_Backspace, Key_Space, Key_KeymapNext_Momentary, Key_Y, Key_U, Key_I, Key_O, Key_P, Key_Equals},\ {Key_PageUp, Key_A, Key_S, Key_D, Key_F, Key_G, Key_Tab, Key_LAlt, Key_RGUI, Key_Return, Key_H, Key_J, Key_K, Key_L, Key_Semicolon, Key_Quote},\ {Key_PageDn, Key_Z, Key_X, Key_C, Key_V, Key_B, Key_Esc, Key_LShift, Key_RShift, Key_skip, Key_N, Key_M, Key_Comma, Key_Period, Key_Slash, Key_Minus},\ }, -#define KEYMAP_MALTRON { /* Generated keymap for MALTRON */ {Key_skip, Key_1, Key_2, Key_3, Key_4, Key_5, Key_skip, Key_skip, Key_6, Key_7, Key_8, Key_9, Key_0, Key_skip},\ - {Key_Backtick, Key_Q, Key_P, Key_Y, Key_C, Key_B, Key_skip, Key_skip, Key_V, Key_M, Key_U, Key_Z, Key_L, Key_Equals},\ - {Key_PageUp, Key_A, Key_N, Key_I, Key_S, Key_F, Key_Tab, Key_Return, Key_D, Key_T, Key_H, Key_O, Key_R, Key_Quote},\ - {Key_PageDn, Key_Comma, Key_Period, Key_J, Key_G, Key_Slash, Key_Esc, Key_Keymap2, Key_Semicolon, Key_W, Key_K, Key_Minus, Key_X, Key_LSquareBracket},\ - {Key_LGUI, Key_E, Key_LShift, Key_Backspace, Key_KeymapNext_Momentary, Key_skip, Key_skip, Key_skip, Key_skip, Key_KeymapNext_Momentary, Key_RCtrl, Key_RShift, Key_Space, Key_RAlt},\ -}, #define KEYMAP_QWERTY_MOO { /* Generated keymap for QWERTY_MOO */ {Key_LEDEffectNext, Key_1, Key_2, Key_3, Key_4, Key_5, Key_skip, Key_LCtrl, Key_RCtrl, Key_skip, Key_6, Key_7, Key_8, Key_9, Key_0, Key_Keymap2},\ {Key_Backtick, Key_Q, Key_W, Key_E, Key_R, Key_T, Key_KeymapNext_Momentary, Key_Backspace, Key_Space, Key_KeymapNext_Momentary, Key_Y, Key_U, Key_I, Key_O, Key_P, Key_Equals},\ {Key_Backslash, Key_A, Key_S, Key_D, Key_F, Key_G, Key_Tab, Key_LShift, Key_RShift, Key_Return, Key_H, Key_J, Key_K, Key_L, Key_Semicolon, Key_Quote},\ {Key_PageDn, Key_Z, Key_X, Key_C, Key_V, Key_B, Key_Esc, Key_LGUI, Key_RAlt, Key_skip, Key_N, Key_M, Key_Comma, Key_Period, Key_Slash, Key_Minus},\ }, -#define KEYMAP_GENERIC_FN2 { /* Generated keymap for GENERIC_FN2 */ {Key_skip, Key_F1, Key_F2, Key_F3, Key_F4, Key_F5, Key_NoKey, Key_LCtrl, Key_RCtrl, Key_NoKey, Key_F6, Key_F7, Key_F8, Key_F9, Key_Keymap0, Key_skip},\ - {Key_Tab, Key_mouseBtnM, Key_mouseUp, Key_skip, Key_mouseWarpNW, Key_mouseWarpNE, Key_NoKey, Key_mouseBtnL, Key_mouseBtnR, Key_NoKey, Key_playPause, Key_LCurlyBracket, Key_RCurlyBracket, Key_LSquareBracket, Key_RSquareBracket, Key_sleep},\ - {Key_Home, Key_mouseL, Key_mouseDn, Key_mouseR, Key_mouseWarpSW, Key_mouseWarpSE, Key_nextTrack, Key_LGUI, Key_RAlt, Key_Delete, Key_LArrow, Key_DnArrow, Key_UpArrow, Key_RArrow, Key_F11, Key_F12},\ - {Key_End, Key_Z, Key_X, Key_C, Key_V, Key_mouseWarpEnd, Key_skip, Key_LShift, Key_RShift, Key_skip, Key_volumeDown, Key_volumeUp, Key_BacklightDn, Key_BacklightUp, Key_Backslash, Key_Pipe},\ +#define KEYMAP_QWERTY_PIERS { /* Generated keymap for QWERTY_PIERS */ {Key_skip, Key_1, Key_2, Key_3, Key_4, Key_5, Key_skip, Key_LCtrl, Key_RCtrl, Key_skip, Key_6, Key_7, Key_8, Key_9, Key_0, Key_skip},\ + {Key_Backtick, Key_Q, Key_W, Key_E, Key_R, Key_T, Key_KeymapNext_Momentary, Key_Backspace, Key_Space, Key_KeymapNext_Momentary, Key_Y, Key_U, Key_I, Key_O, Key_P, Key_Equals},\ + {Key_PageUp, Key_A, Key_S, Key_D, Key_F, Key_G, Key_Tab, Key_LGUI, Key_RAlt, Key_Return, Key_H, Key_J, Key_K, Key_L, Key_Semicolon, Key_Quote},\ + {Key_PageDn, Key_Z, Key_X, Key_C, Key_V, Key_B, Key_Esc, Key_RShift, Key_RShift, Key_skip, Key_N, Key_M, Key_Comma, Key_Period, Key_Slash, Key_Minus},\ +}, +#define KEYMAP_WORKMAN { /* Generated keymap for WORKMAN */ {Key_skip, Key_1, Key_2, Key_3, Key_4, Key_5, Key_skip, Key_skip, Key_6, Key_7, Key_8, Key_9, Key_0, Key_skip},\ + {Key_Backtick, Key_Q, Key_D, Key_R, Key_W, Key_B, Key_skip, Key_skip, Key_J, Key_F, Key_U, Key_P, Key_Semicolon, Key_Equals},\ + {Key_PageUp, Key_A, Key_S, Key_H, Key_T, Key_G, Key_Tab, Key_Return, Key_Y, Key_N, Key_E, Key_O, Key_I, Key_Quote},\ + {Key_PageDn, Key_Z, Key_X, Key_M, Key_C, Key_V, Key_Esc, Key_Keymap0, Key_K, Key_L, Key_Comma, Key_Period, Key_Slash, Key_Minus},\ + {Key_LGUI, Key_Backspace, Key_LShift, Key_LCtrl, Key_KeymapNext_Momentary, Key_skip, Key_skip, Key_skip, Key_skip, Key_KeymapNext_Momentary, Key_RCtrl, Key_RShift, Key_Space, Key_RAlt},\ }, diff --git a/examples/KeyboardioFirmware/layouts/generic_fn2 b/examples/KeyboardioFirmware/layouts/generic_fn2 index 80ae99f2..4d8a9988 100644 --- a/examples/KeyboardioFirmware/layouts/generic_fn2 +++ b/examples/KeyboardioFirmware/layouts/generic_fn2 @@ -1,5 +1,5 @@ #NAME: GENERIC_FN2 -skip F1 F2 F3 F4 F5 NoKey LCtrl RCtrl NoKey F6 F7 F8 F9 Keymap0 skip +skip F1 F2 F3 F4 F5 NoKey LCtrl RCtrl NoKey F6 F7 F8 F9 Trans skip Tab mouseBtnM mouseUp skip mouseWarpNW mouseWarpNE NoKey mouseBtnL mouseBtnR NoKey playPause { } [ ] sleep Home mouseL mouseDn mouseR mouseWarpSW mouseWarpSE nextTrack LGUI RAlt Delete LArrow DnArrow UpArrow RArrow F11 F12 -End Z X C V mouseWarpEnd skip LShift RShift skip volumeDown volumeUp BacklightDn BacklightUp \ | +End Z X C V mouseWarpEnd Trans LShift RShift Trans volumeDown volumeUp BacklightDn BacklightUp \ | diff --git a/examples/KeyboardioFirmware/layouts/numpad b/examples/KeyboardioFirmware/layouts/numpad index 5cacc2ce..869647ec 100644 --- a/examples/KeyboardioFirmware/layouts/numpad +++ b/examples/KeyboardioFirmware/layouts/numpad @@ -1,5 +1,5 @@ #NAME: NUMPAD -LEDEffectNext 1 2 3 4 5 skip LCtrl RCtrl skip 6 Keypad7 Keypad8 Keypad9 KeypadMinus Keymap0 -` Q W E R T Keymap1_Momentary Backspace Space Keymap1_Momentary Y Keypad4 Keypad5 Keypad6 KeypadPlus = -PageUp A S D F G Tab LGUI RAlt Return H Keypad1 Keypad2 Keypad3 Equals ' -PageDn Z X C V B Esc LShift RShift skip N Keypad0 KeypadDot KeypadMultiply KeypadSlash Enter +Trans Trans Trans Trans Trans Trans Trans Trans Trans Trans Trans Keypad7 Keypad8 Keypad9 KeypadMinus Trans +Trans Trans Trans Trans Trans Trans Keymap1_Momentary Trans Trans Keymap1_Momentary Trans Keypad4 Keypad5 Keypad6 KeypadPlus Trans +Trans Trans Trans Trans Trans Trans Trans Trans Trans Trans Trans Keypad1 Keypad2 Keypad3 Equals ' +Trans Trans Trans Trans Trans Trans Trans Trans Trans Trans Trans Keypad0 KeypadDot KeypadMultiply KeypadSlash Enter diff --git a/src/KeyboardioFirmware.cpp b/src/KeyboardioFirmware.cpp index 68ef8bf9..94dce80f 100644 --- a/src/KeyboardioFirmware.cpp +++ b/src/KeyboardioFirmware.cpp @@ -13,8 +13,9 @@ Keyboardio_::setup(const byte keymap_count) { Keyboard.begin(); KeyboardHardware.setup(); LEDControl.setup(); + Layer.begin(); - temporary_keymap = primary_keymap = Storage.load_primary_keymap(keymap_count); + Layer.defaultLayer (Storage.load_primary_keymap (keymap_count)); } custom_loop_t loopHooks[HOOK_MAX]; diff --git a/src/KeyboardioFirmware.h b/src/KeyboardioFirmware.h index e94e5653..6ab0ddeb 100644 --- a/src/KeyboardioFirmware.h +++ b/src/KeyboardioFirmware.h @@ -24,12 +24,10 @@ void setup(); #include "KeyboardConfig.h" #include "key_events.h" #include "plugin.h" +#include "layers.h" extern HARDWARE_IMPLEMENTATION KeyboardHardware; -extern uint8_t primary_keymap; -extern uint8_t temporary_keymap; - #ifndef VERSION #define VERSION "locally-built" #endif diff --git a/src/LED-Numlock.cpp b/src/LED-Numlock.cpp index 05520c04..0f6df86d 100644 --- a/src/LED-Numlock.cpp +++ b/src/LED-Numlock.cpp @@ -1,15 +1,16 @@ #include "LED-Numlock.h" #include "LEDUtils.h" +#include "layers.h" static uint8_t numpadIndex; static uint8_t storedLEDMode; static uint8_t us; LEDNumlock::LEDNumlock (uint8_t numpadIdx) { - numpadIndex = numpadIdx; + numpadIndex = numpadIdx; - breathState.brightness = 0; - breathState.fadeAmount = 1; + breathState.brightness = 0; + breathState.fadeAmount = 1; } void @@ -20,35 +21,35 @@ LEDNumlock::begin (void) { void LEDNumlock::setup (void) { - if (temporary_keymap != numpadIndex) { - LEDControl.next_mode (); - } + if (!Layer.isOn (numpadIndex)) { + LEDControl.next_mode (); + } } void LEDNumlock::update (void) { - for (uint8_t i = 0; i < 44; i++) { - led_set_crgb_at(i, {0, 0, 0}); - } - for (uint8_t i = 44; i < LED_COUNT; i++) { - led_set_crgb_at(i, {255, 0, 0}); - } - - cRGB color = breath_compute (&breathState); - led_set_crgb_at (60, color); + for (uint8_t i = 0; i < 44; i++) { + led_set_crgb_at(i, {0, 0, 0}); + } + for (uint8_t i = 44; i < LED_COUNT; i++) { + led_set_crgb_at(i, {255, 0, 0}); + } + + cRGB color = breath_compute (&breathState); + led_set_crgb_at (60, color); } void LEDNumlock::loopHook (void) { - if (temporary_keymap == numpadIndex) { - if (storedLEDMode != us) { - storedLEDMode = LEDControl.get_mode (); + if (Layer.isOn (numpadIndex)) { + if (storedLEDMode != us) { + storedLEDMode = LEDControl.get_mode (); + } + LEDControl.set_mode (us); } - LEDControl.set_mode (us); - } - if (temporary_keymap != numpadIndex && - LEDControl.get_mode () == us) { - LEDControl.set_mode (storedLEDMode); - } + if (!Layer.isOn (numpadIndex) && + LEDControl.get_mode () == us) { + LEDControl.set_mode (storedLEDMode); + } } diff --git a/src/key_defs.h b/src/key_defs.h index f76a716f..3fb77fc2 100644 --- a/src/key_defs.h +++ b/src/key_defs.h @@ -32,8 +32,9 @@ typedef union { #define IS_SYSCTL B00000001 #define IS_CONSUMER B00000010 #define SWITCH_TO_KEYMAP B00000100 -#define SWITCH_TO_KEYMAP_MOMENTARY B00001000 -#define IS_INTERNAL B00010000 +#define IS_INTERNAL B00001000 + +#define MOMENTARY_OFFSET 42 // IS_INTERNAL key table: @@ -50,12 +51,13 @@ typedef union { #define KEYMAP_7 7 -#define KEYMAP_PREVIOUS 253 -#define KEYMAP_NEXT 254 +#define KEYMAP_PREVIOUS 33 +#define KEYMAP_NEXT 34 #define Key_NoKey (Key){ KEY_FLAGS,0 } #define Key_skip (Key){ KEY_FLAGS,0 } +#define Key_Transparent (Key){ .raw = 0xffff } #define Key_powerDown (Key) {KEY_FLAGS | SYNTHETIC|IS_SYSCTL,HID_SYSTEM_POWER_DOWN } @@ -240,15 +242,15 @@ typedef union { #define Key_Keymap3 (Key){ KEY_FLAGS | SYNTHETIC | SWITCH_TO_KEYMAP , KEYMAP_3 } #define Key_Keymap4 (Key){ KEY_FLAGS | SYNTHETIC | SWITCH_TO_KEYMAP , KEYMAP_4 } #define Key_Keymap5 (Key){ KEY_FLAGS | SYNTHETIC | SWITCH_TO_KEYMAP , KEYMAP_5 } -#define Key_Keymap0_Momentary (Key){ KEY_FLAGS | SYNTHETIC | SWITCH_TO_KEYMAP_MOMENTARY, KEYMAP_0 } -#define Key_Keymap1_Momentary (Key){ KEY_FLAGS | SYNTHETIC | SWITCH_TO_KEYMAP_MOMENTARY, KEYMAP_1 } -#define Key_Keymap2_Momentary (Key){ KEY_FLAGS | SYNTHETIC | SWITCH_TO_KEYMAP_MOMENTARY, KEYMAP_2 } -#define Key_Keymap3_Momentary (Key){ KEY_FLAGS | SYNTHETIC | SWITCH_TO_KEYMAP_MOMENTARY, KEYMAP_3 } -#define Key_Keymap4_Momentary (Key){ KEY_FLAGS | SYNTHETIC | SWITCH_TO_KEYMAP_MOMENTARY, KEYMAP_4 } -#define Key_Keymap5_Momentary (Key){ KEY_FLAGS | SYNTHETIC | SWITCH_TO_KEYMAP_MOMENTARY, KEYMAP_5 } - -#define Key_KeymapNext_Momentary (Key) {KEY_FLAGS | SYNTHETIC | SWITCH_TO_KEYMAP_MOMENTARY, KEYMAP_NEXT } -#define Key_KeymapPrevious_Momentary (Key) {KEY_FLAGS | SYNTHETIC | SWITCH_TO_KEYMAP_MOMENTARY, KEYMAP_PREVIOUS } +#define Key_Keymap0_Momentary (Key){ KEY_FLAGS | SYNTHETIC | SWITCH_TO_KEYMAP, KEYMAP_0 + MOMENTARY_OFFSET} +#define Key_Keymap1_Momentary (Key){ KEY_FLAGS | SYNTHETIC | SWITCH_TO_KEYMAP, KEYMAP_1 + MOMENTARY_OFFSET} +#define Key_Keymap2_Momentary (Key){ KEY_FLAGS | SYNTHETIC | SWITCH_TO_KEYMAP, KEYMAP_2 + MOMENTARY_OFFSET } +#define Key_Keymap3_Momentary (Key){ KEY_FLAGS | SYNTHETIC | SWITCH_TO_KEYMAP, KEYMAP_3 + MOMENTARY_OFFSET } +#define Key_Keymap4_Momentary (Key){ KEY_FLAGS | SYNTHETIC | SWITCH_TO_KEYMAP, KEYMAP_4 + MOMENTARY_OFFSET } +#define Key_Keymap5_Momentary (Key){ KEY_FLAGS | SYNTHETIC | SWITCH_TO_KEYMAP, KEYMAP_5 + MOMENTARY_OFFSET } + +#define Key_KeymapNext_Momentary (Key) {KEY_FLAGS | SYNTHETIC | SWITCH_TO_KEYMAP, KEYMAP_NEXT + MOMENTARY_OFFSET } +#define Key_KeymapPrevious_Momentary (Key) {KEY_FLAGS | SYNTHETIC | SWITCH_TO_KEYMAP, KEYMAP_PREVIOUS + MOMENTARY_OFFSET } diff --git a/src/key_events.cpp b/src/key_events.cpp index 5a5b6671..23030b3b 100644 --- a/src/key_events.cpp +++ b/src/key_events.cpp @@ -1,26 +1,5 @@ #include "key_events.h" - -static void handle_keymap_key_event(Key keymapEntry, uint8_t keyState) { - if (keymapEntry.flags & SWITCH_TO_KEYMAP_MOMENTARY ) { - if (key_toggled_on(keyState)) { - if ( keymapEntry.rawKey == KEYMAP_NEXT) { - temporary_keymap++; - } else if ( keymapEntry.rawKey == KEYMAP_PREVIOUS) { - temporary_keymap--; - } else { - temporary_keymap = keymapEntry.rawKey; - } - } - if (key_toggled_off(keyState)) { - temporary_keymap = primary_keymap; - } - - // switch keymap and stay there - } else if (key_toggled_on(keyState)) { - temporary_keymap = primary_keymap = keymapEntry.rawKey; - Storage.save_primary_keymap(primary_keymap); - } -} +#include "layers.h" static bool handle_synthetic_key_event(Key mappedKey, uint8_t keyState) { if (mappedKey.flags & RESERVED) @@ -42,8 +21,7 @@ static bool handle_synthetic_key_event(Key mappedKey, uint8_t keyState) { ConsumerControl.press(mappedKey.rawKey); } else if (mappedKey.flags & IS_SYSCTL) { SystemControl.press(mappedKey.rawKey); - } else if (mappedKey.flags & SWITCH_TO_KEYMAP || - mappedKey.flags & SWITCH_TO_KEYMAP_MOMENTARY) { + } else if (mappedKey.flags & SWITCH_TO_KEYMAP) { // Should not happen, handled elsewhere. } @@ -52,27 +30,11 @@ static bool handle_synthetic_key_event(Key mappedKey, uint8_t keyState) { custom_handler_t eventHandlers[HOOK_MAX]; -Key lookup_key(byte keymap, byte row, byte col) { - Key mappedKey; - - mappedKey.raw = pgm_read_word(&(keymaps[keymap][row][col])); - - return mappedKey; -} - static bool handle_key_event_default(Key mappedKey, byte row, byte col, uint8_t keyState) { //for every newly pressed button, figure out what logical key it is and send a key down event // for every newly released button, figure out what logical key it is and send a key up event - Key baseKey = Key_NoKey; - if (!(keyState & INJECTED)) { - baseKey = lookup_key(primary_keymap, row, col); - } - - if ((baseKey.flags & SWITCH_TO_KEYMAP - || baseKey.flags & SWITCH_TO_KEYMAP_MOMENTARY)) { - handle_keymap_key_event(baseKey, keyState); - } else if (mappedKey.flags & SYNTHETIC) { + if (mappedKey.flags & SYNTHETIC) { handle_synthetic_key_event( mappedKey, keyState); } else if (key_is_pressed(keyState)) { press_key(mappedKey); @@ -123,7 +85,7 @@ void release_key(Key mappedKey) { void handle_key_event(Key mappedKey, byte row, byte col, uint8_t keyState) { if (!(keyState & INJECTED)) { - mappedKey = lookup_key(temporary_keymap, row, col); + mappedKey = Layer.lookup(row, col); } for (byte i = 0; eventHandlers[i] != NULL && i < HOOK_MAX; i++) { custom_handler_t handler = eventHandlers[i]; diff --git a/src/key_events.h b/src/key_events.h index 6050ffba..d734d648 100644 --- a/src/key_events.h +++ b/src/key_events.h @@ -9,9 +9,6 @@ #include "keymap_metadata.h" #include "hooks.h" -//static const Key keymaps[KEYMAPS][ROWS][COLS]; -extern uint8_t primary_keymap; -extern uint8_t temporary_keymap; extern const Key keymaps[][ROWS][COLS]; // sending events to the computer @@ -48,5 +45,3 @@ void handle_key_event(Key mappedKey, byte row, byte col, uint8_t keyState); // Internal use void press_key(Key mappedKey); void release_key(Key mappedKey); - -Key lookup_key(byte keymap, byte row, byte col); diff --git a/src/layers.cpp b/src/layers.cpp new file mode 100644 index 00000000..0e8d7662 --- /dev/null +++ b/src/layers.cpp @@ -0,0 +1,113 @@ +#include "layers.h" +#include "key_events.h" + +static uint8_t DefaultLayer; +static uint32_t LayerState; + +static void handle_keymap_key_event(Key keymapEntry, uint8_t keyState) { + if (keymapEntry.rawKey >= MOMENTARY_OFFSET) { + if (key_toggled_on(keyState)) { + if ( keymapEntry.rawKey == KEYMAP_NEXT) { + Layer.next(); + } else if ( keymapEntry.rawKey == KEYMAP_PREVIOUS) { + Layer.previous(); + } else { + Layer.on(keymapEntry.rawKey - MOMENTARY_OFFSET); + } + } + if (key_toggled_off(keyState)) { + if ( keymapEntry.rawKey == KEYMAP_NEXT) { + Layer.previous(); + } else if ( keymapEntry.rawKey == KEYMAP_PREVIOUS) { + Layer.next(); + } else { + Layer.off(keymapEntry.rawKey - MOMENTARY_OFFSET); + } + } + + // switch keymap and stay there + } else if (key_toggled_on(keyState)) { + Layer.on (keymapEntry.rawKey); + } +} + +static bool +layerEventHandler(Key mappedKey, byte row, byte col, uint8_t keyState) { + if (mappedKey.flags != (SYNTHETIC | SWITCH_TO_KEYMAP)) + return false; + + handle_keymap_key_event(mappedKey, keyState); + return true; +} + +Layer_::Layer_ (void) { +} + +void Layer_::begin (void) { + defaultLayer (0); + event_handler_hook_add (layerEventHandler); +} + +Key Layer_::lookup(byte row, byte col) { + Key mappedKey; + int8_t layer = 31; + + mappedKey.raw = Key_Transparent.raw; + + while (mappedKey.raw == Key_Transparent.raw && + layer >= DefaultLayer) { + if (Layer.isOn (layer)) + mappedKey.raw = pgm_read_word(&(keymaps[layer][row][col])); + layer--; + } + + return mappedKey; +} + +uint8_t Layer_::top (void) { + for (int8_t i = 31; i >= 0; i--) { + if (bitRead (LayerState, i)) + return i; + } + return 0; +} + +void Layer_::move (uint8_t layer) { + LayerState = 0; + on (layer); +} + +void Layer_::on (uint8_t layer) { + bitSet (LayerState, layer); +} + +void Layer_::off (uint8_t layer) { + bitClear (LayerState, layer); +} + +boolean Layer_::isOn (uint8_t layer) { + return bitRead(LayerState, layer); +} + +void Layer_::next (void) { + on (top () + 1); +} + +void Layer_::previous (void) { + off (top ()); +} + +void Layer_::defaultLayer (uint8_t layer) { + move (layer); + DefaultLayer = layer; +} + +uint8_t Layer_::defaultLayer (void) { + return DefaultLayer; +} + +uint32_t Layer_::getLayerState (void) { + return LayerState; +} + +Layer_ Layer; diff --git a/src/layers.h b/src/layers.h new file mode 100644 index 00000000..25cb615b --- /dev/null +++ b/src/layers.h @@ -0,0 +1,30 @@ +#pragma once + +#include +#include "key_defs.h" +#include "plugin.h" + +class Layer_ : public KeyboardioPlugin { + public: + Layer_(void); + + virtual void begin(void) final; + + static Key lookup(byte row, byte col); + static void on(uint8_t layer); + static void off(uint8_t layer); + static void move(uint8_t layer); + + static uint8_t top(void); + static void next(void); + static void previous(void); + + static boolean isOn(uint8_t layer); + + static void defaultLayer(uint8_t layer); + static uint8_t defaultLayer(void); + + static uint32_t getLayerState(void); +}; + +extern Layer_ Layer;