1 /* Copyright 2016-2017 Jack Humbert
3 * This program is free software: you can redistribute it and/or modify
4 * it under the terms of the GNU General Public License as published by
5 * the Free Software Foundation, either version 2 of the License, or
6 * (at your option) any later version.
8 * This program is distributed in the hope that it will be useful,
9 * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 * GNU General Public License for more details.
13 * You should have received a copy of the GNU General Public License
14 * along with this program. If not, see <http://www.gnu.org/licenses/>.
19 #if !defined(RGBLIGHT_ENABLE) && !defined(RGB_MATRIX_ENABLE)
24 # include "outputselect.h"
27 #ifdef BACKLIGHT_ENABLE
28 # include "backlight.h"
29 extern backlight_config_t backlight_config;
32 #ifdef FAUXCLICKY_ENABLE
33 # include "fauxclicky.h"
41 # include "process_midi.h"
44 #ifdef VELOCIKEY_ENABLE
45 # include "velocikey.h"
58 # define GOODBYE_SONG SONG(GOODBYE_SOUND)
61 # define AG_NORM_SONG SONG(AG_NORM_SOUND)
64 # define AG_SWAP_SONG SONG(AG_SWAP_SOUND)
67 # define CG_NORM_SONG SONG(AG_NORM_SOUND)
70 # define CG_SWAP_SONG SONG(AG_SWAP_SOUND)
72 float goodbye_song[][2] = GOODBYE_SONG;
73 float ag_norm_song[][2] = AG_NORM_SONG;
74 float ag_swap_song[][2] = AG_SWAP_SONG;
75 float cg_norm_song[][2] = CG_NORM_SONG;
76 float cg_swap_song[][2] = CG_SWAP_SONG;
77 # ifdef DEFAULT_LAYER_SONGS
78 float default_layer_songs[][16][2] = DEFAULT_LAYER_SONGS;
82 static void do_code16(uint16_t code, void (*f)(uint8_t)) {
84 case QK_MODS ... QK_MODS_MAX:
90 uint8_t mods_to_send = 0;
92 if (code & QK_RMODS_MIN) { // Right mod flag is set
93 if (code & QK_LCTL) mods_to_send |= MOD_BIT(KC_RCTL);
94 if (code & QK_LSFT) mods_to_send |= MOD_BIT(KC_RSFT);
95 if (code & QK_LALT) mods_to_send |= MOD_BIT(KC_RALT);
96 if (code & QK_LGUI) mods_to_send |= MOD_BIT(KC_RGUI);
98 if (code & QK_LCTL) mods_to_send |= MOD_BIT(KC_LCTL);
99 if (code & QK_LSFT) mods_to_send |= MOD_BIT(KC_LSFT);
100 if (code & QK_LALT) mods_to_send |= MOD_BIT(KC_LALT);
101 if (code & QK_LGUI) mods_to_send |= MOD_BIT(KC_LGUI);
107 void register_code16(uint16_t code) {
108 if (IS_MOD(code) || code == KC_NO) {
109 do_code16(code, register_mods);
111 do_code16(code, register_weak_mods);
116 void unregister_code16(uint16_t code) {
117 unregister_code(code);
118 if (IS_MOD(code) || code == KC_NO) {
119 do_code16(code, unregister_mods);
121 do_code16(code, unregister_weak_mods);
125 void tap_code16(uint16_t code) {
126 register_code16(code);
127 #if TAP_CODE_DELAY > 0
128 wait_ms(TAP_CODE_DELAY);
130 unregister_code16(code);
133 __attribute__((weak)) bool process_action_kb(keyrecord_t *record) { return true; }
135 __attribute__((weak)) bool process_record_kb(uint16_t keycode, keyrecord_t *record) { return process_record_user(keycode, record); }
137 __attribute__((weak)) bool process_record_user(uint16_t keycode, keyrecord_t *record) { return true; }
139 void reset_keyboard(void) {
141 #if defined(MIDI_ENABLE) && defined(MIDI_BASIC)
142 process_midi_all_notes_off();
145 # ifndef NO_MUSIC_MODE
146 music_all_notes_off();
148 uint16_t timer_start = timer_read();
149 PLAY_SONG(goodbye_song);
151 while (timer_elapsed(timer_start) < 250) wait_ms(1);
160 // this is also done later in bootloader.c - not sure if it's neccesary here
161 #ifdef BOOTLOADER_CATERINA
162 *(uint16_t *)0x0800 = 0x7777; // these two are a-star-specific
167 /* true if the last press of GRAVE_ESC was shifted (i.e. GUI or SHIFT were pressed), false otherwise.
168 * Used to ensure that the correct keycode is released if the key is released.
170 static bool grave_esc_was_shifted = false;
172 /* Convert record into usable keycode via the contained event. */
173 uint16_t get_record_keycode(keyrecord_t *record) { return get_event_keycode(record->event); }
175 /* Convert event into usable keycode. Checks the layer cache to ensure that it
176 * retains the correct keycode after a layer change, if the key is still pressed.
178 uint16_t get_event_keycode(keyevent_t event) {
179 #if !defined(NO_ACTION_LAYER) && !defined(STRICT_LAYER_RELEASE)
180 /* TODO: Use store_or_get_action() or a similar function. */
181 if (!disable_action_cache) {
185 layer = layer_switch_get_layer(event.key);
186 update_source_layers_cache(event.key, layer);
188 layer = read_source_layers_cache(event.key);
190 return keymap_key_to_keycode(layer, event.key);
193 return keymap_key_to_keycode(layer_switch_get_layer(event.key), event.key);
196 /* Main keycode processing function. Hands off handling to other functions,
197 * then processes internal Quantum keycodes, then processes ACTIONs.
199 bool process_record_quantum(keyrecord_t *record) {
200 uint16_t keycode = get_record_keycode(record);
202 // This is how you use actions here
203 // if (keycode == KC_LEAD) {
205 // action.code = ACTION_DEFAULT_LAYER_SET(0);
206 // process_action(record, action);
210 #ifdef VELOCIKEY_ENABLE
211 if (velocikey_enabled() && record->event.pressed) {
212 velocikey_accelerate();
216 #ifdef TAP_DANCE_ENABLE
217 preprocess_tap_dance(keycode, record);
221 #if defined(KEY_LOCK_ENABLE)
222 // Must run first to be able to mask key_up events.
223 process_key_lock(&keycode, record) &&
225 #if defined(AUDIO_ENABLE) && defined(AUDIO_CLICKY)
226 process_clicky(keycode, record) &&
227 #endif // AUDIO_CLICKY
229 process_haptic(keycode, record) &&
230 #endif // HAPTIC_ENABLE
231 #if defined(RGB_MATRIX_ENABLE)
232 process_rgb_matrix(keycode, record) &&
234 process_record_kb(keycode, record) &&
235 #if defined(MIDI_ENABLE) && defined(MIDI_ADVANCED)
236 process_midi(keycode, record) &&
239 process_audio(keycode, record) &&
242 process_steno(keycode, record) &&
244 #if (defined(AUDIO_ENABLE) || (defined(MIDI_ENABLE) && defined(MIDI_BASIC))) && !defined(NO_MUSIC_MODE)
245 process_music(keycode, record) &&
247 #ifdef TAP_DANCE_ENABLE
248 process_tap_dance(keycode, record) &&
250 #if defined(UNICODE_ENABLE) || defined(UNICODEMAP_ENABLE) || defined(UCIS_ENABLE)
251 process_unicode_common(keycode, record) &&
254 process_leader(keycode, record) &&
257 process_combo(keycode, record) &&
259 #ifdef PRINTING_ENABLE
260 process_printer(keycode, record) &&
262 #ifdef AUTO_SHIFT_ENABLE
263 process_auto_shift(keycode, record) &&
265 #ifdef TERMINAL_ENABLE
266 process_terminal(keycode, record) &&
268 #ifdef SPACE_CADET_ENABLE
269 process_space_cadet(keycode, record) &&
275 // Shift / paren setup
279 if (record->event.pressed) {
284 if (record->event.pressed) {
287 print("DEBUG: enabled.\n");
289 print("DEBUG: disabled.\n");
294 if (record->event.pressed) {
298 #ifdef FAUXCLICKY_ENABLE
300 if (record->event.pressed) {
305 if (record->event.pressed) {
310 if (record->event.pressed) {
315 #if defined(RGBLIGHT_ENABLE) || defined(RGB_MATRIX_ENABLE)
317 // Split keyboards need to trigger on key-up for edge-case issue
318 # ifndef SPLIT_KEYBOARD
319 if (record->event.pressed) {
321 if (!record->event.pressed) {
326 case RGB_MODE_FORWARD:
327 if (record->event.pressed) {
328 uint8_t shifted = get_mods() & (MOD_BIT(KC_LSHIFT) | MOD_BIT(KC_RSHIFT));
330 rgblight_step_reverse();
336 case RGB_MODE_REVERSE:
337 if (record->event.pressed) {
338 uint8_t shifted = get_mods() & (MOD_BIT(KC_LSHIFT) | MOD_BIT(KC_RSHIFT));
342 rgblight_step_reverse();
347 // Split keyboards need to trigger on key-up for edge-case issue
348 # ifndef SPLIT_KEYBOARD
349 if (record->event.pressed) {
351 if (!record->event.pressed) {
353 rgblight_increase_hue();
357 // Split keyboards need to trigger on key-up for edge-case issue
358 # ifndef SPLIT_KEYBOARD
359 if (record->event.pressed) {
361 if (!record->event.pressed) {
363 rgblight_decrease_hue();
367 // Split keyboards need to trigger on key-up for edge-case issue
368 # ifndef SPLIT_KEYBOARD
369 if (record->event.pressed) {
371 if (!record->event.pressed) {
373 rgblight_increase_sat();
377 // Split keyboards need to trigger on key-up for edge-case issue
378 # ifndef SPLIT_KEYBOARD
379 if (record->event.pressed) {
381 if (!record->event.pressed) {
383 rgblight_decrease_sat();
387 // Split keyboards need to trigger on key-up for edge-case issue
388 # ifndef SPLIT_KEYBOARD
389 if (record->event.pressed) {
391 if (!record->event.pressed) {
393 rgblight_increase_val();
397 // Split keyboards need to trigger on key-up for edge-case issue
398 # ifndef SPLIT_KEYBOARD
399 if (record->event.pressed) {
401 if (!record->event.pressed) {
403 rgblight_decrease_val();
407 if (record->event.pressed) {
408 rgblight_increase_speed();
412 if (record->event.pressed) {
413 rgblight_decrease_speed();
417 if (record->event.pressed) {
418 rgblight_mode(RGBLIGHT_MODE_STATIC_LIGHT);
421 case RGB_MODE_BREATHE:
422 # ifdef RGBLIGHT_EFFECT_BREATHING
423 if (record->event.pressed) {
424 if ((RGBLIGHT_MODE_BREATHING <= rgblight_get_mode()) && (rgblight_get_mode() < RGBLIGHT_MODE_BREATHING_end)) {
427 rgblight_mode(RGBLIGHT_MODE_BREATHING);
432 case RGB_MODE_RAINBOW:
433 # ifdef RGBLIGHT_EFFECT_RAINBOW_MOOD
434 if (record->event.pressed) {
435 if ((RGBLIGHT_MODE_RAINBOW_MOOD <= rgblight_get_mode()) && (rgblight_get_mode() < RGBLIGHT_MODE_RAINBOW_MOOD_end)) {
438 rgblight_mode(RGBLIGHT_MODE_RAINBOW_MOOD);
444 # ifdef RGBLIGHT_EFFECT_RAINBOW_SWIRL
445 if (record->event.pressed) {
446 if ((RGBLIGHT_MODE_RAINBOW_SWIRL <= rgblight_get_mode()) && (rgblight_get_mode() < RGBLIGHT_MODE_RAINBOW_SWIRL_end)) {
449 rgblight_mode(RGBLIGHT_MODE_RAINBOW_SWIRL);
455 # ifdef RGBLIGHT_EFFECT_SNAKE
456 if (record->event.pressed) {
457 if ((RGBLIGHT_MODE_SNAKE <= rgblight_get_mode()) && (rgblight_get_mode() < RGBLIGHT_MODE_SNAKE_end)) {
460 rgblight_mode(RGBLIGHT_MODE_SNAKE);
465 case RGB_MODE_KNIGHT:
466 # ifdef RGBLIGHT_EFFECT_KNIGHT
467 if (record->event.pressed) {
468 if ((RGBLIGHT_MODE_KNIGHT <= rgblight_get_mode()) && (rgblight_get_mode() < RGBLIGHT_MODE_KNIGHT_end)) {
471 rgblight_mode(RGBLIGHT_MODE_KNIGHT);
477 # ifdef RGBLIGHT_EFFECT_CHRISTMAS
478 if (record->event.pressed) {
479 rgblight_mode(RGBLIGHT_MODE_CHRISTMAS);
483 case RGB_MODE_GRADIENT:
484 # ifdef RGBLIGHT_EFFECT_STATIC_GRADIENT
485 if (record->event.pressed) {
486 if ((RGBLIGHT_MODE_STATIC_GRADIENT <= rgblight_get_mode()) && (rgblight_get_mode() < RGBLIGHT_MODE_STATIC_GRADIENT_end)) {
489 rgblight_mode(RGBLIGHT_MODE_STATIC_GRADIENT);
494 case RGB_MODE_RGBTEST:
495 # ifdef RGBLIGHT_EFFECT_RGB_TEST
496 if (record->event.pressed) {
497 rgblight_mode(RGBLIGHT_MODE_RGB_TEST);
501 #endif // defined(RGBLIGHT_ENABLE) || defined(RGB_MATRIX_ENABLE)
502 #ifdef VELOCIKEY_ENABLE
504 if (record->event.pressed) {
511 if (record->event.pressed) {
512 set_output(OUTPUT_AUTO);
516 if (record->event.pressed) {
517 set_output(OUTPUT_USB);
520 # ifdef BLUETOOTH_ENABLE
522 if (record->event.pressed) {
523 set_output(OUTPUT_BLUETOOTH);
528 case MAGIC_SWAP_CONTROL_CAPSLOCK ... MAGIC_TOGGLE_ALT_GUI:
529 case MAGIC_SWAP_LCTL_LGUI ... MAGIC_EE_HANDS_RIGHT:
530 if (record->event.pressed) {
531 // MAGIC actions (BOOTMAGIC without the boot)
532 if (!eeconfig_is_enabled()) {
536 keymap_config.raw = eeconfig_read_keymap();
538 case MAGIC_SWAP_CONTROL_CAPSLOCK:
539 keymap_config.swap_control_capslock = true;
541 case MAGIC_CAPSLOCK_TO_CONTROL:
542 keymap_config.capslock_to_control = true;
544 case MAGIC_SWAP_LALT_LGUI:
545 keymap_config.swap_lalt_lgui = true;
547 case MAGIC_SWAP_RALT_RGUI:
548 keymap_config.swap_ralt_rgui = true;
550 case MAGIC_SWAP_LCTL_LGUI:
551 keymap_config.swap_lctl_lgui = true;
553 case MAGIC_SWAP_RCTL_RGUI:
554 keymap_config.swap_rctl_rgui = true;
557 keymap_config.no_gui = true;
559 case MAGIC_SWAP_GRAVE_ESC:
560 keymap_config.swap_grave_esc = true;
562 case MAGIC_SWAP_BACKSLASH_BACKSPACE:
563 keymap_config.swap_backslash_backspace = true;
565 case MAGIC_HOST_NKRO:
566 clear_keyboard(); // clear first buffer to prevent stuck keys
567 keymap_config.nkro = true;
569 case MAGIC_SWAP_ALT_GUI:
570 keymap_config.swap_lalt_lgui = keymap_config.swap_ralt_rgui = true;
572 PLAY_SONG(ag_swap_song);
575 case MAGIC_SWAP_CTL_GUI:
576 keymap_config.swap_lctl_lgui = keymap_config.swap_rctl_rgui = true;
578 PLAY_SONG(cg_swap_song);
581 case MAGIC_UNSWAP_CONTROL_CAPSLOCK:
582 keymap_config.swap_control_capslock = false;
584 case MAGIC_UNCAPSLOCK_TO_CONTROL:
585 keymap_config.capslock_to_control = false;
587 case MAGIC_UNSWAP_LALT_LGUI:
588 keymap_config.swap_lalt_lgui = false;
590 case MAGIC_UNSWAP_RALT_RGUI:
591 keymap_config.swap_ralt_rgui = false;
593 case MAGIC_UNSWAP_LCTL_LGUI:
594 keymap_config.swap_lctl_lgui = false;
596 case MAGIC_UNSWAP_RCTL_RGUI:
597 keymap_config.swap_rctl_rgui = false;
600 keymap_config.no_gui = false;
602 case MAGIC_UNSWAP_GRAVE_ESC:
603 keymap_config.swap_grave_esc = false;
605 case MAGIC_UNSWAP_BACKSLASH_BACKSPACE:
606 keymap_config.swap_backslash_backspace = false;
608 case MAGIC_UNHOST_NKRO:
609 clear_keyboard(); // clear first buffer to prevent stuck keys
610 keymap_config.nkro = false;
612 case MAGIC_UNSWAP_ALT_GUI:
613 keymap_config.swap_lalt_lgui = keymap_config.swap_ralt_rgui = false;
615 PLAY_SONG(ag_norm_song);
618 case MAGIC_UNSWAP_CTL_GUI:
619 keymap_config.swap_lctl_lgui = keymap_config.swap_rctl_rgui = false;
621 PLAY_SONG(cg_norm_song);
624 case MAGIC_TOGGLE_ALT_GUI:
625 keymap_config.swap_lalt_lgui = !keymap_config.swap_lalt_lgui;
626 keymap_config.swap_ralt_rgui = keymap_config.swap_lalt_lgui;
628 if (keymap_config.swap_ralt_rgui) {
629 PLAY_SONG(ag_swap_song);
631 PLAY_SONG(ag_norm_song);
635 case MAGIC_TOGGLE_CTL_GUI:
636 keymap_config.swap_lctl_lgui = !keymap_config.swap_lctl_lgui;
637 keymap_config.swap_rctl_rgui = keymap_config.swap_lctl_lgui;
639 if (keymap_config.swap_rctl_rgui) {
640 PLAY_SONG(cg_swap_song);
642 PLAY_SONG(cg_norm_song);
646 case MAGIC_TOGGLE_NKRO:
647 clear_keyboard(); // clear first buffer to prevent stuck keys
648 keymap_config.nkro = !keymap_config.nkro;
650 case MAGIC_EE_HANDS_LEFT:
651 eeconfig_update_handedness(true);
653 case MAGIC_EE_HANDS_RIGHT:
654 eeconfig_update_handedness(false);
659 eeconfig_update_keymap(keymap_config.raw);
660 clear_keyboard(); // clear to prevent stuck keys
667 uint8_t shifted = get_mods() & ((MOD_BIT(KC_LSHIFT) | MOD_BIT(KC_RSHIFT) | MOD_BIT(KC_LGUI) | MOD_BIT(KC_RGUI)));
669 #ifdef GRAVE_ESC_ALT_OVERRIDE
670 // if ALT is pressed, ESC is always sent
671 // this is handy for the cmd+opt+esc shortcut on macOS, among other things.
672 if (get_mods() & (MOD_BIT(KC_LALT) | MOD_BIT(KC_RALT))) {
677 #ifdef GRAVE_ESC_CTRL_OVERRIDE
678 // if CTRL is pressed, ESC is always sent
679 // this is handy for the ctrl+shift+esc shortcut on windows, among other things.
680 if (get_mods() & (MOD_BIT(KC_LCTL) | MOD_BIT(KC_RCTL))) {
685 #ifdef GRAVE_ESC_GUI_OVERRIDE
686 // if GUI is pressed, ESC is always sent
687 if (get_mods() & (MOD_BIT(KC_LGUI) | MOD_BIT(KC_RGUI))) {
692 #ifdef GRAVE_ESC_SHIFT_OVERRIDE
693 // if SHIFT is pressed, ESC is always sent
694 if (get_mods() & (MOD_BIT(KC_LSHIFT) | MOD_BIT(KC_RSHIFT))) {
699 if (record->event.pressed) {
700 grave_esc_was_shifted = shifted;
701 add_key(shifted ? KC_GRAVE : KC_ESCAPE);
703 del_key(grave_esc_was_shifted ? KC_GRAVE : KC_ESCAPE);
706 send_keyboard_report();
710 #if defined(BACKLIGHT_ENABLE) && defined(BACKLIGHT_BREATHING)
712 if (record->event.pressed) {
713 backlight_toggle_breathing();
720 return process_action_kb(record);
723 __attribute__((weak)) const bool ascii_to_shift_lut[128] PROGMEM = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
725 0, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 0};
727 __attribute__((weak)) const bool ascii_to_altgr_lut[128] PROGMEM = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
729 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
731 __attribute__((weak)) const uint8_t ascii_to_keycode_lut[128] PROGMEM = {// NUL SOH STX ETX EOT ENQ ACK BEL
732 XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX,
733 // BS TAB LF VT FF CR SO SI
734 KC_BSPC, KC_TAB, KC_ENT, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX,
735 // DLE DC1 DC2 DC3 DC4 NAK SYN ETB
736 XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX,
737 // CAN EM SUB ESC FS GS RS US
738 XXXXXXX, XXXXXXX, XXXXXXX, KC_ESC, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX,
741 KC_SPC, KC_1, KC_QUOT, KC_3, KC_4, KC_5, KC_7, KC_QUOT,
743 KC_9, KC_0, KC_8, KC_EQL, KC_COMM, KC_MINS, KC_DOT, KC_SLSH,
745 KC_0, KC_1, KC_2, KC_3, KC_4, KC_5, KC_6, KC_7,
747 KC_8, KC_9, KC_SCLN, KC_SCLN, KC_COMM, KC_EQL, KC_DOT, KC_SLSH,
749 KC_2, KC_A, KC_B, KC_C, KC_D, KC_E, KC_F, KC_G,
751 KC_H, KC_I, KC_J, KC_K, KC_L, KC_M, KC_N, KC_O,
753 KC_P, KC_Q, KC_R, KC_S, KC_T, KC_U, KC_V, KC_W,
755 KC_X, KC_Y, KC_Z, KC_LBRC, KC_BSLS, KC_RBRC, KC_6, KC_MINS,
757 KC_GRV, KC_A, KC_B, KC_C, KC_D, KC_E, KC_F, KC_G,
759 KC_H, KC_I, KC_J, KC_K, KC_L, KC_M, KC_N, KC_O,
761 KC_P, KC_Q, KC_R, KC_S, KC_T, KC_U, KC_V, KC_W,
763 KC_X, KC_Y, KC_Z, KC_LBRC, KC_BSLS, KC_RBRC, KC_GRV, KC_DEL};
765 void send_string(const char *str) { send_string_with_delay(str, 0); }
767 void send_string_P(const char *str) { send_string_with_delay_P(str, 0); }
769 void send_string_with_delay(const char *str, uint8_t interval) {
771 char ascii_code = *str;
772 if (!ascii_code) break;
773 if (ascii_code == SS_TAP_CODE) {
775 uint8_t keycode = *(++str);
776 register_code(keycode);
777 unregister_code(keycode);
778 } else if (ascii_code == SS_DOWN_CODE) {
780 uint8_t keycode = *(++str);
781 register_code(keycode);
782 } else if (ascii_code == SS_UP_CODE) {
784 uint8_t keycode = *(++str);
785 unregister_code(keycode);
787 send_char(ascii_code);
792 uint8_t ms = interval;
793 while (ms--) wait_ms(1);
798 void send_string_with_delay_P(const char *str, uint8_t interval) {
800 char ascii_code = pgm_read_byte(str);
801 if (!ascii_code) break;
802 if (ascii_code == SS_TAP_CODE) {
804 uint8_t keycode = pgm_read_byte(++str);
805 register_code(keycode);
806 unregister_code(keycode);
807 } else if (ascii_code == SS_DOWN_CODE) {
809 uint8_t keycode = pgm_read_byte(++str);
810 register_code(keycode);
811 } else if (ascii_code == SS_UP_CODE) {
813 uint8_t keycode = pgm_read_byte(++str);
814 unregister_code(keycode);
816 send_char(ascii_code);
821 uint8_t ms = interval;
822 while (ms--) wait_ms(1);
827 void send_char(char ascii_code) {
828 uint8_t keycode = pgm_read_byte(&ascii_to_keycode_lut[(uint8_t)ascii_code]);
829 bool is_shifted = pgm_read_byte(&ascii_to_shift_lut[(uint8_t)ascii_code]);
830 bool is_altgred = pgm_read_byte(&ascii_to_altgr_lut[(uint8_t)ascii_code]);
833 register_code(KC_LSFT);
836 register_code(KC_RALT);
840 unregister_code(KC_RALT);
843 unregister_code(KC_LSFT);
847 void set_single_persistent_default_layer(uint8_t default_layer) {
848 #if defined(AUDIO_ENABLE) && defined(DEFAULT_LAYER_SONGS)
849 PLAY_SONG(default_layer_songs[default_layer]);
851 eeconfig_update_default_layer(1U << default_layer);
852 default_layer_set(1U << default_layer);
855 layer_state_t update_tri_layer_state(layer_state_t state, uint8_t layer1, uint8_t layer2, uint8_t layer3) {
856 layer_state_t mask12 = (1UL << layer1) | (1UL << layer2);
857 layer_state_t mask3 = 1UL << layer3;
858 return (state & mask12) == mask12 ? (state | mask3) : (state & ~mask3);
861 void update_tri_layer(uint8_t layer1, uint8_t layer2, uint8_t layer3) { layer_state_set(update_tri_layer_state(layer_state, layer1, layer2, layer3)); }
863 void tap_random_base64(void) {
864 #if defined(__AVR_ATmega32U4__)
865 uint8_t key = (TCNT0 + TCNT1 + TCNT3 + TCNT4) % 64;
867 uint8_t key = rand() % 64;
871 register_code(KC_LSFT);
872 register_code(key + KC_A);
873 unregister_code(key + KC_A);
874 unregister_code(KC_LSFT);
877 register_code(key - 26 + KC_A);
878 unregister_code(key - 26 + KC_A);
882 unregister_code(KC_0);
885 register_code(key - 53 + KC_1);
886 unregister_code(key - 53 + KC_1);
889 register_code(KC_LSFT);
890 register_code(KC_EQL);
891 unregister_code(KC_EQL);
892 unregister_code(KC_LSFT);
895 register_code(KC_SLSH);
896 unregister_code(KC_SLSH);
901 __attribute__((weak)) void bootmagic_lite(void) {
902 // The lite version of TMK's bootmagic based on Wilba.
903 // 100% less potential for accidentally making the
904 // keyboard do stupid things.
906 // We need multiple scans because debouncing can't be turned off.
908 #if defined(DEBOUNCING_DELAY) && DEBOUNCING_DELAY > 0
909 wait_ms(DEBOUNCING_DELAY * 2);
910 #elif defined(DEBOUNCE) && DEBOUNCE > 0
911 wait_ms(DEBOUNCE * 2);
917 // If the Esc and space bar are held down on power up,
918 // reset the EEPROM valid state and jump to bootloader.
919 // Assumes Esc is at [0,0].
920 // This isn't very generalized, but we need something that doesn't
921 // rely on user's keymaps in firmware or EEPROM.
922 if (matrix_get_row(BOOTMAGIC_LITE_ROW) & (1 << BOOTMAGIC_LITE_COLUMN)) {
924 // Jump to bootloader.
929 void matrix_init_quantum() {
930 #ifdef BOOTMAGIC_LITE
933 if (!eeconfig_is_enabled()) {
936 #ifdef BACKLIGHT_ENABLE
937 # ifdef LED_MATRIX_ENABLE
940 backlight_init_ports();
946 #ifdef RGB_MATRIX_ENABLE
949 #ifdef ENCODER_ENABLE
952 #if defined(UNICODE_ENABLE) || defined(UNICODEMAP_ENABLE) || defined(UCIS_ENABLE)
953 unicode_input_mode_init();
958 #ifdef OUTPUT_AUTO_ENABLE
959 set_output(OUTPUT_AUTO);
961 #ifdef DIP_SWITCH_ENABLE
968 void matrix_scan_quantum() {
969 #if defined(AUDIO_ENABLE) && !defined(NO_MUSIC_MODE)
973 #ifdef TAP_DANCE_ENABLE
974 matrix_scan_tap_dance();
981 #if defined(BACKLIGHT_ENABLE)
982 # if defined(LED_MATRIX_ENABLE)
984 # elif defined(BACKLIGHT_PIN)
989 #ifdef RGB_MATRIX_ENABLE
993 #ifdef ENCODER_ENABLE
1001 #ifdef DIP_SWITCH_ENABLE
1002 dip_switch_read(false);
1008 #ifdef HD44780_ENABLED
1009 # include "hd44780.h"
1012 // Functions for spitting out values
1015 void send_dword(uint32_t number) { // this might not actually work
1016 uint16_t word = (number >> 16);
1018 send_word(number & 0xFFFFUL);
1021 void send_word(uint16_t number) {
1022 uint8_t byte = number >> 8;
1024 send_byte(number & 0xFF);
1027 void send_byte(uint8_t number) {
1028 uint8_t nibble = number >> 4;
1029 send_nibble(nibble);
1030 send_nibble(number & 0xF);
1033 void send_nibble(uint8_t number) {
1036 register_code(KC_0);
1037 unregister_code(KC_0);
1040 register_code(KC_1 + (number - 1));
1041 unregister_code(KC_1 + (number - 1));
1044 register_code(KC_A + (number - 0xA));
1045 unregister_code(KC_A + (number - 0xA));
1050 __attribute__((weak)) uint16_t hex_to_keycode(uint8_t hex) {
1054 } else if (hex < 0xA) {
1055 return KC_1 + (hex - 0x1);
1057 return KC_A + (hex - 0xA);
1061 void api_send_unicode(uint32_t unicode) {
1064 dword_to_bytes(unicode, chunk);
1065 MT_SEND_DATA(DT_UNICODE, chunk, 5);
1069 __attribute__((weak)) void led_set_user(uint8_t usb_led) {}
1071 __attribute__((weak)) void led_set_kb(uint8_t usb_led) { led_set_user(usb_led); }
1073 __attribute__((weak)) void led_init_ports(void) {}
1075 __attribute__((weak)) void led_set(uint8_t usb_led) {
1076 #if defined(BACKLIGHT_CAPS_LOCK) && defined(BACKLIGHT_ENABLE)
1077 // Use backlight as Caps Lock indicator
1078 uint8_t bl_toggle_lvl = 0;
1080 if (IS_LED_ON(usb_led, USB_LED_CAPS_LOCK) && !backlight_config.enable) {
1081 // Turning Caps Lock ON and backlight is disabled in config
1082 // Toggling backlight to the brightest level
1083 bl_toggle_lvl = BACKLIGHT_LEVELS;
1084 } else if (IS_LED_OFF(usb_led, USB_LED_CAPS_LOCK) && backlight_config.enable) {
1085 // Turning Caps Lock OFF and backlight is enabled in config
1086 // Toggling backlight and restoring config level
1087 bl_toggle_lvl = backlight_config.level;
1090 // Set level without modify backlight_config to keep ability to restore state
1091 backlight_set(bl_toggle_lvl);
1094 led_set_kb(usb_led);
1097 //------------------------------------------------------------------------------
1098 // Override these functions in your keymap file to play different tunes on
1099 // different events such as startup and bootloader jump
1101 __attribute__((weak)) void startup_user() {}
1103 __attribute__((weak)) void shutdown_user() {}
1105 //------------------------------------------------------------------------------