Keys normally only change when switching layers, so instead of going through
every key in every cycle to look for modifiers, do that once, when layers
change (using the new `onLayerChange` event), and store the coordinates of keys
we consider modifiers in an array (currently limited to 16 items).
Then, when we want to highlight them, go over this array only, significantly
reducing the work we need to do. In a typical case, on a full-size keyboard, one
would have eight modifiers and a few layer keys, so instead of going through a
hundred keys, we go through sixteen at most, but usually considerably less.
This fixes#403, at the cost of noticeably higher PROGMEM and RAM use.
Signed-off-by: Gergely Nagy <algernon@keyboard.io>
Instead of tracking layer changes ourselves, use the new `onLayerChange` event
to do that for us. This makes the code a tiny bit easier to follow.
Signed-off-by: Gergely Nagy <algernon@keyboard.io>
The intent is to make it easier for plugins to detect layer changes and schedule
work accordingly. There event receives no arguments, the current state can
always be queried with `Layer.getLayerState()`, and if a plugin requires the old
state too, they can track that on their own.
Signed-off-by: Gergely Nagy <algernon@keyboard.io>
If we wish to support hardware that has LEDs, we should not define the `cRGB`
struct and the `CRGB` macro unconditionally. Define them only if the macro is
undefined. This way any hardware that has LEDs, and still wishes to use
`ATMegaKeyboard` as a base can define the macro prior to including the header.
Such hardware will override the LED functions anyway, so there's nothing else we
need to do to support such a scenario.
Signed-off-by: Gergely Nagy <algernon@keyboard.io>
We already support bootloaders that have the same vendor ID as the keyboard, but
a different product ID. We should also support bootloaders that have a different
vendor ID too.
Signed-off-by: Gergely Nagy <algernon@keyboard.io>
Sometimes we'd like to be in control of when reports are sent during macro
playback. This implements a way to achieve that.
Fixes#368.
Signed-off-by: Gergely Nagy <algernon@keyboard.io>
Instead of guarding the ATMegaKeyboard files with an `#if` that hard-coded which
keyboards are based on the class, guard them with
`KALEIDOSCOPE_WITH_ATMEGA_KEYBOARD`, set by the main hardware headers. Those
headers get included early, and are as such, a perfect way to guard these
things.
This way if we add a new keyboard using the base class, we don't have to modify
the base class itself, and the new hardware plugin can be entirely self-contained.
Signed-off-by: Gergely Nagy <algernon@keyboard.io>
Since `keyIndex` is pretty much the same for all boards, it makes sense to have
it in `key_indexes.h`. To be able to do that, we need to implement it as a
macro, otherwise `HARDWARE_IMPLEMENTATION` can't be resolved. With a macro, it
is evaluated on call-sites, where the compiler can resolve that symbol.
Signed-off-by: Gergely Nagy <algernon@keyboard.io>
Whenever calling a function implemented by the class, call it through
`KeyboardHardware`, so they can be overridden.
Signed-off-by: Gergely Nagy <algernon@keyboard.io>
Both the Atreus and the Planck ports use very similar architecture, lift out the
common parts into a base class.
Signed-off-by: Jesse Vincent <jesse@keyboard.io>
Instead of having a separate function for selecting and unselecting rows, have
only one that toggles them - we only ever want to toggle them anyway. While
there, optimize it slightly, by not toggling `DDRD`: if we set those in `setup`,
they'll remain set, and there's no need to toggle them.
This makes the code cleaner and smaller, at the cost of four bytes of RAM.
Signed-off-by: Gergely Nagy <algernon@keyboard.io>
In certain cases we need to delay the unicode input sequence, otherwise the host
is unable to process the input properly. Introduce the `.input_delay()`
setter/getter for this purpose. We're defaulting to zero (no delay) nevertheless.
Signed-off-by: Gergely Nagy <algernon@keyboard.io>