diff options
Diffstat (limited to 'tmk_core/common')
| -rw-r--r-- | tmk_core/common/action.c | 82 | ||||
| -rw-r--r-- | tmk_core/common/action.h | 18 | ||||
| -rw-r--r-- | tmk_core/common/action_code.h | 28 | ||||
| -rw-r--r-- | tmk_core/common/virtser.h | 10 | 
4 files changed, 137 insertions, 1 deletions
diff --git a/tmk_core/common/action.c b/tmk_core/common/action.c index be6dea2b79..08ef22eb97 100644 --- a/tmk_core/common/action.c +++ b/tmk_core/common/action.c @@ -41,6 +41,12 @@ void action_exec(keyevent_t event)          dprint("EVENT: "); debug_event(event); dprintln();      } +#ifdef ONEHAND_ENABLE +    if (!IS_NOEVENT(event)) { +        process_hand_swap(&event); +    } +#endif +      keyrecord_t record = { .event = event };  #ifndef NO_ACTION_TAPPING @@ -53,6 +59,26 @@ void action_exec(keyevent_t event)  #endif  } +#ifdef ONEHAND_ENABLE +bool swap_hands = false; + +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 = hand_swap_config[pos.row][pos.col]; +        swap_state[pos.row] |= col_bit; +    } else { +        swap_state[pos.row] &= ~(col_bit); +    } +} +#endif +  #if !defined(NO_ACTION_LAYER) && defined(PREVENT_STUCK_MODIFIERS)  bool disable_action_cache = false; @@ -440,6 +466,54 @@ void process_action(keyrecord_t *record, action_t action)  #endif          case ACT_COMMAND:              break; +#ifdef ONEHAND_ENABLE +        case ACT_SWAP_HANDS: +            switch (action.swap.code) { +                case OP_SH_TOGGLE: +                    if (event.pressed) { +                        swap_hands = !swap_hands; +                    } +                    break; +                case OP_SH_ON_OFF: +                    swap_hands = event.pressed; +                    break; +                case OP_SH_OFF_ON: +                    swap_hands = !event.pressed; +                    break; +                case OP_SH_ON: +                    if (!event.pressed) { +                        swap_hands = true; +                    } +                    break; +                case OP_SH_OFF: +                    if (!event.pressed) { +                        swap_hands = false; +                    } +                    break; +    #ifndef NO_ACTION_TAPPING +                case OP_SH_TAP_TOGGLE: +                    /* tap toggle */ +                    if (tap_count > 0) { +                        if (!event.pressed) { +                            swap_hands = !swap_hands; +                        } +                    } else { +                        swap_hands = event.pressed; +                    } +                    break; +                default: +                    if (tap_count > 0) { +                        if (event.pressed) { +                            register_code(action.swap.code); +                        } else { +                            unregister_code(action.swap.code); +                        } +                    } else { +                        swap_hands = event.pressed; +                    } +    #endif +            } +#endif  #ifndef NO_ACTION_FUNCTION          case ACT_FUNCTION:              action_function(record, action.func.id, action.func.opt); @@ -652,6 +726,13 @@ bool is_tap_key(keypos_t key)                      return true;              }              return false; +        case ACT_SWAP_HANDS: +            switch (action.swap.code) { +                case 0x00 ... 0xdf: +                case OP_SH_TAP_TOGGLE: +                    return true; +            } +            return false;          case ACT_MACRO:          case ACT_FUNCTION:              if (action.func.opt & FUNC_TAP) { return true; } @@ -692,6 +773,7 @@ void debug_action(action_t action)          case ACT_MACRO:             dprint("ACT_MACRO");             break;          case ACT_COMMAND:           dprint("ACT_COMMAND");           break;          case ACT_FUNCTION:          dprint("ACT_FUNCTION");          break; +        case ACT_SWAP_HANDS:        dprint("ACT_SWAP_HANDS");        break;          default:                    dprint("UNKNOWN");               break;      }      dprintf("[%X:%02X]", action.kind.param>>8, action.kind.param&0xff); diff --git a/tmk_core/common/action.h b/tmk_core/common/action.h index e8aa12a7cb..b9bdfe642c 100644 --- a/tmk_core/common/action.h +++ b/tmk_core/common/action.h @@ -65,6 +65,24 @@ bool process_record_quantum(keyrecord_t *record);  #if !defined(NO_ACTION_LAYER) && defined(PREVENT_STUCK_MODIFIERS)  extern bool disable_action_cache;  #endif + +/* Code for handling one-handed key modifiers. */ +#ifdef ONEHAND_ENABLE +extern bool swap_hands; +extern const keypos_t hand_swap_config[MATRIX_ROWS][MATRIX_COLS]; +#if (MATRIX_COLS <= 8) +typedef  uint8_t    swap_state_row_t; +#elif (MATRIX_COLS <= 16) +typedef  uint16_t   swap_state_row_t; +#elif (MATRIX_COLS <= 32) +typedef  uint32_t   swap_state_row_t; +#else +#error "MATRIX_COLS: invalid value" +#endif + +void process_hand_swap(keyevent_t *record); +#endif +  void process_record_nocache(keyrecord_t *record);  void process_record(keyrecord_t *record);  void process_action(keyrecord_t *record, action_t action); diff --git a/tmk_core/common/action_code.h b/tmk_core/common/action_code.h index ca729aaece..33da35f35f 100644 --- a/tmk_core/common/action_code.h +++ b/tmk_core/common/action_code.h @@ -108,6 +108,8 @@ enum action_kind_id {      /* Other Keys */      ACT_USAGE           = 0b0100,      ACT_MOUSEKEY        = 0b0101, +    /* One-hand Support */ +    ACT_SWAP_HANDS      = 0b0110,      /* Layer Actions */      ACT_LAYER           = 0b1000,      ACT_LAYER_TAP       = 0b1010, /* Layer  0-15 */ @@ -178,6 +180,11 @@ typedef union {          uint8_t  opt    :4;          uint8_t  kind   :4;      } func; +    struct action_swap { +        uint8_t  code   :8; +        uint8_t  opt   :4; +        uint8_t  kind   :4; +    } swap;  } action_t; @@ -295,6 +302,7 @@ enum backlight_opt {      BACKLIGHT_STEP     = 3,      BACKLIGHT_LEVEL    = 4,  }; +  /* Macro */  #define ACTION_MACRO(id)                ACTION(ACT_MACRO, (id))  #define ACTION_MACRO_TAP(id)            ACTION(ACT_MACRO, FUNC_TAP<<8 | (id)) @@ -306,7 +314,7 @@ enum backlight_opt {  #define ACTION_BACKLIGHT_STEP()         ACTION(ACT_BACKLIGHT, BACKLIGHT_STEP << 8)  #define ACTION_BACKLIGHT_LEVEL(level)   ACTION(ACT_BACKLIGHT, BACKLIGHT_LEVEL << 8 | (level))  /* Command */ -#define ACTION_COMMAND(id, opt)         ACTION(ACT_COMMAND,  (opt)<<8 | (addr)) +#define ACTION_COMMAND(id, opt)         ACTION(ACT_COMMAND,  (opt)<<8 | (id))  /* Function */  enum function_opts {      FUNC_TAP = 0x8,     /* indciates function is tappable */ @@ -314,5 +322,23 @@ enum function_opts {  #define ACTION_FUNCTION(id)             ACTION(ACT_FUNCTION, (id))  #define ACTION_FUNCTION_TAP(id)         ACTION(ACT_FUNCTION, FUNC_TAP<<8 | (id))  #define ACTION_FUNCTION_OPT(id, opt)    ACTION(ACT_FUNCTION, (opt)<<8 | (id)) +/* OneHand Support */ +enum swap_hands_pram_tap_op { +    OP_SH_TOGGLE = 0xF0, +    OP_SH_TAP_TOGGLE, +    OP_SH_ON_OFF, +    OP_SH_OFF_ON, +    OP_SH_OFF, +    OP_SH_ON, +}; + +#define ACTION_SWAP_HANDS()             ACTION_SWAP_HANDS_ON_OFF() +#define ACTION_SWAP_HANDS_TOGGLE()      ACTION(ACT_SWAP_HANDS, OP_SH_TOGGLE) +#define ACTION_SWAP_HANDS_TAP_TOGGLE()  ACTION(ACT_SWAP_HANDS, OP_SH_TAP_TOGGLE) +#define ACTION_SWAP_HANDS_TAP_KEY(key)  ACTION(ACT_SWAP_HANDS, key) +#define ACTION_SWAP_HANDS_ON_OFF()      ACTION(ACT_SWAP_HANDS, OP_SH_ON_OFF) +#define ACTION_SWAP_HANDS_OFF_ON()      ACTION(ACT_SWAP_HANDS, OP_SH_OFF_ON) +#define ACTION_SWAP_HANDS_ON()          ACTION(ACT_SWAP_HANDS, OP_SH_ON) +#define ACTION_SWAP_HANDS_OFF()         ACTION(ACT_SWAP_HANDS, OP_SH_OFF)  #endif /* ACTION_CODE_H */ diff --git a/tmk_core/common/virtser.h b/tmk_core/common/virtser.h new file mode 100644 index 0000000000..74891b6ae0 --- /dev/null +++ b/tmk_core/common/virtser.h @@ -0,0 +1,10 @@ +#ifndef _VIRTSER_H_ +#define _VIRTSER_H_ + +/* Define this function in your code to process incoming bytes */ +void virtser_recv(const uint8_t ch); + +/* Call this to send a character over the Virtual Serial Device */ +void virtser_send(const uint8_t byte); + +#endif  | 
