diff options
Diffstat (limited to 'quantum/action.c')
-rw-r--r-- | quantum/action.c | 95 |
1 files changed, 67 insertions, 28 deletions
diff --git a/quantum/action.c b/quantum/action.c index 3efed443a3..4e81a5466f 100644 --- a/quantum/action.c +++ b/quantum/action.c @@ -14,9 +14,18 @@ GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see <http://www.gnu.org/licenses/>. */ +#include <limits.h> + +#ifdef DEBUG_ACTION +# include "debug.h" +#else +# include "nodebug.h" +#endif + #include "host.h" #include "keycode.h" #include "keyboard.h" +#include "keymap.h" #include "mousekey.h" #include "programmable_button.h" #include "command.h" @@ -32,12 +41,6 @@ along with this program. If not, see <http://www.gnu.org/licenses/>. # include "backlight.h" #endif -#ifdef DEBUG_ACTION -# include "debug.h" -#else -# include "nodebug.h" -#endif - #ifdef POINTING_DEVICE_ENABLE # include "pointing_device.h" #endif @@ -89,6 +92,7 @@ void action_exec(keyevent_t event) { } #ifdef SWAP_HANDS_ENABLE + // Swap hands handles both keys and encoders, if ENCODER_MAP_ENABLE is defined. if (!IS_NOEVENT(event)) { process_hand_swap(&event); } @@ -97,7 +101,7 @@ void action_exec(keyevent_t event) { keyrecord_t record = {.event = event}; #ifndef NO_ACTION_ONESHOT - if (!keymap_config.oneshot_disable) { + if (keymap_config.oneshot_enable) { # if (defined(ONESHOT_TIMEOUT) && (ONESHOT_TIMEOUT > 0)) if (has_oneshot_layer_timed_out()) { clear_oneshot_layer_state(ONESHOT_OTHER_KEY_PRESSED); @@ -136,27 +140,65 @@ void action_exec(keyevent_t event) { } #ifdef SWAP_HANDS_ENABLE +extern const keypos_t PROGMEM hand_swap_config[MATRIX_ROWS][MATRIX_COLS]; +# ifdef ENCODER_MAP_ENABLE +extern const uint8_t PROGMEM encoder_hand_swap_config[NUM_ENCODERS]; +# endif // ENCODER_MAP_ENABLE + bool swap_hands = false; bool swap_held = false; +bool should_swap_hands(size_t index, uint8_t *swap_state, bool pressed) { + size_t array_index = index / (CHAR_BIT); + size_t bit_index = index % (CHAR_BIT); + uint8_t bit_val = 1 << bit_index; + bool do_swap = pressed ? swap_hands : swap_state[array_index] & bit_val; + return do_swap; +} + +void set_swap_hands_state(size_t index, uint8_t *swap_state, bool on) { + size_t array_index = index / (CHAR_BIT); + size_t bit_index = index % (CHAR_BIT); + uint8_t bit_val = 1 << bit_index; + if (on) { + swap_state[array_index] |= bit_val; + } else { + swap_state[array_index] &= ~bit_val; + } +} + /** \brief Process Hand Swap * * FIXME: Needs documentation. */ void process_hand_swap(keyevent_t *event) { - static swap_state_row_t swap_state[MATRIX_ROWS]; - - keypos_t pos = event->key; - swap_state_row_t col_bit = (swap_state_row_t)1 << pos.col; - bool do_swap = event->pressed ? swap_hands : swap_state[pos.row] & (col_bit); - - if (do_swap) { - event->key.row = pgm_read_byte(&hand_swap_config[pos.row][pos.col].row); - event->key.col = pgm_read_byte(&hand_swap_config[pos.row][pos.col].col); - swap_state[pos.row] |= col_bit; - } else { - swap_state[pos.row] &= ~(col_bit); + keypos_t pos = event->key; + if (pos.row < MATRIX_ROWS && pos.col < MATRIX_COLS) { + static uint8_t matrix_swap_state[((MATRIX_ROWS * MATRIX_COLS) + (CHAR_BIT)-1) / (CHAR_BIT)]; + size_t index = (size_t)(pos.row * MATRIX_COLS) + pos.col; + bool do_swap = should_swap_hands(index, matrix_swap_state, event->pressed); + if (do_swap) { + event->key.row = pgm_read_byte(&hand_swap_config[pos.row][pos.col].row); + event->key.col = pgm_read_byte(&hand_swap_config[pos.row][pos.col].col); + set_swap_hands_state(index, matrix_swap_state, true); + } else { + set_swap_hands_state(index, matrix_swap_state, false); + } + } +# ifdef ENCODER_MAP_ENABLE + else if (pos.row == KEYLOC_ENCODER_CW || pos.row == KEYLOC_ENCODER_CCW) { + static uint8_t encoder_swap_state[((NUM_ENCODERS) + (CHAR_BIT)-1) / (CHAR_BIT)]; + size_t index = pos.col; + bool do_swap = should_swap_hands(index, encoder_swap_state, event->pressed); + if (do_swap) { + event->key.row = pos.row; + event->key.col = pgm_read_byte(&encoder_hand_swap_config[pos.col]); + set_swap_hands_state(index, encoder_swap_state, true); + } else { + set_swap_hands_state(index, encoder_swap_state, false); + } } +# endif // ENCODER_MAP_ENABLE } #endif @@ -216,7 +258,7 @@ void process_record(keyrecord_t *record) { if (!process_record_quantum(record)) { #ifndef NO_ACTION_ONESHOT - if (is_oneshot_layer_active() && record->event.pressed && !keymap_config.oneshot_disable) { + if (is_oneshot_layer_active() && record->event.pressed && keymap_config.oneshot_enable) { clear_oneshot_layer_state(ONESHOT_OTHER_KEY_PRESSED); } #endif @@ -281,7 +323,7 @@ void process_action(keyrecord_t *record, action_t action) { # ifdef SWAP_HANDS_ENABLE && !(action.kind.id == ACT_SWAP_HANDS && action.swap.code == OP_SH_ONESHOT) # endif - && !keymap_config.oneshot_disable) { + && keymap_config.oneshot_enable) { clear_oneshot_layer_state(ONESHOT_OTHER_KEY_PRESSED); do_release_oneshot = !is_oneshot_layer_active(); } @@ -325,7 +367,7 @@ void process_action(keyrecord_t *record, action_t action) { # ifndef NO_ACTION_ONESHOT case MODS_ONESHOT: // Oneshot modifier - if (keymap_config.oneshot_disable) { + if (!keymap_config.oneshot_enable) { if (event.pressed) { if (mods) { if (IS_MOD(action.key.code) || action.key.code == KC_NO) { @@ -362,7 +404,7 @@ void process_action(keyrecord_t *record, action_t action) { } else if (tap_count == ONESHOT_TAP_TOGGLE) { dprint("MODS_TAP: Toggling oneshot"); clear_oneshot_mods(); - set_oneshot_locked_mods(mods); + set_oneshot_locked_mods(mods | get_oneshot_locked_mods()); register_mods(mods); # endif } else { @@ -376,8 +418,8 @@ void process_action(keyrecord_t *record, action_t action) { // Retain Oneshot mods # if defined(ONESHOT_TAP_TOGGLE) && ONESHOT_TAP_TOGGLE > 1 if (mods & get_mods()) { - clear_oneshot_locked_mods(); clear_oneshot_mods(); + set_oneshot_locked_mods(~mods & get_oneshot_locked_mods()); unregister_mods(mods); } } else if (tap_count == ONESHOT_TAP_TOGGLE) { @@ -571,7 +613,7 @@ void process_action(keyrecord_t *record, action_t action) { # ifndef NO_ACTION_ONESHOT case OP_ONESHOT: // Oneshot modifier - if (keymap_config.oneshot_disable) { + if (!keymap_config.oneshot_enable) { if (event.pressed) { layer_on(action.layer_tap.val); } else { @@ -581,7 +623,6 @@ void process_action(keyrecord_t *record, action_t action) { # if defined(ONESHOT_TAP_TOGGLE) && ONESHOT_TAP_TOGGLE > 1 do_release_oneshot = false; if (event.pressed) { - del_mods(get_oneshot_locked_mods()); if (get_oneshot_layer_state() == ONESHOT_TOGGLED) { reset_oneshot_layer(); layer_off(action.layer_tap.val); @@ -591,10 +632,8 @@ void process_action(keyrecord_t *record, action_t action) { set_oneshot_layer(action.layer_tap.val, ONESHOT_START); } } else { - add_mods(get_oneshot_locked_mods()); if (tap_count >= ONESHOT_TAP_TOGGLE) { reset_oneshot_layer(); - clear_oneshot_locked_mods(); set_oneshot_layer(action.layer_tap.val, ONESHOT_TOGGLED); } else { clear_oneshot_layer_state(ONESHOT_PRESSED); |