X-Git-Url: https://git.donarmstrong.com/?a=blobdiff_plain;f=tmk_core%2Fcommon%2Faction_layer.c;h=dfcbc110ad1941ef4cea4c9223f0dc2970dbcf75;hb=e717dcaa09143615ae0b46bf625621f67a7b55ce;hp=a3c7579642770620542924557072f3ffbf5acd50;hpb=a36b2a0756761513a9853af78d61e8b666b34aa7;p=qmk_firmware.git diff --git a/tmk_core/common/action_layer.c b/tmk_core/common/action_layer.c index a3c757964..dfcbc110a 100644 --- a/tmk_core/common/action_layer.c +++ b/tmk_core/common/action_layer.c @@ -11,193 +11,317 @@ #endif -/* - * Default Layer State +/** \brief Default Layer State */ -uint32_t default_layer_state = 0; +layer_state_t default_layer_state = 0; -static void default_layer_state_set(uint32_t state) -{ - debug("default_layer_state: "); - default_layer_debug(); debug(" to "); - default_layer_state = state; - default_layer_debug(); debug("\n"); - clear_keyboard_but_mods(); // To avoid stuck keys +/** \brief Default Layer State Set At user Level + * + * Run user code on default layer state change + */ +__attribute__((weak)) +layer_state_t default_layer_state_set_user(layer_state_t state) { + return state; +} + +/** \brief Default Layer State Set At Keyboard Level + * + * Run keyboard code on default layer state change + */ +__attribute__((weak)) +layer_state_t default_layer_state_set_kb(layer_state_t state) { + return default_layer_state_set_user(state); +} + +/** \brief Default Layer State Set + * + * Static function to set the default layer state, prints debug info and clears keys + */ +static void default_layer_state_set(layer_state_t state) { + state = default_layer_state_set_kb(state); + debug("default_layer_state: "); + default_layer_debug(); debug(" to "); + default_layer_state = state; + default_layer_debug(); debug("\n"); +#ifdef STRICT_LAYER_RELEASE + clear_keyboard_but_mods(); // To avoid stuck keys +#else + clear_keyboard_but_mods_and_keys(); // Don't reset held keys +#endif } -void default_layer_debug(void) -{ - dprintf("%08lX(%u)", default_layer_state, biton32(default_layer_state)); +/** \brief Default Layer Print + * + * Print out the hex value of the 32-bit default layer state, as well as the value of the highest bit. + */ +void default_layer_debug(void) { + dprintf("%08lX(%u)", default_layer_state, biton32(default_layer_state)); } -void default_layer_set(uint32_t state) -{ - default_layer_state_set(state); +/** \brief Default Layer Set + * + * Sets the default layer state. + */ +void default_layer_set(layer_state_t state) { + default_layer_state_set(state); } #ifndef NO_ACTION_LAYER -void default_layer_or(uint32_t state) -{ - default_layer_state_set(default_layer_state | state); +/** \brief Default Layer Or + * + * Turns on the default layer based on matching bits between specifed layer and existing layer state + */ +void default_layer_or(layer_state_t state) { + default_layer_state_set(default_layer_state | state); } -void default_layer_and(uint32_t state) -{ - default_layer_state_set(default_layer_state & state); +/** \brief Default Layer And + * + * Turns on default layer based on matching enabled bits between specifed layer and existing layer state + */ +void default_layer_and(layer_state_t state) { + default_layer_state_set(default_layer_state & state); } -void default_layer_xor(uint32_t state) -{ - default_layer_state_set(default_layer_state ^ state); +/** \brief Default Layer Xor + * + * Turns on default layer based on non-matching bits between specifed layer and existing layer state + */ +void default_layer_xor(layer_state_t state) { + default_layer_state_set(default_layer_state ^ state); } #endif #ifndef NO_ACTION_LAYER -/* - * Keymap Layer State +/** \brief Keymap Layer State + */ +layer_state_t layer_state = 0; + +/** \brief Layer state set user + * + * Runs user code on layer state change + */ +__attribute__((weak)) +layer_state_t layer_state_set_user(layer_state_t state) { + return state; +} + +/** \brief Layer state set keyboard + * + * Runs keyboard code on layer state change + */ +__attribute__((weak)) +layer_state_t layer_state_set_kb(layer_state_t state) { + return layer_state_set_user(state); +} + +/** \brief Layer state set + * + * Sets the layer to match the specifed state (a bitmask) + */ +void layer_state_set(layer_state_t state) { + state = layer_state_set_kb(state); + dprint("layer_state: "); + layer_debug(); dprint(" to "); + layer_state = state; + layer_debug(); dprintln(); +#ifdef STRICT_LAYER_RELEASE + clear_keyboard_but_mods(); // To avoid stuck keys +#else + clear_keyboard_but_mods_and_keys(); // Don't reset held keys +#endif +} + +/** \brief Layer clear + * + * Turn off all layers */ -uint32_t layer_state = 0; +void layer_clear(void) { + layer_state_set(0); +} -static void layer_state_set(uint32_t state) -{ - dprint("layer_state: "); - layer_debug(); dprint(" to "); - layer_state = state; - layer_debug(); dprintln(); - clear_keyboard_but_mods(); // To avoid stuck keys +/** \brief Layer state is + * + * Return whether the given state is on (it might still be shadowed by a higher state, though) + */ +bool layer_state_is(uint8_t layer) { + return layer_state_cmp(layer_state, layer); } -void layer_clear(void) -{ - layer_state_set(0); +/** \brief Layer state compare + * + * Used for comparing layers {mostly used for unit testing} + */ +bool layer_state_cmp(layer_state_t cmp_layer_state, uint8_t layer) { + if (!cmp_layer_state) { return layer == 0; } + return (cmp_layer_state & (1UL<= 0; i--) { - if (layers & (1UL<= 0; i--) { + if (layers & (1UL << i)) { + action = action_for_key(i, key); + if (action.code != ACTION_TRANSPARENT) { + return i; + } } - /* fall back to layer 0 */ - return 0; + } + /* fall back to layer 0 */ + return 0; #else - return biton32(default_layer_state); + return biton32(default_layer_state); #endif } -action_t layer_switch_get_action(keypos_t key) -{ - return action_for_key(layer_switch_get_layer(key), key); +/** \brief Layer switch get layer + * + * Gets action code based on key position + */ +action_t layer_switch_get_action(keypos_t key) { + return action_for_key(layer_switch_get_layer(key), key); }