aboutsummaryrefslogtreecommitdiff
path: root/keyboards/georgi/sten.h
diff options
context:
space:
mode:
Diffstat (limited to 'keyboards/georgi/sten.h')
-rw-r--r--keyboards/georgi/sten.h277
1 files changed, 32 insertions, 245 deletions
diff --git a/keyboards/georgi/sten.h b/keyboards/georgi/sten.h
index fee05deca..5a9771d9a 100644
--- a/keyboards/georgi/sten.h
+++ b/keyboards/georgi/sten.h
@@ -1,28 +1,43 @@
1// 2019, g Heavy Industries 1// 2019, g Heavy Industries
2// Blessed mother of Christ, please keep this readable
3// and protect us from segfaults. For thine is the clock,
4// the slave and the master. Until we return from main.
5//
6// Amen.
2 7
3#include QMK_KEYBOARD_H 8#include QMK_KEYBOARD_H
4#include "mousekey.h" 9#include "mousekey.h"
5#include "keymap.h" 10#include "keymap.h"
6#include "keymap_steno.h" 11#include "keymap_steno.h"
12#include "wait.h"
7 13
8// Bitfield representing the current chord 14extern size_t keymapsCount; // Total keymaps
9uint32_t cChord = 0; 15extern uint32_t cChord; // Current Chord
10 16
11// See if a given chord is pressed. 17// Function defs
12// P will return 18void processChord(bool useFakeSteno);
13// PJ will continue processing, removing the found chord 19uint32_t processQwerty(bool lookup);
14#define P(chord, act) if (cChord == (chord)) { act; return true; } 20uint32_t processFakeSteno(bool lookup);
15#define PJ(chord, act) if ((cChord & (chord)) == (chord)) { cChord ^= chord; act; } 21void saveState(uint32_t cChord);
22void restoreState(void);
23
24// Macros for use in keymap.c
25void SEND(uint8_t kc);
26void REPEAT(void);
27void SET_STICKY(uint32_t);
28void SWITCH_LAYER(int);
29void CLICK_MOUSE(uint8_t);
30
31// Keymap helper
32#define P(chord, act) if (cChord == (chord)) { if (!lookup) {act;} return chord;}
16 33
17// All Steno Codes
18// Shift to internal representation 34// Shift to internal representation
35// i.e) S(teno)R(ight)F
19#define STN(n) (1L<<n) 36#define STN(n) (1L<<n)
20
21//i.e) S(teno)R(ight)F
22enum ORDER { 37enum ORDER {
23 SFN = 0, SPWR, SST1, SST2, SST3, SST4, SNUM, 38 SFN = 0, SPWR, SST1, SST2, SST3, SST4, SNUML, SNUMR,
24 SLSU, SLSD, SLT, SLK, SLP, SLW, SLH, SLR, SLA, SLO, 39 SLSU, SLSD, SLT, SLK, SLP, SLW, SLH, SLR, SLA, SLO,
25 SRE, SRU, SRF, SRR, SRP, SRB, SRL, SRG, SRT, SRS, SRD, SRZ 40 SRE, SRU, SRF, SRR, SRP, SRB, SRL, SRG, SRT, SRS, SRD, SRZ, SRES1, SRES2
26}; 41};
27 42
28// Break it all out 43// Break it all out
@@ -32,11 +47,14 @@ enum ORDER {
32#define ST2 STN(SST2) 47#define ST2 STN(SST2)
33#define ST3 STN(SST3) 48#define ST3 STN(SST3)
34#define ST4 STN(SST4) 49#define ST4 STN(SST4)
35#define NUM STN(SNUM) // No distinction between left and right 50#define LNO STN(SNUML) // STN1-6
51#define RNO STN(SNUMR) // STN7-C
52#define RES1 STN(SRES1) // Use reserved for sticky state
53#define RES2 STN(SRES2)
36 54
37#define LSU STN(SLSU) 55#define LSU STN(SLSU)
38#define LSD STN(SLSD) 56#define LSD STN(SLSD)
39#define LFT STN(SLT) // (L)e(F)t (T), preprocessor conflict 57#define LFT STN(SLT) // (L)e(F)t (T), preprocessor conflict
40#define LK STN(SLK) 58#define LK STN(SLK)
41#define LP STN(SLP) 59#define LP STN(SLP)
42#define LW STN(SLW) 60#define LW STN(SLW)
@@ -57,234 +75,3 @@ enum ORDER {
57#define RS STN(SRS) 75#define RS STN(SRS)
58#define RD STN(SRD) 76#define RD STN(SRD)
59#define RZ STN(SRZ) 77#define RZ STN(SRZ)
60
61bool processQwerty(void);
62bool processFakeSteno(void);
63void clickMouse(uint8_t kc);
64void SEND(uint8_t kc);
65extern int getKeymapCount(void);
66
67// Mode state
68enum MODE { STENO = 0, QWERTY, COMMAND };
69enum MODE cMode = STENO;
70enum MODE pMode;
71bool QWERSTENO = false;
72
73// Command State
74#define MAX_CMD_BUF 20
75uint8_t CMDBUF[MAX_CMD_BUF];
76uint8_t CMDLEN = 0;
77
78// Key Repeat state
79bool inChord = false;
80uint16_t repTimer = 0;
81#define REP_DELAY 300
82
83// Mousekeys state
84bool inMouse = false;
85int8_t mousePress;
86
87// All processing done at chordUp goes through here
88bool send_steno_chord_user(steno_mode_t mode, uint8_t chord[6]) {
89 // Check for mousekeys, this is release
90#ifdef MOUSEKEY_ENABLE
91 if (inMouse) {
92 inMouse = false;
93 mousekey_off(mousePress);
94 mousekey_send();
95 }
96#endif
97
98 // Toggle Serial/QWERTY steno
99 if (cChord == (PWR | FN | ST1 | ST2)) {
100 uprintf("Fallback Toggle\n");
101 QWERSTENO = !QWERSTENO;
102
103 goto out;
104 }
105
106 // handle command mode
107 if (cChord == (PWR | FN | RD | RZ)) {
108 uprintf("COMMAND Toggle\n");
109 if (cMode != COMMAND) { // Entering Command Mode
110 CMDLEN = 0;
111 pMode = cMode;
112 cMode = COMMAND;
113 } else { // Exiting Command Mode
114 cMode = pMode;
115
116 // Press all and release all
117 for (int i = 0; i < CMDLEN; i++) {
118 register_code(CMDBUF[i]);
119 }
120 clear_keyboard();
121 }
122
123 goto out;
124 }
125
126 // Handle Gaming Toggle,
127 if (cChord == (PWR | FN | ST2 | ST3) && getKeymapCount() > 1) {
128 uprintf("Switching to QMK\n");
129 layer_on(1);
130 goto out;
131 }
132
133 // Lone FN press, toggle QWERTY
134 if (cChord == FN) {
135 (cMode == STENO) ? (cMode = QWERTY) : (cMode = STENO);
136 goto out;
137 }
138
139 // Check for Plover momentary
140 if (cMode == QWERTY && (cChord & FN)) {
141 cChord ^= FN;
142 goto steno;
143 }
144
145 // Do QWERTY and Momentary QWERTY
146 if (cMode == QWERTY || (cMode == COMMAND) || (cChord & (FN | PWR))) {
147 if (cChord & FN) cChord ^= FN;
148 processQwerty();
149 goto out;
150 }
151
152 // Fallback NKRO Steno
153 if (cMode == STENO && QWERSTENO) {
154 processFakeSteno();
155 goto out;
156 }
157
158steno:
159 // Hey that's a steno chord!
160 inChord = false;
161 cChord = 0;
162 return true;
163
164out:
165 inChord = false;
166 clear_keyboard();
167 cChord = 0;
168 return false;
169}
170
171// Update Chord State
172bool process_steno_user(uint16_t keycode, keyrecord_t *record) {
173 // Everything happens in here when steno keys come in.
174 // Bail on keyup
175 if (!record->event.pressed) return true;
176
177 // Update key repeat timers
178 repTimer = timer_read();
179 inChord = true;
180
181 // Switch on the press adding to chord
182 bool pr = record->event.pressed;
183 switch (keycode) {
184 // Mods and stuff
185 case STN_ST1: pr ? (cChord |= (ST1)): (cChord &= ~(ST1)); break;
186 case STN_ST2: pr ? (cChord |= (ST2)): (cChord &= ~(ST2)); break;
187 case STN_ST3: pr ? (cChord |= (ST3)): (cChord &= ~(ST3)); break;
188 case STN_ST4: pr ? (cChord |= (ST4)): (cChord &= ~(ST4)); break;
189 case STN_FN: pr ? (cChord |= (FN)) : (cChord &= ~(FN)); break;
190 case STN_PWR: pr ? (cChord |= (PWR)): (cChord &= ~(PWR)); break;
191 case STN_N1...STN_N6:
192 case STN_N7...STN_NC: pr ? (cChord |= (NUM)): (cChord &= ~(NUM)); break;
193
194 // All the letter keys
195 case STN_S1: pr ? (cChord |= (LSU)) : (cChord &= ~(LSU)); break;
196 case STN_S2: pr ? (cChord |= (LSD)) : (cChord &= ~(LSD)); break;
197 case STN_TL: pr ? (cChord |= (LFT)) : (cChord &= ~(LFT)); break;
198 case STN_KL: pr ? (cChord |= (LK)) : (cChord &= ~(LK)); break;
199 case STN_PL: pr ? (cChord |= (LP)) : (cChord &= ~(LP)); break;
200 case STN_WL: pr ? (cChord |= (LW)) : (cChord &= ~(LW)); break;
201 case STN_HL: pr ? (cChord |= (LH)) : (cChord &= ~(LH)); break;
202 case STN_RL: pr ? (cChord |= (LR)) : (cChord &= ~(LR)); break;
203 case STN_A: pr ? (cChord |= (LA)) : (cChord &= ~(LA)); break;
204 case STN_O: pr ? (cChord |= (LO)) : (cChord &= ~(LO)); break;
205 case STN_E: pr ? (cChord |= (RE)) : (cChord &= ~(RE)); break;
206 case STN_U: pr ? (cChord |= (RU)) : (cChord &= ~(RU)); break;
207 case STN_FR: pr ? (cChord |= (RF)) : (cChord &= ~(RF)); break;
208 case STN_RR: pr ? (cChord |= (RR)) : (cChord &= ~(RR)); break;
209 case STN_PR: pr ? (cChord |= (RP)) : (cChord &= ~(RP)); break;
210 case STN_BR: pr ? (cChord |= (RB)) : (cChord &= ~(RB)); break;
211 case STN_LR: pr ? (cChord |= (RL)) : (cChord &= ~(RL)); break;
212 case STN_GR: pr ? (cChord |= (RG)) : (cChord &= ~(RG)); break;
213 case STN_TR: pr ? (cChord |= (RT)) : (cChord &= ~(RT)); break;
214 case STN_SR: pr ? (cChord |= (RS)) : (cChord &= ~(RS)); break;
215 case STN_DR: pr ? (cChord |= (RD)) : (cChord &= ~(RD)); break;
216 case STN_ZR: pr ? (cChord |= (RZ)) : (cChord &= ~(RZ)); break;
217 }
218
219 // Check for key repeat in QWERTY mode
220 return true;
221}
222void matrix_scan_user(void) {
223 // We abuse this for early sending of key
224 // Key repeat only on QWER/SYMB layers
225 if (cMode != QWERTY) return;
226
227 // Check timers
228 if (timer_elapsed(repTimer) > REP_DELAY) {
229 // Process Key for report
230 processQwerty();
231
232 // Send report to host
233 send_keyboard_report();
234 repTimer = timer_read();
235 }
236};
237
238// Helpers
239bool processFakeSteno(void) {
240 PJ( LSU, SEND(KC_Q););
241 PJ( LSD, SEND(KC_A););
242 PJ( LFT, SEND(KC_W););
243 PJ( LP, SEND(KC_E););
244 PJ( LH, SEND(KC_R););
245 PJ( LK, SEND(KC_S););
246 PJ( LW, SEND(KC_D););
247 PJ( LR, SEND(KC_F););
248 PJ( ST1, SEND(KC_T););
249 PJ( ST2, SEND(KC_G););
250 PJ( LA, SEND(KC_C););
251 PJ( LO, SEND(KC_V););
252 PJ( RE, SEND(KC_N););
253 PJ( RU, SEND(KC_M););
254 PJ( ST3, SEND(KC_Y););
255 PJ( ST4, SEND(KC_H););
256 PJ( RF, SEND(KC_U););
257 PJ( RP, SEND(KC_I););
258 PJ( RL, SEND(KC_O););
259 PJ( RT, SEND(KC_P););
260 PJ( RD, SEND(KC_LBRC););
261 PJ( RR, SEND(KC_J););
262 PJ( RB, SEND(KC_K););
263 PJ( RG, SEND(KC_L););
264 PJ( RS, SEND(KC_SCLN););
265 PJ( RZ, SEND(KC_COMM););
266 PJ( NUM, SEND(KC_1););
267
268 return false;
269}
270void clickMouse(uint8_t kc) {
271#ifdef MOUSEKEY_ENABLE
272 mousekey_on(kc);
273 mousekey_send();
274
275 // Store state for later use
276 inMouse = true;
277 mousePress = kc;
278#endif
279}
280void SEND(uint8_t kc) {
281 // Send Keycode, Does not work for Quantum Codes
282 if (cMode == COMMAND && CMDLEN < MAX_CMD_BUF) {
283 uprintf("CMD LEN: %d BUF: %d\n", CMDLEN, MAX_CMD_BUF);
284 CMDBUF[CMDLEN] = kc;
285 CMDLEN++;
286 }
287
288 if (cMode != COMMAND) register_code(kc);
289 return;
290}