diff options
Diffstat (limited to 'quantum/process_keycode/process_steno.c')
| -rw-r--r-- | quantum/process_keycode/process_steno.c | 115 |
1 files changed, 92 insertions, 23 deletions
diff --git a/quantum/process_keycode/process_steno.c b/quantum/process_keycode/process_steno.c index 211f00a5a..a91268666 100644 --- a/quantum/process_keycode/process_steno.c +++ b/quantum/process_keycode/process_steno.c | |||
| @@ -1,12 +1,8 @@ | |||
| 1 | #include "process_steno.h" | 1 | #include "process_steno.h" |
| 2 | #include "quantum_keycodes.h" | 2 | #include "quantum_keycodes.h" |
| 3 | #include "keymap_steno.h" | 3 | #include "keymap_steno.h" |
| 4 | #include "virtser.h" | 4 | #include "virtser.h" |
| 5 | 5 | ||
| 6 | uint8_t state[4] = {0}; | ||
| 7 | uint8_t pressed = 0; | ||
| 8 | |||
| 9 | |||
| 10 | // TxBolt Codes | 6 | // TxBolt Codes |
| 11 | #define TXB_NUL 0 | 7 | #define TXB_NUL 0 |
| 12 | #define TXB_S_L 0b00000001 | 8 | #define TXB_S_L 0b00000001 |
| @@ -41,6 +37,13 @@ uint8_t pressed = 0; | |||
| 41 | 37 | ||
| 42 | #define TXB_GET_GROUP(code) ((code & TXB_GRPMASK) >> 6) | 38 | #define TXB_GET_GROUP(code) ((code & TXB_GRPMASK) >> 6) |
| 43 | 39 | ||
| 40 | #define BOLT_STATE_SIZE 4 | ||
| 41 | #define GEMINI_STATE_SIZE 6 | ||
| 42 | |||
| 43 | uint8_t state[MAX(BOLT_STATE_SIZE, GEMINI_STATE_SIZE)] = {0}; | ||
| 44 | uint8_t pressed = 0; | ||
| 45 | steno_mode_t mode; | ||
| 46 | |||
| 44 | uint8_t boltmap[64] = { | 47 | uint8_t boltmap[64] = { |
| 45 | TXB_NUL, TXB_NUM, TXB_NUM, TXB_NUM, TXB_NUM, TXB_NUM, TXB_NUM, | 48 | TXB_NUL, TXB_NUM, TXB_NUM, TXB_NUM, TXB_NUM, TXB_NUM, TXB_NUM, |
| 46 | TXB_S_L, TXB_S_L, TXB_T_L, TXB_K_L, TXB_P_L, TXB_W_L, TXB_H_L, | 49 | TXB_S_L, TXB_S_L, TXB_T_L, TXB_K_L, TXB_P_L, TXB_W_L, TXB_H_L, |
| @@ -52,31 +55,97 @@ uint8_t boltmap[64] = { | |||
| 52 | 55 | ||
| 53 | #define BOLTMAP_MASK (sizeof(boltmap) - 1) | 56 | #define BOLTMAP_MASK (sizeof(boltmap) - 1) |
| 54 | 57 | ||
| 55 | void send_steno_state(void) { | 58 | |
| 56 | for (uint8_t i = 0; i < 4; ++i) { | 59 | void steno_clear_state(void) { |
| 57 | if (state[i]) { | 60 | memset(state, 0, sizeof(state)); |
| 61 | } | ||
| 62 | |||
| 63 | void steno_init() { | ||
| 64 | if (!eeconfig_is_enabled()) { | ||
| 65 | eeconfig_init(); | ||
| 66 | } | ||
| 67 | mode = eeprom_read_byte(EECONFIG_STENOMODE); | ||
| 68 | } | ||
| 69 | |||
| 70 | void steno_set_mode(steno_mode_t new_mode) { | ||
| 71 | steno_clear_state(); | ||
| 72 | mode = new_mode; | ||
| 73 | eeprom_update_byte(EECONFIG_STENOMODE, mode); | ||
| 74 | } | ||
| 75 | |||
| 76 | void send_steno_state(uint8_t size, bool send_empty) { | ||
| 77 | for (uint8_t i = 0; i < size; ++i) { | ||
| 78 | if (state[i] || send_empty) { | ||
| 58 | virtser_send(state[i]); | 79 | virtser_send(state[i]); |
| 59 | state[i] = 0; | ||
| 60 | } | 80 | } |
| 61 | } | 81 | } |
| 62 | virtser_send(0); | 82 | steno_clear_state(); |
| 83 | } | ||
| 84 | |||
| 85 | bool update_state_bolt(uint8_t key) { | ||
| 86 | uint8_t boltcode = boltmap[key]; | ||
| 87 | state[TXB_GET_GROUP(boltcode)] |= boltcode; | ||
| 88 | return false; | ||
| 89 | } | ||
| 90 | |||
| 91 | bool send_state_bolt(void) { | ||
| 92 | send_steno_state(BOLT_STATE_SIZE, false); | ||
| 93 | virtser_send(0); // terminating byte | ||
| 94 | return false; | ||
| 95 | } | ||
| 96 | |||
| 97 | bool update_state_gemini(uint8_t key) { | ||
| 98 | state[key / 7] |= 1 << (6 - (key % 7)); | ||
| 99 | return false; | ||
| 100 | } | ||
| 101 | |||
| 102 | bool send_state_gemini(void) { | ||
| 103 | state[0] |= 0x80; // Indicate start of packet | ||
| 104 | send_steno_state(GEMINI_STATE_SIZE, true); | ||
| 105 | return false; | ||
| 63 | } | 106 | } |
| 64 | 107 | ||
| 65 | bool process_steno(uint16_t keycode, keyrecord_t *record) { | 108 | bool process_steno(uint16_t keycode, keyrecord_t *record) { |
| 66 | if(keycode >= QK_STENO && keycode <= QK_STENO_MAX) { | 109 | switch (keycode) { |
| 67 | if(IS_PRESSED(record->event)) { | 110 | case QK_STENO_BOLT: |
| 68 | uint8_t boltcode = boltmap[keycode & BOLTMAP_MASK]; | 111 | if (IS_PRESSED(record->event)) { |
| 69 | ++pressed; | 112 | steno_set_mode(STENO_MODE_BOLT); |
| 70 | state[TXB_GET_GROUP(boltcode)] |= boltcode; | ||
| 71 | } else { | ||
| 72 | --pressed; | ||
| 73 | if (pressed <= 0) { | ||
| 74 | pressed = 0; // protect against spurious up keys | ||
| 75 | send_steno_state(); | ||
| 76 | } | 113 | } |
| 77 | } | 114 | return false; |
| 78 | return false; | 115 | |
| 79 | } | 116 | case QK_STENO_GEMINI: |
| 117 | if (IS_PRESSED(record->event)) { | ||
| 118 | steno_set_mode(STENO_MODE_GEMINI); | ||
| 119 | } | ||
| 120 | return false; | ||
| 80 | 121 | ||
| 122 | case STN__MIN...STN__MAX: | ||
| 123 | if (IS_PRESSED(record->event)) { | ||
| 124 | uint8_t key = keycode - QK_STENO; | ||
| 125 | ++pressed; | ||
| 126 | switch(mode) { | ||
| 127 | case STENO_MODE_BOLT: | ||
| 128 | return update_state_bolt(key); | ||
| 129 | case STENO_MODE_GEMINI: | ||
| 130 | return update_state_gemini(key); | ||
| 131 | default: | ||
| 132 | return false; | ||
| 133 | } | ||
| 134 | } else { | ||
| 135 | --pressed; | ||
| 136 | if (pressed <= 0) { | ||
| 137 | pressed = 0; | ||
| 138 | switch(mode) { | ||
| 139 | case STENO_MODE_BOLT: | ||
| 140 | return send_state_bolt(); | ||
| 141 | case STENO_MODE_GEMINI: | ||
| 142 | return send_state_gemini(); | ||
| 143 | default: | ||
| 144 | return false; | ||
| 145 | } | ||
| 146 | } | ||
| 147 | } | ||
| 148 | |||
| 149 | } | ||
| 81 | return true; | 150 | return true; |
| 82 | } | 151 | } |
