|
|
|
/* Kaleidoscope - Firmware for computer input devices
|
|
|
|
* Copyright (C) 2013-2021 Keyboard.io, Inc.
|
|
|
|
*
|
|
|
|
* 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, version 3.
|
|
|
|
*
|
|
|
|
* 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 <Arduino.h> // for PROGMEM
|
|
|
|
#include <stdint.h> // for uint8_t, int8_t
|
|
|
|
|
|
|
|
#include "kaleidoscope/KeyAddr.h" // for KeyAddr
|
|
|
|
#include "kaleidoscope/KeyEvent.h" // for KeyEvent
|
|
|
|
#include "kaleidoscope/device/device.h" // for Device
|
|
|
|
#include "kaleidoscope/key_defs.h" // for Key
|
|
|
|
#include "kaleidoscope/keymaps.h" // IWYU pragma: keep
|
|
|
|
#include "kaleidoscope/macro_helpers.h" // for __NL__
|
|
|
|
#include "kaleidoscope_internal/device.h" // for device
|
|
|
|
#include "kaleidoscope_internal/shortname.h" // for _INIT_HID_GETSH...
|
|
|
|
#include "kaleidoscope_internal/sketch_exploration/sketch_exploration.h" // for _INIT_SKETCH_EX...
|
|
|
|
|
|
|
|
// clang-format off
|
|
|
|
|
|
|
|
#define START_KEYMAPS __NL__ \
|
|
|
|
constexpr Key keymaps_linear[][kaleidoscope_internal::device.matrix_rows * kaleidoscope_internal::device.matrix_columns] PROGMEM = {
|
|
|
|
|
|
|
|
#define END_KEYMAPS __NL__ \
|
|
|
|
}; __NL__ \
|
|
|
|
uint8_t layer_count __NL__ \
|
|
|
|
= sizeof(keymaps_linear) / sizeof(*keymaps_linear); __NL__ \
|
|
|
|
__NL__ \
|
|
|
|
_INIT_SKETCH_EXPLORATION __NL__ \
|
|
|
|
_INIT_HID_GETSHORTNAME
|
|
|
|
|
|
|
|
// Macro for defining the keymap. This should be used in the sketch
|
|
|
|
// file (*.ino) to define the keymap[] array that holds the user's
|
|
|
|
// layers. It also computes the number of layers in that keymap.
|
|
|
|
#define KEYMAPS(layers...) __NL__ \
|
|
|
|
START_KEYMAPS __NL__ \
|
|
|
|
layers __NL__ \
|
|
|
|
END_KEYMAPS
|
|
|
|
|
|
|
|
// clang-format on
|
|
|
|
|
|
|
|
extern uint8_t layer_count;
|
|
|
|
|
|
|
|
namespace kaleidoscope {
|
|
|
|
class Layer_ {
|
|
|
|
public:
|
|
|
|
Layer_() {}
|
|
|
|
|
|
|
|
void setup();
|
|
|
|
|
|
|
|
// There are two lookup functions here, for historical reasons. Previously,
|
|
|
|
// Kaleidoscope would need to look up a value for each active keyswitch in
|
|
|
|
// every cycle, and pass that value on to the "event" handlers. Most of these
|
|
|
|
// lookups were for keys that were being held, not toggled on or off. Because
|
|
|
|
// these lookups were so frequent, a cache was used to speed them up.
|
|
|
|
//
|
|
|
|
// We no longer need to look up these values every cycle for keys that are
|
|
|
|
// held, because Kaleidoscope now only acts on key events that are actual
|
|
|
|
// toggle-on or toggle-off events, so the speed of the lookups here is not so
|
|
|
|
// critical. However, the old "live composite keymap" cache was also used by
|
|
|
|
// some plugins (and certain parts of Kaleidoscope itself) to override values
|
|
|
|
// in the keymap, and these plugins might use calls to `Layer.lookup()`,
|
|
|
|
// expecting to get the override values.
|
|
|
|
//
|
|
|
|
// Therefore, the `lookup()` function below first checks the `live_keys` array
|
|
|
|
// (the keyboard state array that has replaced the keymap cache). This should
|
|
|
|
// allow old code to continue working, until all the associated code (mostly
|
|
|
|
// the `onKeyswitchEvent()` handlers) is replaced, at which point we can
|
|
|
|
// remove dependence on `live_keys` entirely from this class.
|
|
|
|
//
|
|
|
|
// The `Runtime.lookupKey()` function replaces this one, for plugins that
|
|
|
|
// still want to do this same check.
|
|
|
|
|
|
|
|
static Key lookupOnActiveLayer(KeyAddr key_addr) {
|
Switch to activation-order for Layers
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>
4 years ago
|
|
|
uint8_t layer = active_layer_keymap_[key_addr.toInt()];
|
|
|
|
return (*getKey)(layer, key_addr);
|
|
|
|
}
|
|
|
|
static uint8_t lookupActiveLayer(KeyAddr key_addr) {
|
Switch to activation-order for Layers
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>
4 years ago
|
|
|
return active_layer_keymap_[key_addr.toInt()];
|
|
|
|
}
|
Layer: Rename a few methods, for better clarity
In general, we want method names to be verbs, because they convey actions. The
`Layer.on()`, `Layer.off()`, etc family of functions weren't like that. It
wasn't immediately obvious that they turn layers on and off.
Furthermore, `Layer.next()` and `Layer.previous()` were even more confusing,
because one could easily think they implied moving to the selected layers, while
in practice, they just activated them.
All of these have new names, that better describe what they do. The old names
are still present, but emit a deprecation warning.
Signed-off-by: Gergely Nagy <algernon@keyboard.io>
6 years ago
|
|
|
|
|
|
|
static void activate(uint8_t layer);
|
|
|
|
static void deactivate(uint8_t layer);
|
|
|
|
static void activateNext();
|
Switch to activation-order for Layers
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>
4 years ago
|
|
|
static void deactivateMostRecent();
|
|
|
|
static void move(uint8_t layer);
|
|
|
|
|
Switch to activation-order for Layers
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>
4 years ago
|
|
|
static uint8_t mostRecent() {
|
|
|
|
return active_layers_[active_layer_count_ - 1];
|
|
|
|
}
|
|
|
|
static bool isActive(uint8_t layer);
|
|
|
|
|
|
|
|
static void handleLayerKeyEvent(const KeyEvent &event);
|
|
|
|
|
|
|
|
typedef Key (*GetKeyFunction)(uint8_t layer, KeyAddr key_addr);
|
|
|
|
static GetKeyFunction getKey;
|
|
|
|
|
|
|
|
static Key getKeyFromPROGMEM(uint8_t layer, KeyAddr key_addr);
|
|
|
|
|
|
|
|
static void updateActiveLayers(void);
|
|
|
|
|
Switch to activation-order for Layers
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>
4 years ago
|
|
|
private:
|
|
|
|
using forEachHandler = void (*)(uint8_t index, uint8_t layer);
|
Switch to activation-order for Layers
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>
4 years ago
|
|
|
|
|
|
|
public:
|
|
|
|
static void forEachActiveLayer(forEachHandler h);
|
|
|
|
|
|
|
|
private:
|
Switch to activation-order for Layers
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>
4 years ago
|
|
|
static uint8_t active_layer_count_;
|
|
|
|
static int8_t active_layers_[31];
|
|
|
|
static uint8_t active_layer_keymap_[kaleidoscope_internal::device.numKeys()];
|
|
|
|
};
|
Standardize namespace block closing comments
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>
3 years ago
|
|
|
} // namespace kaleidoscope
|
|
|
|
|
|
|
|
extern kaleidoscope::Layer_ Layer;
|