This standardizes namespace closing brackets for namespace blocks. Each one is
on its own line, with a comment clearly marking which namespace it closes.
Consecutive lines closing namespace blocks have no whitespace between them, but
there is one blank line before and after a set of namespace block closing lines.
To generate the namespace comments, I used clang-format, with
`FixNamespaceComments: true`. But since clang-format can't exactly duplicate
our astyle formatting, it made lots of other changes, too. To isolate the
namespace comments from the other formatting changes, I first ran clang-format
with `FixNamespaceComments: false`, committed those changes, then ran it again
to generate the namespace comments. Then I stashed the namespace comments,
reset `HEAD` to remove the other changes, applied the stashed namespace
comments, and committed the results (after examining them and making a few minor
adjustments by hand).
Signed-off-by: Michael Richters <gedankenexperimenter@gmail.com>
I ran `include-what-you-use` wherever possible, and made a number of manual
changes required to get things working with the new header organization.
Signed-off-by: Michael Richters <gedankenexperimenter@gmail.com>
This removes the pre-`KeyEvent` handler hooks for `onKeyswitchEvent()` and
`beforeReportingState()`. Any third-party plugins that still use either should
be updated to use the new handlers instead.
Signed-off-by: Michael Richters <gedankenexperimenter@gmail.com>
This removes the `key_events.*` files that once contained the main
`handleKeyswitchEvent()` function, and all references to it. Because
`key_events.h` was included in the main `Kaleidoscope.h` header file,
`key_defs.h` and `keyswitch_state.h` were added to that header so that other
code that relies on those things being included via `Kaleidoscope.h` will
continue to work.
Signed-off-by: Michael Richters <gedankenexperimenter@gmail.com>
This function was mainly intended for internal use by Kaleidoscope's event
handling functions. The logic that it used to provide is now handled by
`Runtime.handleKeyEvent()`, and it is not generally necessary or recommended for
plugin or sketch code to directly modify HID reports any longer.
Signed-off-by: Michael Richters <gedankenexperimenter@gmail.com>
This removes several vestigial functions from the `Layer` class:
- `.handleKeymapKeyswitchEvent()` & `.eventHandler()`, which have been replaced
with the `.handleLayerKeyEvent()` function that operates on `KeyEvent` objects.
- `.lookup()`, which has been replaced by either `Runtime.lookupKey()` or
`Layer.lookupOnActiveLayer()`, depending on the specific purpose.
- `.updateLiveCompositeKeymap()`, which referred to a structure that has been
replaced. `live_keys.activate()` serves a similar purpose, but in most cases
shouldn't be called directly by user code.
Signed-off-by: Michael Richters <gedankenexperimenter@gmail.com>
We do not need to redefine `new` on STM32, as it is included in the standard
library, and defining it ourselves would lead to linking errors.
Signed-off-by: Gergely Nagy <algernon@keyboard.io>
The new version of the layer change `Key` handler is more consistent with the
other `KeyEvent` handling functions, and properly checks for a second layer
shift key being held when releasing the first one.
Signed-off-by: Michael Richters <gedankenexperimenter@gmail.com>
This replaces the `Layer.live_composite_keymap_[]` cache with a representation
of the keyboard's current state as an array of `Key` objects, one per key on the
keyboard. In this new array, an idle key will have the value `Key_Transparent`,
and a pressed key will have the value of whatever key it's currently mapped to
in the keymap (or whatever value the active set of plugins has assigned to
it). A value of `Key_NoKey` will mask that key until it is released.
If a plugin returns `ABORT` from its `onKeyswitchEvent()` handler, that means
that the keymap cache should not be updated. It's especially important to have
this occur after plugins like OneShot and Qukeys, where the key can stay
active (or become active) after the physical keyswitch has been released.
Signed-off-by: Michael Richters <gedankenexperimenter@gmail.com>
Instead of only aborting hook functions if a handler returns `EVENT_CONSUMED`,
only continue abortable hooks if a handler returns `OK`. For existing core
plugins, this shouldn't make any difference because none of them use the `ERROR`
return value.
Also rename `shouldAbortOnConsumedEvent` to better match the new conditional.
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>
Within some of the internal headers, we do not have a complete declaration of
some namespaces, and that's ok. Most of these cases are within macros anyway.
Since there's no sane way to make cpplint happy otherwise, lets ignore these
warnings instead.
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>
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>
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>
By means of this macro, headers can check if they are compiled
in the sketch compilation unit or in any other compilation unit.
Signed-off-by: Florian Fleissner <florian.fleissner@inpartik.de>
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>
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 two files kaleidoscope_internal/sketch_preprocessing/sketch_header.h
and kaleidoscope_internal/sketch_preprocessing/sketch_footer.h
are automatically pasted at the top and bottom of the
preprocessed sketch.
Signed-off-by: Florian Fleissner <florian.fleissner@inpartik.de>
Sketch exploration choked on the rare case that an empty keymap
was supplied with `KEYMAP()`.
Signed-off-by: Florian Fleissner <florian.fleissner@inpartik.de>
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 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>
Unions are a C-reminiscense that are better avoided in modern C++.
They cause specific problems due to their nature of representing
independent types. The way they are used in Kaleidoscope, they
can easily be replaced by a class.
This enables it to properly work with Key objects in constexpr context
where with the old union-based implementation the compiler reported
errors when one Key was constructed based on a key_code/flags pair and
another one through raw-data. In such a case, the compiler assumes that
both Key instances represent something entirely different. This is
because unions were never meant for type conversions and the C++
standard considers their use for that purpose as undefined behavior.
The new class provides accessor methods for raw-data access and for
key_code/flags-data access.
This is a breaking change as it is is not possible to replace direct
member access patterns like
key.raw = 0xFFFF;
based on the raw-accessors.
For the .keyCode and .flags members, proxy objects are used
to enable the generation of suitable deprecations warnings.
All direct access via .raw, .keyCode and .flags have been replaced
throughout Kaleidoscope.
Information on how to upgrade is provided in UPGRADING.md
Signed-off-by: Florian Fleissner <florian.fleissner@inpartik.de>
The new device APIs were built on top of composition (instead of inheritance,
like the former one). At the highest level, we have `kaleidoscope::device::Base`
and `kaleidoscope::device::BaseProps`. The latter is a set of overrideable
properties, components that make up the device: the key scanner, LEDs, MCU, and
so on.
Many components - like the key scanner and LEDs - also come in a similar setup:
the base class and properties, because this allows us to make them fairly
efficient templates.
All of the existing devices have been ported to the new APIs. While the old
`Hardware` base class remains - for now, and deprecated - it is not guaranteed
to work.
Signed-off-by: Gergely Nagy <algernon@keyboard.io>
Instead of having to define `HARDWARE_IMPLEMENTATION` to the class name of the
device, and define `KeyboardHardware` from within the plugin, let all devices
set `kaleidoscope::Device` to their own class via a typedef. Furthermore,
instead of `KeyboardHardware`, use `Kaleidoscope.device()` instead. This makes
device plugins a little bit simpler, and our naming more consistent.
Because some parts of the firmware need to access the device object before the
`Kaleidoscope` object is available, we can't make it a member of that. For this
reason, the device object is `kaleidoscope_internal::device`, and
`Kaleidoscope.device()` wraps it. In general, the wrapper should be used. But if
access to the device is required before `Kaleidoscope` is available, then that's
also available.
The `Kaleidoscope` object grew a few more wrappers: `storage()` and
`serialPort()`, so that one doesn't need to use `Kaleidoscope.device()`
directly, but can use the wrappers, which are noticably shorter to write.
Signed-off-by: Gergely Nagy <algernon@keyboard.io>