]> git.donarmstrong.com Git - qmk_firmware.git/blob - keyboards/dichotomy/keymaps/default/keymap.c
Remove empty fn_actions[]
[qmk_firmware.git] / keyboards / dichotomy / 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 "dichotomy.h"
5
6 // Each layer gets a name for readability, which is then used in the keymap matrix below.
7 // The underscores don't mean anything - you can have a layer called STUFF or any other name.
8 // Layer names don't all need to be of the same length, obviously, and you can also skip them
9 // entirely and just use numbers.
10 enum dichotomy_layers {
11         _BS,
12         _SF,
13         _NM,
14         _NS,
15         _MS
16 };
17
18 #define LONGPRESS_COUNT 4
19
20 enum dichotomy_keycodes
21 {
22   CK_1G = SAFE_RANGE,
23   CK_BSPE,
24   CK_QE,
25   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.
26   NS_HYPH,
27   NS_EQU,
28   NUMKEY,
29   SFTKEY,
30   MOUKEY,
31   MS_BTN1,
32   MS_BTN2,
33   MS_BTN3
34 };
35
36 #define CUSTOM_LONGPRESS 150
37 #define CUSTOM_TOGGLE_TIME 300
38
39 #define RED_BRIGHTNESS 3
40 #define GREEN_BRIGHTNESS 2
41 #define BLUE_BRIGHTNESS 2
42
43 // Fillers to make layering more clear
44 #define _______ KC_TRNS
45 #define XXXXXXX KC_NO
46
47 const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = {
48 [_BS] = LAYOUT( /* Base layout, nearly qwerty but with modifications because it's not a full keyboard. Obviously. */
49   CK_TE,   KC_Q,    KC_W,    KC_E,    KC_R,    KC_T,           KC_Y,    KC_U,    KC_I,    KC_O,    KC_P,    KC_BSPC,
50   NUMKEY,  KC_A,    KC_S,    KC_D,    KC_F,    KC_G,           KC_H,    KC_J,    KC_K,    KC_L,    KC_SCLN, CK_QE,
51   SFTKEY,  KC_Z,    KC_X,    KC_C,    KC_V,    KC_B,           KC_N,    KC_M,    KC_COMM, KC_DOT,  KC_SLSH, MOUKEY,
52                              KC_LCTL, KC_LALT, KC_LGUI,        KC_RGUI, KC_RALT, KC_RCTL,
53                     MS_BTN3, KC_LBRC, KC_LPRN, KC_SPC,         KC_SPC,  KC_RPRN, KC_RBRC, MS_BTN3
54 ),
55
56 [_SF] = LAYOUT( /* Shifted layout, small changes (because angle brackets have been moved to thumb cluster buttons) */
57   _______, _______, _______, _______, _______, _______,        _______, _______, _______, _______, _______, _______,
58   _______, _______, _______, _______, _______, _______,        _______, _______, _______, _______, _______, _______,
59   _______, _______, _______, _______, _______, _______,        _______, _______, NS_HYPH, KC_UNDS, _______, _______,
60                              _______, _______, _______,        _______, _______, _______,
61                     _______, _______, KC_LABK, _______,        _______, KC_RABK, _______, _______
62 ),
63
64 [_NM] = LAYOUT( /* Number layout, basically the main function layer */
65   _______, KC_F1,   KC_F2,   KC_F3,   KC_F4,   KC_F5,          KC_F6,   KC_F7,   KC_F8,   KC_F9,   KC_F10,  _______,
66   _______, CK_1G,   KC_2,    KC_3,    KC_4,    KC_5,           KC_6,    KC_7,    KC_8,    KC_9,    KC_0,    CK_BSPE,
67   _______, KC_F11,  KC_F12,  KC_F13,  KC_F14,  KC_F15,         KC_F16,  KC_F17,  KC_F18,  KC_F19,  KC_F20,  _______,
68                              _______, _______, _______,        _______, _______, _______,
69                     _______, _______, _______, _______,        _______, _______, _______, _______
70 ),
71
72 [_NS] = LAYOUT( /* Shifted number/function layout, for per-key control.  Only active when shift is held, and number is toggled or held */
73   _______, _______, _______, _______, _______, _______,        _______, _______, _______, _______, _______, _______,
74   _______, _______, _______, _______, _______, _______,        _______, _______, _______, KC_PLUS, NS_EQU,  _______,
75   _______, _______, _______, _______, _______, _______,        _______, _______, _______, _______, _______, _______,
76                                                          _______, _______, _______,        _______, _______, _______,
77                                         _______, _______, _______, _______,        _______, _______, _______, _______
78 ),
79
80 [_MS] = LAYOUT( /* Mouse layer, including buttons for clicking. */
81   _______, _______, _______, _______, _______, _______,        KC_VOLU, KC_HOME, KC_PGUP, _______, _______, _______,
82   _______, _______, _______, _______, _______, _______,        _______, MS_BTN1, MS_BTN2, _______, _______, _______,
83   _______, _______, _______, _______, _______, _______,        KC_VOLD, KC_END,  KC_PGDN, _______, _______, _______,
84                                                          _______, _______, _______,        _______, KC_UP,   _______,
85                                         _______, _______, _______, _______,        KC_LEFT, KC_DOWN, KC_RGHT, _______
86 )
87
88 };
89
90 static uint16_t special_timers[LONGPRESS_COUNT] = {0xFFFF,0xFFFF,0xFFFF,0xFFFF};
91 static bool special_key_states[LONGPRESS_COUNT] = {0,0,0,0};
92 static bool special_key_pressed[LONGPRESS_COUNT] = {0,0,0,0};
93
94 static uint16_t shift_timer;
95 static uint16_t num_timer;
96 static uint16_t mouse_timer;
97
98 static uint8_t red_timer;
99 static uint8_t green_timer;
100 static uint8_t blue_timer;
101
102 static bool shift_singular_key = false;
103 static bool number_singular_key = false;
104 static bool mouse_singular_key = false;
105 static bool capsLED = false;
106 static bool shiftLED = false;
107 static bool numLED = false;
108 static bool mouseLED = false;
109
110 static bool shift_held = false;
111 static bool shift_suspended = false;
112 report_mouse_t currentReport = {};
113
114 bool process_record_user(uint16_t keycode, keyrecord_t *record) {
115         //uint8_t layer;
116         //layer = biton32(layer_state);  // get the current layer  //Or don't, I didn't use it.
117         bool returnVal = true; //this is to determine if more key processing is needed.
118
119          //custom layer handling for tri_layer,
120         switch (keycode) {
121                 case NUMKEY:
122                         if (record->event.pressed) {
123                                 num_timer = timer_read();
124                                 number_singular_key = true;
125                                 layer_invert(_NM);
126                                 numLED = !numLED;
127                         } else {
128                                 if (timer_elapsed(num_timer) < CUSTOM_TOGGLE_TIME && number_singular_key) {
129                                         //do nothing, the layer has already been inverted
130                                 } else {
131                                         layer_invert(_NM);
132                                         numLED = !numLED;
133                                 }
134                         }
135                         update_tri_layer(_NM, _SF, _NS);
136                         returnVal = false;
137                 break;
138                 //SHIFT is handled as LSHIFT in the general case - 'toggle' shoudl activate caps, while the layer is only active when shift is held.
139                 case SFTKEY:
140                         if (record->event.pressed) {
141                                 shift_held = true;
142                                 shiftLED = true;
143                                 shift_suspended = false;
144                                 shift_timer = timer_read();
145                                 shift_singular_key = true;
146                                 layer_on(_SF);
147                                 register_code(KC_LSFT);
148                         } else {
149                                 shift_held = false;
150                                 shiftLED = false;
151                                 if (timer_elapsed(shift_timer) < CUSTOM_TOGGLE_TIME && shift_singular_key) {
152                                         //this was basically a toggle, so activate/deactivate caps lock.
153                                         SEND_STRING(SS_TAP(X_CAPSLOCK));
154                                         capsLED = !capsLED;
155                                 }
156                                 layer_off(_SF);
157                                 unregister_code(KC_LSFT);
158                         }
159                         update_tri_layer(_NM, _SF, _NS);
160                         returnVal = false;
161                 break;
162                 //MOUSE layer needs to be handled the same way as NUMKEY, but differently from shift
163                 case MOUKEY:
164                         if (record->event.pressed) {
165                                 mouse_timer = timer_read();
166                                 mouse_singular_key = true;
167                                 layer_invert(_MS);
168                                 mouseLED = !mouseLED;
169                         } else {
170                                 if (timer_elapsed(mouse_timer) < CUSTOM_TOGGLE_TIME && mouse_singular_key){
171                                         //do nothing, it was a toggle (and it's already been toggled)
172                                 } else {
173                                         layer_invert(_MS);
174                                         mouseLED = !mouseLED;
175                                 }
176                         }
177                         returnVal = false;
178                 break;
179                 //Custom macros for strange keys with different long-tap behavior
180                 case CK_1G:
181                         if (shift_held && shift_suspended){
182                                 register_code(KC_LSFT);
183                                 shift_suspended = false;
184                         }
185                         if (record->event.pressed) {
186                                 special_timers[CK_1G-SAFE_RANGE] = timer_read();
187                                 special_key_pressed[CK_1G-SAFE_RANGE] = 1;
188                         } else {
189                                 if (special_key_states[CK_1G-SAFE_RANGE]){
190                                         //key was activated after custom_longpress, need to close those keycodes
191                                         special_key_states[CK_1G-SAFE_RANGE] = 0;
192                                         unregister_code(KC_GRAVE);
193                                 } else {
194                                         if (special_key_pressed[CK_1G-SAFE_RANGE]){
195                                                 //key was not activated, return macro activating proper, pre-long-tap key
196                                                 SEND_STRING(SS_TAP(X_1));
197                                                 special_key_pressed[CK_1G-SAFE_RANGE] = 0;
198                                         } else {
199                                                 //the short key was already sent, because another key was pressed.
200                                                 //Do nothing.
201                                         }
202
203                                 }
204                         }
205                         returnVal = false;
206                 break;
207                 case CK_BSPE:
208                         if (shift_held && shift_suspended){
209                                 register_code(KC_LSFT);
210                                 shift_suspended = false;
211                         }
212                         if (record->event.pressed) {
213                                 special_timers[CK_BSPE-SAFE_RANGE] = timer_read();
214                                 special_key_pressed[CK_BSPE-SAFE_RANGE] = 1;
215                         } else {
216                                 if (special_key_states[CK_BSPE-SAFE_RANGE]){
217                                         //key was activated after custom_longpress, need to close those keycodes
218                                         special_key_states[CK_BSPE-SAFE_RANGE] = 0;
219                                         unregister_code(KC_ENTER);
220                                 } else {
221                                         if (special_key_pressed[CK_BSPE-SAFE_RANGE]){
222                                                 //key was not activated, return macro activating proper, pre-long-tap key
223                                                 SEND_STRING(SS_TAP(X_BSLASH));
224                                                 special_key_pressed[CK_BSPE-SAFE_RANGE] = 0;
225                                         } else {
226                                                 //the short key was already sent, because another key was pressed.
227                                                 //Do nothing.
228                                         }
229                                 }
230                         }
231                         returnVal = false;
232                 break;
233                 case CK_QE:
234                         if (shift_held && shift_suspended){
235                                 register_code(KC_LSFT);
236                                 shift_suspended = false;
237                         }
238                         if (record->event.pressed) {
239                                 special_timers[CK_QE-SAFE_RANGE] = timer_read();
240                                 special_key_pressed[CK_QE-SAFE_RANGE] = 1;
241                         } else {
242                                 if (special_key_states[CK_QE-SAFE_RANGE]){
243                                         //key was activated after custom_longpress, need to close those keycodes
244                                         special_key_states[CK_QE-SAFE_RANGE] = 0;
245                                         unregister_code(KC_ENTER);
246                                 } else {
247                                         if (special_key_pressed[CK_QE-SAFE_RANGE]){
248                                                 //the long-press key was not activated, return macro activating proper, pre-long-tap key
249                                                 SEND_STRING(SS_TAP(X_QUOTE));
250                                                 special_key_pressed[CK_QE-SAFE_RANGE] = 0;
251                                         } else {
252                                                 //the short key was already sent, because another key was pressed.
253                                                 //Do nothing.
254                                         }
255                                 }
256                         }
257                         returnVal = false;
258                 break;
259                 case CK_TE:
260                         if (shift_held && shift_suspended){
261                                 register_code(KC_LSFT);
262                                 shift_suspended = false;
263                         }
264                         if (record->event.pressed) {
265                                 special_timers[CK_TE-SAFE_RANGE] = timer_read();
266                                 special_key_pressed[CK_TE-SAFE_RANGE] = 1;
267                         } else {
268                                 if (special_key_states[CK_TE-SAFE_RANGE]){
269                                         //key was activated after custom_longpress, need to close those keycodes
270                                         special_key_states[CK_TE-SAFE_RANGE] = 0;
271                                         unregister_code(KC_ESCAPE);
272                                 } else {
273                                         if (special_key_pressed[CK_TE-SAFE_RANGE]){
274                                                 //the long-press key was not activated, return macro activating proper, pre-long-tap key
275                                                 SEND_STRING(SS_TAP(X_TAB));
276                                                 special_key_pressed[CK_TE-SAFE_RANGE] = 0;
277                                         } else {
278                                                 //the short key was already sent, because another key was pressed.
279                                                 //Do nothing.
280                                         }
281                                 }
282                         }
283                         returnVal = false;
284                 break;
285                 //No-shift keys, they unregister the KC_LSFT code so they can send
286                 //unshifted values - but they don't change the bool. if any other
287                 //key is pressed and the bool is set, KC_LSFT is registered again.
288                 case NS_HYPH:
289                         if (record->event.pressed) {
290                                 shift_suspended = true;
291                                 unregister_code(KC_LSFT);
292                                 register_code(KC_MINS);
293                         } else {
294                                 unregister_code(KC_MINS);
295                                 if (shift_held && shift_suspended){
296                                         register_code(KC_LSFT);
297                                         shift_suspended = false;
298                                 }
299                         }
300                         returnVal = false;
301                 break;
302                 case NS_EQU:
303                         if (record->event.pressed) {
304                                 shift_suspended = true;
305                                 unregister_code(KC_LSFT);
306                                 register_code(KC_EQUAL);
307                         } else {
308                                 unregister_code(KC_EQUAL);
309                                 if (shift_held && shift_suspended){
310                                         register_code(KC_LSFT);
311                                         shift_suspended = false;
312                                 }
313                         }
314                         returnVal = false;
315                 break;
316
317                 //mouse buttons, for 1-3, to update the mouse report:
318                 case MS_BTN1:
319                         currentReport = pointing_device_get_report();
320                         if (record->event.pressed) {
321                                 if (shift_held && shift_suspended){
322                                         register_code(KC_LSFT);
323                                         shift_suspended = false;
324                                 }
325                                 //update mouse report here
326                                 currentReport.buttons |= MOUSE_BTN1; //MOUSE_BTN1 is a const defined in report.h
327                         } else {
328                                 //update mouse report here
329                                 currentReport.buttons &= ~MOUSE_BTN1;
330                         }
331                         pointing_device_set_report(currentReport);
332                         returnVal = false;
333                 break;
334                 case MS_BTN2:
335                         currentReport = pointing_device_get_report();
336                         if (record->event.pressed) {
337                                 if (shift_held && shift_suspended){
338                                         register_code(KC_LSFT);
339                                         shift_suspended = false;
340                                 }
341                                 //update mouse report here
342                                 currentReport.buttons |= MOUSE_BTN2; //MOUSE_BTN2 is a const defined in report.h
343                         } else {
344                                 //update mouse report here
345                                 currentReport.buttons &= ~MOUSE_BTN2;
346                         }
347                         pointing_device_set_report(currentReport);
348                         returnVal = false;
349                 break;
350                 case MS_BTN3:
351                         currentReport = pointing_device_get_report();
352                         if (record->event.pressed) {
353                                 if (shift_held && shift_suspended){
354                                         register_code(KC_LSFT);
355                                         shift_suspended = false;
356                                 }
357                                 //update mouse report here
358                                 currentReport.buttons |= MOUSE_BTN3; //MOUSE_BTN3 is a const defined in report.h
359                         } else {
360                                 //update mouse report here
361                                 currentReport.buttons &= ~MOUSE_BTN3;
362                         }
363                         pointing_device_set_report(currentReport);
364                         returnVal = false;
365                 break;
366                 //Additionally, if NS_ keys are in use, then shift may be held (but is
367                 //disabled for the unshifted keycodes to be send.  Check the bool and
368                 //register shift as necessary.
369                 default:
370                         if (shift_held){
371                                 register_code(KC_LSFT);
372                         }
373                 break;
374         }
375         switch (keycode){
376                 case KC_BSPC:
377                 case KC_NO:
378                 case NUMKEY:
379                 case SFTKEY:
380                 case MOUKEY:
381                         //don't want to reset single key variables
382                 break;
383                 default:
384                         //If any other key was pressed during the layer mod hold period,
385                         //then the layer mod was used momentarily, and should block latching
386                         shift_singular_key = false;
387                         number_singular_key = false;
388                         mouse_singular_key = false;
389                 break;
390         }
391         switch (keycode){
392                 case KC_BSPC:
393                 case KC_NO:
394                 case NUMKEY:
395                 case SFTKEY:
396                 case MOUKEY:
397                 case MOUSE_BTN1:
398                 case MOUSE_BTN2:
399                 case MOUSE_BTN3:
400                 case KC_LCTL:
401                 case KC_LALT:
402                 case KC_LGUI:
403                 case KC_RCTL:
404                 case KC_RALT:
405                 case KC_RGUI:
406                 case CK_1G:
407                 case CK_BSPE:
408                 case CK_QE:
409                 case CK_TE:
410                         //Do nothing, don't want to trigger the timer key rollover
411                 break;
412                 default:
413                         //Now we're checking to see if any of the special timer keys are pressed
414                         //if so, we need to activate their short-press features
415                         if (record->event.pressed) {
416                                 for (uint8_t i = 0; i<LONGPRESS_COUNT; i++){
417                                         if ((!special_key_states[i]) && special_key_pressed[i]){
418                                                 switch (i + SAFE_RANGE){
419                                                         case CK_1G:
420                                                                 SEND_STRING(SS_TAP(X_1));
421                                                         break;
422                                                         case CK_BSPE:
423                                                                 SEND_STRING(SS_TAP(X_BSLASH));
424                                                         break;
425                                                         case CK_QE:
426                                                                 SEND_STRING(SS_TAP(X_QUOTE));
427                                                         break;
428                                                         case CK_TE:
429                                                                 SEND_STRING(SS_TAP(X_TAB));
430                                                         break;
431                                                 }
432                                                 special_key_pressed[i] = 0;
433                                         }
434                                 }
435                         } else {
436                                 //do nothing, we don't want to trigger short presses on key releases.
437                         }
438                 break;
439         }
440         return returnVal;
441 };
442
443 void matrix_scan_user(void) {
444         //uint8_t layer = biton32(layer_state);
445         for (uint8_t i = 0; i<LONGPRESS_COUNT; i++){
446                 if ((timer_elapsed(special_timers[i]) >= CUSTOM_LONGPRESS) && (!special_key_states[i]) && special_key_pressed[i]){
447                         switch (i + SAFE_RANGE){
448                                 case CK_1G:
449                                         register_code(KC_GRAVE);
450                                 break;
451                                 case CK_BSPE:
452                                         register_code(KC_ENTER);
453                                 break;
454                                 case CK_QE:
455                                         register_code(KC_ENTER);
456                                 break;
457                                 case CK_TE:
458                                         register_code(KC_ESCAPE);
459                                 break;
460                         }
461                         special_key_pressed[i] = 0;
462                         special_key_states[i] = 1;
463                 }
464         }
465     if (shiftLED || capsLED){
466                 red_timer++;
467                 if (red_timer < RED_BRIGHTNESS){
468                         red_led_on();
469                 } else {
470                         red_timer = 0;
471                         red_led_off();
472                 }
473     } else {
474                 red_timer = 0;
475                 red_led_off();
476     }
477     if (numLED){
478                 green_timer++;
479                 if (green_timer < GREEN_BRIGHTNESS){
480                         grn_led_on();
481                 } else {
482                         green_timer = 0;
483                         grn_led_off();
484                 }
485     } else {
486                 green_timer = 0;
487                 grn_led_off();
488     }
489     if (mouseLED){
490                 blue_timer++;
491                 if (blue_timer < BLUE_BRIGHTNESS){
492                         blu_led_on();
493                 } else {
494                         blue_timer = 0;
495                         blu_led_off();
496                 }
497     } else {
498                 blue_timer = 0;
499                 blu_led_off();
500     }
501 };