Update linear addressing branch for firmware drift

pull/640/head
Jesse Vincent 6 years ago
parent 00552193e9
commit 617dca07dd

@ -75,7 +75,7 @@ In practice, this boils down to implementing one or more of the following hook p
- `onSetup()`: Called once during device bootup, at the end of the `setup()` method. It takes no arguments, and must return `kaleidoscope::EventHandlerResult::OK`. - `onSetup()`: Called once during device bootup, at the end of the `setup()` method. It takes no arguments, and must return `kaleidoscope::EventHandlerResult::OK`.
- `beforeEachCycle()`: Called once, at the beginning of each cycle of the main loop. This is similar to the old "loop hook" with its `post_clear` argument set to false. Takes no arguments, must return `kaleidoscope::EventHandlerResult::OK`. - `beforeEachCycle()`: Called once, at the beginning of each cycle of the main loop. This is similar to the old "loop hook" with its `post_clear` argument set to false. Takes no arguments, must return `kaleidoscope::EventHandlerResult::OK`.
- `onKeyswitchEvent`: Called for every non-idle key event. This replaces the old "event handler hook". It takes a key reference, coordinates, and a key state. The key reference can be updated to change the key being processed, so that any plugin that processes it further, will see the updated key. Can return `kaleidoscope::EventHandlerResult::OK` to let other plugins process the event further, or `kaleidoscope::EventHandlerResult::EVENT_CONSUMED` to stop processing. - `onKeyswitchEvent`: Called for every non-idle key event. This replaces the old "event handler hook". It takes a key reference, a key address, and a key state. The key reference can be updated to change the key being processed, so that any plugin that processes it further, will see the updated key. Can return `kaleidoscope::EventHandlerResult::OK` to let other plugins process the event further, or `kaleidoscope::EventHandlerResult::EVENT_CONSUMED` to stop processing.
- `onFocusEvent`: Used to implement [bi-directional communication](#bidirectional-communication-for-plugins). This is called whenever the firmware receives a command from the host. The only argument is the command name. Can return `kaleidoscope::EventHandlerResult::OK` to let other plugins process the event further, or `kaleidoscope::EventHandlerResult::EVENT_CONSUMED` to stop processing. - `onFocusEvent`: Used to implement [bi-directional communication](#bidirectional-communication-for-plugins). This is called whenever the firmware receives a command from the host. The only argument is the command name. Can return `kaleidoscope::EventHandlerResult::OK` to let other plugins process the event further, or `kaleidoscope::EventHandlerResult::EVENT_CONSUMED` to stop processing.
- `beforeReportingState`: Called without arguments, just before sending the keyboard and mouse reports to the host. Must return `kaleidoscope::EventHandlerResult::OK`. - `beforeReportingState`: Called without arguments, just before sending the keyboard and mouse reports to the host. Must return `kaleidoscope::EventHandlerResult::OK`.
- `afterEachCycle`: Called without arguments at the very end of each cycle. This is the replacement for the "loop hook" with its `post_clear` argument set. - `afterEachCycle`: Called without arguments at the very end of each cycle. This is the replacement for the "loop hook" with its `post_clear` argument set.
@ -435,6 +435,13 @@ Older versions of the plugin required one to set up `Key_Redial` manually, and l
## Deprecated APIs and their replacements ## Deprecated APIs and their replacements
### Transition to linear indexing
Row/col based indexing was replaced by linear indexing throughout the whole firmware. A compatibility layer of functions was introduced that allows
the firmware to remain backwards compatible, however, these functions are deprecated and will be removed in future versions of the firmware.
Also a new version of the onKeyswitchEvent-handler has been introduced. The old version is deprecated.
### Finer OneShot stickability control ### Finer OneShot stickability control
The [OneShot plugin](doc/plugin/OneShot.md) has much improved stickability control. Instead of only being able to control if one-shot layers should be stickable too, or disabling the sticky feature in general, it is now possible to control stickiness on a per-key basis with the new `OneShot.enableStickability()` and `OneShot.disableStickablity()` methods. The old properties are still available, but will be removed by **2019-04-30**. The [OneShot plugin](doc/plugin/OneShot.md) has much improved stickability control. Instead of only being able to control if one-shot layers should be stickable too, or disabling the sticky feature in general, it is now possible to control stickiness on a per-key basis with the new `OneShot.enableStickability()` and `OneShot.disableStickablity()` methods. The old properties are still available, but will be removed by **2019-04-30**.
@ -572,7 +579,7 @@ class Plugin {
public: public:
EventHandlerResult onSetup(); EventHandlerResult onSetup();
EventHandlerResult beforeEachCycle(); EventHandlerResult beforeEachCycle();
EventHandlerResult onKeyswitchEvent(Key &mapped_key, byte row, byte col, uint8_t key_state); EventHandlerResult onKeyswitchEvent(Key &mapped_key, KeyAddr key_addr, uint8_t key_state);
EventHandlerResult beforeReportingState(); EventHandlerResult beforeReportingState();
EventHandlerResult afterEachCycle(); EventHandlerResult afterEachCycle();
}; };

@ -34,11 +34,11 @@ methods or properties other than those provided by all LED modes.
### `.display(key)` ### `.display(key)`
### `.display(key, col)` ### `.display(key, col)`
### `.display(key, row, col)` ### `.display(key, key_addr)`
### `.display(key, row, col, color)` ### `.display(key, key_addr, color)`
> Display the symbol for `key` at the given row or column, with pixels set to > Display the symbol for `key` at the given led address, with pixels set to
> the specified `color`. If `row` is omitted, the first row - `0` is assumed. If > the specified `color`. If only `col` is provided, the first row - `0` is assumed. If
> the column is omitted, then the third column - `2` - is used. > the column is omitted, then the third column - `2` - is used.
> If the `color` is omitted, the plugin will use the global `.color` property. > If the `color` is omitted, the plugin will use the global `.color` property.
> >
@ -50,8 +50,8 @@ methods or properties other than those provided by all LED modes.
### `.display(symbol)` ### `.display(symbol)`
### `.display(symbol, col)` ### `.display(symbol, col)`
### `.display(symbol, row, col)` ### `.display(symbol, key_addr)`
### `.display(symbol, row, col, color)` ### `.display(symbol, key_addr, color)`
> As the previous function, but instead of a key, it expects a 4x4 bitmap in > As the previous function, but instead of a key, it expects a 4x4 bitmap in
> the form of a 16-bit unsigned integer, where the low bit is the top-right > the form of a 16-bit unsigned integer, where the low bit is the top-right
@ -61,7 +61,7 @@ methods or properties other than those provided by all LED modes.
### `.clear(key)`, `.clear(symbol)` ### `.clear(key)`, `.clear(symbol)`
### `.clear(key, col)`, `.clear(symbol, col)` ### `.clear(key, col)`, `.clear(symbol, col)`
### `.clear(key, col, row)`, `.clear(symbol, col, row)` ### `.clear(key, key_addr)`, `.clear(symbol, key_addr)`
> Just like the `.display()` counterparts, except these clear the symbol, by > Just like the `.display()` counterparts, except these clear the symbol, by
> turning the LED pixels it is made up from off. > turning the LED pixels it is made up from off.

