|
|
|
#include "layers.h"
|
|
|
|
#include "key_events.h"
|
|
|
|
|
|
|
|
static uint8_t DefaultLayer;
|
|
|
|
static uint32_t LayerState;
|
|
|
|
|
|
|
|
uint8_t Layer_::highestLayer;
|
Cache the keymap when changing layers
Instead of going through all the active layers each time we are looking for a
key, whenever we switch layers, compute the effective keymap, and store the
indexes. This makes the lookup a considerably faster operation, and lookups
happen far more often than layer switching.
This comes at a cost of ROWS*COLS amount of memory, and a bit of code, but on
the flip side, the lookup operation is now O(1), which is a very nice property
to have, if you want responsiveness. Changing layers is marginally slower,
however, but even with 32 active layers, doing the computation once, instead of
potentially many dozens of time, is still worth it.
We could further reduce the memory requirements if we stored more columns per
byte, but that's for a future optimization.
Signed-off-by: Gergely Nagy <algernon@madhouse-project.org>
8 years ago
|
|
|
uint8_t Layer_::keyMap[ROWS][COLS];
|
|
|
|
|
|
|
|
static void handle_keymap_key_event(Key keymapEntry, uint8_t keyState) {
|
|
|
|
if (keymapEntry.keyCode >= MOMENTARY_OFFSET) {
|
|
|
|
uint8_t target = keymapEntry.keyCode - MOMENTARY_OFFSET;
|
|
|
|
|
|
|
|
if (key_toggled_on(keyState)) {
|
|
|
|
if ( target == KEYMAP_NEXT) {
|
|
|
|
Layer.next();
|
|
|
|
} else if ( target == KEYMAP_PREVIOUS) {
|
|
|
|
Layer.previous();
|
|
|
|
} else {
|
|
|
|
Layer.on(target);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
if (key_toggled_off(keyState)) {
|
|
|
|
if ( target == KEYMAP_NEXT) {
|
|
|
|
Layer.previous();
|
|
|
|
} else if ( target == KEYMAP_PREVIOUS) {
|
|
|
|
Layer.next();
|
|
|
|
} else {
|
|
|
|
Layer.off(target);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// switch keymap and stay there
|
|
|
|
} else if (key_toggled_on(keyState)) {
|
|
|
|
if (Layer.isOn (keymapEntry.keyCode) && keymapEntry.keyCode)
|
|
|
|
Layer.off(keymapEntry.keyCode);
|
|
|
|
else
|
|
|
|
Layer.on(keymapEntry.keyCode);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
Key
|
|
|
|
Layer_::eventHandler(Key mappedKey, byte row, byte col, uint8_t keyState) {
|
|
|
|
if (mappedKey.flags != (SYNTHETIC | SWITCH_TO_KEYMAP))
|
Event hooks reworked, again
Instead of returning a bool, to signal whether further processing should be
done, return a Key. Reason being, if we want to replace a key with another, for
subsequent handlers, it is a lot easier if we can modify what gets passed along,
than it is to inject a key, and try to avoid loops and infinite recursion.
Nevertheless, injecting keys is still possible.
This is not immediately useful for the core firmware, but makes it trivially
easy to upgrade keys from their normal behaviour to something special: for
example, a one-shot handler can auto-promote modifiers to one-shot, simply by
scheduling a promoter handler before the real one.
Signed-off-by: Gergely Nagy <algernon@madhouse-project.org>
8 years ago
|
|
|
return mappedKey;
|
|
|
|
|
|
|
|
handle_keymap_key_event(mappedKey, keyState);
|
Event hooks reworked, again
Instead of returning a bool, to signal whether further processing should be
done, return a Key. Reason being, if we want to replace a key with another, for
subsequent handlers, it is a lot easier if we can modify what gets passed along,
than it is to inject a key, and try to avoid loops and infinite recursion.
Nevertheless, injecting keys is still possible.
This is not immediately useful for the core firmware, but makes it trivially
easy to upgrade keys from their normal behaviour to something special: for
example, a one-shot handler can auto-promote modifiers to one-shot, simply by
scheduling a promoter handler before the real one.
Signed-off-by: Gergely Nagy <algernon@madhouse-project.org>
8 years ago
|
|
|
return Key_NoKey;
|
|
|
|
}
|
|
|
|
|
|
|
|
Layer_::Layer_ (void) {
|
|
|
|
defaultLayer (0);
|
|
|
|
}
|
|
|
|
|
Cache the keymap when changing layers
Instead of going through all the active layers each time we are looking for a
key, whenever we switch layers, compute the effective keymap, and store the
indexes. This makes the lookup a considerably faster operation, and lookups
happen far more often than layer switching.
This comes at a cost of ROWS*COLS amount of memory, and a bit of code, but on
the flip side, the lookup operation is now O(1), which is a very nice property
to have, if you want responsiveness. Changing layers is marginally slower,
however, but even with 32 active layers, doing the computation once, instead of
potentially many dozens of time, is still worth it.
We could further reduce the memory requirements if we stored more columns per
byte, but that's for a future optimization.
Signed-off-by: Gergely Nagy <algernon@madhouse-project.org>
8 years ago
|
|
|
void
|
|
|
|
Layer_::mergeLayers(void) {
|
|
|
|
|
|
|
|
memset (keyMap, DefaultLayer, ROWS * COLS);
|
|
|
|
|
|
|
|
if (LayerState == (uint32_t)(1 << DefaultLayer))
|
|
|
|
return;
|
|
|
|
|
Cache the keymap when changing layers
Instead of going through all the active layers each time we are looking for a
key, whenever we switch layers, compute the effective keymap, and store the
indexes. This makes the lookup a considerably faster operation, and lookups
happen far more often than layer switching.
This comes at a cost of ROWS*COLS amount of memory, and a bit of code, but on
the flip side, the lookup operation is now O(1), which is a very nice property
to have, if you want responsiveness. Changing layers is marginally slower,
however, but even with 32 active layers, doing the computation once, instead of
potentially many dozens of time, is still worth it.
We could further reduce the memory requirements if we stored more columns per
byte, but that's for a future optimization.
Signed-off-by: Gergely Nagy <algernon@madhouse-project.org>
8 years ago
|
|
|
for (uint8_t r = 0; r < ROWS; r++) {
|
|
|
|
for (uint8_t c = 0; c < COLS; c++) {
|
|
|
|
int8_t layer = highestLayer;
|
|
|
|
|
|
|
|
while (layer > DefaultLayer) {
|
Cache the keymap when changing layers
Instead of going through all the active layers each time we are looking for a
key, whenever we switch layers, compute the effective keymap, and store the
indexes. This makes the lookup a considerably faster operation, and lookups
happen far more often than layer switching.
This comes at a cost of ROWS*COLS amount of memory, and a bit of code, but on
the flip side, the lookup operation is now O(1), which is a very nice property
to have, if you want responsiveness. Changing layers is marginally slower,
however, but even with 32 active layers, doing the computation once, instead of
potentially many dozens of time, is still worth it.
We could further reduce the memory requirements if we stored more columns per
byte, but that's for a future optimization.
Signed-off-by: Gergely Nagy <algernon@madhouse-project.org>
8 years ago
|
|
|
if (Layer.isOn (layer)) {
|
|
|
|
Key mappedKey;
|
|
|
|
|
|
|
|
mappedKey.raw = pgm_read_word(&(keymaps[layer][r][c]));
|
|
|
|
|
|
|
|
if (mappedKey != Key_Transparent) {
|
|
|
|
keyMap[r][c] = layer;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
layer--;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
Cache the keymap when changing layers
Instead of going through all the active layers each time we are looking for a
key, whenever we switch layers, compute the effective keymap, and store the
indexes. This makes the lookup a considerably faster operation, and lookups
happen far more often than layer switching.
This comes at a cost of ROWS*COLS amount of memory, and a bit of code, but on
the flip side, the lookup operation is now O(1), which is a very nice property
to have, if you want responsiveness. Changing layers is marginally slower,
however, but even with 32 active layers, doing the computation once, instead of
potentially many dozens of time, is still worth it.
We could further reduce the memory requirements if we stored more columns per
byte, but that's for a future optimization.
Signed-off-by: Gergely Nagy <algernon@madhouse-project.org>
8 years ago
|
|
|
}
|
|
|
|
|
|
|
|
Key Layer_::lookup(byte row, byte col) {
|
|
|
|
uint8_t layer = keyMap[row][col];
|
|
|
|
Key mappedKey;
|
|
|
|
mappedKey.raw = pgm_read_word(&(keymaps[layer][row][col]));
|
|
|
|
|
|
|
|
return mappedKey;
|
|
|
|
}
|
|
|
|
|
|
|
|
uint8_t Layer_::top (void) {
|
|
|
|
for (int8_t i = 31; i >= 0; i--) {
|
|
|
|
if (bitRead (LayerState, i))
|
|
|
|
return i;
|
|
|
|
}
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
void Layer_::move (uint8_t layer) {
|
|
|
|
LayerState = 0;
|
|
|
|
on (layer);
|
|
|
|
}
|
|
|
|
|
|
|
|
void Layer_::on (uint8_t layer) {
|
|
|
|
bitSet (LayerState, layer);
|
|
|
|
if (layer > highestLayer)
|
|
|
|
highestLayer = layer;
|
Cache the keymap when changing layers
Instead of going through all the active layers each time we are looking for a
key, whenever we switch layers, compute the effective keymap, and store the
indexes. This makes the lookup a considerably faster operation, and lookups
happen far more often than layer switching.
This comes at a cost of ROWS*COLS amount of memory, and a bit of code, but on
the flip side, the lookup operation is now O(1), which is a very nice property
to have, if you want responsiveness. Changing layers is marginally slower,
however, but even with 32 active layers, doing the computation once, instead of
potentially many dozens of time, is still worth it.
We could further reduce the memory requirements if we stored more columns per
byte, but that's for a future optimization.
Signed-off-by: Gergely Nagy <algernon@madhouse-project.org>
8 years ago
|
|
|
mergeLayers();
|
|
|
|
}
|
|
|
|
|
|
|
|
void Layer_::off (uint8_t layer) {
|
|
|
|
bitClear (LayerState, layer);
|
|
|
|
if (layer == highestLayer)
|
|
|
|
highestLayer = top();
|
Cache the keymap when changing layers
Instead of going through all the active layers each time we are looking for a
key, whenever we switch layers, compute the effective keymap, and store the
indexes. This makes the lookup a considerably faster operation, and lookups
happen far more often than layer switching.
This comes at a cost of ROWS*COLS amount of memory, and a bit of code, but on
the flip side, the lookup operation is now O(1), which is a very nice property
to have, if you want responsiveness. Changing layers is marginally slower,
however, but even with 32 active layers, doing the computation once, instead of
potentially many dozens of time, is still worth it.
We could further reduce the memory requirements if we stored more columns per
byte, but that's for a future optimization.
Signed-off-by: Gergely Nagy <algernon@madhouse-project.org>
8 years ago
|
|
|
mergeLayers();
|
|
|
|
}
|
|
|
|
|
|
|
|
boolean Layer_::isOn (uint8_t layer) {
|
|
|
|
return bitRead(LayerState, layer);
|
|
|
|
}
|
|
|
|
|
|
|
|
void Layer_::next (void) {
|
|
|
|
on (top () + 1);
|
|
|
|
}
|
|
|
|
|
|
|
|
void Layer_::previous (void) {
|
|
|
|
off (top ());
|
|
|
|
}
|
|
|
|
|
|
|
|
void Layer_::defaultLayer (uint8_t layer) {
|
|
|
|
move (layer);
|
|
|
|
DefaultLayer = layer;
|
|
|
|
}
|
|
|
|
|
|
|
|
uint8_t Layer_::defaultLayer (void) {
|
|
|
|
return DefaultLayer;
|
|
|
|
}
|
|
|
|
|
|
|
|
uint32_t Layer_::getLayerState (void) {
|
|
|
|
return LayerState;
|
|
|
|
}
|
|
|
|
|
|
|
|
Layer_ Layer;
|