When starting up, we correctly set the active layer counter to one, and the
active layer stack will therefore correctly contain layer 0 as an active layer.
However, we weren't setting the `layer_state_` bitmap up properly, and as such,
`Layer.isActive(0)` was returning false, despite the layer being active as far
as lookups were concerned.
To fix this, we explicitly flip the 0th bit on in the newly introduced
`Layer.setup()` method, where the initial keymap cache update was moved to, too.
Fixes#951.
Signed-off-by: Gergely Nagy <algernon@keyboard.io>
When rollover occurs from a non-modifier key to a qukey, if we delay the release
event of that key until after the qukey's state is resolved, and if the hold
timeout is set to a fairly large value (on the order of 500ms), unintended
repeats would occur for a key that was actually only tapped. To prevent this, if
there's only one event in the queue (the press of the qukey), and we see a
release of a non-modifier key that's not the qukey, it's okay to allow that
release event to skip the queue and simply proceed as if it had been released
before the qukey was pressed.
Signed-off-by: Michael Richters <gedankenexperimenter@gmail.com>
Previously, we used index-ordering for layers, meaning, we looked keys up based
on the index of active layers. This turned out to be confusing, and in many
cases, limiting, since we couldn't easily shift to a lower layer from a higher
one. As such, index-ordering required careful planning of one's layers, and a
deeper understanding of the system.
This patch switches us to activation-ordering: the layer subsystem now keeps
track of the order in which layers are activated, and uses that order to look
keys up, instead of the index of layers. This makes it easier to understand how
the system works, and allows us to shift to lower layers too.
It does require a bit more resources, since we can't just store a bitmap of
active layers, but need 32 bytes to store the order. We still keep the bitmap,
to make `Layer.isActive()` fast: looking up a bit in the bitmap is more
efficient than walking the active layer array, and this function is often used
in cases where speed matters.
As a side effect of the switch, a number of methods were deprecated, and similar
ones with more appropriate names were introduced. See the updated `UPGRADING.md`
document for more details.
Plugins that used the deprecated methods were updated to use the new ones.
Fixes#857.
Signed-off-by: Gergely Nagy <algernon@keyboard.io>
This change makes Qukeys require a certain minimum amount of time for a
key to be held before it is eligible to get its alternate (i.e. modifier)
value. This should help faster typists avoid unintended modifiers in the
output.
Signed-off-by: Michael Richters <gedankenexperimenter@gmail.com>
Two new functions have been introduced in namespace kaleidoscope.
One to conveniently add keyflags to an existing Key variable and
another one that can be overloaded to convert other types to type Key.
The keymap definition macros and the modifier function macro (LCTRL,
LALT, ...) are now using the to-Key conversion functions. This
allows users to use alternative ways to define keymaps by
defining types of their own that automatically convert to type Key.
Signed-off-by: Florian Fleissner <florian.fleissner@inpartik.de>
This refactors the KEYMAPS(...) macro and factors out
a header and footer portion that are now define as individual
macros START_KEYMAPS and END_KEYMAPS. The original
KEYMAPS(...) macro now relies on the newly defined macros.
The newly introduced macros enable keymap definitions that
allow for macro definitions between the start and end part
which is not possible inside the KEYMAPS(...) macro invocation.
Signed-off-by: Florian Fleissner <florian.fleissner@inpartik.de>
There were a few minor problems in the way Consumer `Key` objects were
constructed (using `CONSUMER_KEY()`). First, no masking of the high
bits was being done, so it was possible to create a "Consumer" key
with the `RESERVED` bit set (e.g. `Key_Transparent`), or the
`SWITCH_TO_KEYMAP` bit (in fact, any `Key` value with both the
`SYNTHETIC` and `IS_CONSUMER` bits set was possible).
This change fixes these potential problems by setting the six bits
taht could conflict to zero. When we need to have special behavior
based on those bits, this can change.
There were a few minor problems in the way Consumer `Key` objects were
constructed (using `CONSUMER_KEY()`). First, no masking of the high
bits was being done, so it was possible to create a "Consumer" key
with the `RESERVED` bit set (e.g. `Key_Transparent`), or the
`SWITCH_TO_KEYMAP` bit (in fact, any `Key` value with both the
`SYNTHETIC` and `IS_CONSUMER` bits set was possible).
Second, the high six bits of the raw `Key` value should always be
`010010` (`SYNTHETIC | IS_CONSUMER`), as Consumer keys don't have any
flags. The macro should really only take one argument: a 16-bit
integer keycode value. The `HID_TYPE_*` constants really shouldn't be
used at all in defining the keys in key_defs_consumer.h, because
setting those bits could potentially cause a key to be misidentified
by some plugin.
This change fixes these potential problems by ignoring the `flags`
parameter, masking the high six bits of the `code` supplied, and
setting those high six bits to the correct value.
For some of our single-parameter constructors, we _want_ to have implicit
conversions, because that makes the code more readable. Mark these up for
cpplint to ignore.
Signed-off-by: Gergely Nagy <algernon@keyboard.io>
In both cases, the warning is about a function argument that we do not use.
There's no benefit of doing a c++-style cast there, especially since they're
function arguments. In fact, doing anything else would just make the code less
readable. As such, we opt to ignore these warnings instead.
Signed-off-by: Gergely Nagy <algernon@keyboard.io>
Since there's only two places where we use the `kaleidoscope::ranges` namespace,
and it's easy to use `ranges::` there, instead of the bare enum, lets do that,
and make cpplint happier.
Signed-off-by: Gergely Nagy <algernon@keyboard.io>
All of these places use a template argument (usually indirectly) for array
sizes, so they are _not_ variable sized. It just so happens that cpplint is
unable to figure that out on its own. For this reason, mark them explicitly, and
let cpplint ignore these false positives.
Signed-off-by: Gergely Nagy <algernon@keyboard.io>
While `using namespace` certainly has its downsides, in these cases, the scope
is local to a single file, and makes the code _much_ more readable, offsetting
any downsides the directive otherwise has. As such, lets tell cpplint to ignore
these.
Signed-off-by: Gergely Nagy <algernon@keyboard.io>
We do not need `getShortName()` anymore: setting the shortname is now done via
device properties instead. Doing it with `getShortName` only results in
duplicated symbols.
Signed-off-by: Gergely Nagy <algernon@keyboard.io>
Previously, rolling over from one System Control key to another would
cause the second one to be released as soon as the first one was
released, because the empty release report would be sent
unconditionally on release of any System Control key.
This change stores the value of the last System Control key
pressed. When a System Control key is released, it first checks to see
that the released key's keycode matches the last one pressed before
sending the empty report.
Signed-off-by: Michael Richters <gedankenexperimenter@gmail.com>
Since the PR was made for the ButterStick and FaunchPad, ATMega32U4Keyboard has
had a breaking API update. Follow up on that now.
Signed-off-by: Gergely Nagy <algernon@keyboard.io>
Key masking was a bandaid, and we have better ways to achieve the same thing
now. All current users have been switched over to different methods now, so lets
deprecate the masking.
We only put the `DEPRECATED` label on the `maskKey` method, because the rest are
used internally too, and we do not want to emit warnings for those.
Fixes#884.
Signed-off-by: Gergely Nagy <algernon@keyboard.io>
We want to remove the use of key masking, so instead of masking the key when
escaping a OneShot, map it to `NoKey` instead, and continue doing so until
released. Which is effectively what masking did, but localized and simpler.
Doing this will make our cache have `NoKey` for the key until release, and we'll
avoid sending unintended Escape keycodes, without having to use the global
masking functions.
Signed-off-by: Gergely Nagy <algernon@keyboard.io>
We introduced the masking to avoid sending extra keys when the mapped key
changes prior to release - but since the introduction of the caching mechanism,
we no longer need to do this.
However, for the caching to work the way we want it to, we need to map the key
to `NoKey` once, upon interrupting.
Signed-off-by: Gergely Nagy <algernon@keyboard.io>
squash! TapDance: Do not mask interrupting keys anymore
Signed-off-by: Gergely Nagy <algernon@keyboard.io>
To make their purpose clearer, rearrange our state: we now have the row-based
array on the top level, instead of every member being an array on its own. The
name of the state variable was changed to `matrix_state_`, to reflect its
purpose. This also allowed us to have its members be named `current`,
`previous`, `debouncer` and `masks`.
All devices using these APIs, and the documentation were updated accordingly.
Signed-off-by: Gergely Nagy <algernon@keyboard.io>
We want `readCols` as a separate function, so we can tell the compiler to apply
different optimizations to it.
Signed-off-by: Gergely Nagy <algernon@keyboard.io>
This is a typedef that defines what type we need to use for storing row states.
Defaults to uint16_t. For boards with 8 columns or less, we can use `uint8_t`,
but the default is 16 bits.
Signed-off-by: Gergely Nagy <algernon@keyboard.io>
This makes it easier to initialize them in the cpp (shorter too!), and reduces
code size as well. It's also a bit simpler to understand the initialization
part, because it's no different from the props init.
Signed-off-by: Gergely Nagy <algernon@keyboard.io>
Due to the introduction of MCU properties recently, we need to declare the class
for virtual builds, and can't get away with simply typedefing it to Base.
Signed-off-by: Gergely Nagy <algernon@keyboard.io>
When using the A* pinouts, the bootloader should - by default - be Caterina, not
HalfKay, which should only be used for the legacy Teensy2 pinout.
Signed-off-by: Gergely Nagy <algernon@keyboard.io>
This drops the now unused `ATMEGA32U4_KEYBOARD`, `ATMEGA32U4_DEVICE_PROPS`,
`ATMEGA_KEYSCANNER_PROPS`, `ATMEGA32U4_DEVICE`, `ATMEGA_KEYSCANNER_PROPS`, and
`ATMEGA_KEYSCANNER_BOILERPLATE` macros.
These were macros that made the code less verbose, but none of them were
future-proof, and all of them were pretty opaque. Using them did not help one to
understand the code.
All use of these have been changed to use the raw structures as-is, which is
more verbose, but much more extensible, and a whole lot clearer in intent
aswell.
Since these are not particularly user facing macros, I opted not to include them
in `UPGRADING.md`, and removed them without prior deprecation.
Signed-off-by: Gergely Nagy <algernon@keyboard.io>
Instead of using opaque macros which aren't even extensible, just expand them,
and use the raw data structures for the hardware definition. While this is more
verbose than the macros, it is more future proof, and clearer for the reader
too, because they don't need to understand the magic macros.
Signed-off-by: Gergely Nagy <algernon@keyboard.io>
Instead of using opaque macros which aren't even extensible, just expand them,
and use the raw data structures for the hardware definition. While this is more
verbose than the macros, it is more future proof, and clearer for the reader
too, because they don't need to understand the magic macros.
Signed-off-by: Gergely Nagy <algernon@keyboard.io>
Instead of using opaque macros which aren't even extensible, just expand them,
and use the raw data structures for the hardware definition. While this is more
verbose than the macros, it is more future proof, and clearer for the reader
too, because they don't need to understand the magic macros.
Signed-off-by: Gergely Nagy <algernon@keyboard.io>
Instead of using opaque macros which aren't even extensible, just expand them,
and use the raw data structures for the hardware definition. While this is more
verbose than the macros, it is more future proof, and clearer for the reader
too, because they don't need to understand the magic macros.
Signed-off-by: Gergely Nagy <algernon@keyboard.io>
Instead of using opaque macros which aren't even extensible, just expand them,
and use the raw data structures for the hardware definition. While this is more
verbose than the macros, it is more future proof, and clearer for the reader
too, because they don't need to understand the magic macros.
Signed-off-by: Gergely Nagy <algernon@keyboard.io>
While the code became shorter with the previous commit, it did not become much
easier to understand and follow. Some of the choices made weren't self
explanatory. For that reason, lets put comments around the relevant parts, that
explain why we've done it that way.
Signed-off-by: Gergely Nagy <algernon@keyboard.io>
The `kaleidoscope::Device` aliases are there for use-cases that need to be
device agnostic, we do not need to use them in the hardware plugin itself,
because that plugin _is_ very much tied to the device. We can just use the
device specific original names.
To make things shorter, we can also set up a pair of aliases for
`KeyScannerProps` and `KeyScanner`, to make the declarations even shorter.
Signed-off-by: Gergely Nagy <algernon@keyboard.io>
With this, it is possible to set the time (in milliseconds) between scans. The
aim is to make it possible to change this setting in one's `setup()` in their
own sketch.
One can do that as follows:
`Kaleidoscope.device().keyscanner().setScanCycleTime(2000);`
This is currently only implemented for the ATmega keyscanner.
Signed-off-by: Gergely Nagy <algernon@keyboard.io>
We use 100kHZ for flashing, because that's more reliable. Use the same for
normal operation, for similar reasons. This appears to fix a frequent crash
issue.
Signed-off-by: Gergely Nagy <algernon@keyboard.io>
If LEDControl is used without any LEDMode plugin, `cur_led_mode_` is
an unitialized pointer. This initializes it to `nullptr` and guards
against accessing it.
Signed-off-by: Johannes Becker <alfalfasprossen@gmail.com>
This has been deprecated in March, 2019, has been a no-op since. While no
removal schedule was posted at the time, I believe it is safe to drop it now.
Signed-off-by: Gergely Nagy <algernon@keyboard.io>
Originally scheduled for removal by mid-March. This also removes the similarly
deprecated named hardware object aliases.
Signed-off-by: Gergely Nagy <algernon@keyboard.io>
Handling of the respective keys is moved to `beforeReportingState`
as the state of shift is only then available. Usage together with
OneShot requires OneShot to be initialized before LEDControl.
Signed-off-by: Johannes Becker <alfalfasprossen@gmail.com>
This introduces MCU properties, so that MCU drivers can change their behaviour
and/or setup tasks based on them, without having to write a `setup()` method or
a custom constructor for the top-level device.
In practice, this allows us to tell the MCU driver to - for example - disable
JTAG or clock division during setup, and thus, we won't need to do that in code
in the device constructor.
This is a breaking change, kind of, because the `mcu::Base` and
`mcu::ATmega32U4` drivers changed APIs. However, no device was using those
directly, only via `ATmega32U4Keyboard`, and those parts remain compatible.
While there, updated the `KBD4x` and `Splitography` devices to use the new
properties instead of a custom constructor.
Signed-off-by: Gergely Nagy <algernon@keyboard.io>
This reverts commit c917acb8a1, because that
introduced breaking changes, and we want to address the problem in a different
way instead.
Signed-off-by: Gergely Nagy <algernon@keyboard.io>
This introduces a new plugin - `FlashHelper` - to aid with firmware-assisted
flashing. During the flashing process, this plugin can temporarily disable the
`Prog` key.
Addresses the firmware part of keyboardio/Chrysalis#509.
Signed-off-by: Gergely Nagy <algernon@keyboard.io>
In ConsumerControlWrapper, accept a 10-bit value for the keycode.
Use uint16_t since that is the type KeyboardioHID uses.
Signed-off-by: Chris White <cxwembedded@gmail.com>
It seems the red component in the LEDs is a tiny bit stronger than the others,
so lets adjust the component's value a little on the firmware side to make
colors come out right.
This is not the best solution, it should eventually be configurable, but until
then, this is the best workaround we could come up with.
Signed-off-by: Gergely Nagy <algernon@keyboard.io>
Instead of scanning during the interrupt, do so in the main context, and only
use the interrupt for signaling that we need to scan. This resolves a problem
where scanning took too long, and we ended up missing events.
Fixes#812.
Signed-off-by: Gergely Nagy <algernon@keyboard.io>
While `ShiftToLayer` and `LockLayer` activate the given layer, and keep all
others active as well, `MoveToLayer` activates the given layer, and deactivates
all others. This allows one to have discrete layers that stand on their own,
without any other layers interfering.
Basically, this is a different way to work with layers, a less powerful, but
also simpler one.
Fixes#564.
Signed-off-by: Gergely Nagy <algernon@keyboard.io>
`Layer.move()` relied on `activate()` to update the caches, but `activate()`
worked under the assumption that we also `deactivate()` layers - which we did
not in `move()`, as we directly modified the state. Since we directly modify the
state, we can't rely on `activate()` either, and have to update the caches
ourselves.
Unlike `activate()`, we do this unconditionally, because there isn't a case
where we do not want to update them.
This makes `MoveToLayer()` play well with `Colormap`, and any other plugin that
rely on cached layer information, such as the topmost active layer.
Signed-off-by: Gergely Nagy <algernon@keyboard.io>
This reverts commit 47c1e23fed, because changing
the order in the struct just made things worse. Looks like they _do_ need to be
RGB, but the CRGB macro still puts them in BGR order. This is consistent with
the Raise factory firmware, so lets stick with that.
Signed-off-by: Gergely Nagy <algernon@keyboard.io>
The new plugin exposes some layer control functions over Focus, to be able to
control layers from the host side.
Fixes#780.
Signed-off-by: Gergely Nagy <algernon@keyboard.io>
When setting the idle timeout to zero, stop checking for idleness, and never
turn the LEDs off. Setting the timeout to a higher value again will resume the
plugin's functionality.
Signed-off-by: Gergely Nagy <algernon@keyboard.io>
When handling the `led.brightness` command, we forgot to break out of the switch
statement, thus executing the `setall` branch too. This resulted in very slow
operations, because we had to wait for a read to timeout.
Adding a break fixes all that.
Signed-off-by: Gergely Nagy <algernon@keyboard.io>
This changes the IdleLEDs plugin to only re-enable LEDs if they were disabled
due to idleness. If they were turned off any other way, the plugin will not
re-enable them. This makes it play better with the `Key_LEDToggle` key.
Fixes#790.
Signed-off-by: Gergely Nagy <algernon@keyboard.io>
The new `.setBrightness()` and `.getBrightness()` methods control the brightness
of the LEDs, by dispatching them to the LED drivers. We dispatch to the drivers
so that nothing else needs to be aware of brightness control. Plugins will
always set the unadjusted colors, and anything and anyone who reads colors, will
also get the unadjusted values.
Pushing the adjustment down to the driver level makes everything smooth, and
since we do gamma correction there anyway, it makes sense to do brightness
adjustment at the same place, too.
Fixes#775.
Signed-off-by: Gergely Nagy <algernon@keyboard.io>
The (internal) `::dygma::raise::Hand` class had two methods that weren't used by
Kaleidoscope at all: `.setAllLEDsTo` and `.setOneLEDTo`. Since they're unused,
remove them.
We weren't going to use them anyway, because they immediately sync to the LED
driver, while we want to do that in `syncLeds()`, and in there only.
Signed-off-by: Gergely Nagy <algernon@keyboard.io>
This adds `LEDControl.disable()` and `LEDControl.enable()` which disable and
enable LED operations, respectively. These are meant to replace the current
`LEDControl.paused` property (which is getting deprecated with this change), and
do some additional work on top of just disabling or re-enabling future updates
and sync. Namely, `disable()` will also turn LEDs off, while `enable()` will
refresh them all, too.
We also add a dedicated `Key_LEDToggle` key to disable/enable LEDs. This is
useful when one wants to turn LEDs off, without changing active LED mode to
`LEDOff`.
Signed-off-by: Gergely Nagy <algernon@keyboard.io>
The USB-Quirks plugin was relying on the old HIDAdaptor APIs, including
the (undocumented) defines that enable/disable the boot keyboard. Since we no
longer have those defines, the plugin was effectively a no-op.
This updates the plugin to work with the new APIs, without the need for ifdefs.
Signed-off-by: Gergely Nagy <algernon@keyboard.io>
`RaiseKeyScanner::pressedKeyswitchCount` and `::previousPressedKeyswitchCount()`
used `__builtin_popcountl` to count the bits set in the left and right hand
states, but that only looks at 32 bits out of the 64 we have in each half. We
should be using `__builtin_popcountll` instead.
Signed-off-by: Gergely Nagy <algernon@keyboard.io>
To make it easier to configure which HID implementation - and which parts of it
- a particular board uses, we turn our current HID facade (`kaleidoscope::hid`)
into a proper, Props-supported driver. This also allows us to get rid of the
`Kaleidoscope-HIDAdaptor-KeyboardioHID` library.
Signed-off-by: Gergely Nagy <algernon@keyboard.io>
Make the Model01's `setup()` method non-static, so that we can call the parents
`setup()` method too. We want to do that so if new drivers are added, we
automatically pick those up.
Signed-off-by: Gergely Nagy <algernon@keyboard.io>
- Rewrite decay code to fade brightness smoothly with an x^4
relationship
- Fade hue linearly from orange to red rather than for a subset of
time from red to orange
Signed-off-by: Bart Nagel <bart@tremby.net>
With this change, each device can specify a short name in their device
properties, which will be used to override the HID shortname. Due to link order,
we need to do the override in the user sketch, so we hook into the `KEYMAPS`
macro, to call `_INIT_HID_GETSHORTNAME`, which will set the override up for us.
The short name defaults to "kaleidoscope".
Together with keyboardio/KeyboardioHID#61, fixeskeyboardio/KeyboardioHID#54.
Signed-off-by: Gergely Nagy <algernon@keyboard.io>
The build now fails if the avr-gcc version is too old.
A verbose error message reports Arduino upgrade information.
Signed-off-by: Florian Fleissner <florian.fleissner@inpartik.de>
To be able to compile a firmware for the Raise, we need to include the HID
facade, and the base keyscanner implementation from the Raise device plugin.
Signed-off-by: Gergely Nagy <algernon@keyboard.io>
This was done to enable separate inclusion of the central runtime
class without having to include the central header
kaleidoscope/Kaleidoscope.h which used to pull in a lot of stuff that is
not required in many compilation units.
The new class `Runtime_` lives in namespace kaleidoscope its singleton
instance is `kaleidoscope::Runtime`. It is now only available internally
in library Kaleidoscope but not from the sketch.
The original class name `Kaleidoscope_` in global scope has been deprecated.
The original instance name `Kaleidoscope` in global scope has been
preserved to be used by end users in their sketches.
Signed-off-by: Florian Fleissner <florian.fleissner@inpartik.de>
This implements an extension to the `TapDance` plugin, allowing us to store
`tapDanceActionKeys()`-esque lists in Storage. The core idea here is very
similar to that of `DynamicMacros`: we dump/restore the full list via Focus,
build a cached index on setup and any updates, and play back the selected key
when need be.
Unlike `DynamicMacros`,this plugin is built on top of `TapDance` and cannot
function without it.
Fixes#730.
Signed-off-by: Gergely Nagy <algernon@keyboard.io>
The virtual hid was recently included in the core firmware repo.
Due to missing `#ifdef KALEIDOSCOPE_VIRTUAL_BUILD` in some
files, two versions of the hid library, one for the virtual and one for
the physical device were build. The linker perferred the one that it
encountered first. That caused a link order dependency that possibly
renders some firmware builds without HID reports being send to the host.
This change adds thse missing `#ifdef KALEIDOSCOPE_VIRTUAL_BUILD`
clauses.
Signed-off-by: Florian Fleissner <florian.fleissner@inpartik.de>
This static member did not have an instance under
certain circumstances. A typical workaround for such
a situation is to make it a local static of an accessor
function. By this means the one definition rule is
not violated and the object always instanciated. It is still optimized
away by the compiler in case device::Base<...>::LEDs() is not called.
Signed-off-by: Florian Fleissner <florian.fleissner@inpartik.de>
`RaiseKeyScanner::actOnMatrixScan()` erroneously looped through all the columns
in the matrix, while we only wanted to loop through the left half, since we read
the right half at the same time, not separately. This resulted in half the keys
producing two events, due to overflow. We also calculated the key number
incorrectly.
Both of these issues are fixed with this patch.
Signed-off-by: Gergely Nagy <algernon@keyboard.io>
The submember is a bitfield that needs its own braced list.
Gcc silently tolerates this clang warns about it.
Signed-off-by: Florian Fleissner <florian.fleissner@inpartik.de>
Clang seems to have problem with recognizing that those
functions are actually static members. This change
makes it more obvious to the compiler, which functions we actually refer
to.
Signed-off-by: Florian Fleissner <florian.fleissner@inpartik.de>
This feature unfortunately relies on a non-standard feature
that is supported by gcc as an extension but triggers
errors when build with clang.
The fix is to disable the feature until we find a better solution
to allow virtual builds with clang.
Signed-off-by: Florian Fleissner <florian.fleissner@inpartik.de>
While older GCC versions accept using an unnamed struct, gcc 7+ does not. Use a
named one instead, to make both gcc versions happy.
Signed-off-by: Gergely Nagy <algernon@keyboard.io>
This implements a new device plugin, to drive the Dygma Raise. A few helpers are
also introduces, which are used by the Raise only for now, but are generic
enough so that eventually, other boards may use them too.
Signed-off-by: Gergely Nagy <algernon@keyboard.io>
This commit adds a new template hook exploreSketch() that allows plugins to efficiently
obtain compile-time known information about the sketch.
The hook is called before setup and is passed a _Sketch
template parameter that wraps two more types Plugins and StaticKeymap, whose static constexpr methods can be used
to explore the registered plugins and the static keymap.
Signed-off-by: Florian Fleissner <florian.fleissner@inpartik.de>
Hook methods can now be templated.
A template parameter type list, a list of template parameters and
a list of dummy template arguments have been added to the
macro arguments used in _FOR_EACH_EVENT_HANDLER.
Non-template hooks pass empty parenthesis for the three newly
introduced macro arguments.
Signed-off-by: Florian Fleissner <florian.fleissner@inpartik.de>
This enables compile time exploration of the keymap
from all code that is part of the sketch's compilation unit.
Signed-off-by: Florian Fleissner <florian.fleissner@inpartik.de>
The Model01.h required some reordering of header includes
and some forward defines of certain types that are
used in property classes.
Signed-off-by: Florian Fleissner <florian.fleissner@inpartik.de>
This method is now implemented in the LED driver
base class based on the LED driver properties.Removed method
Signed-off-by: Florian Fleissner <florian.fleissner@inpartik.de>
Kaleidoscope's device API defines two types to be exported
as kaleidoscope::Device and kaleidoscope::DeviceProps.
The newly introduced macro EXPORT_DEVICE can be used
to export those two type names conveniently.
The macro also serves the purpose to only export a type named
kaleidoscope::Device in non-virtual device builds. In virtual
builds, a homonymous type is exported by the virtual device header
Virtual.h.
Signed-off-by: Florian Fleissner <florian.fleissner@inpartik.de>
This is a primitive implementation of a `FlashAsStorage` (or rather,
`FlashAsEEPROM`)-based storage component. It's based on `FlashAsEEPROM`, because
I couldn't find a sane way to push the storage data variable within our template
class.
At some point, this needs to be reworked, to pull the size from Props, and not
use the EEPROM API wrappers.
Signed-off-by: Gergely Nagy <algernon@keyboard.io>
We'd like to be able to run custom code whenever the led mode changes, reliably,
without having to resort to checking the mode every cycle. For this purpose, we
introduce the `onLEDModeChange()` handler plugins can hook into. It will be
called every time `LEDControl.set_mode()` is called, even if that just sets the
mode to the currently active one.
Signed-off-by: Gergely Nagy <algernon@keyboard.io>
LED driver properties now can re-define an array
for their individual mapping from key offsets to LED indices.
This array is both constexpr (can be used at compiletime) and
stored in PROGMEM. The latter is used by the LED driver base
class to map key offsets to LED ids at runtime.
Signed-off-by: Florian Fleissner <florian.fleissner@inpartik.de>