@ -18,8 +18,8 @@ one keycode (i.e. symbol) when tapped, and a different keycode -- most likely a
KALEIDOSCOPE_INIT_PLUGINS(Qukeys); KALEIDOSCOPE_INIT_PLUGINS(Qukeys);
``` ```
- Define some `Qukeys` of the format `Qukey(layer, row, col, alt_keycode)` - Define some `Qukeys` of the format `Qukey(layer, key_addr, alt_keycode)`
(layers, rows and columns are all zero-indexed, rows are top to bottom and (layers, and key addresses are all zero-indexed, in key addresses rows are top to bottom and
columns are left to right): columns are left to right):
- For the Keyboardio Model 01, key coordinates refer to [this header - For the Keyboardio Model 01, key coordinates refer to [this header

@ -28,9 +28,9 @@ void systerAction(kaleidoscope::plugin::Syster::action_t action, const char *sym
Unicode.type (0x2328); Unicode.type (0x2328);
break; break;
case kaleidoscope::plugin::Syster::EndAction: case kaleidoscope::plugin::Syster::EndAction:
handleKeyswitchEvent (Key_Backspace, UNKNOWN_KEYSWITCH_LOCATION, IS_PRESSED | INJECTED); handleKeyswitchEvent (Key_Backspace, UnknownKeyswitchLocation, IS_PRESSED | INJECTED);
kaleidoscope::hid::sendKeyboardReport (); kaleidoscope::hid::sendKeyboardReport ();
handleKeyswitchEvent (Key_Backspace, UNKNOWN_KEYSWITCH_LOCATION, WAS_PRESSED | INJECTED); handleKeyswitchEvent (Key_Backspace, UnknownKeyswitchLocation, WAS_PRESSED | INJECTED);
kaleidoscope::hid::sendKeyboardReport (); kaleidoscope::hid::sendKeyboardReport ();
break; break;
case kaleidoscope::plugin::Syster::SymbolAction: case kaleidoscope::plugin::Syster::SymbolAction:

@ -123,7 +123,7 @@ property only:
> The `tap_count` and `tap_dance_actions` parameters should be the same as the > The `tap_count` and `tap_dance_actions` parameters should be the same as the
> similarly named parameters of the `tapDanceAction` function. > similarly named parameters of the `tapDanceAction` function.
### `tapDanceAction(tap_dance_index, row, col, tap_count, tap_dance_action)` ### `tapDanceAction(tap_dance_index, key_addr, tap_count, tap_dance_action)`
> The heart of the tap-dance plugin is the handler method. This is called every > The heart of the tap-dance plugin is the handler method. This is called every
> time any kind of tap-dance action is to be performed. See the > time any kind of tap-dance action is to be performed. See the

@ -58,6 +58,6 @@ void macroAppSwitchLoop() {
// if appSwitchActive is true, we continue holding Alt. // if appSwitchActive is true, we continue holding Alt.
if (appSwitchActive) { if (appSwitchActive) {
handleKeyswitchEvent(mod, UNKNOWN_KEYSWITCH_LOCATION, IS_PRESSED); handleKeyswitchEvent(mod, UnknownKeyswitchLocation, IS_PRESSED);
} }
} }

@ -45,7 +45,7 @@ class EventDropper_ : public kaleidoscope::Plugin {
public: public:
EventDropper_() {} EventDropper_() {}
kaleidoscope::EventHandlerResult onKeyswitchEvent(Key &mapped_key, byte row, byte col, uint8_t key_state) { kaleidoscope::EventHandlerResult onKeyswitchEvent(Key &mapped_key, KeyAddr key_addr, uint8_t key_state) {
return kaleidoscope::EventHandlerResult::EVENT_CONSUMED; return kaleidoscope::EventHandlerResult::EVENT_CONSUMED;
} }
}; };

@ -64,11 +64,11 @@ KALEIDOSCOPE_INIT_PLUGINS(Qukeys, Macros);
void setup() { void setup() {
QUKEYS( QUKEYS(
kaleidoscope::plugin::Qukey(0, 2, 1, Key_LeftGui), // A/cmd kaleidoscope::plugin::Qukey(0, KeyAddr(2, 1), Key_LeftGui), // A/cmd
kaleidoscope::plugin::Qukey(0, 2, 2, Key_LeftAlt), // S/alt kaleidoscope::plugin::Qukey(0, KeyAddr(2, 2), Key_LeftAlt), // S/alt
kaleidoscope::plugin::Qukey(0, 2, 3, Key_LeftControl), // D/ctrl kaleidoscope::plugin::Qukey(0, KeyAddr(2, 3), Key_LeftControl), // D/ctrl
kaleidoscope::plugin::Qukey(0, 2, 4, Key_LeftShift), // F/shift kaleidoscope::plugin::Qukey(0, KeyAddr(2, 4), Key_LeftShift), // F/shift
kaleidoscope::plugin::Qukey(0, 3, 6, ShiftToLayer(1)) // Q/layer-shift (on `fn`) kaleidoscope::plugin::Qukey(0, KeyAddr(3, 6), ShiftToLayer(1)) // Q/layer-shift (on `fn`)
) )
Qukeys.setTimeout(200); Qukeys.setTimeout(200);
Qukeys.setReleaseDelay(20); Qukeys.setReleaseDelay(20);

@ -50,9 +50,9 @@ void systerAction(kaleidoscope::plugin::Syster::action_t action, const char *sym
Unicode.type(0x2328); Unicode.type(0x2328);
break; break;
case kaleidoscope::plugin::Syster::EndAction: case kaleidoscope::plugin::Syster::EndAction:
handleKeyswitchEvent(Key_Backspace, UNKNOWN_KEYSWITCH_LOCATION, IS_PRESSED | INJECTED); handleKeyswitchEvent(Key_Backspace, UnknownKeyswitchLocation, IS_PRESSED | INJECTED);
kaleidoscope::hid::sendKeyboardReport(); kaleidoscope::hid::sendKeyboardReport();
handleKeyswitchEvent(Key_Backspace, UNKNOWN_KEYSWITCH_LOCATION, WAS_PRESSED | INJECTED); handleKeyswitchEvent(Key_Backspace, UnknownKeyswitchLocation, WAS_PRESSED | INJECTED);
kaleidoscope::hid::sendKeyboardReport(); kaleidoscope::hid::sendKeyboardReport();
break; break;
case kaleidoscope::plugin::Syster::SymbolAction: case kaleidoscope::plugin::Syster::SymbolAction:

@ -44,7 +44,7 @@ static void tapDanceEsc(uint8_t tap_dance_index, uint8_t tap_count, kaleidoscope
tapDanceActionKeys(tap_count, tap_dance_action, Key_Escape, Key_Tab); tapDanceActionKeys(tap_count, tap_dance_action, Key_Escape, Key_Tab);
} }
void tapDanceAction(uint8_t tap_dance_index, byte row, byte col, uint8_t tap_count, kaleidoscope::plugin::TapDance::ActionType tap_dance_action) { void tapDanceAction(uint8_t tap_dance_index, KeyAddr key_addr, uint8_t tap_count, kaleidoscope::plugin::TapDance::ActionType tap_dance_action) {
switch (tap_dance_index) { switch (tap_dance_index) {
case 0: case 0:
return tapDanceActionKeys(tap_count, tap_dance_action, Key_Tab, Key_Escape); return tapDanceActionKeys(tap_count, tap_dance_action, Key_Tab, Key_Escape);

@ -22,6 +22,7 @@
#pragma once #pragma once
#include "kaleidoscope/MatrixAddr.h" #include "kaleidoscope/MatrixAddr.h"
#include "kaleidoscope_internal/deprecations.h"
#ifndef CRGB #ifndef CRGB
#error cRGB and CRGB *must* be defined before including this header! #error cRGB and CRGB *must* be defined before including this header!
@ -57,6 +58,12 @@ namespace kaleidoscope {
*/ */
class Hardware { class Hardware {
public: public:
// To satisfy the interface of those methods that allow
// for matrix addressing we define default key and led address classes.
// Those typedefs are supposed to overridden by derived hardware classes.
typedef MatrixAddr<0, 0> KeyAddr;
/** /**
* @defgroup kaleidoscope_hardware_leds Kaleidoscope::Hardware/LEDs * @defgroup kaleidoscope_hardware_leds Kaleidoscope::Hardware/LEDs
* @{ * @{
@ -66,6 +73,16 @@ class Hardware {
* changes made before this call are reflected on the device. * changes made before this call are reflected on the device.
*/ */
void syncLeds(void) {} void syncLeds(void) {}
/**
* Set the color of a per-key LED at a given row and column.
*
* Setting the color does not need to take effect immediately, it can be
* delayed until @ref syncLeds is called.
*
* @param key_addr is the matrix address of the LED.
* @param color is the color to set the LED to.
*/
void setCrgbAt(KeyAddr key_addr, cRGB color) {}
/** /**
* Set the color of a per-key LED at a given row and column. * Set the color of a per-key LED at a given row and column.
* *
@ -76,7 +93,7 @@ class Hardware {
* @param col is the logical column position of the key. * @param col is the logical column position of the key.
* @param color is the color to set the LED to. * @param color is the color to set the LED to.
*/ */
void setCrgbAt(byte row, byte col, cRGB color) {} DEPRECATED(ROW_COL_FUNC) void setCrgbAt(byte row, byte col, cRGB color) {}
/** /**
* Set the color of a per-key LED at a given LED index. * Set the color of a per-key LED at a given LED index.
* *
@ -100,6 +117,17 @@ class Hardware {
}; };
return c; return c;
} }
/**
* Returns the index of the LED at a given row & column.
*
* @param key_addr is the matrix address of the LED.
*
* @returns The index of the LED at the given position, or -1 if there are no
* LEDs there.
*/
int8_t getLedIndex(KeyAddr key_addr) {
return -1;
}
/** /**
* Returns the index of the LED at a given row & column. * Returns the index of the LED at a given row & column.
* *
@ -109,7 +137,7 @@ class Hardware {
* @returns The index of the LED at the given position, or -1 if there are no * @returns The index of the LED at the given position, or -1 if there are no
* LEDs there. * LEDs there.
*/ */
int8_t getLedIndex(uint8_t row, byte col) { DEPRECATED(ROW_COL_FUNC) int8_t getLedIndex(uint8_t row, byte col) {
return -1; return -1;
} }
/** @} */ /** @} */
@ -149,6 +177,15 @@ class Hardware {
* which is all but hidden from the rest of the plugins. * which is all but hidden from the rest of the plugins.
* @{ * @{
*/ */
/**
* Mask out a key.
*
* Masking a key out means that any other event than a release will be
* ignored until said release.
*
* @param key_addr is the matrix address of the key.
*/
void maskKey(KeyAddr key_addr) {}
/** /**
* Mask out a key. * Mask out a key.
* *
@ -158,7 +195,16 @@ class Hardware {
* @param row is the row the key is located at in the matrix. * @param row is the row the key is located at in the matrix.
* @param col is the column the key is located at in the matrix. * @param col is the column the key is located at in the matrix.
*/ */
void maskKey(byte row, byte col) {} DEPRECATED(ROW_COL_FUNC) void maskKey(byte row, byte col) {}
/**
* Unmask a key.
*
* Remove the mask - if any - for a given key. To be used when the mask
* needs to be removed without the key being released.
*
* @param key_addr is the matrix address of the key.
*/
void unMaskKey(KeyAddr key_addr) {}
/** /**
* Unmask a key. * Unmask a key.
* *
@ -169,6 +215,16 @@ class Hardware {
* @param col is the column the key is located at in the matrix. * @param col is the column the key is located at in the matrix.
*/ */
void unMaskKey(byte row, byte col) {} void unMaskKey(byte row, byte col) {}
/**
* Check whether a key is masked or not.
*
* @param key_addr is the matrix address of the key.
*
* @returns true if the key is masked, false otherwise.
*/
bool isKeyMasked(KeyAddr key_addr) {
return false;
}
/** /**
* Check whether a key is masked or not. * Check whether a key is masked or not.
* *
@ -177,7 +233,7 @@ class Hardware {
* *
* @returns true if the key is masked, false otherwise. * @returns true if the key is masked, false otherwise.
*/ */
bool isKeyMasked(byte row, byte col) { DEPRECATED(ROW_COL_FUNC) bool isKeyMasked(byte row, byte col) {
return false; return false;
} }
/** @} */ /** @} */
@ -223,6 +279,16 @@ class Hardware {
* *
* @{ * @{
*/ */
/**
* Check if a key is pressed at a given position.
*
* @param key_addr is the matrix address of the key.
*
* @returns true if the key is pressed, false otherwise.
*/
bool isKeyswitchPressed(KeyAddr key_addr) {
return false;
}
/** /**
* Check if a key is pressed at a given position. * Check if a key is pressed at a given position.
* *
@ -231,7 +297,7 @@ class Hardware {
* *
* @returns true if the key is pressed, false otherwise. * @returns true if the key is pressed, false otherwise.
*/ */
bool isKeyswitchPressed(byte row, byte col) { DEPRECATED(ROW_COL_FUNC) bool isKeyswitchPressed(byte row, byte col) {
return false; return false;
} }
/** /**
@ -263,7 +329,17 @@ class Hardware {
* *
* @returns true if the key was pressed, false otherwise. * @returns true if the key was pressed, false otherwise.
*/ */
bool wasKeyswitchPressed(byte row, byte col) { DEPRECATED(ROW_COL_FUNC) bool wasKeyswitchPressed(byte row, byte col) {
return false;
}
/**
* Check if a key was pressed at a given position on the previous scan
*
* @param key_addr is the matrix address of the key.
*
* @returns true if the key was pressed, false otherwise.
*/
bool wasKeyswitchPressed(KeyAddr key_addr) {
return false; return false;
} }
/** /**

@ -46,10 +46,8 @@ Kaleidoscope_::setup(void) {
// Update the keymap cache, so we start with a non-empty state. // Update the keymap cache, so we start with a non-empty state.
Layer.updateActiveLayers(); Layer.updateActiveLayers();
for (byte row = 0; row < ROWS; row++) { for (auto key_addr : KeyAddr::all()) {
for (byte col = 0; col < COLS; col++) { Layer.updateLiveCompositeKeymap(key_addr);
Layer.updateLiveCompositeKeymap(row, col);
}
} }
} }

@ -1,44 +0,0 @@
/* -*- mode: c++ -*-
* Kaleidoscope-Qukeys -- Assign two keycodes to a single key
* Copyright (C) 2017 Michael Richters
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#pragma once
#include <Kaleidoscope.h>
// Helper functions for converting between separate (row,col)
// coordinates and a single-byte key number (addr). This works as long
// as the keyboard has fewer than 256 keys.
namespace kaleidoscope {
namespace addr {
inline uint8_t row(uint8_t key_addr) {
return (key_addr / COLS);
}
inline uint8_t col(uint8_t key_addr) {
return (key_addr % COLS);
}
inline uint8_t addr(uint8_t row, uint8_t col) {
return ((row * COLS) + col);
}
inline void mask(uint8_t key_addr) {
KeyboardHardware.maskKey(row(key_addr), col(key_addr));
}
inline void unmask(uint8_t key_addr) {
KeyboardHardware.unMaskKey(row(key_addr), col(key_addr));
}
} // namespace addr {
} // namespace kaleidoscope {

@ -74,15 +74,13 @@ uint8_t ATMegaKeyboard::pressedKeyswitchCount() {
return count; return count;
} }
bool ATMegaKeyboard::isKeyswitchPressed(uint8_t row, byte col) { bool ATMegaKeyboard::isKeyswitchPressed(KeyAddr key_addr) {
return (bitRead(KeyboardHardware.keyState_[row], col) != 0); return (bitRead(KeyboardHardware.keyState_[key_addr.row()], key_addr.col()) != 0);
} }
bool ATMegaKeyboard::isKeyswitchPressed(uint8_t keyIndex) { bool ATMegaKeyboard::isKeyswitchPressed(uint8_t keyIndex) {
keyIndex--; keyIndex--;
return isKeyswitchPressed(keyIndex / KeyboardHardware.matrix_columns, return isKeyswitchPressed(KeyAddr(keyIndex));
keyIndex % KeyboardHardware.matrix_columns);
} }
@ -95,15 +93,14 @@ uint8_t ATMegaKeyboard::previousPressedKeyswitchCount() {
return count; return count;
} }
bool ATMegaKeyboard::wasKeyswitchPressed(uint8_t row, byte col) { bool ATMegaKeyboard::wasKeyswitchPressed(KeyAddr key_addr) {
return (bitRead(KeyboardHardware.previousKeyState_[row], col) != 0); return (bitRead(KeyboardHardware.previousKeyState_[key_addr.row()], key_addr.col()) != 0);
} }
bool ATMegaKeyboard::wasKeyswitchPressed(uint8_t keyIndex) { bool ATMegaKeyboard::wasKeyswitchPressed(uint8_t keyIndex) {
keyIndex--; keyIndex--;
return wasKeyswitchPressed(keyIndex / KeyboardHardware.matrix_columns, return wasKeyswitchPressed(KeyAddr(keyIndex));
keyIndex % KeyboardHardware.matrix_columns);
} }
@ -113,7 +110,7 @@ void __attribute__((optimize(3))) ATMegaKeyboard::actOnMatrixScan() {
uint8_t keyState = (bitRead(KeyboardHardware.previousKeyState_[row], col) << 0) | uint8_t keyState = (bitRead(KeyboardHardware.previousKeyState_[row], col) << 0) |
(bitRead(KeyboardHardware.keyState_[row], col) << 1); (bitRead(KeyboardHardware.keyState_[row], col) << 1);
if (keyState) { if (keyState) {
handleKeyswitchEvent(Key_NoKey, row, col, keyState); handleKeyswitchEvent(Key_NoKey, KeyAddr(row, col), keyState);
} }
} }
KeyboardHardware.previousKeyState_[row] = KeyboardHardware.keyState_[row]; KeyboardHardware.previousKeyState_[row] = KeyboardHardware.keyState_[row];
@ -130,25 +127,25 @@ void ATMegaKeyboard::scanMatrix() {
KeyboardHardware.actOnMatrixScan(); KeyboardHardware.actOnMatrixScan();
} }
void ATMegaKeyboard::maskKey(byte row, byte col) { void ATMegaKeyboard::maskKey(KeyAddr key_addr) {
if (row >= KeyboardHardware.matrix_rows || col >= KeyboardHardware.matrix_columns) if (!key_addr.isValid())
return; return;
bitWrite(KeyboardHardware.masks_[row], col, 1); bitWrite(KeyboardHardware.masks_[key_addr.row()], key_addr.col(), 1);
} }
void ATMegaKeyboard::unMaskKey(byte row, byte col) { void ATMegaKeyboard::unMaskKey(KeyAddr key_addr) {
if (row >= KeyboardHardware.matrix_rows || col >= KeyboardHardware.matrix_columns) if (!key_addr.isValid())
return; return;
bitWrite(KeyboardHardware.masks_[row], col, 0); bitWrite(KeyboardHardware.masks_[key_addr.row()], key_addr.col(), 0);
} }
bool ATMegaKeyboard::isKeyMasked(byte row, byte col) { bool ATMegaKeyboard::isKeyMasked(KeyAddr key_addr) {
if (row >= KeyboardHardware.matrix_rows || col >= KeyboardHardware.matrix_columns) if (!key_addr.isValid())
return false; return false;
return bitRead(KeyboardHardware.masks_[row], col); return bitRead(KeyboardHardware.masks_[key_addr.row()], key_addr.col());
} }
/* /*

@ -22,9 +22,9 @@
#include <Arduino.h> #include <Arduino.h>
#include <KeyboardioHID.h> #include <KeyboardioHID.h>
#include "Kaleidoscope-HIDAdaptor-KeyboardioHID.h" #include "Kaleidoscope-HIDAdaptor-KeyboardioHID.h"
#include "kaleidoscope/MatrixAddr.h"
#include "kaleidoscope/macro_helpers.h" #include "kaleidoscope/macro_helpers.h"
#include "kaleidoscope/key_events.h"
#include "kaleidoscope/hardware/avr/pins_and_ports.h" #include "kaleidoscope/hardware/avr/pins_and_ports.h"
#include <avr/wdt.h> #include <avr/wdt.h>
@ -84,16 +84,31 @@ class ATMegaKeyboard : public kaleidoscope::Hardware {
void scanMatrix(); void scanMatrix();
uint8_t pressedKeyswitchCount(); uint8_t pressedKeyswitchCount();
bool isKeyswitchPressed(uint8_t row, byte col); bool isKeyswitchPressed(KeyAddr key_addr);
DEPRECATED(ROW_COL_FUNC) bool isKeyswitchPressed(uint8_t row, byte col) {
return isKeyswitchPressed(KeyAddr(row, col));
}
bool isKeyswitchPressed(uint8_t keyIndex); bool isKeyswitchPressed(uint8_t keyIndex);
uint8_t previousPressedKeyswitchCount(); uint8_t previousPressedKeyswitchCount();
bool wasKeyswitchPressed(uint8_t row, byte col); bool wasKeyswitchPressed(KeyAddr key_addr);
DEPRECATED(ROW_COL_FUNC) bool wasKeyswitchPressed(uint8_t row, byte col) {
return wasKeyswitchPressed(KeyAddr(row, col));
}
bool wasKeyswitchPressed(uint8_t keyIndex); bool wasKeyswitchPressed(uint8_t keyIndex);
void maskKey(byte row, byte col); void maskKey(KeyAddr key_addr);
void unMaskKey(byte row, byte col); DEPRECATED(ROW_COL_FUNC) void maskKey(byte row, byte col) {
bool isKeyMasked(byte row, byte col); maskKey(KeyAddr(row, col));
}
void unMaskKey(KeyAddr key_addr);
DEPRECATED(ROW_COL_FUNC) void unMaskKey(byte row, byte col) {
unMaskKey(KeyAddr(row, col));
}
bool isKeyMasked(KeyAddr key_addr);
DEPRECATED(ROW_COL_FUNC) bool isKeyMasked(byte row, byte col) {
return isKeyMasked(KeyAddr(row, col));
}
static bool do_scan_; static bool do_scan_;

@ -113,7 +113,7 @@ void __attribute__((optimize(3))) ErgoDox::actOnMatrixScan() {
uint8_t keyState = (bitRead(previousKeyState_[row], col) << 0) | uint8_t keyState = (bitRead(previousKeyState_[row], col) << 0) |
(bitRead(keyState_[row], col) << 1); (bitRead(keyState_[row], col) << 1);
if (keyState) if (keyState)
handleKeyswitchEvent(Key_NoKey, row, col, keyState); handleKeyswitchEvent(Key_NoKey, KeyAddr(row, col), keyState);
} }
previousKeyState_[row] = keyState_[row]; previousKeyState_[row] = keyState_[row];
} }
@ -130,25 +130,25 @@ void ErgoDox::scanMatrix() {
actOnMatrixScan(); actOnMatrixScan();
} }
void ErgoDox::maskKey(byte row, byte col) { void ErgoDox::maskKey(KeyAddr key_addr) {
if (row >= ROWS || col >= COLS) if (!key_addr.isValid())
return; return;
bitWrite(masks_[row], col, 1); bitWrite(masks_[key_addr.row()], key_addr.col(), 1);
} }
void ErgoDox::unMaskKey(byte row, byte col) { void ErgoDox::unMaskKey(KeyAddr key_addr) {
if (row >= ROWS || col >= COLS) if (!key_addr.isValid())
return; return;
bitWrite(masks_[row], col, 0); bitWrite(masks_[key_addr.row()], key_addr.col(), 0);
} }
bool ErgoDox::isKeyMasked(byte row, byte col) { bool ErgoDox::isKeyMasked(KeyAddr key_addr) {
if (row >= ROWS || col >= COLS) if (!key_addr.isValid())
return false; return false;
return bitRead(masks_[row], col); return bitRead(masks_[key_addr.row()], key_addr.col());
} }
// ErgoDox-specific stuff // ErgoDox-specific stuff
@ -223,22 +223,22 @@ void ErgoDox::debounceRow(uint8_t change, uint8_t row) {
} }
} }
bool ErgoDox::isKeyswitchPressed(byte row, byte col) { bool ErgoDox::isKeyswitchPressed(KeyAddr key_addr) {
return (bitRead(keyState_[row], col) != 0); return (bitRead(keyState_[key_addr.row()], key_addr.col()) != 0);
} }
bool ErgoDox::isKeyswitchPressed(uint8_t keyIndex) { bool ErgoDox::isKeyswitchPressed(uint8_t keyIndex) {
keyIndex--; keyIndex--;
return isKeyswitchPressed(keyIndex / COLS, keyIndex % COLS); return isKeyswitchPressed(KeyAddr(keyIndex));
} }
bool ErgoDox::wasKeyswitchPressed(byte row, byte col) { bool ErgoDox::wasKeyswitchPressed(KeyAddr key_addr) {
return (bitRead(previousKeyState_[row], col) != 0); return (bitRead(previousKeyState_[key_addr.row()], key_addr.col()) != 0);
} }
bool ErgoDox::wasKeyswitchPressed(uint8_t keyIndex) { bool ErgoDox::wasKeyswitchPressed(uint8_t keyIndex) {
keyIndex--; keyIndex--;
return wasKeyswitchPressed(keyIndex / COLS, keyIndex % COLS); return wasKeyswitchPressed(KeyAddr(keyIndex));
} }
uint8_t ErgoDox::previousPressedKeyswitchCount() { uint8_t ErgoDox::previousPressedKeyswitchCount() {

@ -43,6 +43,7 @@ struct cRGB {
#define CRGB(r,g,b) (cRGB){b, g, r} #define CRGB(r,g,b) (cRGB){b, g, r}
#include "kaleidoscope/Hardware.h" #include "kaleidoscope/Hardware.h"
#include "kaleidoscope/MatrixAddr.h"
namespace kaleidoscope { namespace kaleidoscope {
namespace hardware { namespace hardware {
@ -66,15 +67,30 @@ class ErgoDox : public kaleidoscope::Hardware {
void actOnMatrixScan(void); void actOnMatrixScan(void);
void setup(); void setup();
void maskKey(byte row, byte col); void maskKey(KeyAddr key_addr);
void unMaskKey(byte row, byte col); DEPRECATED(ROW_COL_FUNC) void maskKey(byte row, byte col) {
bool isKeyMasked(byte row, byte col); maskKey(KeyAddr(row, col));
}
void unMaskKey(KeyAddr key_addr);
DEPRECATED(ROW_COL_FUNC) void unMaskKey(byte row, byte col) {
unMaskKey(KeyAddr(row, col));
}
bool isKeyMasked(KeyAddr key_addr);
DEPRECATED(ROW_COL_FUNC) bool isKeyMasked(byte row, byte col) {
return isKeyMasked(KeyAddr(row, col));
}
bool isKeyswitchPressed(byte row, byte col); bool isKeyswitchPressed(KeyAddr key_addr);
DEPRECATED(ROW_COL_FUNC) bool isKeyswitchPressed(byte row, byte col) {
return isKeyswitchPressed(KeyAddr(row, col));
}
bool isKeyswitchPressed(uint8_t keyIndex); bool isKeyswitchPressed(uint8_t keyIndex);
uint8_t pressedKeyswitchCount(); uint8_t pressedKeyswitchCount();
bool wasKeyswitchPressed(byte row, byte col); bool wasKeyswitchPressed(KeyAddr key_addr);
DEPRECATED(ROW_COL_FUNC) bool wasKeyswitchPressed(byte row, byte col) {
return wasKeyswitchPressed(KeyAddr(row, col));
}
bool wasKeyswitchPressed(uint8_t keyIndex); bool wasKeyswitchPressed(uint8_t keyIndex);
uint8_t previousPressedKeyswitchCount(); uint8_t previousPressedKeyswitchCount();

@ -31,11 +31,11 @@ bool Model01::isLEDChanged = true;
keydata_t Model01::leftHandMask; keydata_t Model01::leftHandMask;
keydata_t Model01::rightHandMask; keydata_t Model01::rightHandMask;
static constexpr int8_t key_led_map[4][16] PROGMEM = { static constexpr int8_t key_led_map[Model01::led_count] PROGMEM = {
{3, 4, 11, 12, 19, 20, 26, 27, 36, 37, 43, 44, 51, 52, 59, 60}, 3, 4, 11, 12, 19, 20, 26, 27, 36, 37, 43, 44, 51, 52, 59, 60,
{2, 5, 10, 13, 18, 21, 25, 28, 35, 38, 42, 45, 50, 53, 58, 61}, 2, 5, 10, 13, 18, 21, 25, 28, 35, 38, 42, 45, 50, 53, 58, 61,
{1, 6, 9, 14, 17, 22, 24, 29, 34, 39, 41, 46, 49, 54, 57, 62}, 1, 6, 9, 14, 17, 22, 24, 29, 34, 39, 41, 46, 49, 54, 57, 62,
{0, 7, 8, 15, 16, 23, 31, 30, 33, 32, 40, 47, 48, 55, 56, 63}, 0, 7, 8, 15, 16, 23, 31, 30, 33, 32, 40, 47, 48, 55, 56, 63,
}; };
Model01::Model01(void) { Model01::Model01(void) {
@ -118,12 +118,12 @@ void Model01::setCrgbAt(int8_t i, cRGB crgb) {
} }
} }
void Model01::setCrgbAt(byte row, byte col, cRGB color) { void Model01::setCrgbAt(KeyAddr key_addr, cRGB color) {
setCrgbAt(getLedIndex(row, col), color); setCrgbAt(getLedIndex(key_addr), color);
} }
int8_t Model01::getLedIndex(byte row, byte col) { int8_t Model01::getLedIndex(KeyAddr key_addr) {
return pgm_read_byte(&(key_led_map[row][col])); return pgm_read_byte(&(key_led_map[key_addr.toInt()]));
} }
cRGB Model01::getCrgbAt(int8_t i) { cRGB Model01::getCrgbAt(int8_t i) {
@ -164,12 +164,12 @@ boolean Model01::ledPowerFault() {
} }
} }
void debugKeyswitchEvent(keydata_t state, keydata_t previousState, uint8_t keynum, uint8_t row, uint8_t col) { void debugKeyswitchEvent(keydata_t state, keydata_t previousState, uint8_t keynum, KeyAddr key_addr) {
if (bitRead(state.all, keynum) != bitRead(previousState.all, keynum)) { if (bitRead(state.all, keynum) != bitRead(previousState.all, keynum)) {
Serial.print("Looking at row "); Serial.print("Looking at row ");
Serial.print(row); Serial.print(key_addr.row());
Serial.print(", col "); Serial.print(", col ");
Serial.print(col); Serial.print(key_addr.col());
Serial.print(" key # "); Serial.print(" key # ");
Serial.print(keynum); Serial.print(keynum);
Serial.print(" "); Serial.print(" ");
@ -202,7 +202,7 @@ void Model01::actOnHalfRow(byte row, byte colState, byte colPrevState, byte star
uint8_t keyState = ((bitRead(colPrevState, 0) << 0) | uint8_t keyState = ((bitRead(colPrevState, 0) << 0) |
(bitRead(colState, 0) << 1)); (bitRead(colState, 0) << 1));
if (keyState) if (keyState)
handleKeyswitchEvent(Key_NoKey, row, startPos - col, keyState); handleKeyswitchEvent(Key_NoKey, KeyAddr(row, startPos - col), keyState);
// Throw away the data we've just used, so we can read the next column // Throw away the data we've just used, so we can read the next column
colState = colState >> 1; colState = colState >> 1;
@ -259,10 +259,12 @@ constexpr byte HAND_BIT = B00001000;
constexpr byte ROW_BITS = B00110000; constexpr byte ROW_BITS = B00110000;
constexpr byte COL_BITS = B00000111; constexpr byte COL_BITS = B00000111;
void Model01::maskKey(byte row, byte col) { void Model01::maskKey(KeyAddr key_addr) {
if (row >= ROWS || col >= COLS) if (!key_addr.isValid())
return; return;
auto row = key_addr.row();
auto col = key_addr.col();
if (col & HAND_BIT) { if (col & HAND_BIT) {
rightHandMask.rows[row] |= (HIGH_BIT >> (col & COL_BITS)); rightHandMask.rows[row] |= (HIGH_BIT >> (col & COL_BITS));
} else { } else {
@ -270,10 +272,12 @@ void Model01::maskKey(byte row, byte col) {
} }
} }
void Model01::unMaskKey(byte row, byte col) { void Model01::unMaskKey(KeyAddr key_addr) {
if (row >= ROWS || col >= COLS) if (!key_addr.isValid())
return; return;
auto row = key_addr.row();
auto col = key_addr.col();
if (col & HAND_BIT) { if (col & HAND_BIT) {
rightHandMask.rows[row] &= ~(HIGH_BIT >> (col & COL_BITS)); rightHandMask.rows[row] &= ~(HIGH_BIT >> (col & COL_BITS));
} else { } else {
@ -281,10 +285,12 @@ void Model01::unMaskKey(byte row, byte col) {
} }
} }
bool Model01::isKeyMasked(byte row, byte col) { bool Model01::isKeyMasked(KeyAddr key_addr) {
if (row >= ROWS || col >= COLS) if (!key_addr.isValid())
return false; return false;
auto row = key_addr.row();
auto col = key_addr.col();
if (col & HAND_BIT) { if (col & HAND_BIT) {
return rightHandMask.rows[row] & (HIGH_BIT >> (col & COL_BITS)); return rightHandMask.rows[row] & (HIGH_BIT >> (col & COL_BITS));
} else { } else {
@ -303,7 +309,9 @@ void Model01::setKeyscanInterval(uint8_t interval) {
rightHand.setKeyscanInterval(interval); rightHand.setKeyscanInterval(interval);
} }
bool Model01::isKeyswitchPressed(byte row, byte col) { bool Model01::isKeyswitchPressed(KeyAddr key_addr) {
auto row = key_addr.row();
auto col = key_addr.col();
if (col <= 7) { if (col <= 7) {
return (bitRead(leftHandState.rows[row], 7 - col) != 0); return (bitRead(leftHandState.rows[row], 7 - col) != 0);
} else { } else {
@ -313,11 +321,13 @@ bool Model01::isKeyswitchPressed(byte row, byte col) {
bool Model01::isKeyswitchPressed(uint8_t keyIndex) { bool Model01::isKeyswitchPressed(uint8_t keyIndex) {
keyIndex--; keyIndex--;
return isKeyswitchPressed(keyIndex / COLS, keyIndex % COLS); return isKeyswitchPressed(KeyAddr(keyIndex));
} }
bool Model01::wasKeyswitchPressed(byte row, byte col) { bool Model01::wasKeyswitchPressed(KeyAddr key_addr) {
auto row = key_addr.row();
auto col = key_addr.col();
if (col <= 7) { if (col <= 7) {
return (bitRead(previousLeftHandState.rows[row], 7 - col) != 0); return (bitRead(previousLeftHandState.rows[row], 7 - col) != 0);
} else { } else {
@ -327,7 +337,7 @@ bool Model01::wasKeyswitchPressed(byte row, byte col) {
bool Model01::wasKeyswitchPressed(uint8_t keyIndex) { bool Model01::wasKeyswitchPressed(uint8_t keyIndex) {
keyIndex--; keyIndex--;
return wasKeyswitchPressed(keyIndex / COLS, keyIndex % COLS); return wasKeyswitchPressed(KeyAddr(keyIndex));
} }
uint8_t Model01::pressedKeyswitchCount() { uint8_t Model01::pressedKeyswitchCount() {

@ -30,6 +30,7 @@
#define CRGB(r,g,b) (cRGB){b, g, r} #define CRGB(r,g,b) (cRGB){b, g, r}
#include "kaleidoscope/Hardware.h" #include "kaleidoscope/Hardware.h"
#include "kaleidoscope/MatrixAddr.h"
namespace kaleidoscope { namespace kaleidoscope {
namespace hardware { namespace hardware {
@ -49,10 +50,16 @@ class Model01 : public kaleidoscope::Hardware {
} }
void syncLeds(void); void syncLeds(void);
void setCrgbAt(byte row, byte col, cRGB color); void setCrgbAt(KeyAddr key_addr, cRGB color);
DEPRECATED(ROW_COL_FUNC) void setCrgbAt(byte row, byte col, cRGB color) {
setCrgbAt(KeyAddr(row, col), color);
}
void setCrgbAt(int8_t i, cRGB crgb); void setCrgbAt(int8_t i, cRGB crgb);
cRGB getCrgbAt(int8_t i); cRGB getCrgbAt(int8_t i);
int8_t getLedIndex(byte row, byte col); int8_t getLedIndex(KeyAddr key_addr);
DEPRECATED(ROW_COL_FUNC) int8_t getLedIndex(byte row, byte col) {
return getLedIndex(KeyAddr(row, col));
}
void scanMatrix(void); void scanMatrix(void);
void readMatrix(void); void readMatrix(void);
@ -68,16 +75,31 @@ class Model01 : public kaleidoscope::Hardware {
void setKeyscanInterval(uint8_t interval); void setKeyscanInterval(uint8_t interval);
boolean ledPowerFault(void); boolean ledPowerFault(void);
void maskKey(byte row, byte col); void maskKey(KeyAddr key_addr);
void unMaskKey(byte row, byte col); DEPRECATED(ROW_COL_FUNC) void maskKey(byte row, byte col) {
bool isKeyMasked(byte row, byte col); maskKey(KeyAddr(row, col));
}
void unMaskKey(KeyAddr key_addr);
DEPRECATED(ROW_COL_FUNC) void unMaskKey(byte row, byte col) {
unMaskKey(KeyAddr(row, col));
}
bool isKeyMasked(KeyAddr key_addr);
DEPRECATED(ROW_COL_FUNC) bool isKeyMasked(byte row, byte col) {
return isKeyMasked(KeyAddr(row, col));
}
void maskHeldKeys(void); void maskHeldKeys(void);
bool isKeyswitchPressed(byte row, byte col); bool isKeyswitchPressed(KeyAddr key_addr);
DEPRECATED(ROW_COL_FUNC) bool isKeyswitchPressed(byte row, byte col) {
return isKeyswitchPressed(KeyAddr(row, col));
}
bool isKeyswitchPressed(uint8_t keyIndex); bool isKeyswitchPressed(uint8_t keyIndex);
uint8_t pressedKeyswitchCount(); uint8_t pressedKeyswitchCount();
bool wasKeyswitchPressed(byte row, byte col); bool wasKeyswitchPressed(KeyAddr key_addr);
DEPRECATED(ROW_COL_FUNC) bool wasKeyswitchPressed(byte row, byte col) {
return wasKeyswitchPressed(KeyAddr(row, col));
}
bool wasKeyswitchPressed(uint8_t keyIndex); bool wasKeyswitchPressed(uint8_t keyIndex);
uint8_t previousPressedKeyswitchCount(); uint8_t previousPressedKeyswitchCount();

@ -29,7 +29,8 @@ union Key;
// Forward declaration required to enable friend declarations // Forward declaration required to enable friend declarations
// in class Hooks. // in class Hooks.
class kaleidoscope_; class kaleidoscope_;
extern void handleKeyswitchEvent(kaleidoscope::Key mappedKey, byte row, byte col, uint8_t keyState); extern void handleKeyswitchEvent(kaleidoscope::Key mappedKey, KeyAddr key_addr, uint8_t keyState);
DEPRECATED(ROW_COL_FUNC) extern void handleKeyswitchEvent(kaleidoscope::Key mappedKey, byte row, byte col, uint8_t keyState);
namespace kaleidoscope { namespace kaleidoscope {
@ -57,7 +58,7 @@ class Hooks {
// ::handleKeyswitchEvent(...) calls Hooks::onKeyswitchEvent. // ::handleKeyswitchEvent(...) calls Hooks::onKeyswitchEvent.
friend void ::handleKeyswitchEvent(kaleidoscope::Key mappedKey, friend void ::handleKeyswitchEvent(kaleidoscope::Key mappedKey,
byte row, byte col, uint8_t keyState); KeyAddr key_addr, uint8_t keyState);
private: private:

@ -43,7 +43,7 @@ static bool handleSyntheticKeyswitchEvent(Key mappedKey, uint8_t keyState) {
return true; return true;
} }
static bool handleKeyswitchEventDefault(Key mappedKey, byte row, byte col, uint8_t keyState) { static bool handleKeyswitchEventDefault(Key mappedKey, KeyAddr key_addr, uint8_t keyState) {
//for every newly pressed button, figure out what logical key it is and send a key down event //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 // for every newly released button, figure out what logical key it is and send a key up event
@ -59,33 +59,33 @@ static bool handleKeyswitchEventDefault(Key mappedKey, byte row, byte col, uint8
return true; return true;
} }
void handleKeyswitchEvent(Key mappedKey, byte row, byte col, uint8_t keyState) { void handleKeyswitchEvent(Key mappedKey, KeyAddr key_addr, uint8_t keyState) {
/* These first steps are only done for keypresses that have a real (row,col). /* These first steps are only done for keypresses that have a valid key_addr.
* In particular, doing them for keypresses with out-of-bounds (row,col) * In particular, doing them for keypresses with out-of-bounds key_addr
* would cause out-of-bounds array accesses in Layer.lookup(), * would cause out-of-bounds array accesses in Layer.lookup(),
* Layer.updateLiveCompositeKeymap(), etc. * Layer.updateLiveCompositeKeymap(), etc.
* Note that many INJECTED keypresses use the UNKNOWN_KEYSWITCH_LOCATION macro * Note that many INJECTED keypresses use UnknownKeyswitchLocation
* which gives us row==255, col==255 here. Therefore, it's legitimate that * which gives us an invalid key_addr here. Therefore, it's legitimate that
* we may have keypresses with out-of-bounds (row, col). * we may have keypresses with out-of-bounds key_addr.
* However, some INJECTED keypresses do have valid (row, col) if they are * However, some INJECTED keypresses do have valid key_addr if they are
* injecting an event tied to a physical keyswitch - and we want them to go * injecting an event tied to a physical keyswitch - and we want them to go
* through this lookup. * through this lookup.
* So we can't just test for INJECTED here, we need to test the row and col * So we can't just test for INJECTED here, we need to test the key_addr
* directly. * directly.
* Note also that this (row, col) test avoids out-of-bounds accesses in *core*, * Note also that this key_addr test avoids out-of-bounds accesses in *core*,
* but doesn't guarantee anything about event handlers - event handlers may * but doesn't guarantee anything about event handlers - event handlers may
* still receive out-of-bounds (row, col), and handling that properly is on * still receive out-of-bounds key_addr, and handling that properly is on
* them. * them.
*/ */
if (row < ROWS && col < COLS) { if (key_addr.isValid()) {
/* If a key had an on event, we update the live composite keymap. See /* If a key had an on event, we update the live composite keymap. See
* layers.h for an explanation about the different caches we have. */ * layers.h for an explanation about the different caches we have. */
if (keyToggledOn(keyState)) { if (keyToggledOn(keyState)) {
if (mappedKey.raw == Key_NoKey.raw || keyState & EPHEMERAL) { if (mappedKey.raw == Key_NoKey.raw || keyState & EPHEMERAL) {
Layer.updateLiveCompositeKeymap(row, col); Layer.updateLiveCompositeKeymap(key_addr);
} else { } else {
Layer.updateLiveCompositeKeymap(row, col, mappedKey); Layer.updateLiveCompositeKeymap(key_addr, mappedKey);
} }
} }
@ -96,32 +96,44 @@ void handleKeyswitchEvent(Key mappedKey, byte row, byte col, uint8_t keyState) {
* See layers.cpp for an example that masks keys, and the reason why it does * See layers.cpp for an example that masks keys, and the reason why it does
* so. * so.
*/ */
if (KeyboardHardware.isKeyMasked(row, col)) { if (KeyboardHardware.isKeyMasked(key_addr)) {
if (keyToggledOff(keyState)) { if (keyToggledOff(keyState)) {
KeyboardHardware.unMaskKey(row, col); KeyboardHardware.unMaskKey(key_addr);
} else { } else {
return; return;
} }
} }
/* Convert (row, col) to the correct mappedKey /* Convert key_addr to the correct mappedKey
* The condition here means that if mappedKey and (row, col) are both valid, * The condition here means that if mappedKey and key_addr are both valid,
* the mappedKey wins - we don't re-look-up the mappedKey * the mappedKey wins - we don't re-look-up the mappedKey
*/ */
if (mappedKey.raw == Key_NoKey.raw) { if (mappedKey.raw == Key_NoKey.raw) {
mappedKey = Layer.lookup(row, col); mappedKey = Layer.lookup(key_addr);
} }
} // row < ROWS && col < COLS } // key_addr valid
// Keypresses with out-of-bounds (row,col) start here in the processing chain // Keypresses with out-of-bounds key_addr start here in the processing chain
// New event handler interface // We call both versions of onKeyswitchEvent. This assumes that a plugin
if (kaleidoscope::Hooks::onKeyswitchEvent(mappedKey, row, col, keyState) != kaleidoscope::EventHandlerResult::OK) // implements either the old or the new version of the hook.
// The call to that version that is not implemented is optimized out
// by the caller. This is possible as the call would fall back to
// the version of the hook that is implemented in the base class of the
// plugin. This fallback version is an empty inline noop method that
// is simple for the compiler to optimize out.
// New event handler interface version 2 (key address version)
if (kaleidoscope::Hooks::onKeyswitchEvent(mappedKey, key_addr, keyState) != kaleidoscope::EventHandlerResult::OK)
return;
// New event handler interface (deprecated version)
if (kaleidoscope::Hooks::onKeyswitchEvent(mappedKey, key_addr.row(), key_addr.col(), keyState) != kaleidoscope::EventHandlerResult::OK)
return; return;
mappedKey = Layer.eventHandler(mappedKey, row, col, keyState); mappedKey = Layer.eventHandler(mappedKey, key_addr, keyState);
if (mappedKey.raw == Key_NoKey.raw) if (mappedKey.raw == Key_NoKey.raw)
return; return;
handleKeyswitchEventDefault(mappedKey, row, col, keyState); handleKeyswitchEventDefault(mappedKey, key_addr, keyState);
} }

@ -24,6 +24,10 @@
// Code can use this macro on injected key events to signal that // Code can use this macro on injected key events to signal that
// the event isn't tied to a specific physical keyswitch // the event isn't tied to a specific physical keyswitch
//
// TODO DEPRECATED(ROW_COL_FUNC): Once row/col based key/LED access
// is deprecated, deprecate UNKNOWN_KEYSWITCH_LOCATION as well.
//
#define UNKNOWN_KEYSWITCH_LOCATION 255,255 #define UNKNOWN_KEYSWITCH_LOCATION 255,255
// UnknownKeyswitchLocation represents an invalid (as default constructed) // UnknownKeyswitchLocation represents an invalid (as default constructed)
@ -35,7 +39,7 @@
// Conversely, if an injected event *is* tied to a physical keyswitch and should // Conversely, if an injected event *is* tied to a physical keyswitch and should
// be resolved by the current keymap, code can use Key_NoKey on the injected event // be resolved by the current keymap, code can use Key_NoKey on the injected event
// with a real (row, col) location // with a real key address
// sending events to the computer // sending events to the computer
/* The event handling starts with the Scanner calling handleKeyswitchEvent() for /* The event handling starts with the Scanner calling handleKeyswitchEvent() for
@ -62,10 +66,13 @@
* too. * too.
* *
* For this reason, the handleKeyswitchEvent receives four arguments: the mapped key * For this reason, the handleKeyswitchEvent receives four arguments: the mapped key
* (or Key_NoKey if we do not want to override what is in the keymap), the row * (or Key_NoKey if we do not want to override what is in the keymap), the matrix
* and column of the key, so we can look up the code for it, and the current and * address 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. The * previous state of the key, so we can determine what the event is. The
* currentState may be flagged INJECTED, which signals that the event was * currentState may be flagged INJECTED, which signals that the event was
* injected, and is not a direct result of a keypress, coming from the scanner. * injected, and is not a direct result of a keypress, coming from the scanner.
*/ */
void handleKeyswitchEvent(Key mappedKey, byte row, byte col, uint8_t keyState); void handleKeyswitchEvent(Key mappedKey, KeyAddr key_addr, uint8_t keyState);
DEPRECATED(ROW_COL_FUNC) inline void handleKeyswitchEvent(Key mappedKey, byte row, byte col, uint8_t keyState) {
handleKeyswitchEvent(mappedKey, KeyAddr(row, col), keyState);
}

@ -23,8 +23,8 @@ extern const Key keymaps_linear[][ROWS * COLS];
namespace kaleidoscope { namespace kaleidoscope {
inline inline
Key keyFromKeymap(uint8_t layer, uint8_t row, uint8_t col) { Key keyFromKeymap(uint8_t layer, KeyAddr key_addr) {
return pgm_read_word(&keymaps_linear[layer][row * COLS + col]); return pgm_read_word(&keymaps_linear[layer][key_addr.toInt()]);
} }
namespace internal { namespace internal {

@ -38,9 +38,9 @@ extern const Key keymaps_linear[][ROWS * COLS] = {};
namespace kaleidoscope { namespace kaleidoscope {
uint32_t Layer_::layer_state_; uint32_t Layer_::layer_state_;
uint8_t Layer_::top_active_layer_; uint8_t Layer_::top_active_layer_;
Key Layer_::live_composite_keymap_[ROWS][COLS]; Key Layer_::live_composite_keymap_[KeyboardHardware.numKeys()];
uint8_t Layer_::active_layers_[ROWS][COLS]; uint8_t Layer_::active_layers_[KeyboardHardware.numKeys()];
Key(*Layer_::getKey)(uint8_t layer, byte row, byte col) = Layer.getKeyFromPROGMEM; Key(*Layer_::getKey)(uint8_t layer, KeyAddr key_addr) = Layer.getKeyFromPROGMEM;
void Layer_::handleKeymapKeyswitchEvent(Key keymapEntry, uint8_t keyState) { void Layer_::handleKeymapKeyswitchEvent(Key keymapEntry, uint8_t keyState) {
if (keymapEntry.keyCode >= LAYER_SHIFT_OFFSET) { if (keymapEntry.keyCode >= LAYER_SHIFT_OFFSET) {
@ -93,7 +93,7 @@ void Layer_::handleKeymapKeyswitchEvent(Key keymapEntry, uint8_t keyState) {
} }
} }
Key Layer_::eventHandler(Key mappedKey, byte row, byte col, uint8_t keyState) { Key Layer_::eventHandler(Key mappedKey, KeyAddr key_addr, uint8_t keyState) {
if (mappedKey.flags != (SYNTHETIC | SWITCH_TO_KEYMAP)) if (mappedKey.flags != (SYNTHETIC | SWITCH_TO_KEYMAP))
return mappedKey; return mappedKey;
@ -101,27 +101,26 @@ Key Layer_::eventHandler(Key mappedKey, byte row, byte col, uint8_t keyState) {
return Key_NoKey; return Key_NoKey;
} }
Key Layer_::getKeyFromPROGMEM(uint8_t layer, byte row, byte col) { Key Layer_::getKeyFromPROGMEM(uint8_t layer, KeyAddr key_addr) {
return keyFromKeymap(layer, row, col); return keyFromKeymap(layer, key_addr);
} }
void Layer_::updateLiveCompositeKeymap(byte row, byte col) { void Layer_::updateLiveCompositeKeymap(KeyAddr key_addr) {
int8_t layer = active_layers_[row][col]; int8_t layer = active_layers_[key_addr.toInt()];
live_composite_keymap_[row][col] = (*getKey)(layer, row, col); live_composite_keymap_[key_addr.toInt()] = (*getKey)(layer, key_addr);
} }
void Layer_::updateActiveLayers(void) { void Layer_::updateActiveLayers(void) {
memset(active_layers_, 0, KeyboardHardware.numKeys()); memset(active_layers_, 0, KeyboardHardware.numKeys());
for (byte row = 0; row < ROWS; row++) { for (auto key_addr : KeyAddr::all()) {
for (byte col = 0; col < COLS; col++) {
int8_t layer = top_active_layer_; int8_t layer = top_active_layer_;
while (layer > 0) { while (layer > 0) {
if (Layer.isActive(layer)) { if (Layer.isActive(layer)) {
Key mappedKey = (*getKey)(layer, row, col); Key mappedKey = (*getKey)(layer, key_addr);
if (mappedKey != Key_Transparent) { if (mappedKey != Key_Transparent) {
active_layers_[row][col] = layer; active_layers_[key_addr.toInt()] = layer;
break; break;
} }
} }
@ -129,7 +128,6 @@ void Layer_::updateActiveLayers(void) {
} }
} }
} }
}
void Layer_::updateTopActiveLayer(void) { void Layer_::updateTopActiveLayer(void) {
// If layer_count is set, start there, otherwise search from the // If layer_count is set, start there, otherwise search from the

@ -70,15 +70,26 @@ class Layer_ {
* are curious what the active layer state describes the key as, use * are curious what the active layer state describes the key as, use
* `lookupOnActiveLayer`. * `lookupOnActiveLayer`.
*/ */
static Key lookup(byte row, byte col) { static Key lookup(KeyAddr key_addr) {
return live_composite_keymap_[row][col]; return live_composite_keymap_[key_addr.toInt()];
} }
static Key lookupOnActiveLayer(byte row, byte col) { DEPRECATED(ROW_COL_FUNC) static Key lookup(byte row, byte col) {
uint8_t layer = active_layers_[row][col]; return live_composite_keymap_[KeyAddr(row, col).toInt()];
return (*getKey)(layer, row, col);
} }
static uint8_t lookupActiveLayer(byte row, byte col) { static Key lookupOnActiveLayer(KeyAddr key_addr) {
return active_layers_[row][col]; uint8_t layer = active_layers_[key_addr.toInt()];
return (*getKey)(layer, key_addr);
}
DEPRECATED(ROW_COL_FUNC) static Key lookupOnActiveLayer(byte row, byte col) {
KeyAddr key_addr(row, col);
uint8_t layer = active_layers_[key_addr.toInt()];
return (*getKey)(layer, key_addr);
}
static uint8_t lookupActiveLayer(KeyAddr key_addr) {
return active_layers_[key_addr.toInt()];
}
DEPRECATED(ROW_COL_FUNC) static uint8_t lookupActiveLayer(byte row, byte col) {
return active_layers_[KeyAddr(row, col).toInt()];
} }
static void activate(uint8_t layer); static void activate(uint8_t layer);
@ -96,23 +107,35 @@ class Layer_ {
return layer_state_; return layer_state_;
} }
static Key eventHandler(Key mappedKey, byte row, byte col, uint8_t keyState); static Key eventHandler(Key mappedKey, KeyAddr key_addr, uint8_t keyState);
DEPRECATED(ROW_COL_FUNC) static Key eventHandler(Key mappedKey, byte row, byte col, uint8_t keyState) {
return eventHandler(mappedKey, KeyAddr(row, col), keyState);
}
static Key(*getKey)(uint8_t layer, byte row, byte col); static Key(*getKey)(uint8_t layer, KeyAddr key_addr);
static Key getKeyFromPROGMEM(uint8_t layer, byte row, byte col); static Key getKeyFromPROGMEM(uint8_t layer, KeyAddr key_addr);
DEPRECATED(ROW_COL_FUNC) static Key getKeyFromPROGMEM(uint8_t layer, byte row, byte col) {
return getKeyFromPROGMEM(layer, KeyAddr(row, col));
}
static void updateLiveCompositeKeymap(byte row, byte col); static void updateLiveCompositeKeymap(KeyAddr key_addr, Key mappedKey) {
static void updateLiveCompositeKeymap(byte row, byte col, Key mappedKey) { live_composite_keymap_[key_addr.toInt()] = mappedKey;
live_composite_keymap_[row][col] = mappedKey; }
DEPRECATED(ROW_COL_FUNC) static void updateLiveCompositeKeymap(byte row, byte col, Key mappedKey) {
updateLiveCompositeKeymap(KeyAddr(row, col), mappedKey);
}
static void updateLiveCompositeKeymap(KeyAddr key_addr);
DEPRECATED(ROW_COL_FUNC) static void updateLiveCompositeKeymap(byte row, byte col) {
updateLiveCompositeKeymap(KeyAddr(row, col));
} }
static void updateActiveLayers(void); static void updateActiveLayers(void);
private: private:
static uint32_t layer_state_; static uint32_t layer_state_;
static uint8_t top_active_layer_; static uint8_t top_active_layer_;
static Key live_composite_keymap_[ROWS][COLS]; static Key live_composite_keymap_[KeyboardHardware.numKeys()];
static uint8_t active_layers_[ROWS][COLS]; static uint8_t active_layers_[KeyboardHardware.numKeys()];
static void handleKeymapKeyswitchEvent(Key keymapEntry, uint8_t keyState); static void handleKeymapKeyswitchEvent(Key keymapEntry, uint8_t keyState);
static void updateTopActiveLayer(void); static void updateTopActiveLayer(void);

@ -44,9 +44,9 @@ void ColormapEffect::TransientLEDMode::onActivate(void) {
::LEDPaletteTheme.updateHandler(parent_->map_base_, parent_->top_layer_); ::LEDPaletteTheme.updateHandler(parent_->map_base_, parent_->top_layer_);
} }
void ColormapEffect::TransientLEDMode::refreshAt(byte row, byte col) { void ColormapEffect::TransientLEDMode::refreshAt(KeyAddr key_addr) {
if (parent_->top_layer_ <= parent_->max_layers_) if (parent_->top_layer_ <= parent_->max_layers_)
::LEDPaletteTheme.refreshAt(parent_->map_base_, parent_->top_layer_, row, col); ::LEDPaletteTheme.refreshAt(parent_->map_base_, parent_->top_layer_, key_addr);
} }
EventHandlerResult ColormapEffect::onLayerChange() { EventHandlerResult ColormapEffect::onLayerChange() {

@ -49,8 +49,10 @@ class ColormapEffect : public Plugin,
friend class ColormapEffect; friend class ColormapEffect;
virtual void onActivate(void) final; virtual void onActivate(void) final;
virtual void refreshAt(byte row, byte col) final; virtual void refreshAt(KeyAddr key_addr) final;
DEPRECATED(ROW_COL_FUNC) void refreshAt(byte row, byte col) final {
refreshAt(KeyAddr(row, col));
}
private: private:
const ColormapEffect *parent_; const ColormapEffect *parent_;

@ -33,14 +33,14 @@ uint8_t Cycle::cycle_count_;
// --- api --- // --- api ---
void Cycle::replace(Key key) { void Cycle::replace(Key key) {
handleKeyswitchEvent(Key_Backspace, UNKNOWN_KEYSWITCH_LOCATION, IS_PRESSED | INJECTED); handleKeyswitchEvent(Key_Backspace, UnknownKeyswitchLocation, IS_PRESSED | INJECTED);
hid::sendKeyboardReport(); hid::sendKeyboardReport();
handleKeyswitchEvent(Key_Backspace, UNKNOWN_KEYSWITCH_LOCATION, WAS_PRESSED | INJECTED); handleKeyswitchEvent(Key_Backspace, UnknownKeyswitchLocation, WAS_PRESSED | INJECTED);
hid::sendKeyboardReport(); hid::sendKeyboardReport();
handleKeyswitchEvent(key, UNKNOWN_KEYSWITCH_LOCATION, IS_PRESSED | INJECTED); handleKeyswitchEvent(key, UnknownKeyswitchLocation, IS_PRESSED | INJECTED);
hid::sendKeyboardReport(); hid::sendKeyboardReport();
handleKeyswitchEvent(key, UNKNOWN_KEYSWITCH_LOCATION, WAS_PRESSED | INJECTED); handleKeyswitchEvent(key, UnknownKeyswitchLocation, WAS_PRESSED | INJECTED);
hid::sendKeyboardReport(); hid::sendKeyboardReport();
} }
@ -54,7 +54,7 @@ void Cycle::replace(uint8_t cycle_size, const Key cycle_steps[]) {
// --- hooks --- // --- hooks ---
EventHandlerResult Cycle::onKeyswitchEvent(Key &mapped_key, byte row, byte col, uint8_t key_state) { EventHandlerResult Cycle::onKeyswitchEvent(Key &mapped_key, KeyAddr key_addr, uint8_t key_state) {
if (key_state & INJECTED) if (key_state & INJECTED)
return EventHandlerResult::OK; return EventHandlerResult::OK;

@ -36,7 +36,7 @@ class Cycle : public kaleidoscope::Plugin {
static void replace(Key key); static void replace(Key key);
static void replace(uint8_t cycle_size, const Key cycle_steps[]); static void replace(uint8_t cycle_size, const Key cycle_steps[]);
EventHandlerResult onKeyswitchEvent(Key &mapped_key, byte row, byte col, uint8_t key_state); EventHandlerResult onKeyswitchEvent(Key &mapped_key, KeyAddr key_addr, uint8_t key_state);
private: private:
static uint8_t toModFlag(uint8_t keyCode); static uint8_t toModFlag(uint8_t keyCode);

@ -50,16 +50,16 @@ void EEPROMKeymapProgrammer::cancel(void) {
state_ = INACTIVE; state_ = INACTIVE;
} }
EventHandlerResult EEPROMKeymapProgrammer::onKeyswitchEvent(Key &mapped_key, byte row, byte col, uint8_t key_state) { EventHandlerResult EEPROMKeymapProgrammer::onKeyswitchEvent(Key &mapped_key, KeyAddr key_addr, uint8_t key_state) {
if (state_ == INACTIVE) if (state_ == INACTIVE)
return EventHandlerResult::OK; return EventHandlerResult::OK;
if (state_ == WAIT_FOR_KEY) { if (state_ == WAIT_FOR_KEY) {
if (keyToggledOn(key_state)) { if (keyToggledOn(key_state)) {
update_position_ = Layer.top() * KeyboardHardware.numKeys() + row * COLS + col; update_position_ = Layer.top() * KeyboardHardware.numKeys() + key_addr.toInt();
} }
if (keyToggledOff(key_state)) { if (keyToggledOff(key_state)) {
if ((uint16_t)(Layer.top() * KeyboardHardware.numKeys() + row * COLS + col) == update_position_) if ((uint16_t)(Layer.top() * KeyboardHardware.numKeys() + key_addr.toInt()) == update_position_)
nextState(); nextState();
} }
return EventHandlerResult::EVENT_CONSUMED; return EventHandlerResult::EVENT_CONSUMED;
@ -67,10 +67,10 @@ EventHandlerResult EEPROMKeymapProgrammer::onKeyswitchEvent(Key &mapped_key, byt
if (state_ == WAIT_FOR_SOURCE_KEY) { if (state_ == WAIT_FOR_SOURCE_KEY) {
if (keyToggledOn(key_state)) { if (keyToggledOn(key_state)) {
new_key_ = Layer.getKeyFromPROGMEM(Layer.top(), row, col); new_key_ = Layer.getKeyFromPROGMEM(Layer.top(), key_addr);
} }
if (keyToggledOff(key_state)) { if (keyToggledOff(key_state)) {
if (new_key_ == Layer.getKeyFromPROGMEM(Layer.top(), row, col)) if (new_key_ == Layer.getKeyFromPROGMEM(Layer.top(), key_addr))
nextState(); nextState();
} }
return EventHandlerResult::EVENT_CONSUMED; return EventHandlerResult::EVENT_CONSUMED;

@ -38,7 +38,7 @@ class EEPROMKeymapProgrammer : public kaleidoscope::Plugin {
static void nextState(void); static void nextState(void);
static void cancel(void); static void cancel(void);
EventHandlerResult onKeyswitchEvent(Key &mapped_key, byte row, byte col, uint8_t key_state); EventHandlerResult onKeyswitchEvent(Key &mapped_key, KeyAddr key_addr, uint8_t key_state);
EventHandlerResult onFocusEvent(const char *command); EventHandlerResult onFocusEvent(const char *command);
private: private:

@ -47,13 +47,13 @@ void EEPROMKeymap::max_layers(uint8_t max) {
keymap_base_ = ::EEPROMSettings.requestSlice(max_layers_ * KeyboardHardware.numKeys() * 2); keymap_base_ = ::EEPROMSettings.requestSlice(max_layers_ * KeyboardHardware.numKeys() * 2);
} }
Key EEPROMKeymap::getKey(uint8_t layer, byte row, byte col) { Key EEPROMKeymap::getKey(uint8_t layer, KeyAddr key_addr) {
Key key; Key key;
if (layer >= max_layers_) if (layer >= max_layers_)
return Key_NoKey; return Key_NoKey;
uint16_t pos = ((layer * KeyboardHardware.numKeys()) + (row * COLS) + col) * 2; uint16_t pos = ((layer * KeyboardHardware.numKeys()) + key_addr.toInt()) * 2;
key.flags = EEPROM.read(keymap_base_ + pos); key.flags = EEPROM.read(keymap_base_ + pos);
key.keyCode = EEPROM.read(keymap_base_ + pos + 1); key.keyCode = EEPROM.read(keymap_base_ + pos + 1);
@ -61,16 +61,15 @@ Key EEPROMKeymap::getKey(uint8_t layer, byte row, byte col) {
return key; return key;
} }
Key EEPROMKeymap::getKeyExtended(uint8_t layer, byte row, byte col) { Key EEPROMKeymap::getKeyExtended(uint8_t layer, KeyAddr key_addr) {
Key key;
// If the layer is within PROGMEM bounds, look it up from there // If the layer is within PROGMEM bounds, look it up from there
if (layer < progmem_layers_) { if (layer < progmem_layers_) {
return Layer.getKeyFromPROGMEM(layer, row, col); return Layer.getKeyFromPROGMEM(layer, key_addr);
} }
// If the layer is outside of PROGMEM, look up from EEPROM // If the layer is outside of PROGMEM, look up from EEPROM
return getKey(layer - progmem_layers_, row, col); return getKey(layer - progmem_layers_, key_addr);
} }
uint16_t EEPROMKeymap::keymap_base(void) { uint16_t EEPROMKeymap::keymap_base(void) {
@ -82,16 +81,24 @@ void EEPROMKeymap::updateKey(uint16_t base_pos, Key key) {
EEPROM.update(keymap_base_ + base_pos * 2 + 1, key.keyCode); EEPROM.update(keymap_base_ + base_pos * 2 + 1, key.keyCode);
} }
void EEPROMKeymap::dumpKeymap(uint8_t layers, Key(*getkey)(uint8_t, byte, byte)) { void EEPROMKeymap::dumpKeymap(uint8_t layers, Key(*getkey)(uint8_t, KeyAddr)) {
for (uint8_t layer = 0; layer < layers; layer++) { for (uint8_t layer = 0; layer < layers; layer++) {
for (uint8_t row = 0; row < ROWS; row++) { for (auto key_addr : KeyAddr::all()) {
for (uint8_t col = 0; col < COLS; col++) { Key k = (*getkey)(layer, key_addr);
Key k = (*getkey)(layer, row, col);
::Focus.send(k); ::Focus.send(k);
} }
} }
} }
void EEPROMKeymap::dumpKeymap(uint8_t layers, Key(*getkey)(uint8_t, byte, byte)) {
for (uint8_t layer = 0; layer < layers; layer++) {
for (auto key_addr : KeyAddr::all()) {
Key k = (*getkey)(layer, key_addr.row(), key_addr.col());
::Focus.send(k);
}
}
} }
EventHandlerResult EEPROMKeymap::onFocusEvent(const char *command) { EventHandlerResult EEPROMKeymap::onFocusEvent(const char *command) {
@ -122,7 +129,12 @@ EventHandlerResult EEPROMKeymap::onFocusEvent(const char *command) {
} }
if (strcmp_P(command + 7, PSTR("default")) == 0) { if (strcmp_P(command + 7, PSTR("default")) == 0) {
dumpKeymap(progmem_layers_, Layer.getKeyFromPROGMEM); // By using a cast to the appropriate function type,
// tell the compiler which overload of getKeyFromPROGMEM
// we actully want.
//
dumpKeymap(progmem_layers_,
static_cast<Key(*)(uint8_t, KeyAddr)>(Layer.getKeyFromPROGMEM));
return EventHandlerResult::EVENT_CONSUMED; return EventHandlerResult::EVENT_CONSUMED;
} }
@ -130,7 +142,11 @@ EventHandlerResult EEPROMKeymap::onFocusEvent(const char *command) {
return EventHandlerResult::OK; return EventHandlerResult::OK;
if (::Focus.isEOL()) { if (::Focus.isEOL()) {
dumpKeymap(max_layers_, getKey); // By using a cast to the appropriate function type,
// tell the compiler which overload of getKey
// we actually want.
//
dumpKeymap(max_layers_, static_cast<Key(*)(uint8_t, KeyAddr)>(getKey));
} else { } else {
uint16_t i = 0; uint16_t i = 0;

@ -47,8 +47,14 @@ class EEPROMKeymap : public kaleidoscope::Plugin {
static uint16_t keymap_base(void); static uint16_t keymap_base(void);
static Key getKey(uint8_t layer, byte row, byte col); static Key getKey(uint8_t layer, KeyAddr key_addr);
static Key getKeyExtended(uint8_t layer, byte row, byte col); DEPRECATED(ROW_COL_FUNC) static Key getKey(uint8_t layer, byte row, byte col) {
return getKey(layer, KeyAddr(row, col));
}
static Key getKeyExtended(uint8_t layer, KeyAddr key_addr);
DEPRECATED(ROW_COL_FUNC) static Key getKeyExtended(uint8_t layer, byte row, byte col) {
return getKeyExtended(layer, KeyAddr(row, col));
}
static void updateKey(uint16_t base_pos, Key key); static void updateKey(uint16_t base_pos, Key key);
@ -59,7 +65,8 @@ class EEPROMKeymap : public kaleidoscope::Plugin {
static Key parseKey(void); static Key parseKey(void);
static void printKey(Key key); static void printKey(Key key);
static void dumpKeymap(uint8_t layers, Key(*getkey)(uint8_t, byte, byte)); static void dumpKeymap(uint8_t layers, Key(*getkey)(uint8_t, KeyAddr));
DEPRECATED(ROW_COL_FUNC) static void dumpKeymap(uint8_t layers, Key(*getkey)(uint8_t, byte, byte));
}; };
} }
} }

@ -22,7 +22,7 @@
namespace kaleidoscope { namespace kaleidoscope {
namespace plugin { namespace plugin {
EventHandlerResult EscapeOneShot::onKeyswitchEvent(Key &mapped_key, byte row, byte col, uint8_t keyState) { EventHandlerResult EscapeOneShot::onKeyswitchEvent(Key &mapped_key, KeyAddr key_addr, uint8_t keyState) {
if (mapped_key.raw != Key_Escape.raw || if (mapped_key.raw != Key_Escape.raw ||
(keyState & INJECTED) || (keyState & INJECTED) ||
!keyToggledOn(keyState)) !keyToggledOn(keyState))
@ -32,7 +32,7 @@ EventHandlerResult EscapeOneShot::onKeyswitchEvent(Key &mapped_key, byte row, by
return EventHandlerResult::OK; return EventHandlerResult::OK;
} }
KeyboardHardware.maskKey(row, col); KeyboardHardware.maskKey(key_addr);
::OneShot.cancel(true); ::OneShot.cancel(true);
return EventHandlerResult::EVENT_CONSUMED; return EventHandlerResult::EVENT_CONSUMED;

@ -25,7 +25,7 @@ class EscapeOneShot : public kaleidoscope::Plugin {
public: public:
EscapeOneShot(void) {} EscapeOneShot(void) {}
EventHandlerResult onKeyswitchEvent(Key &mapped_key, byte row, byte col, uint8_t keyState); EventHandlerResult onKeyswitchEvent(Key &mapped_key, KeyAddr key_addr, uint8_t keyState);
}; };
} }
} }

@ -37,15 +37,15 @@ void FingerPainter::update(void) {
::LEDPaletteTheme.updateHandler(color_base_, 0); ::LEDPaletteTheme.updateHandler(color_base_, 0);
} }
void FingerPainter::refreshAt(byte row, byte col) { void FingerPainter::refreshAt(KeyAddr key_addr) {
::LEDPaletteTheme.refreshAt(color_base_, 0, row, col); ::LEDPaletteTheme.refreshAt(color_base_, 0, key_addr);
} }
void FingerPainter::toggle(void) { void FingerPainter::toggle(void) {
edit_mode_ = !edit_mode_; edit_mode_ = !edit_mode_;
} }
EventHandlerResult FingerPainter::onKeyswitchEvent(Key &mapped_key, byte row, byte col, uint8_t key_state) { EventHandlerResult FingerPainter::onKeyswitchEvent(Key &mapped_key, KeyAddr key_addr, uint8_t key_state) {
if (!Kaleidoscope.has_leds || !edit_mode_) if (!Kaleidoscope.has_leds || !edit_mode_)
return EventHandlerResult::OK; return EventHandlerResult::OK;
@ -53,10 +53,12 @@ EventHandlerResult FingerPainter::onKeyswitchEvent(Key &mapped_key, byte row, by
return EventHandlerResult::EVENT_CONSUMED; return EventHandlerResult::EVENT_CONSUMED;
} }
if (row >= ROWS || col >= COLS) if (!key_addr.isValid())
return EventHandlerResult::EVENT_CONSUMED; return EventHandlerResult::EVENT_CONSUMED;
uint8_t color_index = ::LEDPaletteTheme.lookupColorIndexAtPosition(color_base_, KeyboardHardware.getLedIndex(row, col)); // TODO: The following works only for keyboards with LEDs for each key.
uint8_t color_index = ::LEDPaletteTheme.lookupColorIndexAtPosition(color_base_, KeyboardHardware.getLedIndex(key_addr));
// Find the next color in the palette that is different. // Find the next color in the palette that is different.
// But do not loop forever! // But do not loop forever!
@ -73,7 +75,7 @@ EventHandlerResult FingerPainter::onKeyswitchEvent(Key &mapped_key, byte row, by
new_color = ::LEDPaletteTheme.lookupPaletteColor(color_index); new_color = ::LEDPaletteTheme.lookupPaletteColor(color_index);
} }
::LEDPaletteTheme.updateColorIndexAtPosition(color_base_, KeyboardHardware.getLedIndex(row, col), color_index); ::LEDPaletteTheme.updateColorIndexAtPosition(color_base_, KeyboardHardware.getLedIndex(key_addr), color_index);
return EventHandlerResult::EVENT_CONSUMED; return EventHandlerResult::EVENT_CONSUMED;
} }

@ -32,13 +32,16 @@ class FingerPainter : public LEDMode {
static void toggle(void); static void toggle(void);
EventHandlerResult onKeyswitchEvent(Key &mapped_key, byte row, byte col, uint8_t key_state); EventHandlerResult onKeyswitchEvent(Key &mapped_key, KeyAddr key_addr, uint8_t key_state);
EventHandlerResult onFocusEvent(const char *command); EventHandlerResult onFocusEvent(const char *command);
EventHandlerResult onSetup(); EventHandlerResult onSetup();
protected: protected:
void update(void) final; void update(void) final;
void refreshAt(byte row, byte col) final; void refreshAt(KeyAddr key_addr) final;
DEPRECATED(ROW_COL_FUNC) void refreshAt(byte row, byte col) final {
refreshAt(KeyAddr(row, col));
}
private: private:
static uint16_t color_base_; static uint16_t color_base_;

@ -24,7 +24,7 @@ namespace steno {
uint8_t GeminiPR::keys_held_; uint8_t GeminiPR::keys_held_;
uint8_t GeminiPR::state_[6]; uint8_t GeminiPR::state_[6];
EventHandlerResult GeminiPR::onKeyswitchEvent(Key &mapped_key, byte row, byte col, uint8_t keyState) { EventHandlerResult GeminiPR::onKeyswitchEvent(Key &mapped_key, KeyAddr key_addr, uint8_t keyState) {
if (mapped_key < geminipr::START || if (mapped_key < geminipr::START ||
mapped_key > geminipr::END) mapped_key > geminipr::END)
return EventHandlerResult::OK; return EventHandlerResult::OK;

@ -29,8 +29,7 @@ class GeminiPR : public kaleidoscope::Plugin {
public: public:
GeminiPR(void) {} GeminiPR(void) {}
EventHandlerResult onKeyswitchEvent(Key &mapped_key, byte row, byte col, uint8_t keyState); EventHandlerResult onKeyswitchEvent(Key &mapped_key, KeyAddr key_addr, uint8_t keyState);
private: private:
static uint8_t keys_held_; static uint8_t keys_held_;
static uint8_t state_[6]; static uint8_t state_[6];

@ -55,12 +55,12 @@ EventHandlerResult GhostInTheFirmware::beforeReportingState() {
byte row = pgm_read_byte(&(ghost_keys[current_pos_].row)); byte row = pgm_read_byte(&(ghost_keys[current_pos_].row));
byte col = pgm_read_byte(&(ghost_keys[current_pos_].col)); byte col = pgm_read_byte(&(ghost_keys[current_pos_].col));
handleKeyswitchEvent(Key_NoKey, row, col, WAS_PRESSED); handleKeyswitchEvent(Key_NoKey, KeyAddr(row, col), WAS_PRESSED);
} else if (is_pressed_) { } else if (is_pressed_) {
byte row = pgm_read_byte(&(ghost_keys[current_pos_].row)); byte row = pgm_read_byte(&(ghost_keys[current_pos_].row));
byte col = pgm_read_byte(&(ghost_keys[current_pos_].col)); byte col = pgm_read_byte(&(ghost_keys[current_pos_].col));
handleKeyswitchEvent(Key_NoKey, row, col, IS_PRESSED); handleKeyswitchEvent(Key_NoKey, KeyAddr(row, col), IS_PRESSED);
} else if (Kaleidoscope.hasTimeExpired(start_time_, delay_timeout_)) { } else if (Kaleidoscope.hasTimeExpired(start_time_, delay_timeout_)) {
current_pos_++; current_pos_++;
press_timeout_ = 0; press_timeout_ = 0;

@ -76,7 +76,7 @@ void HardwareTestMode::testLeds(void) {
void HardwareTestMode::testMatrix() { void HardwareTestMode::testMatrix() {
// Reset bad keys from previous tests. // Reset bad keys from previous tests.
chatter_data state[KeyboardHardware.matrix_columns * KeyboardHardware.matrix_rows] = {0, 0, 0}; chatter_data state[KeyboardHardware.numKeys()] = {0, 0, 0};
constexpr cRGB red = CRGB(201, 0, 0); constexpr cRGB red = CRGB(201, 0, 0);
constexpr cRGB blue = CRGB(0, 0, 201); constexpr cRGB blue = CRGB(0, 0, 201);
@ -85,12 +85,11 @@ void HardwareTestMode::testMatrix() {
while (1) { while (1) {
KeyboardHardware.readMatrix(); KeyboardHardware.readMatrix();
for (byte row = 0; row < KeyboardHardware.matrix_rows; row++) { for (auto key_addr : KeyAddr::all()) {
for (byte col = 0; col < KeyboardHardware.matrix_columns; col++) { uint8_t keynum = key_addr.toInt();
uint8_t keynum = (row * KeyboardHardware.matrix_columns) + (col);
// If the key is toggled on // If the key is toggled on
if (KeyboardHardware.isKeyswitchPressed(row, col) && ! KeyboardHardware.wasKeyswitchPressed(row, col)) { if (KeyboardHardware.isKeyswitchPressed(key_addr) && ! KeyboardHardware.wasKeyswitchPressed(key_addr)) {
// And it's too soon (in terms of cycles between changes) // And it's too soon (in terms of cycles between changes)
state[keynum].tested = 1; state[keynum].tested = 1;
if (state[keynum].cyclesSinceStateChange < CHATTER_CYCLE_LIMIT) { if (state[keynum].cyclesSinceStateChange < CHATTER_CYCLE_LIMIT) {
@ -101,20 +100,19 @@ void HardwareTestMode::testMatrix() {
state[keynum].cyclesSinceStateChange++; state[keynum].cyclesSinceStateChange++;
} }
// If the key is held down // If the key is held down
if (KeyboardHardware.isKeyswitchPressed(row, col) && KeyboardHardware.wasKeyswitchPressed(row, col)) { if (KeyboardHardware.isKeyswitchPressed(key_addr) && KeyboardHardware.wasKeyswitchPressed(key_addr)) {
KeyboardHardware.setCrgbAt(row, col, green); KeyboardHardware.setCrgbAt(key_addr, green);
} }
// If we triggered chatter detection ever on this key // If we triggered chatter detection ever on this key
else if (state[keynum].bad == 1) { else if (state[keynum].bad == 1) {
KeyboardHardware.setCrgbAt(row, col, red); KeyboardHardware.setCrgbAt(key_addr, red);
} else if (state[keynum].tested == 0) { } else if (state[keynum].tested == 0) {
KeyboardHardware.setCrgbAt(row, col, yellow); KeyboardHardware.setCrgbAt(key_addr, yellow);
} }
// If the key is not currently pressed and was not just released and is not marked bad // If the key is not currently pressed and was not just released and is not marked bad
else if (! KeyboardHardware.isKeyswitchPressed(row, col)) { else if (! KeyboardHardware.isKeyswitchPressed(key_addr)) {
KeyboardHardware.setCrgbAt(row, col, blue); KeyboardHardware.setCrgbAt(key_addr, blue);
}
} }
} }
::LEDControl.syncLeds(); ::LEDControl.syncLeds();

@ -106,10 +106,8 @@ void Heatmap::TransientLEDMode::shiftStats(void) {
// 2. highest_ reach heat_colors_length*512 (see Heatmap::loopHook) // 2. highest_ reach heat_colors_length*512 (see Heatmap::loopHook)
// we divide every heatmap element by 2 // we divide every heatmap element by 2
for (uint8_t r = 0; r < ROWS; r++) { for (auto key_addr : KeyAddr::all()) {
for (uint8_t c = 0; c < COLS; c++) { heatmap_[key_addr.toInt()] = heatmap_[key_addr.toInt()] >> 1;
heatmap_[r][c] = heatmap_[r][c] >> 1;
}
} }
// and also divide highest_ accordingly // and also divide highest_ accordingly
@ -128,16 +126,14 @@ void Heatmap::TransientLEDMode::resetMap() {
// this method can be used as a way to work around an existing bug with a single key // this method can be used as a way to work around an existing bug with a single key
// getting special attention or if the user just wants a button to reset the map // getting special attention or if the user just wants a button to reset the map
for (uint8_t r = 0; r < ROWS; r++) { for (auto key_addr : KeyAddr::all()) {
for (uint8_t c = 0; c < COLS; c++) { heatmap_[key_addr.toInt()] = 0;
heatmap_[r][c] = 0;
}
} }
highest_ = 1; highest_ = 1;
} }
EventHandlerResult Heatmap::onKeyswitchEvent(Key &mapped_key, byte row, byte col, uint8_t key_state) { EventHandlerResult Heatmap::onKeyswitchEvent(Key &mapped_key, KeyAddr key_addr, uint8_t key_state) {
if (!Kaleidoscope.has_leds) if (!Kaleidoscope.has_leds)
return EventHandlerResult::OK; return EventHandlerResult::OK;
@ -157,16 +153,16 @@ EventHandlerResult Heatmap::onKeyswitchEvent(Key &mapped_key, byte row, byte col
return EventHandlerResult::OK; return EventHandlerResult::OK;
return ::LEDControl.get_mode<TransientLEDMode>() return ::LEDControl.get_mode<TransientLEDMode>()
->onKeyswitchEvent(mapped_key, row, col, key_state); ->onKeyswitchEvent(mapped_key, key_addr, key_state);
} }
EventHandlerResult Heatmap::TransientLEDMode::onKeyswitchEvent(Key &mapped_key, byte row, byte col, uint8_t key_state) { EventHandlerResult Heatmap::TransientLEDMode::onKeyswitchEvent(Key &mapped_key, KeyAddr key_addr, uint8_t key_state) {
// increment the heatmap_ value related to the key // increment the heatmap_ value related to the key
heatmap_[row][col]++; heatmap_[key_addr.toInt()]++;
// check highest_ // check highest_
if (highest_ < heatmap_[row][col]) { if (highest_ < heatmap_[key_addr.toInt()]) {
highest_ = heatmap_[row][col]; highest_ = heatmap_[key_addr.toInt()];
// if highest_ (and so heatmap_ value related to the key) // if highest_ (and so heatmap_ value related to the key)
// is close to overflow: call shiftStats // is close to overflow: call shiftStats
@ -221,19 +217,17 @@ void Heatmap::TransientLEDMode::update(void) {
last_heatmap_comp_time_ = Kaleidoscope.millisAtCycleStart(); last_heatmap_comp_time_ = Kaleidoscope.millisAtCycleStart();
// for each key // for each key
for (uint8_t r = 0; r < ROWS; r++) { for (auto key_addr : KeyAddr::all()) {
for (uint8_t c = 0; c < COLS; c++) {
// how much the key was pressed compared to the others (between 0 and 1) // how much the key was pressed compared to the others (between 0 and 1)
// (total_keys_ can't be equal to 0) // (total_keys_ can't be equal to 0)
float v = static_cast<float>(heatmap_[r][c]) / highest_; float v = static_cast<float>(heatmap_[key_addr.toInt()]) / highest_;
// we could have used an interger instead of a float, but then we would // we could have used an interger instead of a float, but then we would
// have had to change some multiplication in division. // have had to change some multiplication in division.
// / on uint is slower than * on float, so I stay with the float // / on uint is slower than * on float, so I stay with the float
// https://forum.arduino.cc/index.php?topic=92684.msg2733723#msg2733723 // https://forum.arduino.cc/index.php?topic=92684.msg2733723#msg2733723
// set the LED color accordingly // set the LED color accordingly
::LEDControl.setCrgbAt(r, c, computeColor(v)); ::LEDControl.setCrgbAt(KeyAddr(key_addr), computeColor(v));
}
} }
} }

@ -33,7 +33,7 @@ class Heatmap : public Plugin,
static uint8_t heat_colors_length; static uint8_t heat_colors_length;
void resetMap(void); void resetMap(void);
EventHandlerResult onKeyswitchEvent(Key &mapped_key, byte row, byte col, uint8_t key_state); EventHandlerResult onKeyswitchEvent(Key &mapped_key, KeyAddr key_addr, uint8_t key_state);
EventHandlerResult beforeEachCycle(); EventHandlerResult beforeEachCycle();
// This class' instance has dynamic lifetime // This class' instance has dynamic lifetime
@ -48,7 +48,7 @@ class Heatmap : public Plugin,
TransientLEDMode(const Heatmap *parent); TransientLEDMode(const Heatmap *parent);
void resetMap(); void resetMap();
EventHandlerResult onKeyswitchEvent(Key &mapped_key, byte row, byte col, uint8_t key_state); EventHandlerResult onKeyswitchEvent(Key &mapped_key, KeyAddr key_addr, uint8_t key_state);
EventHandlerResult beforeEachCycle(); EventHandlerResult beforeEachCycle();
protected: protected:
@ -59,7 +59,7 @@ class Heatmap : public Plugin,
const Heatmap *parent_; const Heatmap *parent_;
uint16_t heatmap_[ROWS][COLS]; uint16_t heatmap_[KeyboardHardware.numKeys()];
uint16_t highest_; uint16_t highest_;
uint16_t last_heatmap_comp_time_; uint16_t last_heatmap_comp_time_;

@ -36,7 +36,7 @@ EventHandlerResult IdleLEDs::beforeEachCycle() {
return EventHandlerResult::OK; return EventHandlerResult::OK;
} }
EventHandlerResult IdleLEDs::onKeyswitchEvent(Key &mapped_key, byte row, byte col, uint8_t key_state) { EventHandlerResult IdleLEDs::onKeyswitchEvent(Key &mapped_key, KeyAddr key_addr, uint8_t key_state) {
if (::LEDControl.paused) { if (::LEDControl.paused) {
::LEDControl.paused = false; ::LEDControl.paused = false;

@ -29,7 +29,7 @@ class IdleLEDs: public kaleidoscope::Plugin {
static uint16_t idle_time_limit; static uint16_t idle_time_limit;
EventHandlerResult beforeEachCycle(); EventHandlerResult beforeEachCycle();
EventHandlerResult onKeyswitchEvent(Key &mapped_key, byte row, byte col, uint8_t key_state); EventHandlerResult onKeyswitchEvent(Key &mapped_key, KeyAddr key_addr, uint8_t key_state);
private: private:
static uint32_t start_time_; static uint32_t start_time_;

@ -52,8 +52,8 @@ void LEDActiveLayerColorEffect::TransientLEDMode::onActivate(void) {
::LEDControl.set_all_leds_to(active_color_); ::LEDControl.set_all_leds_to(active_color_);
} }
void LEDActiveLayerColorEffect::TransientLEDMode::refreshAt(byte row, byte col) { void LEDActiveLayerColorEffect::TransientLEDMode::refreshAt(KeyAddr key_addr) {
::LEDControl.setCrgbAt(row, col, active_color_); ::LEDControl.setCrgbAt(key_addr, active_color_);
} }
EventHandlerResult LEDActiveLayerColorEffect::onLayerChange() { EventHandlerResult LEDActiveLayerColorEffect::onLayerChange() {

@ -44,7 +44,10 @@ class LEDActiveLayerColorEffect : public Plugin,
protected: protected:
virtual void onActivate(void) final; virtual void onActivate(void) final;
virtual void refreshAt(byte row, byte col) final; virtual void refreshAt(KeyAddr key_addr) final;
DEPRECATED(ROW_COL_FUNC) void refreshAt(byte row, byte col) final {
refreshAt(KeyAddr(row, col));
}
private: private:

@ -22,7 +22,7 @@
namespace kaleidoscope { namespace kaleidoscope {
namespace plugin { namespace plugin {
uint8_t ActiveModColorEffect::mod_keys_[MAX_MODS_PER_LAYER]; KeyAddr ActiveModColorEffect::mod_keys_[MAX_MODS_PER_LAYER];
uint8_t ActiveModColorEffect::mod_key_count_; uint8_t ActiveModColorEffect::mod_key_count_;
bool ActiveModColorEffect::highlight_normal_modifiers_ = true; bool ActiveModColorEffect::highlight_normal_modifiers_ = true;
@ -38,17 +38,14 @@ EventHandlerResult ActiveModColorEffect::onLayerChange() {
mod_key_count_ = 0; mod_key_count_ = 0;
for (byte r = 0; r < ROWS; r++) { for (auto key_addr : KeyAddr::all()) {
for (byte c = 0; c < COLS; c++) { Key k = Layer.lookupOnActiveLayer(key_addr);
Key k = Layer.lookupOnActiveLayer(r, c);
if (::OneShot.isOneShotKey(k) || if (::OneShot.isOneShotKey(k) ||
(highlight_normal_modifiers_ && ( (highlight_normal_modifiers_ && (
(k.raw >= Key_LeftControl.raw && k.raw <= Key_RightGui.raw) || (k.raw >= Key_LeftControl.raw && k.raw <= Key_RightGui.raw) ||
(k.flags == (SYNTHETIC | SWITCH_TO_KEYMAP))))) { (k.flags == (SYNTHETIC | SWITCH_TO_KEYMAP))))) {
uint8_t coords = r * COLS + c; mod_keys_[mod_key_count_++] = key_addr;
mod_keys_[mod_key_count_++] = coords;
}
} }
} }
@ -61,33 +58,31 @@ EventHandlerResult ActiveModColorEffect::beforeReportingState() {
} }
for (uint8_t i = 0; i < mod_key_count_; i++) { for (uint8_t i = 0; i < mod_key_count_; i++) {
uint8_t coords = mod_keys_[i]; const KeyAddr &key_addr = mod_keys_[i];
byte c = coords % COLS;
byte r = (coords - c) / COLS;
Key k = Layer.lookupOnActiveLayer(r, c); Key k = Layer.lookupOnActiveLayer(key_addr);
if (::OneShot.isOneShotKey(k)) { if (::OneShot.isOneShotKey(k)) {
if (::OneShot.isSticky(k)) if (::OneShot.isSticky(k))
::LEDControl.setCrgbAt(r, c, sticky_color); ::LEDControl.setCrgbAt(key_addr, sticky_color);
else if (::OneShot.isActive(k)) else if (::OneShot.isActive(k))
::LEDControl.setCrgbAt(r, c, highlight_color); ::LEDControl.setCrgbAt(key_addr, highlight_color);
else else
::LEDControl.refreshAt(r, c); ::LEDControl.refreshAt(key_addr);
} else if (k.raw >= Key_LeftControl.raw && k.raw <= Key_RightGui.raw) { } else if (k.raw >= Key_LeftControl.raw && k.raw <= Key_RightGui.raw) {
if (hid::isModifierKeyActive(k)) if (hid::isModifierKeyActive(k))
::LEDControl.setCrgbAt(r, c, highlight_color); ::LEDControl.setCrgbAt(key_addr, highlight_color);
else else
::LEDControl.refreshAt(r, c); ::LEDControl.refreshAt(key_addr);
} else if (k.flags == (SYNTHETIC | SWITCH_TO_KEYMAP)) { } else if (k.flags == (SYNTHETIC | SWITCH_TO_KEYMAP)) {
uint8_t layer = k.keyCode; uint8_t layer = k.keyCode;
if (layer >= LAYER_SHIFT_OFFSET) if (layer >= LAYER_SHIFT_OFFSET)
layer -= LAYER_SHIFT_OFFSET; layer -= LAYER_SHIFT_OFFSET;
if (Layer.isActive(layer)) if (Layer.isActive(layer))
::LEDControl.setCrgbAt(r, c, highlight_color); ::LEDControl.setCrgbAt(key_addr, highlight_color);
else else
::LEDControl.refreshAt(r, c); ::LEDControl.refreshAt(key_addr);
} }
} }

@ -40,7 +40,7 @@ class ActiveModColorEffect : public kaleidoscope::Plugin {
private: private:
static bool highlight_normal_modifiers_; static bool highlight_normal_modifiers_;
static uint8_t mod_keys_[MAX_MODS_PER_LAYER]; static KeyAddr mod_keys_[MAX_MODS_PER_LAYER];
static uint8_t mod_key_count_; static uint8_t mod_key_count_;
}; };
} }

@ -63,7 +63,7 @@ static const uint16_t alphabet[] PROGMEM = {
cRGB AlphaSquare::color = {0x80, 0x80, 0x80}; cRGB AlphaSquare::color = {0x80, 0x80, 0x80};
void AlphaSquare::display(Key key, uint8_t row, uint8_t col, cRGB key_color) { void AlphaSquare::display(Key key, KeyAddr key_addr, cRGB key_color) {
if (!Kaleidoscope.has_leds) if (!Kaleidoscope.has_leds)
return; return;
@ -73,14 +73,14 @@ void AlphaSquare::display(Key key, uint8_t row, uint8_t col, cRGB key_color) {
uint8_t index = key.keyCode - Key_A.keyCode; uint8_t index = key.keyCode - Key_A.keyCode;
uint16_t symbol = pgm_read_word(&alphabet[index]); uint16_t symbol = pgm_read_word(&alphabet[index]);
display(symbol, row, col, key_color); display(symbol, key_addr, key_color);
} }
void AlphaSquare::display(Key key, uint8_t row, uint8_t col) { void AlphaSquare::display(Key key, KeyAddr key_addr) {
display(key, row, col, color); display(key, key_addr, color);
} }
void AlphaSquare::display(uint16_t symbol, uint8_t row, uint8_t col, cRGB key_color) { void AlphaSquare::display(uint16_t symbol, KeyAddr key_addr, cRGB key_color) {
if (!Kaleidoscope.has_leds) if (!Kaleidoscope.has_leds)
return; return;
@ -90,20 +90,22 @@ void AlphaSquare::display(uint16_t symbol, uint8_t row, uint8_t col, cRGB key_co
if (!pixel) if (!pixel)
continue; continue;
::LEDControl.setCrgbAt(row + r, col + c, key_color); KeyAddr shifted_addr = key_addr.shifted(r, c);
::LEDControl.setCrgbAt(shifted_addr, key_color);
} }
} }
::LEDControl.syncLeds(); ::LEDControl.syncLeds();
} }
void AlphaSquare::display(uint16_t symbol, uint8_t row, uint8_t col) { void AlphaSquare::display(uint16_t symbol, KeyAddr key_addr) {
display(symbol, row, col, color); display(symbol, key_addr, color);
} }
bool AlphaSquare::isSymbolPart(Key key, bool AlphaSquare::isSymbolPart(Key key,
uint8_t display_row, uint8_t display_col, KeyAddr displayLedAddr,
uint8_t row, uint8_t col) { KeyAddr key_addr) {
if (!Kaleidoscope.has_leds) if (!Kaleidoscope.has_leds)
return false; return false;
@ -113,12 +115,12 @@ bool AlphaSquare::isSymbolPart(Key key,
uint8_t index = key.keyCode - Key_A.keyCode; uint8_t index = key.keyCode - Key_A.keyCode;
uint16_t symbol = pgm_read_word(&alphabet[index]); uint16_t symbol = pgm_read_word(&alphabet[index]);
return isSymbolPart(symbol, display_row, display_col, row, col); return isSymbolPart(symbol, displayLedAddr, key_addr);
} }
bool AlphaSquare::isSymbolPart(uint16_t symbol, bool AlphaSquare::isSymbolPart(uint16_t symbol,
uint8_t display_row, uint8_t display_col, KeyAddr displayLedAddr,
uint8_t row, uint8_t col) { KeyAddr key_addr) {
if (!Kaleidoscope.has_leds) if (!Kaleidoscope.has_leds)
return false; return false;
@ -126,8 +128,8 @@ bool AlphaSquare::isSymbolPart(uint16_t symbol,
for (uint8_t c = 0; c < 4; c++) { for (uint8_t c = 0; c < 4; c++) {
uint8_t pixel = bitRead(symbol, r * 4 + c); uint8_t pixel = bitRead(symbol, r * 4 + c);
if (display_row + r == row && KeyAddr addr_shifted = displayLedAddr.shifted(r, c);
display_col + c == col) if (addr_shifted == key_addr)
return !!pixel; return !!pixel;
} }
} }

@ -35,52 +35,81 @@ namespace kaleidoscope {
namespace plugin { namespace plugin {
class AlphaSquare : public kaleidoscope::Plugin { class AlphaSquare : public kaleidoscope::Plugin {
public: public:
AlphaSquare(void) {} AlphaSquare(void) {}
static void display(Key key, uint8_t row, uint8_t col, cRGB key_color); static void display(Key key, KeyAddr key_addr, cRGB key_color);
static void display(Key key, uint8_t row, uint8_t col); DEPRECATED(ROW_COL_FUNC) static void display(Key key, uint8_t row, uint8_t col, cRGB key_color) {
display(key, KeyAddr(row, col), key_color);
}
static void display(Key key, KeyAddr key_addr);
DEPRECATED(ROW_COL_FUNC) static void display(Key key, uint8_t row, uint8_t col) {
display(key, KeyAddr(row, col));
}
static void display(Key key) { static void display(Key key) {
display(key, 0, 2); display(key, KeyAddr(0, 2));
} }
static void display(Key key, uint8_t col) { static void display(Key key, uint8_t col) {
display(key, 0, col); display(key, KeyAddr(0, col));
} }
static void display(uint16_t symbol, uint8_t row, uint8_t col, cRGB key_color); static void display(uint16_t symbol, KeyAddr key_addr, cRGB key_color);
static void display(uint16_t symbol, uint8_t row, uint8_t col); DEPRECATED(ROW_COL_FUNC) static void display(uint16_t symbol, uint8_t row, uint8_t col, cRGB key_color) {
display(symbol, KeyAddr(row, col), key_color);
}
static void display(uint16_t symbol, KeyAddr key_addr);
DEPRECATED(ROW_COL_FUNC) static void display(uint16_t symbol, uint8_t row, uint8_t col) {
display(symbol, KeyAddr(row, col));
}
static void display(uint16_t symbol) { static void display(uint16_t symbol) {
display(symbol, 0, 2); display(symbol, KeyAddr(0, 2));
} }
static void display(uint16_t symbol, uint8_t col) { static void display(uint16_t symbol, uint8_t col) {
display(symbol, 0, col); display(symbol, KeyAddr(0, col));
} }
static void clear(Key key, uint8_t row, uint8_t col) { static void clear(Key key, KeyAddr key_addr) {
display(key, row, col, {0, 0, 0}); display(key, key_addr, {0, 0, 0});
}
DEPRECATED(ROW_COL_FUNC) static void clear(Key key, uint8_t row, uint8_t col) {
clear(key, KeyAddr(row, col));
} }
static void clear(Key key, uint8_t col) { static void clear(Key key, uint8_t col) {
clear(key, 0, col); clear(key, KeyAddr(0, col));
} }
static void clear(Key key) { static void clear(Key key) {
clear(key, 0, 2); clear(key, KeyAddr(0, 2));
} }
static void clear(uint16_t symbol, uint8_t row, uint8_t col) { static void clear(uint16_t symbol, KeyAddr key_addr) {
display(symbol, row, col, {0, 0, 0}); display(symbol, key_addr, {0, 0, 0});
}
DEPRECATED(ROW_COL_FUNC) static void clear(uint16_t symbol, uint8_t row, uint8_t col) {
clear(symbol, KeyAddr(row, col));
} }
static void clear(uint16_t symbol, uint8_t col) { static void clear(uint16_t symbol, uint8_t col) {
clear(symbol, 0, col); clear(symbol, KeyAddr(0, col));
} }
static void clear(uint16_t symbol) { static void clear(uint16_t symbol) {
clear(symbol, 0, 2); clear(symbol, KeyAddr(0, 2));
} }
static bool isSymbolPart(Key key, static bool isSymbolPart(Key key,
KeyAddr displayLedAddr,
KeyAddr key_addr);
DEPRECATED(ROW_COL_FUNC) static bool isSymbolPart(Key key,
uint8_t display_row, uint8_t display_col, uint8_t display_row, uint8_t display_col,
uint8_t row, uint8_t col); uint8_t row, uint8_t col) {
return isSymbolPart(key, KeyAddr(display_row, display_col), KeyAddr(row, col));
}
static bool isSymbolPart(uint16_t symbol, static bool isSymbolPart(uint16_t symbol,
KeyAddr displayLedAddr,
KeyAddr key_addr);
DEPRECATED(ROW_COL_FUNC) static bool isSymbolPart(uint16_t symbol,
uint8_t display_row, uint8_t display_col, uint8_t display_row, uint8_t display_col,
uint8_t row, uint8_t col); uint8_t row, uint8_t col) {
return isSymbolPart(symbol, KeyAddr(display_row, display_col), KeyAddr(row, col));
}
static cRGB color; static cRGB color;
}; };

@ -43,12 +43,12 @@ void AlphaSquareEffect::TransientLEDMode::update(void) {
} }
} }
void AlphaSquareEffect::TransientLEDMode::refreshAt(byte row, byte col) { void AlphaSquareEffect::TransientLEDMode::refreshAt(KeyAddr key_addr) {
bool timed_out; bool timed_out;
uint8_t display_col = 2; uint8_t display_col = 2;
Key key = last_key_left_; Key key = last_key_left_;
if (col < COLS / 2) { if (key_addr.col() < COLS / 2) {
timed_out = Kaleidoscope.hasTimeExpired(start_time_left_, length); timed_out = Kaleidoscope.hasTimeExpired(start_time_left_, length);
} else { } else {
key = last_key_right_; key = last_key_right_;
@ -56,11 +56,11 @@ void AlphaSquareEffect::TransientLEDMode::refreshAt(byte row, byte col) {
timed_out = Kaleidoscope.hasTimeExpired(start_time_right_, length); timed_out = Kaleidoscope.hasTimeExpired(start_time_right_, length);
} }
if (!::AlphaSquare.isSymbolPart(key, 0, display_col, row, col) || timed_out) if (!::AlphaSquare.isSymbolPart(key, KeyAddr(0, display_col), key_addr) || timed_out)
::LEDControl.setCrgbAt(row, col, CRGB(0, 0, 0)); ::LEDControl.setCrgbAt(key_addr, CRGB(0, 0, 0));
} }
EventHandlerResult AlphaSquareEffect::onKeyswitchEvent(Key &mappedKey, byte row, byte col, uint8_t keyState) { EventHandlerResult AlphaSquareEffect::onKeyswitchEvent(Key &mappedKey, KeyAddr key_addr, uint8_t keyState) {
if (!Kaleidoscope.has_leds) if (!Kaleidoscope.has_leds)
return EventHandlerResult::OK; return EventHandlerResult::OK;
@ -81,7 +81,7 @@ EventHandlerResult AlphaSquareEffect::onKeyswitchEvent(Key &mappedKey, byte row,
Key prev_key = this_led_mode->last_key_left_; Key prev_key = this_led_mode->last_key_left_;
if (col < COLS / 2) { if (key_addr.col() < COLS / 2) {
this_led_mode->last_key_left_ = mappedKey; this_led_mode->last_key_left_ = mappedKey;
this_led_mode->start_time_left_ = Kaleidoscope.millisAtCycleStart(); this_led_mode->start_time_left_ = Kaleidoscope.millisAtCycleStart();
} else { } else {

@ -30,7 +30,7 @@ class AlphaSquareEffect : public Plugin,
static uint16_t length; static uint16_t length;
EventHandlerResult onKeyswitchEvent(Key &mappedKey, byte row, byte col, uint8_t keyState); EventHandlerResult onKeyswitchEvent(Key &mappedKey, KeyAddr key_addr, uint8_t keyState);
// This class' instance has dynamic lifetime // This class' instance has dynamic lifetime
// //
@ -40,7 +40,10 @@ class AlphaSquareEffect : public Plugin,
protected: protected:
void update(void) final; void update(void) final;
void refreshAt(byte row, byte col) final; void refreshAt(KeyAddr key_addr) final;
DEPRECATED(ROW_COL_FUNC) void refreshAt(byte row, byte col) final {
refreshAt(KeyAddr(row, col));
}
private: private:
uint16_t start_time_left_, start_time_right_; uint16_t start_time_left_, start_time_right_;

@ -37,21 +37,21 @@ void LEDPaletteTheme::updateHandler(uint16_t theme_base, uint8_t theme) {
uint16_t map_base = theme_base + (theme * KeyboardHardware.numKeys() / 2); uint16_t map_base = theme_base + (theme * KeyboardHardware.numKeys() / 2);
for (uint16_t pos = 0; pos < KeyboardHardware.numKeys(); pos++) { for (uint8_t pos = 0; pos < KeyboardHardware.numKeys(); pos++) {
cRGB color = lookupColorAtPosition(map_base, pos); cRGB color = lookupColorAtPosition(map_base, pos);
::LEDControl.setCrgbAt(pos, color); ::LEDControl.setCrgbAt(pos, color);
} }
} }
void LEDPaletteTheme::refreshAt(uint16_t theme_base, uint8_t theme, byte row, byte col) { void LEDPaletteTheme::refreshAt(uint16_t theme_base, uint8_t theme, KeyAddr key_addr) {
if (!Kaleidoscope.has_leds) if (!Kaleidoscope.has_leds)
return; return;
uint16_t map_base = theme_base + (theme * KeyboardHardware.numKeys() / 2); uint16_t map_base = theme_base + (theme * KeyboardHardware.numKeys() / 2);
uint16_t pos = KeyboardHardware.getLedIndex(row, col); uint8_t pos = KeyboardHardware.getLedIndex(key_addr);
cRGB color = lookupColorAtPosition(map_base, pos); cRGB color = lookupColorAtPosition(map_base, pos);
::LEDControl.setCrgbAt(pos, color); ::LEDControl.setCrgbAt(KeyAddr(pos), color);
} }

@ -29,7 +29,10 @@ class LEDPaletteTheme : public kaleidoscope::Plugin {
static uint16_t reserveThemes(uint8_t max_themes); static uint16_t reserveThemes(uint8_t max_themes);
static void updateHandler(uint16_t theme_base, uint8_t theme); static void updateHandler(uint16_t theme_base, uint8_t theme);
static void refreshAt(uint16_t theme_base, uint8_t theme, byte row, byte col); static void refreshAt(uint16_t theme_base, uint8_t theme, KeyAddr key_addr);
DEPRECATED(ROW_COL_FUNC) static void refreshAt(uint16_t theme_base, uint8_t theme, byte row, byte col) {
refreshAt(theme_base, theme, KeyAddr(row, col));
}
static const uint8_t lookupColorIndexAtPosition(uint16_t theme_base, uint16_t position); static const uint8_t lookupColorIndexAtPosition(uint16_t theme_base, uint16_t position);
static const cRGB lookupColorAtPosition(uint16_t theme_base, uint16_t position); static const cRGB lookupColorAtPosition(uint16_t theme_base, uint16_t position);

@ -33,18 +33,18 @@ StalkerEffect::TransientLEDMode::TransientLEDMode(const StalkerEffect *parent)
map_{} map_{}
{} {}
EventHandlerResult StalkerEffect::onKeyswitchEvent(Key &mapped_key, byte row, byte col, uint8_t keyState) { EventHandlerResult StalkerEffect::onKeyswitchEvent(Key &mapped_key, KeyAddr key_addr, uint8_t keyState) {
if (!Kaleidoscope.has_leds) if (!Kaleidoscope.has_leds)
return EventHandlerResult::OK; return EventHandlerResult::OK;
if (row >= ROWS || col >= COLS) if (!key_addr.isValid())
return EventHandlerResult::OK; return EventHandlerResult::OK;
if (::LEDControl.get_mode_index() != led_mode_id_) if (::LEDControl.get_mode_index() != led_mode_id_)
return EventHandlerResult::OK; return EventHandlerResult::OK;
if (keyIsPressed(keyState)) { if (keyIsPressed(keyState)) {
::LEDControl.get_mode<TransientLEDMode>()->map_[row][col] = 0xff; ::LEDControl.get_mode<TransientLEDMode>()->map_[key_addr.toInt()] = 0xff;
} }
return EventHandlerResult::OK; return EventHandlerResult::OK;
@ -60,18 +60,16 @@ void StalkerEffect::TransientLEDMode::update(void) {
if (!Kaleidoscope.hasTimeExpired(step_start_time_, parent_->step_length)) if (!Kaleidoscope.hasTimeExpired(step_start_time_, parent_->step_length))
return; return;
for (byte r = 0; r < ROWS; r++) { for (auto key_addr : KeyAddr::all()) {
for (byte c = 0; c < COLS; c++) { uint8_t step = map_[key_addr.toInt()];
uint8_t step = map_[r][c];
if (step) { if (step) {
::LEDControl.setCrgbAt(r, c, parent_->variant->compute(&step)); ::LEDControl.setCrgbAt(key_addr, parent_->variant->compute(&step));
} }
map_[r][c] = step; map_[key_addr.toInt()] = step;
if (!map_[r][c]) if (!map_[key_addr.toInt()])
::LEDControl.setCrgbAt(r, c, parent_->inactive_color); ::LEDControl.setCrgbAt(key_addr, parent_->inactive_color);
}
} }
step_start_time_ = Kaleidoscope.millisAtCycleStart(); step_start_time_ = Kaleidoscope.millisAtCycleStart();

@ -39,7 +39,7 @@ class StalkerEffect : public Plugin,
static uint16_t step_length; static uint16_t step_length;
static cRGB inactive_color; static cRGB inactive_color;
EventHandlerResult onKeyswitchEvent(Key &mapped_key, byte row, byte col, uint8_t keyState); EventHandlerResult onKeyswitchEvent(Key &mapped_key, KeyAddr key_addr, uint8_t keyState);
// This class' instance has dynamic lifetime // This class' instance has dynamic lifetime
// //
@ -61,7 +61,7 @@ class StalkerEffect : public Plugin,
const StalkerEffect *parent_; const StalkerEffect *parent_;
uint16_t step_start_time_; uint16_t step_start_time_;
uint8_t map_[ROWS][COLS]; uint8_t map_[KeyboardHardware.numKeys()];
friend class StalkerEffect; friend class StalkerEffect;
}; };

@ -45,21 +45,20 @@ WavepoolEffect::TransientLEDMode::TransientLEDMode(const WavepoolEffect *parent)
page_(0) page_(0)
{} {}
EventHandlerResult WavepoolEffect::onKeyswitchEvent(Key &mapped_key, byte row, byte col, uint8_t key_state) { EventHandlerResult WavepoolEffect::onKeyswitchEvent(Key &mapped_key, KeyAddr key_addr, uint8_t key_state) {
if (row >= ROWS || col >= COLS) if (!key_addr.isValid())
return EventHandlerResult::OK; return EventHandlerResult::OK;
if (::LEDControl.get_mode_index() != led_mode_id_) if (::LEDControl.get_mode_index() != led_mode_id_)
return EventHandlerResult::OK; return EventHandlerResult::OK;
return ::LEDControl.get_mode<TransientLEDMode>() return ::LEDControl.get_mode<TransientLEDMode>()
->onKeyswitchEvent(mapped_key, row, col, key_state); ->onKeyswitchEvent(mapped_key, key_addr, key_state);
} }
EventHandlerResult WavepoolEffect::TransientLEDMode::onKeyswitchEvent(Key &mapped_key, byte row, byte col, uint8_t key_state) { EventHandlerResult WavepoolEffect::TransientLEDMode::onKeyswitchEvent(Key &mapped_key, KeyAddr key_addr, uint8_t key_state) {
if (keyIsPressed(key_state)) { if (keyIsPressed(key_state)) {
uint8_t offset = (row * COLS) + col; surface_[page_][pgm_read_byte(rc2pos + key_addr.toInt())] = 0x7f;
surface_[page_][pgm_read_byte(rc2pos + offset)] = 0x7f;
frames_since_event_ = 0; frames_since_event_ = 0;
} }
@ -191,14 +190,12 @@ void WavepoolEffect::TransientLEDMode::update(void) {
#endif #endif
// draw the water on the keys // draw the water on the keys
for (byte r = 0; r < ROWS; r++) { for (auto key_addr : KeyAddr::all()) {
for (byte c = 0; c < COLS; c++) { int8_t height = oldpg[pgm_read_byte(rc2pos + key_addr.toInt())];
uint8_t offset = (r * COLS) + c;
int8_t height = oldpg[pgm_read_byte(rc2pos + offset)];
#ifdef INTERPOLATE #ifdef INTERPOLATE
if (now & 1) { // odd frames only if (now & 1) { // odd frames only
// average height with other frame // average height with other frame
height = ((int16_t)height + newpg[pgm_read_byte(rc2pos + offset)]) >> 1; height = ((int16_t)height + newpg[pgm_read_byte(rc2pos + key_addr.toInt())]) >> 1;
} }
#endif #endif
@ -215,8 +212,7 @@ void WavepoolEffect::TransientLEDMode::update(void) {
cRGB color = hsvToRgb(hue, saturation, value); cRGB color = hsvToRgb(hue, saturation, value);
::LEDControl.setCrgbAt(r, c, color); ::LEDControl.setCrgbAt(key_addr, color);
}
} }
#ifdef INTERPOLATE #ifdef INTERPOLATE

@ -34,7 +34,7 @@ class WavepoolEffect : public Plugin,
public: public:
WavepoolEffect(void) {} WavepoolEffect(void) {}
EventHandlerResult onKeyswitchEvent(Key &mapped_key, byte row, byte col, uint8_t key_state); EventHandlerResult onKeyswitchEvent(Key &mapped_key, KeyAddr key_addr, uint8_t key_state);
// ms before idle animation starts after last keypress // ms before idle animation starts after last keypress
static uint16_t idle_timeout; static uint16_t idle_timeout;
@ -53,7 +53,7 @@ class WavepoolEffect : public Plugin,
// //
TransientLEDMode(const WavepoolEffect *parent); TransientLEDMode(const WavepoolEffect *parent);
EventHandlerResult onKeyswitchEvent(Key &mapped_key, byte row, byte col, uint8_t key_state); EventHandlerResult onKeyswitchEvent(Key &mapped_key, KeyAddr key_addr, uint8_t key_state);
protected: protected:

@ -101,16 +101,19 @@ void LEDControl::set_all_leds_to(cRGB color) {
} }
} }
void LEDControl::setCrgbAt(int8_t i, cRGB crgb) { void LEDControl::setCrgbAt(int8_t led_index, cRGB crgb) {
KeyboardHardware.setCrgbAt(i, crgb); KeyboardHardware.setCrgbAt(led_index, crgb);
} }
void LEDControl::setCrgbAt(byte row, byte col, cRGB color) { void LEDControl::setCrgbAt(KeyAddr key_addr, cRGB color) {
KeyboardHardware.setCrgbAt(row, col, color); KeyboardHardware.setCrgbAt(key_addr, color);
} }
cRGB LEDControl::getCrgbAt(int8_t i) { cRGB LEDControl::getCrgbAt(int8_t led_index) {
return KeyboardHardware.getCrgbAt(i); return KeyboardHardware.getCrgbAt(led_index);
}
cRGB LEDControl::getCrgbAt(KeyAddr key_addr) {
return KeyboardHardware.getCrgbAt(KeyboardHardware.getLedIndex(key_addr));
} }
void LEDControl::syncLeds(void) { void LEDControl::syncLeds(void) {
@ -132,7 +135,7 @@ kaleidoscope::EventHandlerResult LEDControl::onSetup() {
return EventHandlerResult::OK; return EventHandlerResult::OK;
} }
kaleidoscope::EventHandlerResult LEDControl::onKeyswitchEvent(Key &mappedKey, byte row, byte col, uint8_t keyState) { kaleidoscope::EventHandlerResult LEDControl::onKeyswitchEvent(Key &mappedKey, KeyAddr key_addr, uint8_t keyState) {
if (mappedKey.flags != (SYNTHETIC | IS_INTERNAL | LED_TOGGLE)) if (mappedKey.flags != (SYNTHETIC | IS_INTERNAL | LED_TOGGLE))
return kaleidoscope::EventHandlerResult::OK; return kaleidoscope::EventHandlerResult::OK;
@ -236,22 +239,24 @@ EventHandlerResult FocusLEDCommand::onFocusEvent(const char *command) {
} }
case THEME: { case THEME: {
if (::Focus.isEOL()) { if (::Focus.isEOL()) {
for (int8_t idx = 0; idx < LED_COUNT; idx++) { for (auto key_addr : KeyAddr::all()) {
cRGB c = ::LEDControl.getCrgbAt(idx); cRGB c = ::LEDControl.getCrgbAt(key_addr);
::Focus.send(c); ::Focus.send(c);
} }
break; break;
} }
int8_t idx = 0; for (auto key_addr : KeyAddr::all()) {
while (idx < LED_COUNT && !::Focus.isEOL()) { if (::Focus.isEOL()) {
break;
}
cRGB color; cRGB color;
::Focus.read(color); ::Focus.read(color);
::LEDControl.setCrgbAt(idx, color); ::LEDControl.setCrgbAt(key_addr, color);
idx++;
} }
break; break;
} }

@ -46,11 +46,11 @@ class LEDControl : public kaleidoscope::Plugin {
cur_led_mode_->update(); cur_led_mode_->update();
} }
static void refreshAt(byte row, byte col) { static void refreshAt(KeyAddr key_addr) {
if (!Kaleidoscope.has_leds) if (!Kaleidoscope.has_leds)
return; return;
cur_led_mode_->refreshAt(row, col); cur_led_mode_->refreshAt(key_addr);
} }
static void set_mode(uint8_t mode_id); static void set_mode(uint8_t mode_id);
static uint8_t get_mode_index() { static uint8_t get_mode_index() {
@ -62,6 +62,10 @@ class LEDControl : public kaleidoscope::Plugin {
template<typename LEDMode__> template<typename LEDMode__>
static LEDMode__ *get_mode() { static LEDMode__ *get_mode() {
return static_cast<LEDMode__*>(cur_led_mode_); return static_cast<LEDMode__*>(cur_led_mode_);
}
DEPRECATED(ROW_COL_FUNC) static void refreshAt(byte row, byte col) {
refreshAt(KeyAddr(row, col));
} }
static void refreshAll() { static void refreshAll() {
@ -81,9 +85,16 @@ class LEDControl : public kaleidoscope::Plugin {
return 0; return 0;
} }
static void setCrgbAt(int8_t i, cRGB crgb); static void setCrgbAt(int8_t led_index, cRGB crgb);
static void setCrgbAt(byte row, byte col, cRGB color); static void setCrgbAt(KeyAddr key_addr, cRGB color);
static cRGB getCrgbAt(int8_t i); DEPRECATED(ROW_COL_FUNC) static void setCrgbAt(byte row, byte col, cRGB color) {
setCrgbAt(KeyAddr(row, col), color);
}
static cRGB getCrgbAt(int8_t led_index);
static cRGB getCrgbAt(KeyAddr key_addr);
DEPRECATED(ROW_COL_FUNC) static cRGB getCrgbAt(byte row, byte col) {
return getCrgbAt(KeyAddr(row, col));
}
static void syncLeds(void); static void syncLeds(void);
static void set_all_leds_to(uint8_t r, uint8_t g, uint8_t b); static void set_all_leds_to(uint8_t r, uint8_t g, uint8_t b);
@ -99,7 +110,7 @@ class LEDControl : public kaleidoscope::Plugin {
static bool paused; static bool paused;
kaleidoscope::EventHandlerResult onSetup(); kaleidoscope::EventHandlerResult onSetup();
kaleidoscope::EventHandlerResult onKeyswitchEvent(Key &mappedKey, byte row, byte col, uint8_t keyState); kaleidoscope::EventHandlerResult onKeyswitchEvent(Key &mappedKey, KeyAddr key_addr, uint8_t keyState);
kaleidoscope::EventHandlerResult beforeReportingState(); kaleidoscope::EventHandlerResult beforeReportingState();
private: private:

@ -22,8 +22,8 @@ void LEDOff::onActivate(void) {
::LEDControl.set_all_leds_to({0, 0, 0}); ::LEDControl.set_all_leds_to({0, 0, 0});
} }
void LEDOff::refreshAt(byte row, byte col) { void LEDOff::refreshAt(KeyAddr key_addr) {
::LEDControl.setCrgbAt(row, col, {0, 0, 0}); ::LEDControl.setCrgbAt(key_addr, {0, 0, 0});
} }
} }
} }

@ -30,7 +30,10 @@ class LEDOff : public LEDMode {
protected: protected:
void onActivate(void) final; void onActivate(void) final;
void refreshAt(byte row, byte col) final; void refreshAt(KeyAddr key_addr) final;
DEPRECATED(ROW_COL_FUNC) void refreshAt(byte row, byte col) final {
refreshAt(KeyAddr(row, col));
}
}; };
} }
} }

@ -52,22 +52,19 @@ EventHandlerResult BootAnimationEffect::afterEachCycle() {
return EventHandlerResult::OK; return EventHandlerResult::OK;
} }
byte row = 255, col = 255; KeyAddr key_addr_found;
for (uint8_t r = 0; r < ROWS; r++) { for (auto key_addr : KeyAddr::all()) {
for (uint8_t c = 0; c < COLS; c++) { Key k = Layer.lookupOnActiveLayer(key_addr);
Key k = Layer.lookupOnActiveLayer(r, c);
Key g; Key g;
g.flags = 0; g.flags = 0;
g.keyCode = pgm_read_byte(&greeting_[current_index_]); g.keyCode = pgm_read_byte(&greeting_[current_index_]);
if (k.raw == g.raw) { if (k.raw == g.raw) {
row = r; key_addr_found = key_addr;
col = c;
break; break;
} }
} }
}
if (Kaleidoscope.hasTimeExpired(start_time_, timeout)) { if (Kaleidoscope.hasTimeExpired(start_time_, timeout)) {
current_index_++; current_index_++;
@ -75,13 +72,13 @@ EventHandlerResult BootAnimationEffect::afterEachCycle() {
done_ = true; done_ = true;
start_time_ += timeout; start_time_ += timeout;
if (row != 255 && col != 255) if (key_addr_found.isValid())
::LEDControl.refreshAt(row, col); ::LEDControl.refreshAt(KeyAddr(key_addr_found));
return EventHandlerResult::OK; return EventHandlerResult::OK;
} }
if (row != 255 && col != 255) { if (key_addr_found.isValid()) {
::LEDControl.setCrgbAt(row, col, color); ::LEDControl.setCrgbAt(KeyAddr(key_addr_found), color);
} }
return EventHandlerResult::OK; return EventHandlerResult::OK;

@ -21,40 +21,33 @@ namespace kaleidoscope {
namespace plugin { namespace plugin {
bool BootGreetingEffect::done_ = false; bool BootGreetingEffect::done_ = false;
byte BootGreetingEffect::row_; KeyAddr BootGreetingEffect::key_addr_;
byte BootGreetingEffect::col_; KeyAddr BootGreetingEffect::user_key_addr;
byte BootGreetingEffect::key_row = 255;
byte BootGreetingEffect::key_col = 255;
Key BootGreetingEffect::search_key = Key_LEDEffectNext; Key BootGreetingEffect::search_key = Key_LEDEffectNext;
uint8_t BootGreetingEffect::hue = 170; uint8_t BootGreetingEffect::hue = 170;
uint16_t BootGreetingEffect::start_time = 0; uint16_t BootGreetingEffect::start_time = 0;
uint16_t BootGreetingEffect::timeout = 9200; uint16_t BootGreetingEffect::timeout = 9200;
BootGreetingEffect::BootGreetingEffect(byte pos_row, byte pos_col) { BootGreetingEffect::BootGreetingEffect(KeyAddr key_addr) {
key_row = pos_row; user_key_addr = key_addr;
key_col = pos_col;
} }
void BootGreetingEffect::findLed(void) { void BootGreetingEffect::findLed(void) {
if (key_col != 255 && key_row != 255) { if (user_key_addr.isValid()) {
row_ = key_row; key_addr_ = user_key_addr;
col_ = key_col;
done_ = true; done_ = true;
return; return;
} }
// Find the LED key. // Find the LED key.
for (uint8_t r = 0; r < ROWS; r++) { for (auto key_addr : KeyAddr::all()) {
for (uint8_t c = 0; c < COLS; c++) { Key k = Layer.lookupOnActiveLayer(key_addr);
Key k = Layer.lookupOnActiveLayer(r, c);
if (k.raw == search_key.raw) { if (k.raw == search_key.raw) {
row_ = r; key_addr_ = key_addr;
col_ = c;
return; return;
} }
} }
}
// We didn't find the LED key. Let's just pretend we're "done". // We didn't find the LED key. Let's just pretend we're "done".
done_ = true; done_ = true;
@ -77,12 +70,12 @@ EventHandlerResult BootGreetingEffect::afterEachCycle() {
//Only run for 'timeout' milliseconds //Only run for 'timeout' milliseconds
if (Kaleidoscope.hasTimeExpired(start_time, timeout)) { if (Kaleidoscope.hasTimeExpired(start_time, timeout)) {
done_ = true; done_ = true;
::LEDControl.refreshAt(row_, col_); ::LEDControl.refreshAt(key_addr_);
return EventHandlerResult::OK; return EventHandlerResult::OK;
} }
cRGB color = breath_compute(hue); cRGB color = breath_compute(hue);
::LEDControl.setCrgbAt(row_, col_, color); ::LEDControl.setCrgbAt(key_addr_, color);
return EventHandlerResult::OK; return EventHandlerResult::OK;
} }

@ -24,10 +24,11 @@ namespace plugin {
class BootGreetingEffect : public kaleidoscope::Plugin { class BootGreetingEffect : public kaleidoscope::Plugin {
public: public:
BootGreetingEffect(void) {} BootGreetingEffect(void) {}
BootGreetingEffect(byte, byte); BootGreetingEffect(KeyAddr key_addr);
DEPRECATED(ROW_COL_FUNC) BootGreetingEffect(byte row, byte col)
: BootGreetingEffect(KeyAddr(row, col)) {}
static byte key_row; static KeyAddr user_key_addr;
static byte key_col;
static Key search_key; static Key search_key;
static uint8_t hue; static uint8_t hue;
static uint16_t timeout; static uint16_t timeout;
@ -38,8 +39,7 @@ class BootGreetingEffect : public kaleidoscope::Plugin {
private: private:
static void findLed(void); static void findLed(void);
static bool done_; static bool done_;
static byte row_; static KeyAddr key_addr_;
static byte col_;
static uint16_t start_time; static uint16_t start_time;
}; };
} }

@ -58,7 +58,7 @@ class LEDChaseEffect : public Plugin,
const LEDChaseEffect *parent_; const LEDChaseEffect *parent_;
int8_t pos_ = 0; int8_t pos_ = uint8_t(0);
int8_t direction_ = 1; int8_t direction_ = 1;
uint16_t last_update_; uint16_t last_update_;
}; };

@ -61,13 +61,13 @@ void LEDRainbowWaveEffect::TransientLEDMode::update(void) {
rainbow_last_update += parent_->rainbow_update_delay; rainbow_last_update += parent_->rainbow_update_delay;
} }
for (int8_t i = 0; i < LED_COUNT; i++) { for (auto key_addr : KeyAddr::all()) {
uint16_t key_hue = rainbow_hue + 16 * (i / 4); uint16_t key_hue = rainbow_hue + 16 * (key_addr.toInt() / 4);
if (key_hue >= 255) { if (key_hue >= 255) {
key_hue -= 255; key_hue -= 255;
} }
cRGB rainbow = hsvToRgb(key_hue, rainbow_saturation, parent_->rainbow_value); cRGB rainbow = hsvToRgb(key_hue, rainbow_saturation, parent_->rainbow_value);
::LEDControl.setCrgbAt(i, rainbow); ::LEDControl.setCrgbAt(key_addr.toInt(), rainbow);
} }
rainbow_hue += rainbow_wave_steps; rainbow_hue += rainbow_wave_steps;
if (rainbow_hue >= 255) { if (rainbow_hue >= 255) {

@ -25,8 +25,8 @@ void LEDSolidColor::TransientLEDMode::onActivate(void) {
parent_->b_); parent_->b_);
} }
void LEDSolidColor::TransientLEDMode::refreshAt(byte row, byte col) { void LEDSolidColor::TransientLEDMode::refreshAt(KeyAddr key_addr) {
::LEDControl.setCrgbAt(row, col, ::LEDControl.setCrgbAt(key_addr,
CRGB(parent_->r_, CRGB(parent_->r_,
parent_->g_, parent_->g_,
parent_->b_)); parent_->b_));

@ -42,7 +42,10 @@ class LEDSolidColor : public Plugin,
protected: protected:
virtual void onActivate(void) final; virtual void onActivate(void) final;
virtual void refreshAt(byte row, byte col) final; virtual void refreshAt(KeyAddr key_addr) final;
DEPRECATED(ROW_COL_FUNC) virtual void refreshAt(byte row, byte col) final {
refreshAt(KeyAddr(row, col));
}
private: private:

@ -81,6 +81,17 @@ class LEDMode : public kaleidoscope::Plugin,
*/ */
virtual void update(void) {} virtual void update(void) {}
/** Refresh the color of a given key.
*
* If we have another plugin that overrides colors set by the active LED mode
* (either at @onActivate time, or via @ref update), if that plugin wants to
* restore whatever color the mode would set the key color to, this is the
* method it will call.
*
* @param key_addr is the matrix coordinate of the key to refresh the color of.
*/
virtual void refreshAt(KeyAddr key_addr) {}
/** Refresh the color of a given key. /** Refresh the color of a given key.
* *
* If we have another plugin that overrides colors set by the active LED mode * If we have another plugin that overrides colors set by the active LED mode
@ -91,7 +102,9 @@ class LEDMode : public kaleidoscope::Plugin,
* @param row is the row coordinate of the key to refresh the color of. * @param row is the row coordinate of the key to refresh the color of.
* @param col is the column coordinate of the key to refresh the color of. * @param col is the column coordinate of the key to refresh the color of.
*/ */
virtual void refreshAt(byte row, byte col) {} DEPRECATED(ROW_COL_FUNC) virtual void refreshAt(byte row, byte col) {
refreshAt(KeyAddr(row, col));
}
public: public:

@ -77,11 +77,11 @@ void Leader::reset(void) {
} }
void Leader::inject(Key key, uint8_t key_state) { void Leader::inject(Key key, uint8_t key_state) {
onKeyswitchEvent(key, UNKNOWN_KEYSWITCH_LOCATION, key_state); onKeyswitchEvent(key, UnknownKeyswitchLocation, key_state);
} }
// --- hooks --- // --- hooks ---
EventHandlerResult Leader::onKeyswitchEvent(Key &mapped_key, byte row, byte col, uint8_t keyState) { EventHandlerResult Leader::onKeyswitchEvent(Key &mapped_key, KeyAddr key_addr, uint8_t keyState) {
if (keyState & INJECTED) if (keyState & INJECTED)
return EventHandlerResult::OK; return EventHandlerResult::OK;

@ -46,7 +46,7 @@ class Leader : public kaleidoscope::Plugin {
void inject(Key key, uint8_t key_state); void inject(Key key, uint8_t key_state);
EventHandlerResult onKeyswitchEvent(Key &mapped_key, byte row, byte col, uint8_t keyState); EventHandlerResult onKeyswitchEvent(Key &mapped_key, KeyAddr key_addr, uint8_t keyState);
EventHandlerResult afterEachCycle(); EventHandlerResult afterEachCycle();
private: private:

@ -27,10 +27,10 @@ namespace plugin {
MacroKeyEvent Macros_::active_macros[]; MacroKeyEvent Macros_::active_macros[];
byte Macros_::active_macro_count; byte Macros_::active_macro_count;
byte Macros_::row, Macros_::col; KeyAddr Macros_::key_addr;
void playMacroKeyswitchEvent(Key key, uint8_t keyswitch_state, bool explicit_report) { void playMacroKeyswitchEvent(Key key, uint8_t keyswitch_state, bool explicit_report) {
handleKeyswitchEvent(key, UNKNOWN_KEYSWITCH_LOCATION, keyswitch_state | INJECTED); handleKeyswitchEvent(key, UnknownKeyswitchLocation, keyswitch_state | INJECTED);
if (explicit_report) if (explicit_report)
return; return;
@ -219,12 +219,11 @@ const macro_t *Macros_::type(const char *string) {
return MACRO_NONE; return MACRO_NONE;
} }
EventHandlerResult Macros_::onKeyswitchEvent(Key &mappedKey, byte row, byte col, uint8_t keyState) { EventHandlerResult Macros_::onKeyswitchEvent(Key &mappedKey, KeyAddr key_addr, uint8_t keyState) {
if (mappedKey.flags != (SYNTHETIC | IS_MACRO)) if (mappedKey.flags != (SYNTHETIC | IS_MACRO))
return EventHandlerResult::OK; return EventHandlerResult::OK;
byte key_id = (row * COLS) + col; addActiveMacroKey(mappedKey.keyCode, key_addr.toInt(), keyState);
addActiveMacroKey(mappedKey.keyCode, key_id, keyState);
return EventHandlerResult::EVENT_CONSUMED; return EventHandlerResult::EVENT_CONSUMED;
} }
@ -238,12 +237,9 @@ EventHandlerResult Macros_::afterEachCycle() {
EventHandlerResult Macros_::beforeReportingState() { EventHandlerResult Macros_::beforeReportingState() {
for (byte i = 0; i < active_macro_count; ++i) { for (byte i = 0; i < active_macro_count; ++i) {
if (active_macros[i].key_id == 0xFF) { if (active_macros[i].key_id == 0xFF) {
// i.e. UNKNOWN_KEYSWITCH_LOCATION key_addr = UnknownKeyswitchLocation;
row = 0xFF;
col = 0xFF;
} else { } else {
row = active_macros[i].key_id / COLS; key_addr = KeyAddr(active_macros[i].key_id);
col = active_macros[i].key_id % COLS;
} }
const macro_t *m = macroAction(active_macros[i].key_code, const macro_t *m = macroAction(active_macros[i].key_code,
active_macros[i].key_state); active_macros[i].key_state);

@ -53,7 +53,7 @@ class Macros_ : public kaleidoscope::Plugin {
++active_macro_count; ++active_macro_count;
} }
EventHandlerResult onKeyswitchEvent(Key &mappedKey, byte row, byte col, uint8_t keyState); EventHandlerResult onKeyswitchEvent(Key &mappedKey, KeyAddr key_addr, uint8_t keyState);
EventHandlerResult beforeReportingState(); EventHandlerResult beforeReportingState();
EventHandlerResult afterEachCycle(); EventHandlerResult afterEachCycle();
@ -74,7 +74,7 @@ class Macros_ : public kaleidoscope::Plugin {
return type(strings...); return type(strings...);
} }
static byte row, col; static KeyAddr key_addr;
private: private:
Key lookupAsciiCode(uint8_t ascii_code); Key lookupAsciiCode(uint8_t ascii_code);

@ -92,13 +92,13 @@ void TestMode::test_leds(void) {
void TestMode::handleKeyEvent(side_data_t *side, keydata_t *oldState, keydata_t *newState, uint8_t row, uint8_t col, uint8_t col_offset) { void TestMode::handleKeyEvent(side_data_t *side, keydata_t *oldState, keydata_t *newState, KeyAddr key_addr, uint8_t col_offset) {
constexpr cRGB red = CRGB(201, 0, 0); constexpr cRGB red = CRGB(201, 0, 0);
constexpr cRGB blue = CRGB(0, 0, 201); constexpr cRGB blue = CRGB(0, 0, 201);
constexpr cRGB green = CRGB(0, 201, 0); constexpr cRGB green = CRGB(0, 201, 0);
const uint8_t keynum = (row * 8) + (col); auto keynum = key_addr.toInt();
const uint8_t keyState = ((bitRead(oldState->all, keynum) << 1) | const uint8_t keyState = ((bitRead(oldState->all, keynum) << 1) |
(bitRead(newState->all, keynum) << 0)); (bitRead(newState->all, keynum) << 0));
@ -111,17 +111,17 @@ void TestMode::handleKeyEvent(side_data_t *side, keydata_t *oldState, keydata_t
side->cyclesSinceStateChange[keynum]++; side->cyclesSinceStateChange[keynum]++;
} }
auto key_addr_col_shifted = KeyAddr(key_addr.row(), col_offset - key_addr.col());
// If the key is held down // If the key is held down
if (keyState == HELD) { if (keyState == HELD) {
KeyboardHardware.setCrgbAt(row, col_offset - col, green); KeyboardHardware.setCrgbAt(key_addr_col_shifted, green);
} else if (bitRead(side->badKeys, keynum) == 1) { } else if (bitRead(side->badKeys, key_addr_col_shifted.toInt()) == 1) {
// If we triggered chatter detection ever on this key // If we triggered chatter detection ever on this key
KeyboardHardware.setCrgbAt(row, col_offset - col, red); KeyboardHardware.setCrgbAt(key_addr_col_shifted, red);
} else if (keyState == TOGGLED_OFF) { } else if (keyState == TOGGLED_OFF) {
// If the key was just released // If the key was just released
KeyboardHardware.setCrgbAt(row, col_offset - col, blue); KeyboardHardware.setCrgbAt(key_addr_col_shifted, blue);
} }
} }
@ -143,11 +143,9 @@ void TestMode::testMatrix() {
KeyboardHardware.pressedKeyswitchCount() == 3) { KeyboardHardware.pressedKeyswitchCount() == 3) {
break; break;
} }
for (byte row = 0; row < 4; row++) { for (auto key_addr : KeyAddr::all()) {
for (byte col = 0; col < 8; col++) { handleKeyEvent(&left, &(KeyboardHardware.previousLeftHandState), &(KeyboardHardware.leftHandState), key_addr, 7);
handleKeyEvent(&left, &(KeyboardHardware.previousLeftHandState), &(KeyboardHardware.leftHandState), row, col, 7); handleKeyEvent(&right, &(KeyboardHardware.previousRightHandState), &(KeyboardHardware.rightHandState), key_addr, 15);
handleKeyEvent(&right, &(KeyboardHardware.previousRightHandState), &(KeyboardHardware.rightHandState), row, col, 15);
}
} }
::LEDControl.syncLeds(); ::LEDControl.syncLeds();
} }

@ -41,7 +41,7 @@ class TestMode : public kaleidoscope::Plugin {
static void test_leds(); static void test_leds();
static void testMatrix(); static void testMatrix();
static void toggle_programming_leds_on(); static void toggle_programming_leds_on();
static void handleKeyEvent(side_data_t *side, keydata_t *oldState, keydata_t *newState, uint8_t row, uint8_t col, uint8_t col_offset); static void handleKeyEvent(side_data_t *side, keydata_t *oldState, keydata_t *newState, KeyAddr key_addr, uint8_t col_offset);
static void waitForKeypress(); static void waitForKeypress();
static void set_leds(cRGB color); static void set_leds(cRGB color);
}; };

@ -104,7 +104,7 @@ EventHandlerResult MouseKeys_::beforeReportingState() {
return EventHandlerResult::OK; return EventHandlerResult::OK;
} }
EventHandlerResult MouseKeys_::onKeyswitchEvent(Key &mappedKey, byte row, byte col, uint8_t keyState) { EventHandlerResult MouseKeys_::onKeyswitchEvent(Key &mappedKey, KeyAddr key_addr, uint8_t keyState) {
if (mappedKey.flags != (SYNTHETIC | IS_MOUSE_KEY)) if (mappedKey.flags != (SYNTHETIC | IS_MOUSE_KEY))
return EventHandlerResult::OK; return EventHandlerResult::OK;

@ -40,7 +40,7 @@ class MouseKeys_ : public kaleidoscope::Plugin {
EventHandlerResult onSetup(); EventHandlerResult onSetup();
EventHandlerResult beforeReportingState(); EventHandlerResult beforeReportingState();
EventHandlerResult afterEachCycle(); EventHandlerResult afterEachCycle();
EventHandlerResult onKeyswitchEvent(Key &mappedKey, byte row, byte col, uint8_t keyState); EventHandlerResult onKeyswitchEvent(Key &mappedKey, KeyAddr key_addr, uint8_t keyState);
private: private:
static uint8_t mouseMoveIntent; static uint8_t mouseMoveIntent;

@ -25,7 +25,7 @@ cRGB NumPad::color = CRGB(160, 0, 0);
uint8_t NumPad::lock_hue = 170; uint8_t NumPad::lock_hue = 170;
// private: // private:
byte NumPad::numpadLayerToggleKeyRow = 255, NumPad::numpadLayerToggleKeyCol = 255; KeyAddr NumPad::numpadLayerToggleKeyAddr;
bool NumPad::numpadActive = false; bool NumPad::numpadActive = false;
EventHandlerResult NumPad::onSetup(void) { EventHandlerResult NumPad::onSetup(void) {
@ -35,27 +35,24 @@ EventHandlerResult NumPad::onSetup(void) {
void NumPad::setKeyboardLEDColors(void) { void NumPad::setKeyboardLEDColors(void) {
::LEDControl.set_mode(::LEDControl.get_mode_index()); ::LEDControl.set_mode(::LEDControl.get_mode_index());
for (uint8_t r = 0; r < ROWS; r++) { for (auto key_addr : KeyAddr::all()) {
for (uint8_t c = 0; c < COLS; c++) { Key k = Layer.lookupOnActiveLayer(key_addr);
Key k = Layer.lookupOnActiveLayer(r, c); Key layer_key = Layer.getKey(numPadLayer, key_addr);
Key layer_key = Layer.getKey(numPadLayer, r, c);
if (k == LockLayer(numPadLayer)) { if (k == LockLayer(numPadLayer)) {
numpadLayerToggleKeyRow = r; numpadLayerToggleKeyAddr = key_addr;
numpadLayerToggleKeyCol = c;
} }
if ((k != layer_key) || (k == Key_NoKey) || (k.flags != KEY_FLAGS)) { if ((k != layer_key) || (k == Key_NoKey) || (k.flags != KEY_FLAGS)) {
::LEDControl.refreshAt(r, c); ::LEDControl.refreshAt(KeyAddr(key_addr));
} else { } else {
::LEDControl.setCrgbAt(r, c, color); ::LEDControl.setCrgbAt(KeyAddr(key_addr), color);
}
} }
} }
if ((numpadLayerToggleKeyRow <= ROWS) && (numpadLayerToggleKeyCol <= COLS)) { if (numpadLayerToggleKeyAddr.isValid()) {
cRGB lock_color = breath_compute(lock_hue); cRGB lock_color = breath_compute(lock_hue);
::LEDControl.setCrgbAt(numpadLayerToggleKeyRow, numpadLayerToggleKeyCol, lock_color); ::LEDControl.setCrgbAt(KeyAddr(numpadLayerToggleKeyAddr), lock_color);
} }
} }

@ -36,8 +36,7 @@ class NumPad : public kaleidoscope::Plugin {
void setKeyboardLEDColors(void); void setKeyboardLEDColors(void);
static uint8_t numpadLayerToggleKeyRow; static KeyAddr numpadLayerToggleKeyAddr;
static uint8_t numpadLayerToggleKeyCol;
static bool numpadActive; static bool numpadActive;
}; };
} }

@ -54,7 +54,6 @@ bool OneShot::isStickable(Key key) {
// ---- OneShot stuff ---- // ---- OneShot stuff ----
void OneShot::injectNormalKey(uint8_t idx, uint8_t key_state) { void OneShot::injectNormalKey(uint8_t idx, uint8_t key_state) {
Key key; Key key;
byte row, col;
if (idx < 8) { if (idx < 8) {
key.flags = Key_LeftControl.flags; key.flags = Key_LeftControl.flags;
@ -64,7 +63,7 @@ void OneShot::injectNormalKey(uint8_t idx, uint8_t key_state) {
key.keyCode = LAYER_SHIFT_OFFSET + idx - 8; key.keyCode = LAYER_SHIFT_OFFSET + idx - 8;
} }
handleKeyswitchEvent(key, UNKNOWN_KEYSWITCH_LOCATION, key_state | INJECTED); handleKeyswitchEvent(key, UnknownKeyswitchLocation, key_state | INJECTED);
} }
void OneShot::activateOneShot(uint8_t idx) { void OneShot::activateOneShot(uint8_t idx) {
@ -76,7 +75,7 @@ void OneShot::cancelOneShot(uint8_t idx) {
injectNormalKey(idx, WAS_PRESSED); injectNormalKey(idx, WAS_PRESSED);
} }
EventHandlerResult OneShot::onKeyswitchEvent(Key &mapped_key, byte row, byte col, uint8_t keyState) { EventHandlerResult OneShot::onKeyswitchEvent(Key &mapped_key, KeyAddr key_addr, uint8_t keyState) {
uint8_t idx = mapped_key.raw - ranges::OS_FIRST; uint8_t idx = mapped_key.raw - ranges::OS_FIRST;
if (keyState & INJECTED) if (keyState & INJECTED)
@ -91,7 +90,7 @@ EventHandlerResult OneShot::onKeyswitchEvent(Key &mapped_key, byte row, byte col
state_[idx].pressed = false; state_[idx].pressed = false;
} else if (keyToggledOn(keyState)) { } else if (keyToggledOn(keyState)) {
start_time_ = Kaleidoscope.millisAtCycleStart(); start_time_ = Kaleidoscope.millisAtCycleStart();
state_[idx].position = row * COLS + col; state_[idx].position = key_addr.toInt();
state_[idx].pressed = true; state_[idx].pressed = true;
state_[idx].active = true; state_[idx].active = true;
prev_key_ = mapped_key; prev_key_ = mapped_key;
@ -131,7 +130,7 @@ EventHandlerResult OneShot::onKeyswitchEvent(Key &mapped_key, byte row, byte col
} else { } else {
start_time_ = Kaleidoscope.millisAtCycleStart(); start_time_ = Kaleidoscope.millisAtCycleStart();
state_[idx].position = row * COLS + col; state_[idx].position = key_addr.toInt();
state_[idx].active = true; state_[idx].active = true;
prev_key_ = mapped_key; prev_key_ = mapped_key;
@ -204,7 +203,7 @@ EventHandlerResult OneShot::afterEachCycle() {
} }
void OneShot::inject(Key mapped_key, uint8_t key_state) { void OneShot::inject(Key mapped_key, uint8_t key_state) {
onKeyswitchEvent(mapped_key, UNKNOWN_KEYSWITCH_LOCATION, key_state); onKeyswitchEvent(mapped_key, UnknownKeyswitchLocation, key_state);
} }
// --- glue code --- // --- glue code ---

@ -74,7 +74,7 @@ class OneShot : public kaleidoscope::Plugin {
EventHandlerResult beforeReportingState(); EventHandlerResult beforeReportingState();
EventHandlerResult afterEachCycle(); EventHandlerResult afterEachCycle();
EventHandlerResult onKeyswitchEvent(Key &mapped_key, byte row, byte col, uint8_t keyState); EventHandlerResult onKeyswitchEvent(Key &mapped_key, KeyAddr key_addr, uint8_t keyState);
void inject(Key mapped_key, uint8_t key_state); void inject(Key mapped_key, uint8_t key_state);

@ -40,10 +40,9 @@ bool isDualUse(Key k) {
} }
inline inline
bool isDualUse(byte key_addr) { bool isDualUse(byte key_addr_offset) {
byte row = addr::row(key_addr); KeyAddr key_addr(key_addr_offset);
byte col = addr::col(key_addr); Key k = Layer.lookup(key_addr);
Key k = Layer.lookup(row, col);
return isDualUse(k); return isDualUse(k);
} }
@ -74,9 +73,9 @@ Key getDualUseAlternateKey(Key k) {
} }
Qukey::Qukey(int8_t layer, byte row, byte col, Key alt_keycode) { Qukey::Qukey(int8_t layer, KeyAddr key_addr, Key alt_keycode) {
this->layer = layer; this->layer = layer;
this->addr = addr::addr(row, col); this->addr = key_addr.toInt();
this->alt_keycode = alt_keycode; this->alt_keycode = alt_keycode;
} }
@ -97,16 +96,15 @@ constexpr uint16_t QUKEYS_RELEASE_DELAY_OFFSET = 4096;
// Empty constructor; nothing is stored at the instance level // Empty constructor; nothing is stored at the instance level
Qukeys::Qukeys(void) {} Qukeys::Qukeys(void) {}
int8_t Qukeys::lookupQukey(uint8_t key_addr) { int8_t Qukeys::lookupQukey(uint8_t key_addr_offset) {
if (key_addr == QUKEY_UNKNOWN_ADDR) { if (key_addr_offset == QUKEY_UNKNOWN_ADDR) {
return QUKEY_NOT_FOUND; return QUKEY_NOT_FOUND;
} }
for (int8_t i = 0; i < qukeys_count; i++) { for (int8_t i = 0; i < qukeys_count; i++) {
if (qukeys[i].addr == key_addr) { if (qukeys[i].addr == key_addr_offset) {
byte row = addr::row(key_addr); KeyAddr key_addr(key_addr_offset);
byte col = addr::col(key_addr);
if ((qukeys[i].layer == QUKEY_ALL_LAYERS) || if ((qukeys[i].layer == QUKEY_ALL_LAYERS) ||
(qukeys[i].layer == Layer.lookupActiveLayer(row, col))) { (qukeys[i].layer == Layer.lookupActiveLayer(key_addr))) {
return i; return i;
} }
} }
@ -138,9 +136,8 @@ int8_t Qukeys::searchQueue(uint8_t key_addr) {
bool Qukeys::flushKey(bool qukey_state, uint8_t keyswitch_state) { bool Qukeys::flushKey(bool qukey_state, uint8_t keyswitch_state) {
int8_t qukey_index = lookupQukey(key_queue_[0].addr); int8_t qukey_index = lookupQukey(key_queue_[0].addr);
bool is_qukey = (qukey_index != QUKEY_NOT_FOUND); bool is_qukey = (qukey_index != QUKEY_NOT_FOUND);
byte row = addr::row(key_queue_[0].addr); KeyAddr key_addr(key_queue_[0].addr);
byte col = addr::col(key_queue_[0].addr); Key keycode = Layer.lookupOnActiveLayer(key_addr);
Key keycode = Layer.lookupOnActiveLayer(row, col);
bool is_dual_use = isDualUse(keycode); bool is_dual_use = isDualUse(keycode);
if (is_qukey || is_dual_use) { if (is_qukey || is_dual_use) {
if (qukey_state == QUKEY_STATE_PRIMARY) { if (qukey_state == QUKEY_STATE_PRIMARY) {
@ -184,7 +181,7 @@ bool Qukeys::flushKey(bool qukey_state, uint8_t keyswitch_state) {
// we can ignore it and don't start an infinite loop. It would be // we can ignore it and don't start an infinite loop. It would be
// nice if we could use key_state to also indicate which plugin // nice if we could use key_state to also indicate which plugin
// injected the key. // injected the key.
handleKeyswitchEvent(keycode, row, col, IS_PRESSED); handleKeyswitchEvent(keycode, key_addr, IS_PRESSED);
// Now we send the report (if there were any changes) // Now we send the report (if there were any changes)
hid::sendKeyboardReport(); hid::sendKeyboardReport();
@ -193,10 +190,10 @@ bool Qukeys::flushKey(bool qukey_state, uint8_t keyswitch_state) {
// Last, if the key is still down, add its code back in // Last, if the key is still down, add its code back in
if (keyswitch_state & IS_PRESSED) { if (keyswitch_state & IS_PRESSED) {
handleKeyswitchEvent(keycode, row, col, IS_PRESSED | WAS_PRESSED); handleKeyswitchEvent(keycode, key_addr, IS_PRESSED | WAS_PRESSED);
} else { } else {
// If this is the key that was released, send that release event now // If this is the key that was released, send that release event now
handleKeyswitchEvent(Key_NoKey, row, col, WAS_PRESSED); handleKeyswitchEvent(Key_NoKey, key_addr, WAS_PRESSED);
// ...and if there's another key in the queue that's about to also be // ...and if there's another key in the queue that's about to also be
// flushed, we need to do something to clear this one's modifier flags (if // flushed, we need to do something to clear this one's modifier flags (if
// any) from the previous report // any) from the previous report
@ -256,10 +253,10 @@ bool Qukeys::isQukey(uint8_t addr) {
return (isDualUse(addr) || lookupQukey(addr) != QUKEY_NOT_FOUND); return (isDualUse(addr) || lookupQukey(addr) != QUKEY_NOT_FOUND);
} }
EventHandlerResult Qukeys::onKeyswitchEvent(Key &mapped_key, byte row, byte col, uint8_t key_state) { EventHandlerResult Qukeys::onKeyswitchEvent(Key &mapped_key, KeyAddr key_addr, uint8_t key_state) {
// If key_addr is not a physical key, ignore it; some other plugin injected it // If key_addr is not a physical key, ignore it; some other plugin injected it
if (row >= ROWS || col >= COLS || (key_state & INJECTED) != 0) if (!key_addr.isValid() || (key_state & INJECTED) != 0)
return EventHandlerResult::OK; return EventHandlerResult::OK;
// If Qukeys is turned off, continue to next plugin // If Qukeys is turned off, continue to next plugin
@ -269,8 +266,7 @@ EventHandlerResult Qukeys::onKeyswitchEvent(Key &mapped_key, byte row, byte col,
} }
// get key addr & qukey (if any) // get key addr & qukey (if any)
uint8_t key_addr = addr::addr(row, col); int8_t qukey_index = lookupQukey(key_addr.toInt());
int8_t qukey_index = lookupQukey(key_addr);
// If the key was injected (from the queue being flushed) // If the key was injected (from the queue being flushed)
if (flushing_queue_) { if (flushing_queue_) {
@ -287,13 +283,13 @@ EventHandlerResult Qukeys::onKeyswitchEvent(Key &mapped_key, byte row, byte col,
} }
// Otherwise, queue the key and stop processing: // Otherwise, queue the key and stop processing:
enqueue(key_addr); enqueue(key_addr.toInt());
// flushQueue() has already handled this key release // flushQueue() has already handled this key release
return EventHandlerResult::EVENT_CONSUMED; return EventHandlerResult::EVENT_CONSUMED;
} }
// In all other cases, we need to know if the key is queued already // In all other cases, we need to know if the key is queued already
int8_t queue_index = searchQueue(key_addr); int8_t queue_index = searchQueue(key_addr.toInt());
// If the key was just released: // If the key was just released:
if (keyToggledOff(key_state)) { if (keyToggledOff(key_state)) {
@ -305,12 +301,10 @@ EventHandlerResult Qukeys::onKeyswitchEvent(Key &mapped_key, byte row, byte col,
// order to send a toggle off of a `ShiftToLayer()` key; otherwise, that layer gets // order to send a toggle off of a `ShiftToLayer()` key; otherwise, that layer gets
// stuck on if there's a release delay and a rollover. // stuck on if there's a release delay and a rollover.
if (delayed_qukey_addr_ != QUKEY_UNKNOWN_ADDR) { if (delayed_qukey_addr_ != QUKEY_UNKNOWN_ADDR) {
int8_t r = addr::row(delayed_qukey_addr_);
int8_t c = addr::col(delayed_qukey_addr_);
flushQueue(queue_index); flushQueue(queue_index);
flushQueue(); flushQueue();
flushing_queue_ = true; flushing_queue_ = true;
handleKeyswitchEvent(Key_NoKey, r, c, WAS_PRESSED); handleKeyswitchEvent(Key_NoKey, KeyAddr(delayed_qukey_addr_), WAS_PRESSED);
flushing_queue_ = false; flushing_queue_ = false;
delayed_qukey_addr_ = QUKEY_UNKNOWN_ADDR; delayed_qukey_addr_ = QUKEY_UNKNOWN_ADDR;
} else { } else {

@ -19,7 +19,6 @@
#pragma once #pragma once
#include <Kaleidoscope.h> #include <Kaleidoscope.h>
#include <kaleidoscope/addr.h>
#include <Kaleidoscope-Ranges.h> #include <Kaleidoscope-Ranges.h>
// Maximum length of the pending queue // Maximum length of the pending queue
@ -59,7 +58,9 @@ namespace plugin {
struct Qukey { struct Qukey {
public: public:
Qukey(void) {} Qukey(void) {}
Qukey(int8_t layer, byte row, byte col, Key alt_keycode); Qukey(int8_t layer, KeyAddr key_addr, Key alt_keycode);
DEPRECATED(ROW_COL_FUNC) Qukey(int8_t layer, byte row, byte col, Key alt_keycode)
: Qukey(layer, KeyAddr(row, col), alt_keycode) {}
int8_t layer; int8_t layer;
uint8_t addr; uint8_t addr;
@ -102,7 +103,7 @@ class Qukeys : public kaleidoscope::Plugin {
static uint8_t qukeys_count; static uint8_t qukeys_count;
EventHandlerResult onSetup(); EventHandlerResult onSetup();
EventHandlerResult onKeyswitchEvent(Key &mapped_key, byte row, byte col, uint8_t key_state); EventHandlerResult onKeyswitchEvent(Key &mapped_key, KeyAddr key_addr, uint8_t key_state);
EventHandlerResult beforeReportingState(); EventHandlerResult beforeReportingState();
private: private:

@ -24,7 +24,7 @@ Key Redial::key_to_redial_;
Key Redial::last_key_; Key Redial::last_key_;
bool Redial::redial_held_ = false; bool Redial::redial_held_ = false;
EventHandlerResult Redial::onKeyswitchEvent(Key &mapped_key, byte row, byte col, uint8_t key_state) { EventHandlerResult Redial::onKeyswitchEvent(Key &mapped_key, KeyAddr key_addr, uint8_t key_state) {
if (mapped_key == Key_Redial) { if (mapped_key == Key_Redial) {
if (keyToggledOff(key_state)) if (keyToggledOff(key_state))
key_to_redial_ = last_key_; key_to_redial_ = last_key_;

@ -31,7 +31,7 @@ class Redial : public kaleidoscope::Plugin {
static bool shouldRemember(Key mappedKey); static bool shouldRemember(Key mappedKey);
EventHandlerResult onKeyswitchEvent(Key &mapped_key, byte row, byte col, uint8_t key_state); EventHandlerResult onKeyswitchEvent(Key &mapped_key, KeyAddr key_addr, uint8_t key_state);
private: private:
static Key key_to_redial_; static Key key_to_redial_;

@ -30,7 +30,7 @@ EventHandlerResult ShapeShifter::beforeReportingState() {
return EventHandlerResult::OK; return EventHandlerResult::OK;
} }
EventHandlerResult ShapeShifter::onKeyswitchEvent(Key &mapped_key, byte row, byte col, uint8_t key_state) { EventHandlerResult ShapeShifter::onKeyswitchEvent(Key &mapped_key, KeyAddr key_addr, uint8_t key_state) {
if (!dictionary) if (!dictionary)
return EventHandlerResult::OK; return EventHandlerResult::OK;

@ -32,7 +32,7 @@ class ShapeShifter : public kaleidoscope::Plugin {
static const dictionary_t *dictionary; static const dictionary_t *dictionary;
EventHandlerResult onKeyswitchEvent(Key &mapped_key, byte row, byte col, uint8_t key_state); EventHandlerResult onKeyswitchEvent(Key &mapped_key, KeyAddr key_addr, uint8_t key_state);
EventHandlerResult beforeReportingState(); EventHandlerResult beforeReportingState();
private: private:

@ -70,7 +70,7 @@ bool SpaceCadet::active() {
return !disabled; return !disabled;
} }
EventHandlerResult SpaceCadet::onKeyswitchEvent(Key &mapped_key, byte row, byte col, uint8_t key_state) { EventHandlerResult SpaceCadet::onKeyswitchEvent(Key &mapped_key, KeyAddr key_addr, uint8_t key_state) {
//Handle our synthetic keys for enabling and disabling functionality //Handle our synthetic keys for enabling and disabling functionality
if (mapped_key.raw >= kaleidoscope::ranges::SC_FIRST && if (mapped_key.raw >= kaleidoscope::ranges::SC_FIRST &&
mapped_key.raw <= kaleidoscope::ranges::SC_LAST) { mapped_key.raw <= kaleidoscope::ranges::SC_LAST) {
@ -130,7 +130,7 @@ EventHandlerResult SpaceCadet::onKeyswitchEvent(Key &mapped_key, byte row, byte
//hit another key after this -- if it's a modifier, we want the modifier //hit another key after this -- if it's a modifier, we want the modifier
//key to be added to the report, for things like ctrl, alt, shift, etc) //key to be added to the report, for things like ctrl, alt, shift, etc)
if (map[i].flagged) { if (map[i].flagged) {
handleKeyswitchEvent(map[i].input, UNKNOWN_KEYSWITCH_LOCATION, IS_PRESSED | INJECTED); handleKeyswitchEvent(map[i].input, UnknownKeyswitchLocation, IS_PRESSED | INJECTED);
} }
//The keypress wasn't a match, so we need to mark it as not flagged and //The keypress wasn't a match, so we need to mark it as not flagged and
@ -225,7 +225,7 @@ EventHandlerResult SpaceCadet::onKeyswitchEvent(Key &mapped_key, byte row, byte
//only need to send that key and not the original key. //only need to send that key and not the original key.
//inject our new key //inject our new key
handleKeyswitchEvent(alternate_key, row, col, IS_PRESSED | INJECTED); handleKeyswitchEvent(alternate_key, key_addr, IS_PRESSED | INJECTED);
//Unflag the key so we don't try this again. //Unflag the key so we don't try this again.
map[index].flagged = false; map[index].flagged = false;

@ -66,7 +66,7 @@ class SpaceCadet : public kaleidoscope::Plugin {
static uint16_t time_out; // The global timeout in milliseconds static uint16_t time_out; // The global timeout in milliseconds
static SpaceCadet::KeyBinding * map; // The map of key bindings static SpaceCadet::KeyBinding * map; // The map of key bindings
EventHandlerResult onKeyswitchEvent(Key &mapped_key, byte row, byte col, uint8_t key_state); EventHandlerResult onKeyswitchEvent(Key &mapped_key, KeyAddr key_addr, uint8_t key_state);
private: private:
static bool disabled; static bool disabled;

@ -43,7 +43,7 @@ bool Syster::is_active(void) {
} }
// --- hooks --- // --- hooks ---
EventHandlerResult Syster::onKeyswitchEvent(Key &mapped_key, byte row, byte col, uint8_t keyState) { EventHandlerResult Syster::onKeyswitchEvent(Key &mapped_key, KeyAddr key_addr, uint8_t keyState) {
if (!is_active_) { if (!is_active_) {
if (!isSyster(mapped_key)) if (!isSyster(mapped_key))
return EventHandlerResult::OK; return EventHandlerResult::OK;
@ -69,9 +69,9 @@ EventHandlerResult Syster::onKeyswitchEvent(Key &mapped_key, byte row, byte col,
if (keyToggledOff(keyState)) { if (keyToggledOff(keyState)) {
if (mapped_key == Key_Spacebar) { if (mapped_key == Key_Spacebar) {
for (uint8_t i = 0; i <= symbol_pos_; i++) { for (uint8_t i = 0; i <= symbol_pos_; i++) {
handleKeyswitchEvent(Key_Backspace, UNKNOWN_KEYSWITCH_LOCATION, IS_PRESSED | INJECTED); handleKeyswitchEvent(Key_Backspace, UnknownKeyswitchLocation, IS_PRESSED | INJECTED);
hid::sendKeyboardReport(); hid::sendKeyboardReport();
handleKeyswitchEvent(Key_Backspace, UNKNOWN_KEYSWITCH_LOCATION, WAS_PRESSED | INJECTED); handleKeyswitchEvent(Key_Backspace, UnknownKeyswitchLocation, WAS_PRESSED | INJECTED);
hid::sendKeyboardReport(); hid::sendKeyboardReport();
} }

@ -41,7 +41,7 @@ class Syster : public kaleidoscope::Plugin {
bool is_active(void); bool is_active(void);
EventHandlerResult onKeyswitchEvent(Key &mapped_key, byte row, byte col, uint8_t keyState); EventHandlerResult onKeyswitchEvent(Key &mapped_key, KeyAddr key_addr, uint8_t keyState);
private: private:
static char symbol_[SYSTER_MAX_SYMBOL_LENGTH + 1]; static char symbol_[SYSTER_MAX_SYMBOL_LENGTH + 1];

@ -26,20 +26,19 @@ uint16_t TapDance::start_time_;
uint16_t TapDance::time_out = 200; uint16_t TapDance::time_out = 200;
TapDance::TapDanceState TapDance::state_[TapDance::TAPDANCE_KEY_COUNT]; TapDance::TapDanceState TapDance::state_[TapDance::TAPDANCE_KEY_COUNT];
Key TapDance::last_tap_dance_key_ = Key_NoKey; Key TapDance::last_tap_dance_key_ = Key_NoKey;
byte TapDance::last_tap_dance_row_; KeyAddr TapDance::last_tap_dance_addr_;
byte TapDance::last_tap_dance_col_;
// --- actions --- // --- actions ---
void TapDance::interrupt(byte row, byte col) { void TapDance::interrupt(KeyAddr key_addr) {
uint8_t idx = last_tap_dance_key_.raw - ranges::TD_FIRST; uint8_t idx = last_tap_dance_key_.raw - ranges::TD_FIRST;
tapDanceAction(idx, last_tap_dance_row_, last_tap_dance_col_, state_[idx].count, Interrupt); tapDanceAction(idx, last_tap_dance_addr_, state_[idx].count, Interrupt);
state_[idx].triggered = true; state_[idx].triggered = true;
last_tap_dance_key_ = Key_NoKey; last_tap_dance_key_ = Key_NoKey;
KeyboardHardware.maskKey(row, col); KeyboardHardware.maskKey(key_addr);
kaleidoscope::hid::sendKeyboardReport(); kaleidoscope::hid::sendKeyboardReport();
kaleidoscope::hid::releaseAllKeys(); kaleidoscope::hid::releaseAllKeys();
@ -52,7 +51,7 @@ void TapDance::interrupt(byte row, byte col) {
void TapDance::timeout(void) { void TapDance::timeout(void) {
uint8_t idx = last_tap_dance_key_.raw - ranges::TD_FIRST; uint8_t idx = last_tap_dance_key_.raw - ranges::TD_FIRST;
tapDanceAction(idx, last_tap_dance_row_, last_tap_dance_col_, state_[idx].count, Timeout); tapDanceAction(idx, last_tap_dance_addr_, state_[idx].count, Timeout);
state_[idx].triggered = true; state_[idx].triggered = true;
if (state_[idx].pressed) if (state_[idx].pressed)
@ -77,7 +76,7 @@ void TapDance::tap(void) {
state_[idx].count++; state_[idx].count++;
start_time_ = Kaleidoscope.millisAtCycleStart(); start_time_ = Kaleidoscope.millisAtCycleStart();
tapDanceAction(idx, last_tap_dance_row_, last_tap_dance_col_, state_[idx].count, Tap); tapDanceAction(idx, last_tap_dance_addr_, state_[idx].count, Tap);
} }
// --- api --- // --- api ---
@ -94,21 +93,21 @@ void TapDance::actionKeys(uint8_t tap_count, ActionType tap_dance_action, uint8_
break; break;
case Interrupt: case Interrupt:
case Timeout: case Timeout:
handleKeyswitchEvent(key, last_tap_dance_row_, last_tap_dance_col_, IS_PRESSED | INJECTED); handleKeyswitchEvent(key, last_tap_dance_addr_, IS_PRESSED | INJECTED);
break; break;
case Hold: case Hold:
handleKeyswitchEvent(key, last_tap_dance_row_, last_tap_dance_col_, IS_PRESSED | WAS_PRESSED | INJECTED); handleKeyswitchEvent(key, last_tap_dance_addr_, IS_PRESSED | WAS_PRESSED | INJECTED);
break; break;
case Release: case Release:
hid::sendKeyboardReport(); hid::sendKeyboardReport();
handleKeyswitchEvent(key, last_tap_dance_row_, last_tap_dance_col_, WAS_PRESSED | INJECTED); handleKeyswitchEvent(key, last_tap_dance_addr_, WAS_PRESSED | INJECTED);
break; break;
} }
} }
// --- hooks --- // --- hooks ---
EventHandlerResult TapDance::onKeyswitchEvent(Key &mapped_key, byte row, byte col, uint8_t keyState) { EventHandlerResult TapDance::onKeyswitchEvent(Key &mapped_key, KeyAddr key_addr, uint8_t keyState) {
if (keyState & INJECTED) if (keyState & INJECTED)
return EventHandlerResult::OK; return EventHandlerResult::OK;
@ -117,10 +116,10 @@ EventHandlerResult TapDance::onKeyswitchEvent(Key &mapped_key, byte row, byte co
return EventHandlerResult::OK; return EventHandlerResult::OK;
if (keyToggledOn(keyState)) if (keyToggledOn(keyState))
interrupt(row, col); interrupt(key_addr);
if (KeyboardHardware.isKeyMasked(row, col)) { if (KeyboardHardware.isKeyMasked(key_addr)) {
KeyboardHardware.unMaskKey(row, col); KeyboardHardware.unMaskKey(key_addr);
return EventHandlerResult::EVENT_CONSUMED; return EventHandlerResult::EVENT_CONSUMED;
} }
return EventHandlerResult::OK; return EventHandlerResult::OK;
@ -142,8 +141,7 @@ EventHandlerResult TapDance::onKeyswitchEvent(Key &mapped_key, byte row, byte co
} }
last_tap_dance_key_.raw = mapped_key.raw; last_tap_dance_key_.raw = mapped_key.raw;
last_tap_dance_row_ = row; last_tap_dance_addr_ = key_addr;
last_tap_dance_col_ = col;
tap(); tap();
@ -158,7 +156,7 @@ EventHandlerResult TapDance::onKeyswitchEvent(Key &mapped_key, byte row, byte co
return EventHandlerResult::EVENT_CONSUMED; return EventHandlerResult::EVENT_CONSUMED;
} }
interrupt(row, col); interrupt(key_addr);
} }
} }
@ -169,8 +167,7 @@ EventHandlerResult TapDance::onKeyswitchEvent(Key &mapped_key, byte row, byte co
} }
last_tap_dance_key_.raw = mapped_key.raw; last_tap_dance_key_.raw = mapped_key.raw;
last_tap_dance_row_ = row; last_tap_dance_addr_ = key_addr;
last_tap_dance_col_ = col;
state_[tap_dance_index].pressed = true; state_[tap_dance_index].pressed = true;
if (keyToggledOn(keyState)) { if (keyToggledOn(keyState)) {
@ -179,7 +176,7 @@ EventHandlerResult TapDance::onKeyswitchEvent(Key &mapped_key, byte row, byte co
} }
if (state_[tap_dance_index].triggered) if (state_[tap_dance_index].triggered)
tapDanceAction(tap_dance_index, row, col, state_[tap_dance_index].count, Hold); tapDanceAction(tap_dance_index, key_addr, state_[tap_dance_index].count, Hold);
return EventHandlerResult::EVENT_CONSUMED; return EventHandlerResult::EVENT_CONSUMED;
} }
@ -189,7 +186,7 @@ EventHandlerResult TapDance::afterEachCycle() {
if (!state_[i].release_next) if (!state_[i].release_next)
continue; continue;
tapDanceAction(i, last_tap_dance_row_, last_tap_dance_col_, state_[i].count, Release); tapDanceAction(i, last_tap_dance_addr_, state_[i].count, Release);
state_[i].count = 0; state_[i].count = 0;
state_[i].release_next = false; state_[i].release_next = false;
} }
@ -210,4 +207,10 @@ __attribute__((weak)) void tapDanceAction(uint8_t tap_dance_index, byte row, byt
kaleidoscope::plugin::TapDance::ActionType tap_dance_action) { kaleidoscope::plugin::TapDance::ActionType tap_dance_action) {
} }
// Let the future version be the wrapper to enable backward compatibility.
__attribute__((weak)) void tapDanceAction(uint8_t tap_dance_index, KeyAddr key_addr, uint8_t tap_count,
kaleidoscope::plugin::TapDance::ActionType tap_dance_action) {
tapDanceAction(tap_dance_index, key_addr.row(), key_addr.col(), tap_count, tap_dance_action);
}
kaleidoscope::plugin::TapDance TapDance; kaleidoscope::plugin::TapDance TapDance;

@ -46,7 +46,7 @@ class TapDance : public kaleidoscope::Plugin {
void actionKeys(uint8_t tap_count, ActionType tap_dance_action, uint8_t max_keys, const Key tap_keys[]); void actionKeys(uint8_t tap_count, ActionType tap_dance_action, uint8_t max_keys, const Key tap_keys[]);
EventHandlerResult onKeyswitchEvent(Key &mapped_key, byte row, byte col, uint8_t keyState); EventHandlerResult onKeyswitchEvent(Key &mapped_key, KeyAddr key_addr, uint8_t keyState);
EventHandlerResult afterEachCycle(); EventHandlerResult afterEachCycle();
private: private:
@ -61,11 +61,10 @@ class TapDance : public kaleidoscope::Plugin {
static uint16_t start_time_; static uint16_t start_time_;
static Key last_tap_dance_key_; static Key last_tap_dance_key_;
static byte last_tap_dance_row_; static KeyAddr last_tap_dance_addr_;
static byte last_tap_dance_col_;
static void tap(void); static void tap(void);
static void interrupt(byte row, byte col); static void interrupt(KeyAddr key_addr);
static void timeout(void); static void timeout(void);
static void release(uint8_t tap_dance_index); static void release(uint8_t tap_dance_index);
}; };
@ -73,6 +72,14 @@ class TapDance : public kaleidoscope::Plugin {
} }
void tapDanceAction(uint8_t tap_dance_index, KeyAddr key_addr, uint8_t tap_count,
kaleidoscope::plugin::TapDance::ActionType tap_dance_action);
// The old version of te tapdance action is DEPRECATED(ROW_COL_FUNC) although this
// cannot be flagged to the user. The weak function is called by the tap dance
// plugin's implementation. That's why the deprecation warning would always
// fire.
//
void tapDanceAction(uint8_t tap_dance_index, byte row, byte col, uint8_t tap_count, void tapDanceAction(uint8_t tap_dance_index, byte row, byte col, uint8_t tap_count,
kaleidoscope::plugin::TapDance::ActionType tap_dance_action); kaleidoscope::plugin::TapDance::ActionType tap_dance_action);

@ -25,7 +25,7 @@ uint8_t TopsyTurvy::last_pressed_position_;
bool TopsyTurvy::is_shifted_; bool TopsyTurvy::is_shifted_;
bool TopsyTurvy::is_active_; bool TopsyTurvy::is_active_;
EventHandlerResult TopsyTurvy::onKeyswitchEvent(Key &mapped_key, byte row, byte col, uint8_t key_state) { EventHandlerResult TopsyTurvy::onKeyswitchEvent(Key &mapped_key, KeyAddr key_addr, uint8_t key_state) {
if (mapped_key == Key_LeftShift || if (mapped_key == Key_LeftShift ||
mapped_key == Key_RightShift) { mapped_key == Key_RightShift) {
@ -36,7 +36,7 @@ EventHandlerResult TopsyTurvy::onKeyswitchEvent(Key &mapped_key, byte row, byte
if (mapped_key < ranges::TT_FIRST || mapped_key > ranges::TT_LAST) { if (mapped_key < ranges::TT_FIRST || mapped_key > ranges::TT_LAST) {
if (keyToggledOn(key_state) && (mapped_key < Key_LeftControl || mapped_key > Key_RightGui)) { if (keyToggledOn(key_state) && (mapped_key < Key_LeftControl || mapped_key > Key_RightGui)) {
last_pressed_position_ = row * COLS + col; last_pressed_position_ = key_addr.toInt();
} }
return EventHandlerResult::OK; return EventHandlerResult::OK;
@ -45,9 +45,9 @@ EventHandlerResult TopsyTurvy::onKeyswitchEvent(Key &mapped_key, byte row, byte
is_active_ = keyIsPressed(key_state); is_active_ = keyIsPressed(key_state);
if (keyToggledOn(key_state)) { if (keyToggledOn(key_state)) {
last_pressed_position_ = row * COLS + col; last_pressed_position_ = key_addr.toInt();
} else { } else {
if (last_pressed_position_ != row * COLS + col) { if (last_pressed_position_ != key_addr.toInt()) {
return EventHandlerResult::EVENT_CONSUMED; return EventHandlerResult::EVENT_CONSUMED;
} }
} }

@ -29,7 +29,7 @@ class TopsyTurvy: public kaleidoscope::Plugin {
public: public:
TopsyTurvy(void) {} TopsyTurvy(void) {}
EventHandlerResult onKeyswitchEvent(Key &mapped_key, byte row, byte col, uint8_t key_state); EventHandlerResult onKeyswitchEvent(Key &mapped_key, KeyAddr key_addr, uint8_t key_state);
private: private:
static uint8_t last_pressed_position_; static uint8_t last_pressed_position_;

@ -27,13 +27,12 @@ TriColor::TriColor(cRGB base_color, cRGB mod_color, cRGB esc_color) {
} }
void TriColor::TransientLEDMode::update(void) { void TriColor::TransientLEDMode::update(void) {
for (uint8_t r = 0; r < ROWS; r++) { for (auto key_addr : KeyAddr::all()) {
for (uint8_t c = 0; c < COLS; c++) { Key k = Layer.lookup(key_addr);
Key k = Layer.lookup(r, c);
// Special keys are always mod_color // Special keys are always mod_color
if (k.flags != 0) { if (k.flags != 0) {
::LEDControl.setCrgbAt(r, c, parent_->mod_color_); ::LEDControl.setCrgbAt(KeyAddr(key_addr), parent_->mod_color_);
continue; continue;
} }
@ -53,8 +52,7 @@ void TriColor::TransientLEDMode::update(void) {
break; break;
} }
::LEDControl.setCrgbAt(r, c, color); ::LEDControl.setCrgbAt(KeyAddr(key_addr), color);
}
} }
} }

@ -38,7 +38,7 @@ uint16_t TypingBreaks::left_hand_keys_;
uint16_t TypingBreaks::right_hand_keys_; uint16_t TypingBreaks::right_hand_keys_;
uint16_t TypingBreaks::settings_base_; uint16_t TypingBreaks::settings_base_;
EventHandlerResult TypingBreaks::onKeyswitchEvent(Key &mapped_key, byte row, byte col, uint8_t key_state) { EventHandlerResult TypingBreaks::onKeyswitchEvent(Key &mapped_key, KeyAddr key_addr, uint8_t key_state) {
uint32_t lock_length = settings.lock_length * 1000; uint32_t lock_length = settings.lock_length * 1000;
uint32_t idle_time_limit = settings.idle_time_limit * 1000; uint32_t idle_time_limit = settings.idle_time_limit * 1000;
uint32_t lock_time_out = settings.lock_time_out * 1000; uint32_t lock_time_out = settings.lock_time_out * 1000;
@ -91,7 +91,7 @@ EventHandlerResult TypingBreaks::onKeyswitchEvent(Key &mapped_key, byte row, byt
// counters if need be. // counters if need be.
if (keyToggledOn(key_state)) { if (keyToggledOn(key_state)) {
if (col <= COLS / 2) if (key_addr.col() <= COLS / 2)
left_hand_keys_++; left_hand_keys_++;
else else
right_hand_keys_++; right_hand_keys_++;

@ -36,7 +36,7 @@ class TypingBreaks : public kaleidoscope::Plugin {
static settings_t settings; static settings_t settings;
EventHandlerResult onKeyswitchEvent(Key &mapped_key, byte row, byte col, uint8_t key_state); EventHandlerResult onKeyswitchEvent(Key &mapped_key, KeyAddr key_addr, uint8_t key_state);
EventHandlerResult onFocusEvent(const char *command); EventHandlerResult onFocusEvent(const char *command);
EventHandlerResult onSetup(); EventHandlerResult onSetup();

Some files were not shown because too many files have changed in this diff Show More

Loading…
Cancel
Save