]> git.donarmstrong.com Git - qmk_firmware.git/blob - keyboards/dichotemy/keymaps/default/keymap.c
a failed attempt at hot-plugging
[qmk_firmware.git] / keyboards / dichotemy / keymaps / default / keymap.c
1 // this is the style you want to emulate.
2 // This is the canonical layout file for the Quantum project. If you want to add another keyboard,
3
4 #include "dichotemy.h"
5 #include "report.h"
6 #include "pointing_device.h"
7
8 // Each layer gets a name for readability, which is then used in the keymap matrix below.
9 // The underscores don't mean anything - you can have a layer called STUFF or any other name.
10 // Layer names don't all need to be of the same length, obviously, and you can also skip them
11 // entirely and just use numbers.
12 enum dichotemy_layers
13 {
14         _BS,
15         _SF,
16         _NM,
17         _NS,
18         _MS
19 };
20
21 #define LONGPRESS_COUNT 4
22
23 enum dichotemy_keycodes 
24 {
25   CK_1G = SAFE_RANGE,
26   CK_BSPE,
27   CK_QE,
28   CK_TE, //these 4 CK_XXXX keys are special "alternate long-press" keys controlled with unique timers.  Make sure you understand them before you mess with them.
29   NS_HYPH,
30   NS_EQU,
31   NUMKEY,
32   SFTKEY,
33   MOUSE,
34   MS_BTN1,
35   MS_BTN2
36   //MS_BTN3
37 };
38
39 // Macro definitions for readability
40 enum dichotemy_macros
41 {
42         VOLU,
43         VOLD,
44         ESCM
45 };
46
47 #define LONGPRESS_DELAY 150
48 #define MAX_TOGGLE_LENGTH 300
49 #define TAPPING_TOGGLE 1
50
51 // Fillers to make layering more clear
52 #define _______ KC_TRNS
53 #define XXXXXXX KC_NO
54
55 const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = {
56 [_BS] = { /* Base layout, nearly qwerty but with modifications because it's not a full keyboard. Obviously. */
57   {CK_TE,   KC_Q,    KC_W,    KC_E,    KC_R,    KC_T,           KC_Y,    KC_U,    KC_I,    KC_O,    KC_P,    KC_BSPC },
58   {NUMKEY,  KC_A,    KC_S,    KC_D,    KC_F,    KC_G,           KC_H,    KC_J,    KC_K,    KC_L,    KC_SCLN, CK_QE   },
59   {SFTKEY,  KC_Z,    KC_X,    KC_C,    KC_V,    KC_B,           KC_N,    KC_M,    KC_COMM, KC_DOT,  KC_SLSH, MOUSE   },
60   {XXXXXXX, XXXXXXX, XXXXXXX, KC_LCTL, KC_LALT, KC_LGUI,        KC_RGUI, KC_RALT, KC_RCTL, XXXXXXX, XXXXXXX, XXXXXXX },
61   {XXXXXXX, XXXXXXX, XXXXXXX, KC_LBRC, KC_LPRN, KC_QUOT,        KC_SPC,  KC_RPRN, KC_RBRC, XXXXXXX, XXXXXXX, XXXXXXX }
62 },
63
64 [_SF] = { /* Shifted layout, small changes (because angle brackets have been moved to thumb cluster buttons) */
65   {_______, _______, _______, _______, _______, _______,        _______, _______, _______, _______, _______, _______ },
66   {_______, _______, _______, _______, _______, _______,        _______, _______, _______, _______, _______, _______ },
67   {_______, _______, _______, _______, _______, _______,        _______, _______, NS_HYPH, KC_UNDS, _______, _______ },
68   {XXXXXXX, XXXXXXX, XXXXXXX, _______, _______, _______,        _______, _______, _______, XXXXXXX, XXXXXXX, XXXXXXX },
69   {XXXXXXX, XXXXXXX, XXXXXXX, _______, KC_LABK, _______,        _______, KC_RABK, _______, XXXXXXX, XXXXXXX, XXXXXXX }
70 },
71
72 [_NM] = { /* Number layout, basically the main function layer */
73   {_______, KC_F1,   KC_F2,   KC_F3,   KC_F4,   KC_F5,          KC_F6,   KC_F7,   KC_F8,   KC_F9,   KC_F10,  _______ },
74   {_______, CK_1G,   KC_2,    KC_3,    KC_4,    KC_5,           KC_6,    KC_7,    KC_8,    KC_9,    KC_0,    CK_BSPE },
75   {_______, KC_F11,  KC_F12,  KC_F13,  KC_F14,  KC_F15,         KC_F16,  KC_F17,  KC_F18,  KC_F19,  KC_F20,  _______ },
76   {XXXXXXX, XXXXXXX, XXXXXXX, _______, _______, _______,        _______, _______, _______, XXXXXXX, XXXXXXX, XXXXXXX },
77   {XXXXXXX, XXXXXXX, XXXXXXX, _______, _______, _______,        _______, _______, _______, XXXXXXX, XXXXXXX, XXXXXXX }
78 },
79
80 [_NS] = { /* Shifted number/function layout, for per-key control.  Only active when shift is held, and number is toggled or held */
81   {_______, _______, _______, _______, _______, _______,        _______, _______, _______, _______, _______, _______ },
82   {_______, _______, _______, _______, _______, _______,        _______, _______, _______, KC_PLUS, NS_EQU,  _______ },
83   {_______, _______, _______, _______, _______, _______,        _______, _______, _______, _______, _______, _______ },
84   {XXXXXXX, XXXXXXX, XXXXXXX, _______, _______, _______,        _______, _______, _______, XXXXXXX, XXXXXXX, XXXXXXX },
85   {XXXXXXX, XXXXXXX, XXXXXXX, _______, _______, _______,        _______, _______, _______, XXXXXXX, XXXXXXX, XXXXXXX }
86 },
87
88 [_MS] = { /* Mouse layer, including buttons for clicking. */
89   {_______, _______, _______, _______, _______, _______,        KC_VOLU, KC_HOME, KC_PGUP, _______, _______, _______ },
90   {_______, _______, _______, _______, _______, _______,        _______, MS_BTN1, MS_BTN2, _______, _______, _______ },
91   {_______, _______, _______, _______, _______, _______,        KC_VOLD, KC_END,  KC_PGDN, _______, _______, _______ },
92   {XXXXXXX, XXXXXXX, XXXXXXX, _______, _______, _______,        _______, KC_UP,   _______, XXXXXXX, XXXXXXX, XXXXXXX },
93   {XXXXXXX, XXXXXXX, XXXXXXX, _______, _______, _______,        KC_LEFT, KC_DOWN, KC_RGHT, XXXXXXX, XXXXXXX, XXXXXXX }
94 }
95
96 };
97
98
99 const uint16_t PROGMEM fn_actions[] = {
100
101 };
102
103 static uint16_t special_timers[LONGPRESS_COUNT] = {0xFFFF,0xFFFF,0xFFFF,0xFFFF};
104 static bool special_key_states[LONGPRESS_COUNT] = {0,0,0,0};
105
106 static uint16_t shift_timer;
107 static uint16_t num_timer;
108 static uint16_t mouse_timer;
109
110 static bool shift_singular_key = false;
111 static bool number_singular_key = false;
112 static bool mouse_singular_key = false;
113
114 static bool shift_held = false;
115 static bool shift_suspended = false;
116 report_mouse_t currentReport = {};
117
118 bool process_record_user(uint16_t keycode, keyrecord_t *record) {
119
120         //uint8_t layer;
121         //layer = biton32(layer_state);  // get the current layer  //Or don't, I didn't use it.
122
123          //custom layer handling for tri_layer,
124         switch (keycode) {
125                 case NUMKEY:
126                         if (record->event.pressed) {
127                                 num_timer = timer_read();
128                                 number_singular_key = true;
129                                 layer_invert(_NM);
130                         } else {
131                                 if (timer_elapsed(num_timer) < MAX_TOGGLE_LENGTH && number_singular_key) {
132                                         //do nothing, the layer has already been inverted
133                                 } else {
134                                         layer_invert(_NM);
135                                 }
136                         }
137                         update_tri_layer(_NM, _SF, _NS);
138                         return false;
139                 break;
140                 //SHIFT is handled as LSHIFT in the general case - 'toggle' shoudl activate caps, while the layer is only active when shift is held.
141                 case SFTKEY:
142                         if (record->event.pressed) {
143                                 shift_held = true;
144                                 shift_suspended = false;
145                                 shift_timer = timer_read();
146                                 shift_singular_key = true;
147                                 layer_on(_SF);
148                                 register_code(KC_LSFT);
149                         } else {
150                                 shift_held = false;
151                                 if (timer_elapsed(shift_timer) < MAX_TOGGLE_LENGTH && shift_singular_key) {
152                                         //this was basically a toggle, so activate/deactivate caps lock.
153                                         SEND_STRING(SS_TAP(X_CAPSLOCK));
154                                 }
155                                 layer_off(_SF);
156                                 unregister_code(KC_LSFT);
157                         }
158                         update_tri_layer(_NM, _SF, _NS);
159                         return false;
160                 break;
161                 //MOUSE layer needs to be handled the same way as NUMKEY, but differently from shift
162                 case MOUSE:
163                         if (record->event.pressed) {
164                                 mouse_timer = timer_read();
165                                 mouse_singular_key = true;
166                                 layer_invert(_MS);
167                         } else {
168                                 if (timer_elapsed(mouse_timer) < MAX_TOGGLE_LENGTH && number_singular_key){
169                                         //do nothing, it was a toggle (and it's already been toggled)
170                                 } else {
171                                         layer_invert(_MS);
172                                 }
173                         }
174                         return false;
175                 break;
176                 //Custom macros for strange keys with different long-tap behavior
177                 case CK_1G:
178                         if (shift_held && shift_suspended){
179                                 register_code(KC_LSFT);
180                                 shift_suspended = false;
181                         }
182                         shift_singular_key = false;
183                         number_singular_key = false;
184                         mouse_singular_key = false;
185                         if (record->event.pressed) {
186                                 special_timers[CK_1G-SAFE_RANGE] = timer_read();
187                         } else {
188                                 if (special_key_states[CK_1G-SAFE_RANGE]){
189                                         //key was activated after longpress_delay, need to close those keycodes
190                                         special_key_states[CK_1G-SAFE_RANGE] = 0;
191                                         unregister_code(KC_GRAVE);
192                                 } else {
193                                         //key was not activated, return macro activating proper, pre-long-tap key
194                                         SEND_STRING(SS_TAP(X_1));
195                                 }
196                                 special_timers[CK_1G-SAFE_RANGE] = 0xFFFF;
197                         }
198                 break;
199                 case CK_BSPE:
200                         if (shift_held && shift_suspended){
201                                 register_code(KC_LSFT);
202                                 shift_suspended = false;
203                         }
204                         shift_singular_key = false;
205                         number_singular_key = false;
206                         mouse_singular_key = false;
207                         if (record->event.pressed) {
208                                 special_timers[CK_BSPE-SAFE_RANGE] = timer_read();
209                         } else {
210                                 if (special_key_states[CK_BSPE-SAFE_RANGE]){
211                                         //key was activated after longpress_delay, need to close those keycodes
212                                         special_key_states[CK_BSPE-SAFE_RANGE] = 0;
213                                         unregister_code(KC_ENTER);
214                                 } else {
215                                         //key was not activated, return macro activating proper, pre-long-tap key
216                                         SEND_STRING(SS_TAP(X_BSLASH));
217                                 }
218                                 special_timers[CK_BSPE-SAFE_RANGE] = 0xFFFF;
219                         }
220                 break;
221                 case CK_QE:
222                         if (shift_held && shift_suspended){
223                                 register_code(KC_LSFT);
224                                 shift_suspended = false;
225                         }
226                         shift_singular_key = false;
227                         number_singular_key = false;
228                         mouse_singular_key = false;
229                         if (record->event.pressed) {
230                                 special_timers[CK_QE-SAFE_RANGE] = timer_read();
231                         } else {
232                                 if (special_key_states[CK_QE-SAFE_RANGE]){
233                                         //key was activated after longpress_delay, need to close those keycodes
234                                         special_key_states[CK_QE-SAFE_RANGE] = 0;
235                                         unregister_code(KC_ENTER);
236                                 } else {
237                                         //key was not activated, return macro activating proper, pre-long-tap key
238                                         SEND_STRING(SS_TAP(X_QUOTE));
239                                 }
240                                 special_timers[CK_QE-SAFE_RANGE] = 0xFFFF;
241                         }
242                 break;
243                 case CK_TE:
244                         if (shift_held && shift_suspended){
245                                 register_code(KC_LSFT);
246                                 shift_suspended = false;
247                         }
248                         if (record->event.pressed) {
249                                 special_timers[CK_TE-SAFE_RANGE] = timer_read();
250                         } else {
251                                 if (special_key_states[CK_TE-SAFE_RANGE]){
252                                         //key was activated after longpress_delay, need to close those keycodes
253                                         special_key_states[CK_TE-SAFE_RANGE] = 0;
254                                         unregister_code(KC_ENTER);
255                                 } else {
256                                         //key was not activated, return macro activating proper, pre-long-tap key
257                                         SEND_STRING(SS_TAP(X_TAB));
258                                 }
259                                 special_timers[CK_TE-SAFE_RANGE] = 0xFFFF;
260                         }
261                 break;
262                 //No-shift keys, they unregister the KC_LSFT code so they can send 
263                 //unshifted values - but they don't change the bool. if any other 
264                 //key is pressed and the bool is set, KC_LSFT is registered again.
265                 case NS_HYPH:
266                         if (record->event.pressed) {
267                                 shift_suspended = true;
268                                 unregister_code(KC_LSFT);
269                                 register_code(KC_MINS);
270                         } else {
271                                 unregister_code(KC_MINS);
272                                 if (shift_held && shift_suspended){
273                                         register_code(KC_LSFT);
274                                         shift_suspended = false;
275                                 }
276                         }
277                 break;
278                 case NS_EQU:
279                         if (record->event.pressed) {
280                                 shift_suspended = true;
281                                 unregister_code(KC_LSFT);
282                                 register_code(KC_EQUAL);
283                         } else {
284                                 unregister_code(KC_EQUAL);
285                                 if (shift_held && shift_suspended){
286                                         register_code(KC_LSFT);
287                                         shift_suspended = false;
288                                 }
289                         }
290                 break;
291                 
292                 //mouse buttons, for 1-3, to update the mouse report:
293                 case MS_BTN1:
294                         currentReport = pointing_device_get_report();
295                         if (record->event.pressed) {
296                                 if (shift_held && shift_suspended){
297                                         register_code(KC_LSFT);
298                                         shift_suspended = false;
299                                 }
300                                 //update mouse report here
301                                 currentReport.buttons |= MOUSE_BTN1; //MOUSE_BTN1 is a const defined in report.h
302                         } else {
303                                 //update mouse report here
304                                 currentReport.buttons &= ~MOUSE_BTN1;
305                         }
306                         pointing_device_set_report(currentReport);
307                 break;
308                 case MS_BTN2:
309                         currentReport = pointing_device_get_report();
310                         if (record->event.pressed) {
311                                 if (shift_held && shift_suspended){
312                                         register_code(KC_LSFT);
313                                         shift_suspended = false;
314                                 }
315                                 //update mouse report here
316                                 currentReport.buttons |= MOUSE_BTN2; //MOUSE_BTN2 is a const defined in report.h
317                         } else {
318                                 //update mouse report here
319                         }
320                         pointing_device_set_report(currentReport);
321                 break;
322                 //there is a case for button 3, but that's handled in dichotemy.c, and this is being
323                 //disabled to avoid any conflict.
324                 /*case MS_BTN3:
325                         currentReport = pointing_device_get_report();
326                         if (record->event.pressed) {
327                                 if (shift_held && shift_suspended){
328                                         register_code(KC_LSFT);
329                                         shift_suspended = false;
330                                 }
331                                 //update mouse report here
332                                 currentReport.buttons |= MOUSE_BTN3; //MOUSE_BTN2 is a const defined in report.h
333                         } else {
334                                 //update mouse report here
335                         }
336                         pointing_device_set_report(currentReport);
337                 break;*/
338                 
339                 //If any other key was pressed during the layer mod hold period,
340                 //then the layer mod was used momentarily, and should block latching
341                 //Additionally, if NS_ keys are in use, then shift may be held (but is
342                 //disabled for the unshifted keycodes to be send.  Check the bool and
343                 //register shift as necessary.
344                 default:
345                         if (shift_held){
346                                 register_code(KC_LSFT);
347                         }
348                         shift_singular_key = false;
349                         number_singular_key = false;
350                         mouse_singular_key = false;
351                 break;
352         }
353         return true;
354 };
355
356 void matrix_scan_user(void) {
357     uint8_t layer = biton32(layer_state);
358     for (uint8_t i = 0; i<LONGPRESS_COUNT; i++){
359                 if (timer_elapsed(special_timers[i]) >= LONGPRESS_DELAY && !special_key_states[i]){
360                         switch (i + SAFE_RANGE){
361                                 case CK_1G:
362                                         register_code(KC_GRAVE);
363                                 break;
364                                 case CK_BSPE:
365                                         register_code(KC_ENTER);
366                                 break;
367                                 case CK_QE:
368                                         register_code(KC_ENTER);
369                                 break;
370                                 case CK_TE:
371                                         register_code(KC_ESCAPE);
372                                 break;
373                         }
374                         special_key_states[i] = 1;
375                 }
376         }
377     switch (layer) {
378         case _BS:
379                 set_led_off;
380                 break;
381         case _NM:
382             set_led_blue;
383             break;
384         case _SF:
385             set_led_red;
386             break;
387         case _NS:
388                 set_led_green;
389                 break;
390         default:
391             break;
392     }
393 };
394