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 | } |