diff options
Diffstat (limited to 'tmk_core/common/action_layer.c')
| -rw-r--r-- | tmk_core/common/action_layer.c | 77 |
1 files changed, 71 insertions, 6 deletions
diff --git a/tmk_core/common/action_layer.c b/tmk_core/common/action_layer.c index c535615f4..fc721a732 100644 --- a/tmk_core/common/action_layer.c +++ b/tmk_core/common/action_layer.c | |||
| @@ -110,9 +110,71 @@ void layer_debug(void) | |||
| 110 | } | 110 | } |
| 111 | #endif | 111 | #endif |
| 112 | 112 | ||
| 113 | #if !defined(NO_ACTION_LAYER) && defined(PREVENT_STUCK_MODIFIERS) | ||
| 114 | uint8_t source_layers_cache[MAX_LAYER_BITS][(MATRIX_ROWS * MATRIX_COLS + 7) / 8] = {0}; | ||
| 113 | 115 | ||
| 116 | void update_source_layers_cache(keypos_t key, uint8_t layer) | ||
| 117 | { | ||
| 118 | const uint8_t key_number = key.col + (key.row * MATRIX_COLS); | ||
| 119 | const uint8_t storage_row = key_number / 8; | ||
| 120 | const uint8_t storage_bit = key_number % 8; | ||
| 114 | 121 | ||
| 115 | action_t layer_switch_get_action(keypos_t key) | 122 | for (uint8_t bit_number = 0; bit_number < MAX_LAYER_BITS; bit_number++) { |
| 123 | source_layers_cache[bit_number][storage_row] ^= | ||
| 124 | (-((layer & (1U << bit_number)) != 0) | ||
| 125 | ^ source_layers_cache[bit_number][storage_row]) | ||
| 126 | & (1U << storage_bit); | ||
| 127 | } | ||
| 128 | } | ||
| 129 | |||
| 130 | uint8_t read_source_layers_cache(keypos_t key) | ||
| 131 | { | ||
| 132 | const uint8_t key_number = key.col + (key.row * MATRIX_COLS); | ||
| 133 | const uint8_t storage_row = key_number / 8; | ||
| 134 | const uint8_t storage_bit = key_number % 8; | ||
| 135 | uint8_t layer = 0; | ||
| 136 | |||
| 137 | for (uint8_t bit_number = 0; bit_number < MAX_LAYER_BITS; bit_number++) { | ||
| 138 | layer |= | ||
| 139 | ((source_layers_cache[bit_number][storage_row] | ||
| 140 | & (1U << storage_bit)) != 0) | ||
| 141 | << bit_number; | ||
| 142 | } | ||
| 143 | |||
| 144 | return layer; | ||
| 145 | } | ||
| 146 | #endif | ||
| 147 | |||
| 148 | /* | ||
| 149 | * Make sure the action triggered when the key is released is the same | ||
| 150 | * one as the one triggered on press. It's important for the mod keys | ||
| 151 | * when the layer is switched after the down event but before the up | ||
| 152 | * event as they may get stuck otherwise. | ||
| 153 | */ | ||
| 154 | action_t store_or_get_action(bool pressed, keypos_t key) | ||
| 155 | { | ||
| 156 | #if !defined(NO_ACTION_LAYER) && defined(PREVENT_STUCK_MODIFIERS) | ||
| 157 | if (disable_action_cache) { | ||
| 158 | return layer_switch_get_action(key); | ||
| 159 | } | ||
| 160 | |||
| 161 | uint8_t layer; | ||
| 162 | |||
| 163 | if (pressed) { | ||
| 164 | layer = layer_switch_get_layer(key); | ||
| 165 | update_source_layers_cache(key, layer); | ||
| 166 | } | ||
| 167 | else { | ||
| 168 | layer = read_source_layers_cache(key); | ||
| 169 | } | ||
| 170 | return action_for_key(layer, key); | ||
| 171 | #else | ||
| 172 | return layer_switch_get_action(key); | ||
| 173 | #endif | ||
| 174 | } | ||
| 175 | |||
| 176 | |||
| 177 | int8_t layer_switch_get_layer(keypos_t key) | ||
| 116 | { | 178 | { |
| 117 | action_t action; | 179 | action_t action; |
| 118 | action.code = ACTION_TRANSPARENT; | 180 | action.code = ACTION_TRANSPARENT; |
| @@ -124,15 +186,18 @@ action_t layer_switch_get_action(keypos_t key) | |||
| 124 | if (layers & (1UL<<i)) { | 186 | if (layers & (1UL<<i)) { |
| 125 | action = action_for_key(i, key); | 187 | action = action_for_key(i, key); |
| 126 | if (action.code != ACTION_TRANSPARENT) { | 188 | if (action.code != ACTION_TRANSPARENT) { |
| 127 | return action; | 189 | return i; |
| 128 | } | 190 | } |
| 129 | } | 191 | } |
| 130 | } | 192 | } |
| 131 | /* fall back to layer 0 */ | 193 | /* fall back to layer 0 */ |
| 132 | action = action_for_key(0, key); | 194 | return 0; |
| 133 | return action; | ||
| 134 | #else | 195 | #else |
| 135 | action = action_for_key(biton32(default_layer_state), key); | 196 | return biton32(default_layer_state); |
| 136 | return action; | ||
| 137 | #endif | 197 | #endif |
| 138 | } | 198 | } |
| 199 | |||
| 200 | action_t layer_switch_get_action(keypos_t key) | ||
| 201 | { | ||
| 202 | return action_for_key(layer_switch_get_layer(key), key); | ||
| 203 | } | ||
