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); | 
