aboutsummaryrefslogtreecommitdiff
path: root/quantum/action_layer.c
diff options
context:
space:
mode:
authorJoel Challis <git@zvecr.com>2021-08-18 00:18:58 +0100
committerGitHub <noreply@github.com>2021-08-18 00:18:58 +0100
commitb8e913c8db73ebf890e4604ee41991a34354a600 (patch)
tree258035f8fda9f83f08a309f6cd608b9c61476678 /quantum/action_layer.c
parent96e2b13d1de227cdc2b918fb0292bd832d346a25 (diff)
downloadqmk_firmware-b8e913c8db73ebf890e4604ee41991a34354a600.tar.gz
qmk_firmware-b8e913c8db73ebf890e4604ee41991a34354a600.zip
Migrate platform independent code from tmk_core -> quantum (#13673)
* Migrate action|keyboard|keycode|eeconfig from tmk_core -> quantum
Diffstat (limited to 'quantum/action_layer.c')
-rw-r--r--quantum/action_layer.c279
1 files changed, 279 insertions, 0 deletions
diff --git a/quantum/action_layer.c b/quantum/action_layer.c
new file mode 100644
index 000000000..ed1a4bd20
--- /dev/null
+++ b/quantum/action_layer.c
@@ -0,0 +1,279 @@
1#include <stdint.h>
2#include "keyboard.h"
3#include "action.h"
4#include "util.h"
5#include "action_layer.h"
6
7#ifdef DEBUG_ACTION
8# include "debug.h"
9#else
10# include "nodebug.h"
11#endif
12
13/** \brief Default Layer State
14 */
15layer_state_t default_layer_state = 0;
16
17/** \brief Default Layer State Set At user Level
18 *
19 * Run user code on default layer state change
20 */
21__attribute__((weak)) layer_state_t default_layer_state_set_user(layer_state_t state) { return state; }
22
23/** \brief Default Layer State Set At Keyboard Level
24 *
25 * Run keyboard code on default layer state change
26 */
27__attribute__((weak)) layer_state_t default_layer_state_set_kb(layer_state_t state) { return default_layer_state_set_user(state); }
28
29/** \brief Default Layer State Set
30 *
31 * Static function to set the default layer state, prints debug info and clears keys
32 */
33static void default_layer_state_set(layer_state_t state) {
34 state = default_layer_state_set_kb(state);
35 debug("default_layer_state: ");
36 default_layer_debug();
37 debug(" to ");
38 default_layer_state = state;
39 default_layer_debug();
40 debug("\n");
41#ifdef STRICT_LAYER_RELEASE
42 clear_keyboard_but_mods(); // To avoid stuck keys
43#else
44 clear_keyboard_but_mods_and_keys(); // Don't reset held keys
45#endif
46}
47
48/** \brief Default Layer Print
49 *
50 * Print out the hex value of the 32-bit default layer state, as well as the value of the highest bit.
51 */
52void default_layer_debug(void) { dprintf("%08lX(%u)", default_layer_state, get_highest_layer(default_layer_state)); }
53
54/** \brief Default Layer Set
55 *
56 * Sets the default layer state.
57 */
58void default_layer_set(layer_state_t state) { default_layer_state_set(state); }
59
60#ifndef NO_ACTION_LAYER
61/** \brief Default Layer Or
62 *
63 * Turns on the default layer based on matching bits between specifed layer and existing layer state
64 */
65void default_layer_or(layer_state_t state) { default_layer_state_set(default_layer_state | state); }
66/** \brief Default Layer And
67 *
68 * Turns on default layer based on matching enabled bits between specifed layer and existing layer state
69 */
70void default_layer_and(layer_state_t state) { default_layer_state_set(default_layer_state & state); }
71/** \brief Default Layer Xor
72 *
73 * Turns on default layer based on non-matching bits between specifed layer and existing layer state
74 */
75void default_layer_xor(layer_state_t state) { default_layer_state_set(default_layer_state ^ state); }
76#endif
77
78#ifndef NO_ACTION_LAYER
79/** \brief Keymap Layer State
80 */
81layer_state_t layer_state = 0;
82
83/** \brief Layer state set user
84 *
85 * Runs user code on layer state change
86 */
87__attribute__((weak)) layer_state_t layer_state_set_user(layer_state_t state) { return state; }
88
89/** \brief Layer state set keyboard
90 *
91 * Runs keyboard code on layer state change
92 */
93__attribute__((weak)) layer_state_t layer_state_set_kb(layer_state_t state) { return layer_state_set_user(state); }
94
95/** \brief Layer state set
96 *
97 * Sets the layer to match the specifed state (a bitmask)
98 */
99void layer_state_set(layer_state_t state) {
100 state = layer_state_set_kb(state);
101 dprint("layer_state: ");
102 layer_debug();
103 dprint(" to ");
104 layer_state = state;
105 layer_debug();
106 dprintln();
107# ifdef STRICT_LAYER_RELEASE
108 clear_keyboard_but_mods(); // To avoid stuck keys
109# else
110 clear_keyboard_but_mods_and_keys(); // Don't reset held keys
111# endif
112}
113
114/** \brief Layer clear
115 *
116 * Turn off all layers
117 */
118void layer_clear(void) { layer_state_set(0); }
119
120/** \brief Layer state is
121 *
122 * Return whether the given state is on (it might still be shadowed by a higher state, though)
123 */
124bool layer_state_is(uint8_t layer) { return layer_state_cmp(layer_state, layer); }
125
126/** \brief Layer state compare
127 *
128 * Used for comparing layers {mostly used for unit testing}
129 */
130bool layer_state_cmp(layer_state_t cmp_layer_state, uint8_t layer) {
131 if (!cmp_layer_state) {
132 return layer == 0;
133 }
134 return (cmp_layer_state & ((layer_state_t)1 << layer)) != 0;
135}
136
137/** \brief Layer move
138 *
139 * Turns on the given layer and turn off all other layers
140 */
141void layer_move(uint8_t layer) { layer_state_set((layer_state_t)1 << layer); }
142
143/** \brief Layer on
144 *
145 * Turns on given layer
146 */
147void layer_on(uint8_t layer) { layer_state_set(layer_state | ((layer_state_t)1 << layer)); }
148
149/** \brief Layer off
150 *
151 * Turns off given layer
152 */
153void layer_off(uint8_t layer) { layer_state_set(layer_state & ~((layer_state_t)1 << layer)); }
154
155/** \brief Layer invert
156 *
157 * Toggle the given layer (set it if it's unset, or unset it if it's set)
158 */
159void layer_invert(uint8_t layer) { layer_state_set(layer_state ^ ((layer_state_t)1 << layer)); }
160
161/** \brief Layer or
162 *
163 * Turns on layers based on matching bits between specifed layer and existing layer state
164 */
165void layer_or(layer_state_t state) { layer_state_set(layer_state | state); }
166/** \brief Layer and
167 *
168 * Turns on layers based on matching enabled bits between specifed layer and existing layer state
169 */
170void layer_and(layer_state_t state) { layer_state_set(layer_state & state); }
171/** \brief Layer xor
172 *
173 * Turns on layers based on non-matching bits between specifed layer and existing layer state
174 */
175void layer_xor(layer_state_t state) { layer_state_set(layer_state ^ state); }
176
177/** \brief Layer debug printing
178 *
179 * Print out the hex value of the 32-bit layer state, as well as the value of the highest bit.
180 */
181void layer_debug(void) { dprintf("%08lX(%u)", layer_state, get_highest_layer(layer_state)); }
182#endif
183
184#if !defined(NO_ACTION_LAYER) && !defined(STRICT_LAYER_RELEASE)
185/** \brief source layer cache
186 */
187
188uint8_t source_layers_cache[(MATRIX_ROWS * MATRIX_COLS + 7) / 8][MAX_LAYER_BITS] = {{0}};
189
190/** \brief update source layers cache
191 *
192 * Updates the cached keys when changing layers
193 */
194void update_source_layers_cache(keypos_t key, uint8_t layer) {
195 const uint8_t key_number = key.col + (key.row * MATRIX_COLS);
196 const uint8_t storage_row = key_number / 8;
197 const uint8_t storage_bit = key_number % 8;
198
199 for (uint8_t bit_number = 0; bit_number < MAX_LAYER_BITS; bit_number++) {
200 source_layers_cache[storage_row][bit_number] ^= (-((layer & (1U << bit_number)) != 0) ^ source_layers_cache[storage_row][bit_number]) & (1U << storage_bit);
201 }
202}
203
204/** \brief read source layers cache
205 *
206 * reads the cached keys stored when the layer was changed
207 */
208uint8_t read_source_layers_cache(keypos_t key) {
209 const uint8_t key_number = key.col + (key.row * MATRIX_COLS);
210 const uint8_t storage_row = key_number / 8;
211 const uint8_t storage_bit = key_number % 8;
212 uint8_t layer = 0;
213
214 for (uint8_t bit_number = 0; bit_number < MAX_LAYER_BITS; bit_number++) {
215 layer |= ((source_layers_cache[storage_row][bit_number] & (1U << storage_bit)) != 0) << bit_number;
216 }
217
218 return layer;
219}
220#endif
221
222/** \brief Store or get action (FIXME: Needs better summary)
223 *
224 * Make sure the action triggered when the key is released is the same
225 * one as the one triggered on press. It's important for the mod keys
226 * when the layer is switched after the down event but before the up
227 * event as they may get stuck otherwise.
228 */
229action_t store_or_get_action(bool pressed, keypos_t key) {
230#if !defined(NO_ACTION_LAYER) && !defined(STRICT_LAYER_RELEASE)
231 if (disable_action_cache) {
232 return layer_switch_get_action(key);
233 }
234
235 uint8_t layer;
236
237 if (pressed) {
238 layer = layer_switch_get_layer(key);
239 update_source_layers_cache(key, layer);
240 } else {
241 layer = read_source_layers_cache(key);
242 }
243 return action_for_key(layer, key);
244#else
245 return layer_switch_get_action(key);
246#endif
247}
248
249/** \brief Layer switch get layer
250 *
251 * Gets the layer based on key info
252 */
253uint8_t layer_switch_get_layer(keypos_t key) {
254#ifndef NO_ACTION_LAYER
255 action_t action;
256 action.code = ACTION_TRANSPARENT;
257
258 layer_state_t layers = layer_state | default_layer_state;
259 /* check top layer first */
260 for (int8_t i = MAX_LAYER - 1; i >= 0; i--) {
261 if (layers & ((layer_state_t)1 << i)) {
262 action = action_for_key(i, key);
263 if (action.code != ACTION_TRANSPARENT) {
264 return i;
265 }
266 }
267 }
268 /* fall back to layer 0 */
269 return 0;
270#else
271 return get_highest_layer(default_layer_state);
272#endif
273}
274
275/** \brief Layer switch get layer
276 *
277 * Gets action code based on key position
278 */
279action_t layer_switch_get_action(keypos_t key) { return action_for_key(layer_switch_get_layer(key), key); }