diff options
| author | Thiago Alves <talk@thiagoalves.com.br> | 2016-05-05 18:41:37 -0700 |
|---|---|---|
| committer | Jack Humbert <jack.humb@gmail.com> | 2016-05-05 21:41:37 -0400 |
| commit | 74e97eefd7ae76f9ddcb76890a30aa9038804cdb (patch) | |
| tree | 9bdf7ce6ffb97a024c8230e5e960d53503262ced /tmk_core/common | |
| parent | d4520cd3ac7550fc7243e9a76824d9ba674875c6 (diff) | |
| download | qmk_firmware-74e97eefd7ae76f9ddcb76890a30aa9038804cdb.tar.gz qmk_firmware-74e97eefd7ae76f9ddcb76890a30aa9038804cdb.zip | |
Adds oneshot layer and oneshot tap toggling (#308)
This commit is mostly a cherry-pick from `ahtn` at
https://github.com/tmk/tmk_keyboard/pull/255.
These are the changes:
* Adds ACTION_LAYER_ONESHOT
* Adds ONESHOT_TAP_TOGGLE
* Mentions sticky keys in the docs on oneshot.
Diffstat (limited to 'tmk_core/common')
| -rw-r--r-- | tmk_core/common/action.c | 97 | ||||
| -rw-r--r-- | tmk_core/common/action_code.h | 5 | ||||
| -rw-r--r-- | tmk_core/common/action_util.c | 70 | ||||
| -rw-r--r-- | tmk_core/common/action_util.h | 20 |
4 files changed, 179 insertions, 13 deletions
diff --git a/tmk_core/common/action.c b/tmk_core/common/action.c index f9e6c17dc..081e90b2d 100644 --- a/tmk_core/common/action.c +++ b/tmk_core/common/action.c | |||
| @@ -74,6 +74,7 @@ void process_action_kb(keyrecord_t *record) {} | |||
| 74 | 74 | ||
| 75 | void process_action(keyrecord_t *record) | 75 | void process_action(keyrecord_t *record) |
| 76 | { | 76 | { |
| 77 | bool do_release_oneshot = false; | ||
| 77 | keyevent_t event = record->event; | 78 | keyevent_t event = record->event; |
| 78 | #ifndef NO_ACTION_TAPPING | 79 | #ifndef NO_ACTION_TAPPING |
| 79 | uint8_t tap_count = record->tap.count; | 80 | uint8_t tap_count = record->tap.count; |
| @@ -81,6 +82,13 @@ void process_action(keyrecord_t *record) | |||
| 81 | 82 | ||
| 82 | if (IS_NOEVENT(event)) { return; } | 83 | if (IS_NOEVENT(event)) { return; } |
| 83 | 84 | ||
| 85 | #if (defined(ONESHOT_TIMEOUT) && (ONESHOT_TIMEOUT > 0)) | ||
| 86 | if (has_oneshot_layer_timed_out()) { | ||
| 87 | dprintf("Oneshot layer: timeout\n"); | ||
| 88 | clear_oneshot_layer_state(ONESHOT_OTHER_KEY_PRESSED); | ||
| 89 | } | ||
| 90 | #endif | ||
| 91 | |||
| 84 | process_action_kb(record); | 92 | process_action_kb(record); |
| 85 | 93 | ||
| 86 | action_t action = store_or_get_action(event.pressed, event.key); | 94 | action_t action = store_or_get_action(event.pressed, event.key); |
| @@ -95,6 +103,15 @@ void process_action(keyrecord_t *record) | |||
| 95 | // clear the potential weak mods left by previously pressed keys | 103 | // clear the potential weak mods left by previously pressed keys |
| 96 | clear_weak_mods(); | 104 | clear_weak_mods(); |
| 97 | } | 105 | } |
| 106 | |||
| 107 | #ifndef NO_ACTION_ONESHOT | ||
| 108 | // notice we only clear the one shot layer if the pressed key is not a modifier. | ||
| 109 | if (is_oneshot_layer_active() && event.pressed && !IS_MOD(action.key.code)) { | ||
| 110 | clear_oneshot_layer_state(ONESHOT_OTHER_KEY_PRESSED); | ||
| 111 | do_release_oneshot = !is_oneshot_layer_active(); | ||
| 112 | } | ||
| 113 | #endif | ||
| 114 | |||
| 98 | switch (action.kind.id) { | 115 | switch (action.kind.id) { |
| 99 | /* Key and Mods */ | 116 | /* Key and Mods */ |
| 100 | case ACT_LMODS: | 117 | case ACT_LMODS: |
| @@ -139,24 +156,37 @@ void process_action(keyrecord_t *record) | |||
| 139 | // Oneshot modifier | 156 | // Oneshot modifier |
| 140 | if (event.pressed) { | 157 | if (event.pressed) { |
| 141 | if (tap_count == 0) { | 158 | if (tap_count == 0) { |
| 159 | dprint("MODS_TAP: Oneshot: 0\n"); | ||
| 142 | register_mods(mods); | 160 | register_mods(mods); |
| 143 | } | 161 | } else if (tap_count == 1) { |
| 144 | else if (tap_count == 1) { | ||
| 145 | dprint("MODS_TAP: Oneshot: start\n"); | 162 | dprint("MODS_TAP: Oneshot: start\n"); |
| 146 | set_oneshot_mods(mods); | 163 | set_oneshot_mods(mods); |
| 147 | } | 164 | #if defined(ONESHOT_TAP_TOGGLE) && ONESHOT_TAP_TOGGLE > 1 |
| 148 | else { | 165 | } else if (tap_count == ONESHOT_TAP_TOGGLE) { |
| 166 | dprint("MODS_TAP: Toggling oneshot"); | ||
| 167 | clear_oneshot_mods(); | ||
| 168 | set_oneshot_locked_mods(mods); | ||
| 169 | register_mods(mods); | ||
| 170 | #endif | ||
| 171 | } else { | ||
| 149 | register_mods(mods); | 172 | register_mods(mods); |
| 150 | } | 173 | } |
| 151 | } else { | 174 | } else { |
| 152 | if (tap_count == 0) { | 175 | if (tap_count == 0) { |
| 153 | clear_oneshot_mods(); | 176 | clear_oneshot_mods(); |
| 154 | unregister_mods(mods); | 177 | unregister_mods(mods); |
| 155 | } | 178 | } else if (tap_count == 1) { |
| 156 | else if (tap_count == 1) { | ||
| 157 | // Retain Oneshot mods | 179 | // Retain Oneshot mods |
| 158 | } | 180 | #if defined(ONESHOT_TAP_TOGGLE) && ONESHOT_TAP_TOGGLE > 1 |
| 159 | else { | 181 | if (mods & get_mods()) { |
| 182 | clear_oneshot_locked_mods(); | ||
| 183 | clear_oneshot_mods(); | ||
| 184 | unregister_mods(mods); | ||
| 185 | } | ||
| 186 | } else if (tap_count == ONESHOT_TAP_TOGGLE) { | ||
| 187 | // Toggle Oneshot Layer | ||
| 188 | #endif | ||
| 189 | } else { | ||
| 160 | clear_oneshot_mods(); | 190 | clear_oneshot_mods(); |
| 161 | unregister_mods(mods); | 191 | unregister_mods(mods); |
| 162 | } | 192 | } |
| @@ -309,6 +339,44 @@ void process_action(keyrecord_t *record) | |||
| 309 | event.pressed ? layer_move(action.layer_tap.val) : | 339 | event.pressed ? layer_move(action.layer_tap.val) : |
| 310 | layer_clear(); | 340 | layer_clear(); |
| 311 | break; | 341 | break; |
| 342 | #ifndef NO_ACTION_ONESHOT | ||
| 343 | case OP_ONESHOT: | ||
| 344 | // Oneshot modifier | ||
| 345 | #if defined(ONESHOT_TAP_TOGGLE) && ONESHOT_TAP_TOGGLE > 1 | ||
| 346 | do_release_oneshot = false; | ||
| 347 | if (event.pressed) { | ||
| 348 | del_mods(get_oneshot_locked_mods()); | ||
| 349 | if (get_oneshot_layer_state() == ONESHOT_TOGGLED) { | ||
| 350 | reset_oneshot_layer(); | ||
| 351 | layer_off(action.layer_tap.val); | ||
| 352 | break; | ||
| 353 | } else if (tap_count < ONESHOT_TAP_TOGGLE) { | ||
| 354 | layer_on(action.layer_tap.val); | ||
| 355 | set_oneshot_layer(action.layer_tap.val, ONESHOT_START); | ||
| 356 | } | ||
| 357 | } else { | ||
| 358 | add_mods(get_oneshot_locked_mods()); | ||
| 359 | if (tap_count >= ONESHOT_TAP_TOGGLE) { | ||
| 360 | reset_oneshot_layer(); | ||
| 361 | clear_oneshot_locked_mods(); | ||
| 362 | set_oneshot_layer(action.layer_tap.val, ONESHOT_TOGGLED); | ||
| 363 | } else { | ||
| 364 | clear_oneshot_layer_state(ONESHOT_PRESSED); | ||
| 365 | } | ||
| 366 | } | ||
| 367 | #else | ||
| 368 | if (event.pressed) { | ||
| 369 | layer_on(action.layer_tap.val); | ||
| 370 | set_oneshot_layer(action.layer_tap.val, ONESHOT_START); | ||
| 371 | } else { | ||
| 372 | clear_oneshot_layer_state(ONESHOT_PRESSED); | ||
| 373 | if (tap_count > 1) { | ||
| 374 | clear_oneshot_layer_state(ONESHOT_OTHER_KEY_PRESSED); | ||
| 375 | } | ||
| 376 | } | ||
| 377 | #endif | ||
| 378 | break; | ||
| 379 | #endif | ||
| 312 | default: | 380 | default: |
| 313 | /* tap key */ | 381 | /* tap key */ |
| 314 | if (event.pressed) { | 382 | if (event.pressed) { |
| @@ -372,6 +440,18 @@ void process_action(keyrecord_t *record) | |||
| 372 | default: | 440 | default: |
| 373 | break; | 441 | break; |
| 374 | } | 442 | } |
| 443 | |||
| 444 | #ifndef NO_ACTION_ONESHOT | ||
| 445 | /* Because we switch layers after a oneshot event, we need to release the | ||
| 446 | * key before we leave the layer or no key up event will be generated. | ||
| 447 | */ | ||
| 448 | if (do_release_oneshot && !(get_oneshot_layer_state() & ONESHOT_PRESSED ) ) { | ||
| 449 | record->event.pressed = false; | ||
| 450 | layer_on(get_oneshot_layer()); | ||
| 451 | process_action(record); | ||
| 452 | layer_off(get_oneshot_layer()); | ||
| 453 | } | ||
| 454 | #endif | ||
| 375 | } | 455 | } |
| 376 | 456 | ||
| 377 | 457 | ||
| @@ -560,6 +640,7 @@ bool is_tap_key(keypos_t key) | |||
| 560 | switch (action.layer_tap.code) { | 640 | switch (action.layer_tap.code) { |
| 561 | case 0x00 ... 0xdf: | 641 | case 0x00 ... 0xdf: |
| 562 | case OP_TAP_TOGGLE: | 642 | case OP_TAP_TOGGLE: |
| 643 | case OP_ONESHOT: | ||
| 563 | return true; | 644 | return true; |
| 564 | } | 645 | } |
| 565 | return false; | 646 | return false; |
diff --git a/tmk_core/common/action_code.h b/tmk_core/common/action_code.h index 2b0b0b077..ca729aaec 100644 --- a/tmk_core/common/action_code.h +++ b/tmk_core/common/action_code.h | |||
| @@ -76,7 +76,8 @@ along with this program. If not, see <http://www.gnu.org/licenses/>. | |||
| 76 | * 101E|LLLL|1111 0001 On/Off (0xF1) [NOT TAP] | 76 | * 101E|LLLL|1111 0001 On/Off (0xF1) [NOT TAP] |
| 77 | * 101E|LLLL|1111 0010 Off/On (0xF2) [NOT TAP] | 77 | * 101E|LLLL|1111 0010 Off/On (0xF2) [NOT TAP] |
| 78 | * 101E|LLLL|1111 0011 Set/Clear (0xF3) [NOT TAP] | 78 | * 101E|LLLL|1111 0011 Set/Clear (0xF3) [NOT TAP] |
| 79 | * 101E|LLLL|1111 xxxx Reserved (0xF4-FF) | 79 | * 101E|LLLL|1111 0100 One Shot Layer (0xF4) [TAP] |
| 80 | * 101E|LLLL|1111 xxxx Reserved (0xF5-FF) | ||
| 80 | * ELLLL: layer 0-31(E: extra bit for layer 16-31) | 81 | * ELLLL: layer 0-31(E: extra bit for layer 16-31) |
| 81 | * | 82 | * |
| 82 | * | 83 | * |
| @@ -250,6 +251,7 @@ enum layer_pram_tap_op { | |||
| 250 | OP_ON_OFF, | 251 | OP_ON_OFF, |
| 251 | OP_OFF_ON, | 252 | OP_OFF_ON, |
| 252 | OP_SET_CLEAR, | 253 | OP_SET_CLEAR, |
| 254 | OP_ONESHOT, | ||
| 253 | }; | 255 | }; |
| 254 | #define ACTION_LAYER_BITOP(op, part, bits, on) (ACT_LAYER<<12 | (op)<<10 | (on)<<8 | (part)<<5 | ((bits)&0x1f)) | 256 | #define ACTION_LAYER_BITOP(op, part, bits, on) (ACT_LAYER<<12 | (op)<<10 | (on)<<8 | (part)<<5 | ((bits)&0x1f)) |
| 255 | #define ACTION_LAYER_TAP(layer, key) (ACT_LAYER_TAP<<12 | (layer)<<8 | (key)) | 257 | #define ACTION_LAYER_TAP(layer, key) (ACT_LAYER_TAP<<12 | (layer)<<8 | (key)) |
| @@ -266,6 +268,7 @@ enum layer_pram_tap_op { | |||
| 266 | #define ACTION_LAYER_ON_OFF(layer) ACTION_LAYER_TAP((layer), OP_ON_OFF) | 268 | #define ACTION_LAYER_ON_OFF(layer) ACTION_LAYER_TAP((layer), OP_ON_OFF) |
| 267 | #define ACTION_LAYER_OFF_ON(layer) ACTION_LAYER_TAP((layer), OP_OFF_ON) | 269 | #define ACTION_LAYER_OFF_ON(layer) ACTION_LAYER_TAP((layer), OP_OFF_ON) |
| 268 | #define ACTION_LAYER_SET_CLEAR(layer) ACTION_LAYER_TAP((layer), OP_SET_CLEAR) | 270 | #define ACTION_LAYER_SET_CLEAR(layer) ACTION_LAYER_TAP((layer), OP_SET_CLEAR) |
| 271 | #define ACTION_LAYER_ONESHOT(layer) ACTION_LAYER_TAP((layer), OP_ONESHOT) | ||
| 269 | #define ACTION_LAYER_MODS(layer, mods) ACTION_LAYER_TAP((layer), 0xe0 | ((mods)&0x0f)) | 272 | #define ACTION_LAYER_MODS(layer, mods) ACTION_LAYER_TAP((layer), 0xe0 | ((mods)&0x0f)) |
| 270 | /* With Tapping */ | 273 | /* With Tapping */ |
| 271 | #define ACTION_LAYER_TAP_KEY(layer, key) ACTION_LAYER_TAP((layer), (key)) | 274 | #define ACTION_LAYER_TAP_KEY(layer, key) ACTION_LAYER_TAP((layer), (key)) |
diff --git a/tmk_core/common/action_util.c b/tmk_core/common/action_util.c index a2d6577b2..61ff202be 100644 --- a/tmk_core/common/action_util.c +++ b/tmk_core/common/action_util.c | |||
| @@ -18,6 +18,7 @@ along with this program. If not, see <http://www.gnu.org/licenses/>. | |||
| 18 | #include "report.h" | 18 | #include "report.h" |
| 19 | #include "debug.h" | 19 | #include "debug.h" |
| 20 | #include "action_util.h" | 20 | #include "action_util.h" |
| 21 | #include "action_layer.h" | ||
| 21 | #include "timer.h" | 22 | #include "timer.h" |
| 22 | 23 | ||
| 23 | static inline void add_key_byte(uint8_t code); | 24 | static inline void add_key_byte(uint8_t code); |
| @@ -47,11 +48,70 @@ report_keyboard_t *keyboard_report = &(report_keyboard_t){}; | |||
| 47 | 48 | ||
| 48 | #ifndef NO_ACTION_ONESHOT | 49 | #ifndef NO_ACTION_ONESHOT |
| 49 | static int8_t oneshot_mods = 0; | 50 | static int8_t oneshot_mods = 0; |
| 51 | static int8_t oneshot_locked_mods = 0; | ||
| 52 | int8_t get_oneshot_locked_mods(void) { return oneshot_locked_mods; } | ||
| 53 | void set_oneshot_locked_mods(int8_t mods) { oneshot_locked_mods = mods; } | ||
| 54 | void clear_oneshot_locked_mods(void) { oneshot_locked_mods = 0; } | ||
| 50 | #if (defined(ONESHOT_TIMEOUT) && (ONESHOT_TIMEOUT > 0)) | 55 | #if (defined(ONESHOT_TIMEOUT) && (ONESHOT_TIMEOUT > 0)) |
| 51 | static int16_t oneshot_time = 0; | 56 | static int16_t oneshot_time = 0; |
| 57 | inline bool has_oneshot_mods_timed_out() { | ||
| 58 | return TIMER_DIFF_16(timer_read(), oneshot_time) >= ONESHOT_TIMEOUT; | ||
| 59 | } | ||
| 52 | #endif | 60 | #endif |
| 53 | #endif | 61 | #endif |
| 54 | 62 | ||
| 63 | /* oneshot layer */ | ||
| 64 | #ifndef NO_ACTION_ONESHOT | ||
| 65 | /* oneshot_layer_data bits | ||
| 66 | * LLLL LSSS | ||
| 67 | * where: | ||
| 68 | * L => are layer bits | ||
| 69 | * S => oneshot state bits | ||
| 70 | */ | ||
| 71 | static int8_t oneshot_layer_data = 0; | ||
| 72 | |||
| 73 | inline uint8_t get_oneshot_layer(void) { return oneshot_layer_data >> 3; } | ||
| 74 | inline uint8_t get_oneshot_layer_state(void) { return oneshot_layer_data & 0b111; } | ||
| 75 | |||
| 76 | #if (defined(ONESHOT_TIMEOUT) && (ONESHOT_TIMEOUT > 0)) | ||
| 77 | static int16_t oneshot_layer_time = 0; | ||
| 78 | inline bool has_oneshot_layer_timed_out() { | ||
| 79 | return TIMER_DIFF_16(timer_read(), oneshot_layer_time) >= ONESHOT_TIMEOUT && | ||
| 80 | !(get_oneshot_layer_state() & ONESHOT_TOGGLED); | ||
| 81 | } | ||
| 82 | #endif | ||
| 83 | |||
| 84 | /* Oneshot layer */ | ||
| 85 | void set_oneshot_layer(uint8_t layer, uint8_t state) | ||
| 86 | { | ||
| 87 | oneshot_layer_data = layer << 3 | state; | ||
| 88 | layer_on(layer); | ||
| 89 | #if (defined(ONESHOT_TIMEOUT) && (ONESHOT_TIMEOUT > 0)) | ||
| 90 | oneshot_layer_time = timer_read(); | ||
| 91 | #endif | ||
| 92 | } | ||
| 93 | void reset_oneshot_layer(void) { | ||
| 94 | oneshot_layer_data = 0; | ||
| 95 | #if (defined(ONESHOT_TIMEOUT) && (ONESHOT_TIMEOUT > 0)) | ||
| 96 | oneshot_layer_time = 0; | ||
| 97 | #endif | ||
| 98 | } | ||
| 99 | void clear_oneshot_layer_state(oneshot_fullfillment_t state) | ||
| 100 | { | ||
| 101 | uint8_t start_state = oneshot_layer_data; | ||
| 102 | oneshot_layer_data &= ~state; | ||
| 103 | if (!get_oneshot_layer_state() && start_state != oneshot_layer_data) { | ||
| 104 | layer_off(get_oneshot_layer()); | ||
| 105 | #if (defined(ONESHOT_TIMEOUT) && (ONESHOT_TIMEOUT > 0)) | ||
| 106 | oneshot_layer_time = 0; | ||
| 107 | #endif | ||
| 108 | } | ||
| 109 | } | ||
| 110 | bool is_oneshot_layer_active(void) | ||
| 111 | { | ||
| 112 | return get_oneshot_layer_state(); | ||
| 113 | } | ||
| 114 | #endif | ||
| 55 | 115 | ||
| 56 | void send_keyboard_report(void) { | 116 | void send_keyboard_report(void) { |
| 57 | keyboard_report->mods = real_mods; | 117 | keyboard_report->mods = real_mods; |
| @@ -60,7 +120,7 @@ void send_keyboard_report(void) { | |||
| 60 | #ifndef NO_ACTION_ONESHOT | 120 | #ifndef NO_ACTION_ONESHOT |
| 61 | if (oneshot_mods) { | 121 | if (oneshot_mods) { |
| 62 | #if (defined(ONESHOT_TIMEOUT) && (ONESHOT_TIMEOUT > 0)) | 122 | #if (defined(ONESHOT_TIMEOUT) && (ONESHOT_TIMEOUT > 0)) |
| 63 | if (TIMER_DIFF_16(timer_read(), oneshot_time) >= ONESHOT_TIMEOUT) { | 123 | if (has_oneshot_mods_timed_out()) { |
| 64 | dprintf("Oneshot: timeout\n"); | 124 | dprintf("Oneshot: timeout\n"); |
| 65 | clear_oneshot_mods(); | 125 | clear_oneshot_mods(); |
| 66 | } | 126 | } |
| @@ -70,6 +130,7 @@ void send_keyboard_report(void) { | |||
| 70 | clear_oneshot_mods(); | 130 | clear_oneshot_mods(); |
| 71 | } | 131 | } |
| 72 | } | 132 | } |
| 133 | |||
| 73 | #endif | 134 | #endif |
| 74 | host_keyboard_send(keyboard_report); | 135 | host_keyboard_send(keyboard_report); |
| 75 | } | 136 | } |
| @@ -143,11 +204,12 @@ void clear_oneshot_mods(void) | |||
| 143 | oneshot_time = 0; | 204 | oneshot_time = 0; |
| 144 | #endif | 205 | #endif |
| 145 | } | 206 | } |
| 207 | uint8_t get_oneshot_mods(void) | ||
| 208 | { | ||
| 209 | return oneshot_mods; | ||
| 210 | } | ||
| 146 | #endif | 211 | #endif |
| 147 | 212 | ||
| 148 | |||
| 149 | |||
| 150 | |||
| 151 | /* | 213 | /* |
| 152 | * inspect keyboard state | 214 | * inspect keyboard state |
| 153 | */ | 215 | */ |
diff --git a/tmk_core/common/action_util.h b/tmk_core/common/action_util.h index 1a95cec10..dd0c4c2bf 100644 --- a/tmk_core/common/action_util.h +++ b/tmk_core/common/action_util.h | |||
| @@ -56,10 +56,30 @@ void clear_macro_mods(void); | |||
| 56 | 56 | ||
| 57 | /* oneshot modifier */ | 57 | /* oneshot modifier */ |
| 58 | void set_oneshot_mods(uint8_t mods); | 58 | void set_oneshot_mods(uint8_t mods); |
| 59 | uint8_t get_oneshot_mods(void); | ||
| 59 | void clear_oneshot_mods(void); | 60 | void clear_oneshot_mods(void); |
| 60 | void oneshot_toggle(void); | 61 | void oneshot_toggle(void); |
| 61 | void oneshot_enable(void); | 62 | void oneshot_enable(void); |
| 62 | void oneshot_disable(void); | 63 | void oneshot_disable(void); |
| 64 | bool has_oneshot_mods_timed_out(void); | ||
| 65 | |||
| 66 | int8_t get_oneshot_locked_mods(void); | ||
| 67 | void set_oneshot_locked_mods(int8_t mods); | ||
| 68 | void clear_oneshot_locked_mods(void); | ||
| 69 | |||
| 70 | typedef enum { | ||
| 71 | ONESHOT_PRESSED = 0b01, | ||
| 72 | ONESHOT_OTHER_KEY_PRESSED = 0b10, | ||
| 73 | ONESHOT_START = 0b11, | ||
| 74 | ONESHOT_TOGGLED = 0b100 | ||
| 75 | } oneshot_fullfillment_t; | ||
| 76 | void set_oneshot_layer(uint8_t layer, uint8_t state); | ||
| 77 | uint8_t get_oneshot_layer(void); | ||
| 78 | void clear_oneshot_layer_state(oneshot_fullfillment_t state); | ||
| 79 | void reset_oneshot_layer(void); | ||
| 80 | bool is_oneshot_layer_active(void); | ||
| 81 | uint8_t get_oneshot_layer_state(void); | ||
| 82 | bool has_oneshot_layer_timed_out(void); | ||
| 63 | 83 | ||
| 64 | /* inspect */ | 84 | /* inspect */ |
| 65 | uint8_t has_anykey(void); | 85 | uint8_t has_anykey(void); |
