diff --git a/src/Model01.cpp b/src/Model01.cpp index f8fda144..7290b70f 100644 --- a/src/Model01.cpp +++ b/src/Model01.cpp @@ -107,12 +107,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/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 d1753ba5..09c24aa6 100644 --- a/src/key_events.cpp +++ b/src/key_events.cpp @@ -49,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 633f9f0a..55b3945c 100644 --- a/src/key_events.h +++ b/src/key_events.h @@ -15,11 +15,39 @@ 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);