You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
220 lines
6.3 KiB
220 lines
6.3 KiB
6 years ago
|
/* Kaleidoscope - Firmware for computer input devices
|
||
|
* Copyright (C) 2013-2018 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/>.
|
||
|
*/
|
||
|
|
||
6 years ago
|
#include "kaleidoscope/Kaleidoscope.h"
|
||
8 years ago
|
|
||
7 years ago
|
// The maximum number of layers allowed. `LayerState`, which stores
|
||
|
// the on/off status of the layers in a bitfield has only 32 bits, and
|
||
|
// that should be enough for almost any layout.
|
||
6 years ago
|
#define MAX_LAYERS sizeof(uint32_t) * 8;
|
||
8 years ago
|
|
||
7 years ago
|
// The total number of defined layers in the firmware sketch keymaps[]
|
||
7 years ago
|
// array. If the keymap wasn't defined using KEYMAPS(), set it to the
|
||
|
// highest possible number of layers.
|
||
|
uint8_t layer_count __attribute__((weak)) = MAX_LAYERS;
|
||
7 years ago
|
|
||
6 years ago
|
namespace kaleidoscope {
|
||
|
uint8_t Layer_::DefaultLayer;
|
||
|
uint32_t Layer_::LayerState;
|
||
|
uint8_t Layer_::highestLayer;
|
||
|
Key Layer_::liveCompositeKeymap[ROWS][COLS];
|
||
|
uint8_t Layer_::activeLayers[ROWS][COLS];
|
||
|
Key(*Layer_::getKey)(uint8_t layer, byte row, byte col) = Layer.getKeyFromPROGMEM;
|
||
|
|
||
|
void Layer_::handleKeymapKeyswitchEvent(Key keymapEntry, uint8_t keyState) {
|
||
7 years ago
|
if (keymapEntry.keyCode >= LAYER_SHIFT_OFFSET) {
|
||
|
uint8_t target = keymapEntry.keyCode - LAYER_SHIFT_OFFSET;
|
||
8 years ago
|
|
||
7 years ago
|
switch (target) {
|
||
|
case KEYMAP_NEXT:
|
||
|
if (keyToggledOn(keyState))
|
||
6 years ago
|
next();
|
||
7 years ago
|
else if (keyToggledOff(keyState))
|
||
6 years ago
|
previous();
|
||
7 years ago
|
break;
|
||
|
|
||
|
case KEYMAP_PREVIOUS:
|
||
|
if (keyToggledOn(keyState))
|
||
6 years ago
|
previous();
|
||
7 years ago
|
else if (keyToggledOff(keyState))
|
||
6 years ago
|
next();
|
||
7 years ago
|
break;
|
||
|
|
||
|
default:
|
||
7 years ago
|
/* The default case is when we are switching to a layer by its number, and
|
||
|
* is a bit more complicated than switching there when the key toggles on,
|
||
|
* and away when it toggles off.
|
||
|
*
|
||
|
* We want to handle the case where we have more than one momentary layer
|
||
|
* key on our keymap that point to the same target layer, and we hold
|
||
|
* both, and release one. In this case, the layer should remain active,
|
||
|
* because the second momentary key is still held.
|
||
|
*
|
||
|
* To do this, we turn the layer back on if the switcher key is still
|
||
|
* held, not only when it toggles on. So when one of them is released,
|
||
|
* that does turn the layer off, but with the other still being held, the
|
||
|
* layer will toggle back on in the same cycle.
|
||
|
*/
|
||
7 years ago
|
if (keyIsPressed(keyState)) {
|
||
|
if (!Layer.isOn(target))
|
||
6 years ago
|
on(target);
|
||
7 years ago
|
} else if (keyToggledOff(keyState)) {
|
||
6 years ago
|
off(target);
|
||
8 years ago
|
}
|
||
7 years ago
|
break;
|
||
8 years ago
|
}
|
||
8 years ago
|
} else if (keyToggledOn(keyState)) {
|
||
7 years ago
|
// switch keymap and stay there
|
||
8 years ago
|
if (Layer.isOn(keymapEntry.keyCode) && keymapEntry.keyCode)
|
||
6 years ago
|
off(keymapEntry.keyCode);
|
||
8 years ago
|
else
|
||
6 years ago
|
on(keymapEntry.keyCode);
|
||
8 years ago
|
}
|
||
8 years ago
|
}
|
||
|
|
||
6 years ago
|
Key Layer_::eventHandler(Key mappedKey, byte row, byte col, uint8_t keyState) {
|
||
8 years ago
|
if (mappedKey.flags != (SYNTHETIC | SWITCH_TO_KEYMAP))
|
||
|
return mappedKey;
|
||
8 years ago
|
|
||
8 years ago
|
handleKeymapKeyswitchEvent(mappedKey, keyState);
|
||
8 years ago
|
return Key_NoKey;
|
||
8 years ago
|
}
|
||
|
|
||
6 years ago
|
Key Layer_::getKeyFromPROGMEM(uint8_t layer, byte row, byte col) {
|
||
8 years ago
|
Key key;
|
||
8 years ago
|
|
||
8 years ago
|
key.raw = pgm_read_word(&(keymaps[layer][row][col]));
|
||
8 years ago
|
|
||
8 years ago
|
return key;
|
||
8 years ago
|
}
|
||
|
|
||
6 years ago
|
void Layer_::updateLiveCompositeKeymap(byte row, byte col) {
|
||
7 years ago
|
int8_t layer = activeLayers[row][col];
|
||
|
liveCompositeKeymap[row][col] = (*getKey)(layer, row, col);
|
||
8 years ago
|
}
|
||
|
|
||
6 years ago
|
void Layer_::updateActiveLayers(void) {
|
||
7 years ago
|
memset(activeLayers, DefaultLayer, ROWS * COLS);
|
||
7 years ago
|
for (byte row = 0; row < ROWS; row++) {
|
||
|
for (byte col = 0; col < COLS; col++) {
|
||
7 years ago
|
int8_t layer = highestLayer;
|
||
|
|
||
|
while (layer > DefaultLayer) {
|
||
|
if (Layer.isOn(layer)) {
|
||
|
Key mappedKey = (*getKey)(layer, row, col);
|
||
|
|
||
|
if (mappedKey != Key_Transparent) {
|
||
7 years ago
|
activeLayers[row][col] = layer;
|
||
7 years ago
|
break;
|
||
|
}
|
||
|
}
|
||
|
layer--;
|
||
|
}
|
||
7 years ago
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
7 years ago
|
void Layer_::updateHighestLayer(void) {
|
||
7 years ago
|
// If layer_count is set, start there, otherwise search from the
|
||
7 years ago
|
// highest possible layer (MAX_LAYERS) for the top active layer
|
||
|
for (byte i = (layer_count - 1); i > DefaultLayer; i--) {
|
||
7 years ago
|
if (bitRead(LayerState, i)) {
|
||
|
highestLayer = i;
|
||
|
return;
|
||
|
}
|
||
8 years ago
|
}
|
||
7 years ago
|
// It's not possible to turn off the default layer (see
|
||
|
// updateActiveLayers()), so if no other layers are active:
|
||
7 years ago
|
highestLayer = DefaultLayer;
|
||
8 years ago
|
}
|
||
|
|
||
8 years ago
|
void Layer_::move(uint8_t layer) {
|
||
|
LayerState = 0;
|
||
|
on(layer);
|
||
8 years ago
|
}
|
||
|
|
||
7 years ago
|
// Activate a given layer
|
||
8 years ago
|
void Layer_::on(uint8_t layer) {
|
||
7 years ago
|
// If we're trying to turn on a layer that doesn't exist, abort (but
|
||
7 years ago
|
// if the keymap wasn't defined using the KEYMAPS() macro, proceed anyway
|
||
7 years ago
|
if (layer >= layer_count)
|
||
7 years ago
|
return;
|
||
|
|
||
7 years ago
|
// If the target layer was already on, return
|
||
|
if (isOn(layer))
|
||
|
return;
|
||
7 years ago
|
|
||
7 years ago
|
// Otherwise, turn on its bit in LayerState
|
||
8 years ago
|
bitSet(LayerState, layer);
|
||
7 years ago
|
|
||
|
// If the target layer is above the previous highest active layer,
|
||
|
// update highestLayer
|
||
8 years ago
|
if (layer > highestLayer)
|
||
7 years ago
|
updateHighestLayer();
|
||
7 years ago
|
|
||
7 years ago
|
// Update the keymap cache (but not liveCompositeKeymap; that gets
|
||
|
// updated separately, when keys toggle on or off. See layers.h)
|
||
|
updateActiveLayers();
|
||
8 years ago
|
}
|
||
|
|
||
7 years ago
|
// Deactivate a given layer
|
||
8 years ago
|
void Layer_::off(uint8_t layer) {
|
||
7 years ago
|
// If the target layer was already off, return
|
||
|
if (!bitRead(LayerState, layer))
|
||
|
return;
|
||
7 years ago
|
|
||
7 years ago
|
// Turn off its bit in LayerState
|
||
8 years ago
|
bitClear(LayerState, layer);
|
||
7 years ago
|
|
||
|
// If the target layer was the previous highest active layer,
|
||
|
// update highestLayer
|
||
8 years ago
|
if (layer == highestLayer)
|
||
7 years ago
|
updateHighestLayer();
|
||
7 years ago
|
|
||
7 years ago
|
// Update the keymap cache (but not liveCompositeKeymap; that gets
|
||
|
// updated separately, when keys toggle on or off. See layers.h)
|
||
|
updateActiveLayers();
|
||
8 years ago
|
}
|
||
|
|
||
8 years ago
|
boolean Layer_::isOn(uint8_t layer) {
|
||
|
return bitRead(LayerState, layer);
|
||
8 years ago
|
}
|
||
|
|
||
8 years ago
|
void Layer_::next(void) {
|
||
7 years ago
|
on(highestLayer + 1);
|
||
8 years ago
|
}
|
||
|
|
||
8 years ago
|
void Layer_::previous(void) {
|
||
7 years ago
|
off(highestLayer);
|
||
8 years ago
|
}
|
||
|
|
||
8 years ago
|
void Layer_::defaultLayer(uint8_t layer) {
|
||
|
move(layer);
|
||
|
DefaultLayer = layer;
|
||
8 years ago
|
}
|
||
|
|
||
8 years ago
|
uint8_t Layer_::defaultLayer(void) {
|
||
|
return DefaultLayer;
|
||
8 years ago
|
}
|
||
|
|
||
8 years ago
|
uint32_t Layer_::getLayerState(void) {
|
||
|
return LayerState;
|
||
8 years ago
|
}
|
||
|
|
||
6 years ago
|
}
|
||
|
|
||
|
kaleidoscope::Layer_ Layer;
|