diff --git a/Makefile b/Makefile index 1d6862d6..ef0c9ed5 100644 --- a/Makefile +++ b/Makefile @@ -86,8 +86,8 @@ astyle: find . -type f -name \*.h |xargs -n 1 astyle --style=google generate-keymaps: - -rm src/generated/keymaps.h - cd layouts && ( find . -type f |xargs -n 1 -I % sh -c 'perl ../tools/generate_keymaps.pl < % >> ../src/generated/keymaps.h' ) + -rm examples/KeyboardioFirmware/generated/keymaps.h + cd examples/KeyboardioFirmware/layouts && ( find . -type f | sort | xargs -n 1 -I % sh -c 'perl ../../../tools/generate_keymaps.pl < % >> ../generated/keymaps.h' ) dirs: mkdir -p $(OUTPUT_PATH) diff --git a/examples/KeyboardioFirmware/KeyboardioFirmware.ino b/examples/KeyboardioFirmware/KeyboardioFirmware.ino index def1b25f..274f4243 100644 --- a/examples/KeyboardioFirmware/KeyboardioFirmware.ino +++ b/examples/KeyboardioFirmware/KeyboardioFirmware.ino @@ -1,15 +1,23 @@ +// -*- mode: c++ -*- // Copyright 2016 Keyboardio, inc. // See "LICENSE" for license details #define DEBUG_SERIAL false #include "KeyboardioFirmware.h" +#include "generated/keymaps.h" uint8_t primary_keymap = 0; uint8_t temporary_keymap = 0; +#define KEYMAPS 3 +#define NUMPAD_KEYMAP 2 +#define KEYMAP_LIST KEYMAP_QWERTY KEYMAP_GENERIC_FN2 KEYMAP_NUMPAD + +const Key keymaps[][ROWS][COLS] PROGMEM = { KEYMAP_LIST }; + void setup() { - Keyboardio.setup(); + Keyboardio.setup(KEYMAPS, NUMPAD_KEYMAP); } diff --git a/src/generated/keymaps.h b/examples/KeyboardioFirmware/generated/keymaps.h similarity index 100% rename from src/generated/keymaps.h rename to examples/KeyboardioFirmware/generated/keymaps.h diff --git a/layouts/colemak b/examples/KeyboardioFirmware/layouts/colemak similarity index 100% rename from layouts/colemak rename to examples/KeyboardioFirmware/layouts/colemak diff --git a/layouts/dvorak b/examples/KeyboardioFirmware/layouts/dvorak similarity index 100% rename from layouts/dvorak rename to examples/KeyboardioFirmware/layouts/dvorak diff --git a/layouts/generic_fn2 b/examples/KeyboardioFirmware/layouts/generic_fn2 similarity index 100% rename from layouts/generic_fn2 rename to examples/KeyboardioFirmware/layouts/generic_fn2 diff --git a/layouts/generic_fn2-moo b/examples/KeyboardioFirmware/layouts/generic_fn2-moo similarity index 100% rename from layouts/generic_fn2-moo rename to examples/KeyboardioFirmware/layouts/generic_fn2-moo diff --git a/layouts/maltron b/examples/KeyboardioFirmware/layouts/maltron similarity index 100% rename from layouts/maltron rename to examples/KeyboardioFirmware/layouts/maltron diff --git a/layouts/numpad b/examples/KeyboardioFirmware/layouts/numpad similarity index 100% rename from layouts/numpad rename to examples/KeyboardioFirmware/layouts/numpad diff --git a/layouts/qwerty b/examples/KeyboardioFirmware/layouts/qwerty similarity index 100% rename from layouts/qwerty rename to examples/KeyboardioFirmware/layouts/qwerty diff --git a/layouts/qwerty-moo b/examples/KeyboardioFirmware/layouts/qwerty-moo similarity index 100% rename from layouts/qwerty-moo rename to examples/KeyboardioFirmware/layouts/qwerty-moo diff --git a/layouts/qwerty_alt_cmd b/examples/KeyboardioFirmware/layouts/qwerty_alt_cmd similarity index 100% rename from layouts/qwerty_alt_cmd rename to examples/KeyboardioFirmware/layouts/qwerty_alt_cmd diff --git a/layouts/qwerty_piers b/examples/KeyboardioFirmware/layouts/qwerty_piers similarity index 100% rename from layouts/qwerty_piers rename to examples/KeyboardioFirmware/layouts/qwerty_piers diff --git a/layouts/workman b/examples/KeyboardioFirmware/layouts/workman similarity index 100% rename from layouts/workman rename to examples/KeyboardioFirmware/layouts/workman diff --git a/src/KeyboardioFirmware.cpp b/src/KeyboardioFirmware.cpp index 00ac2a5c..6909c0df 100644 --- a/src/KeyboardioFirmware.cpp +++ b/src/KeyboardioFirmware.cpp @@ -1,10 +1,12 @@ #include "KeyboardioFirmware.h" +byte NUMPAD_KEYMAP = 0; + Keyboardio_::Keyboardio_(void) { } void -Keyboardio_::setup(void) { +Keyboardio_::setup(const byte keymap_count, const byte numpad_layer) { event_handler_hook_add (handle_key_event_default); wdt_disable(); delay(100); @@ -14,7 +16,8 @@ Keyboardio_::setup(void) { KeyboardHardware.setup(); LEDControl.boot_animation(); - temporary_keymap = primary_keymap = Storage.load_primary_keymap(KEYMAPS); + NUMPAD_KEYMAP = numpad_layer; + temporary_keymap = primary_keymap = Storage.load_primary_keymap(keymap_count); } custom_loop_t loopHooks[HOOK_MAX] = {NULL}; diff --git a/src/KeyboardioFirmware.h b/src/KeyboardioFirmware.h index a88821cc..3cbe9de4 100644 --- a/src/KeyboardioFirmware.h +++ b/src/KeyboardioFirmware.h @@ -22,7 +22,6 @@ void setup(); #include #include "KeyboardConfig.h" -#include "generated/keymaps.h" #include "key_events.h" extern HARDWARE_IMPLEMENTATION KeyboardHardware; @@ -38,7 +37,7 @@ class Keyboardio_ { public: Keyboardio_(void); - void setup(void); + void setup(const byte keymap_count, const byte numpad_layer); void loop(void); }; diff --git a/src/LEDControl.h b/src/LEDControl.h index 7ea36e3c..bea7be8d 100644 --- a/src/LEDControl.h +++ b/src/LEDControl.h @@ -91,3 +91,5 @@ class LEDControl_ { }; extern LEDControl_ LEDControl; + +extern byte NUMPAD_KEYMAP; diff --git a/src/Model01.cpp b/src/Model01.cpp index d8553b06..28a6f668 100644 --- a/src/Model01.cpp +++ b/src/Model01.cpp @@ -117,12 +117,12 @@ void Model01::act_on_matrix_scan() { uint8_t keynum = (row*8)+(col); - handle_key_event(row, 7-col, + handle_key_event(Key_NoKey, row, 7-col, bitRead(leftHandState.all, keynum), bitRead(previousLeftHandState.all, keynum) ); - handle_key_event(row, (15- col), + handle_key_event(Key_NoKey, row, (15- col), bitRead(rightHandState.all, keynum), bitRead(previousRightHandState.all, keynum) ); diff --git a/src/Model01.h b/src/Model01.h index d9f7c4d9..1e7b35fb 100644 --- a/src/Model01.h +++ b/src/Model01.h @@ -48,7 +48,7 @@ class Model01 { }; -#define SCANBIT(row,col) (1 << (row * 8 + (7 - col))) +#define SCANBIT(row,col) ((uint32_t)1 << (row * 8 + (7 - col))) #define R0C0 SCANBIT(0, 0) #define R0C1 SCANBIT(0, 1) diff --git a/src/TestMode.cpp b/src/TestMode.cpp index 5d10d4a6..4edc0239 100644 --- a/src/TestMode.cpp +++ b/src/TestMode.cpp @@ -61,7 +61,7 @@ void TestMode_::TestMatrix () { void TestMode_::setup() { eventHandlers[0] = handle_key_event_test; } -bool handle_key_event_test(byte row, byte col, uint8_t currentState, uint8_t previousState) { +bool handle_key_event_test(Key mappedKey, byte row, byte col, uint8_t currentState, uint8_t previousState) { Serial.write(row); } diff --git a/src/TestMode.h b/src/TestMode.h index 3d99d465..4dcf8cf8 100644 --- a/src/TestMode.h +++ b/src/TestMode.h @@ -15,4 +15,4 @@ class TestMode_ { extern TestMode_ TestMode; -bool handle_key_event_test(byte row, byte col, uint8_t currentState, uint8_t previousState); +bool handle_key_event_test(Key mappedKey, byte row, byte col, uint8_t currentState, uint8_t previousState); diff --git a/src/hooks.h b/src/hooks.h index 93b4057d..cec4da50 100644 --- a/src/hooks.h +++ b/src/hooks.h @@ -1,10 +1,11 @@ #pragma once #include +#include "key_defs.h" #define HOOK_MAX 64 -typedef bool (*custom_handler_t)(byte row, byte col, uint8_t currentState, uint8_t previousState); +typedef bool (*custom_handler_t)(Key mappedKey, byte row, byte col, uint8_t currentState, uint8_t previousState); extern custom_handler_t eventHandlers[HOOK_MAX]; void event_handler_hook_add (custom_handler_t hook); diff --git a/src/key_events.cpp b/src/key_events.cpp index a1f6541c..09c24aa6 100644 --- a/src/key_events.cpp +++ b/src/key_events.cpp @@ -1,7 +1,5 @@ #include "key_events.h" -static const Key keymaps[KEYMAPS][ROWS][COLS] PROGMEM = { KEYMAP_LIST }; - void handle_synthetic_key_event(Key mappedKey, uint8_t currentState, uint8_t previousState) { if (mappedKey.flags & IS_MOUSE_KEY && !( mappedKey.rawKey & KEY_MOUSE_WARP) ) { handle_mouse_key_event(mappedKey, currentState, previousState); @@ -51,19 +49,21 @@ Key lookup_key(byte keymap, byte row, byte col) { return mappedKey; } -void handle_key_event(byte row, byte col, uint8_t currentState, uint8_t previousState) { +void handle_key_event(Key mappedKey, byte row, byte col, uint8_t currentState, uint8_t previousState) { for (byte i = 0; eventHandlers[i] != NULL && i < HOOK_MAX; i++) { custom_handler_t handler = eventHandlers[i]; - if ((*handler)(row, col, currentState, previousState)) + if ((*handler)(mappedKey, row, col, currentState, previousState)) return; } } -bool handle_key_event_default(byte row, byte col, uint8_t currentState, uint8_t previousState) { +bool handle_key_event_default(Key mappedKey, byte row, byte col, uint8_t currentState, uint8_t previousState) { //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 mappedKey = lookup_key(temporary_keymap, row, col); + if (mappedKey.raw == Key_NoKey.raw) { + mappedKey = lookup_key(temporary_keymap, row, col); + } Key baseKey = lookup_key(primary_keymap, row, col); if ((baseKey.flags & SWITCH_TO_KEYMAP diff --git a/src/key_events.h b/src/key_events.h index da687301..55b3945c 100644 --- a/src/key_events.h +++ b/src/key_events.h @@ -7,19 +7,47 @@ #include "LEDControl.h" #include "Storage.h" #include "keymap_metadata.h" -#include "generated/keymaps.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 +/* The event handling starts with the Scanner calling handle_key_event() for + * every key in the matrix, and it is the task of this method to figure out what + * to do, it is the main entry point. + * + * This function will iterate through an array of handler functions, and stop as + * soon as one of them signals that the event has been handled. To make it + * possible to inject synthetic events, one can call handle_key_event from + * within a custom handler (making the event handling recursive), with a + * different keycode. + * + * This is useful for example for one-shot modifiers, where we would like to + * temporarily disable the one-shot functionality, and have them work as a + * normal modifier instead. In this case, the keymap would contain a key with + * OSM flags set, and the event handler would remove the OSM flags, and let the + * system handle the key as it would have, without the OSM flags. So we simply + * clear the flags, and call handle_key_event again, with the modifier keycode + * as the first argument. This way, we could insert an event, and have the whole + * chain re-process it, instead of registering the keycode ourselves with HID + * ourselves. Injecting allows any and all custom handlers to have a chance, + * too. + * + * For this reason, the handle_key_event receives four arguments: the mapped key + * (or Key_NoKey if we do not want to override what is in the keymap), the row + * and column of the key, so we can look up the code for it, and the current and + * previous state of the key, so we can determine what the event is. + */ +void handle_key_event(Key mappedKey, byte row, byte col, uint8_t currentState, uint8_t previousState); + +// Internal use void handle_synthetic_key_event( Key mappedKey, uint8_t currentState, uint8_t previousState); -void handle_key_event(byte row, byte col, uint8_t currentState, uint8_t previousState); void press_key(Key mappedKey); void handle_keymap_key_event(Key keymapEntry, uint8_t currentState, uint8_t previousState); void handle_mouse_key_event(Key mappedKey, uint8_t currentState, uint8_t previousState); -bool handle_key_event_default(byte row, byte col, uint8_t currentState, uint8_t previousState); +bool handle_key_event_default(Key mappedKey, byte row, byte col, uint8_t currentState, uint8_t previousState); Key lookup_key(byte keymap, byte row, byte col); diff --git a/src/keymap_metadata.h b/src/keymap_metadata.h index ab3c8d2a..81207eba 100644 --- a/src/keymap_metadata.h +++ b/src/keymap_metadata.h @@ -2,6 +2,3 @@ #define COLS 16 #define ROWS 4 -#define KEYMAPS 3 -#define NUMPAD_KEYMAP 2 -#define KEYMAP_LIST KEYMAP_QWERTY KEYMAP_GENERIC_FN2 KEYMAP_NUMPAD