Commit | Line | Data |
---|---|---|
23839b8c | 1 | /* Copyright 2016-2017 Jack Humbert |
2 | * | |
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. | |
7 | * | |
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. | |
12 | * | |
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/>. | |
15 | */ | |
16 | ||
1a8c0dd2 | 17 | #include "quantum.h" |
2e8b32b9 | 18 | |
e7c4f621 | 19 | #ifdef PROTOCOL_LUFA |
b624f32f | 20 | # include "outputselect.h" |
2bef8b5b | 21 | #endif |
1a8c0dd2 | 22 | |
abfd6ed9 JC |
23 | #ifdef BACKLIGHT_ENABLE |
24 | # include "backlight.h" | |
542cb0a8 | 25 | extern backlight_config_t backlight_config; |
abfd6ed9 | 26 | #endif |
db1e9a46 | 27 | |
8c93c5d9 | 28 | #ifdef FAUXCLICKY_ENABLE |
b624f32f | 29 | # include "fauxclicky.h" |
8c93c5d9 | 30 | #endif |
8d0fdf10 | 31 | |
53ff8a31 | 32 | #ifdef API_ENABLE |
b624f32f | 33 | # include "api.h" |
53ff8a31 | 34 | #endif |
35 | ||
36 | #ifdef MIDI_ENABLE | |
b624f32f | 37 | # include "process_midi.h" |
53ff8a31 | 38 | #endif |
39 | ||
c1c5922a | 40 | #ifdef VELOCIKEY_ENABLE |
b624f32f | 41 | # include "velocikey.h" |
c1c5922a CL |
42 | #endif |
43 | ||
2cee371b | 44 | #ifdef HAPTIC_ENABLE |
b624f32f | 45 | # include "haptic.h" |
2cee371b | 46 | #endif |
85688e5b JH |
47 | |
48 | #ifdef ENCODER_ENABLE | |
b624f32f | 49 | # include "encoder.h" |
85688e5b JH |
50 | #endif |
51 | ||
6a3c6677 | 52 | #ifdef AUDIO_ENABLE |
b624f32f | 53 | # ifndef GOODBYE_SONG |
54 | # define GOODBYE_SONG SONG(GOODBYE_SOUND) | |
55 | # endif | |
b624f32f | 56 | float goodbye_song[][2] = GOODBYE_SONG; |
b624f32f | 57 | # ifdef DEFAULT_LAYER_SONGS |
58 | float default_layer_songs[][16][2] = DEFAULT_LAYER_SONGS; | |
59 | # endif | |
e5501d48 | 60 | # ifdef SENDSTRING_BELL |
61 | float bell_song[][2] = SONG(TERMINAL_SOUND); | |
62 | # endif | |
b624f32f | 63 | #endif |
64 | ||
65 | static void do_code16(uint16_t code, void (*f)(uint8_t)) { | |
66 | switch (code) { | |
67 | case QK_MODS ... QK_MODS_MAX: | |
68 | break; | |
69 | default: | |
70 | return; | |
71 | } | |
72 | ||
63f4806d | 73 | uint8_t mods_to_send = 0; |
b624f32f | 74 | |
542cb0a8 | 75 | if (code & QK_RMODS_MIN) { // Right mod flag is set |
63f4806d | 76 | if (code & QK_LCTL) mods_to_send |= MOD_BIT(KC_RCTL); |
77 | if (code & QK_LSFT) mods_to_send |= MOD_BIT(KC_RSFT); | |
78 | if (code & QK_LALT) mods_to_send |= MOD_BIT(KC_RALT); | |
79 | if (code & QK_LGUI) mods_to_send |= MOD_BIT(KC_RGUI); | |
80 | } else { | |
81 | if (code & QK_LCTL) mods_to_send |= MOD_BIT(KC_LCTL); | |
82 | if (code & QK_LSFT) mods_to_send |= MOD_BIT(KC_LSFT); | |
83 | if (code & QK_LALT) mods_to_send |= MOD_BIT(KC_LALT); | |
84 | if (code & QK_LGUI) mods_to_send |= MOD_BIT(KC_LGUI); | |
85 | } | |
2b385993 | 86 | |
63f4806d | 87 | f(mods_to_send); |
2b385993 S |
88 | } |
89 | ||
b624f32f | 90 | void register_code16(uint16_t code) { |
91 | if (IS_MOD(code) || code == KC_NO) { | |
63f4806d | 92 | do_code16(code, register_mods); |
b624f32f | 93 | } else { |
63f4806d | 94 | do_code16(code, register_weak_mods); |
b624f32f | 95 | } |
96 | register_code(code); | |
0d28787c GN |
97 | } |
98 | ||
b624f32f | 99 | void unregister_code16(uint16_t code) { |
100 | unregister_code(code); | |
101 | if (IS_MOD(code) || code == KC_NO) { | |
63f4806d | 102 | do_code16(code, unregister_mods); |
b624f32f | 103 | } else { |
63f4806d | 104 | do_code16(code, unregister_weak_mods); |
b624f32f | 105 | } |
0d28787c GN |
106 | } |
107 | ||
02d44beb | 108 | void tap_code16(uint16_t code) { |
b624f32f | 109 | register_code16(code); |
110 | #if TAP_CODE_DELAY > 0 | |
02d44beb | 111 | wait_ms(TAP_CODE_DELAY); |
b624f32f | 112 | #endif |
113 | unregister_code16(code); | |
02d44beb DJ |
114 | } |
115 | ||
b624f32f | 116 | __attribute__((weak)) bool process_action_kb(keyrecord_t *record) { return true; } |
1a8c0dd2 | 117 | |
b624f32f | 118 | __attribute__((weak)) bool process_record_kb(uint16_t keycode, keyrecord_t *record) { return process_record_user(keycode, record); } |
17977a7e | 119 | |
b624f32f | 120 | __attribute__((weak)) bool process_record_user(uint16_t keycode, keyrecord_t *record) { return true; } |
17977a7e | 121 | |
a28a6e5b | 122 | void reset_keyboard(void) { |
b624f32f | 123 | clear_keyboard(); |
e6b91549 | 124 | #if defined(MIDI_ENABLE) && defined(MIDI_BASIC) |
b624f32f | 125 | process_midi_all_notes_off(); |
365b8635 | 126 | #endif |
ef5b161b | 127 | #ifdef AUDIO_ENABLE |
b624f32f | 128 | # ifndef NO_MUSIC_MODE |
ef5b161b | 129 | music_all_notes_off(); |
b624f32f | 130 | # endif |
131 | uint16_t timer_start = timer_read(); | |
132 | PLAY_SONG(goodbye_song); | |
133 | shutdown_user(); | |
134 | while (timer_elapsed(timer_start) < 250) wait_ms(1); | |
135 | stop_all_notes(); | |
6a3c6677 | 136 | #else |
b624f32f | 137 | shutdown_user(); |
138 | wait_ms(250); | |
6a3c6677 | 139 | #endif |
2cee371b | 140 | #ifdef HAPTIC_ENABLE |
b624f32f | 141 | haptic_shutdown(); |
2cee371b | 142 | #endif |
9fdc2762 JH |
143 | // this is also done later in bootloader.c - not sure if it's neccesary here |
144 | #ifdef BOOTLOADER_CATERINA | |
b624f32f | 145 | *(uint16_t *)0x0800 = 0x7777; // these two are a-star-specific |
a28a6e5b | 146 | #endif |
b624f32f | 147 | bootloader_jump(); |
a28a6e5b PV |
148 | } |
149 | ||
5701b75e | 150 | /* Convert record into usable keycode via the contained event. */ |
b624f32f | 151 | uint16_t get_record_keycode(keyrecord_t *record) { return get_event_keycode(record->event); } |
5701b75e DJ |
152 | |
153 | /* Convert event into usable keycode. Checks the layer cache to ensure that it | |
154 | * retains the correct keycode after a layer change, if the key is still pressed. | |
155 | */ | |
156 | uint16_t get_event_keycode(keyevent_t event) { | |
b624f32f | 157 | #if !defined(NO_ACTION_LAYER) && !defined(STRICT_LAYER_RELEASE) |
644c8c79 WS |
158 | /* TODO: Use store_or_get_action() or a similar function. */ |
159 | if (!disable_action_cache) { | |
b624f32f | 160 | uint8_t layer; |
161 | ||
162 | if (event.pressed) { | |
163 | layer = layer_switch_get_layer(event.key); | |
164 | update_source_layers_cache(event.key, layer); | |
165 | } else { | |
166 | layer = read_source_layers_cache(event.key); | |
167 | } | |
168 | return keymap_key_to_keycode(layer, event.key); | |
644c8c79 | 169 | } else |
b624f32f | 170 | #endif |
171 | return keymap_key_to_keycode(layer_switch_get_layer(event.key), event.key); | |
5701b75e DJ |
172 | } |
173 | ||
174 | /* Main keycode processing function. Hands off handling to other functions, | |
175 | * then processes internal Quantum keycodes, then processes ACTIONs. | |
176 | */ | |
177 | bool process_record_quantum(keyrecord_t *record) { | |
178 | uint16_t keycode = get_record_keycode(record); | |
1a8c0dd2 | 179 | |
bf5c2cce JH |
180 | // This is how you use actions here |
181 | // if (keycode == KC_LEAD) { | |
182 | // action_t action; | |
183 | // action.code = ACTION_DEFAULT_LAYER_SET(0); | |
184 | // process_action(record, action); | |
185 | // return false; | |
186 | // } | |
187 | ||
b624f32f | 188 | #ifdef VELOCIKEY_ENABLE |
189 | if (velocikey_enabled() && record->event.pressed) { | |
190 | velocikey_accelerate(); | |
191 | } | |
192 | #endif | |
c1c5922a | 193 | |
b624f32f | 194 | #ifdef TAP_DANCE_ENABLE |
9fcda953 | 195 | preprocess_tap_dance(keycode, record); |
b624f32f | 196 | #endif |
558f3ec1 | 197 | |
b624f32f | 198 | if (!( |
199 | #if defined(KEY_LOCK_ENABLE) | |
200 | // Must run first to be able to mask key_up events. | |
201 | process_key_lock(&keycode, record) && | |
202 | #endif | |
542cb0a8 DJ |
203 | #if defined(DYNAMIC_MACRO_ENABLE) && !defined(DYNAMIC_MACRO_USER_CALL) |
204 | // Must run asap to ensure all keypresses are recorded. | |
205 | process_dynamic_macro(keycode, record) && | |
206 | #endif | |
b624f32f | 207 | #if defined(AUDIO_ENABLE) && defined(AUDIO_CLICKY) |
208 | process_clicky(keycode, record) && | |
209 | #endif // AUDIO_CLICKY | |
210 | #ifdef HAPTIC_ENABLE | |
211 | process_haptic(keycode, record) && | |
212 | #endif // HAPTIC_ENABLE | |
213 | #if defined(RGB_MATRIX_ENABLE) | |
214 | process_rgb_matrix(keycode, record) && | |
320822d7 W |
215 | #endif |
216 | #if defined(VIA_ENABLE) | |
217 | process_record_via(keycode, record) && | |
b624f32f | 218 | #endif |
219 | process_record_kb(keycode, record) && | |
220 | #if defined(MIDI_ENABLE) && defined(MIDI_ADVANCED) | |
221 | process_midi(keycode, record) && | |
222 | #endif | |
223 | #ifdef AUDIO_ENABLE | |
224 | process_audio(keycode, record) && | |
225 | #endif | |
226 | #ifdef STENO_ENABLE | |
227 | process_steno(keycode, record) && | |
228 | #endif | |
229 | #if (defined(AUDIO_ENABLE) || (defined(MIDI_ENABLE) && defined(MIDI_BASIC))) && !defined(NO_MUSIC_MODE) | |
230 | process_music(keycode, record) && | |
231 | #endif | |
232 | #ifdef TAP_DANCE_ENABLE | |
233 | process_tap_dance(keycode, record) && | |
234 | #endif | |
235 | #if defined(UNICODE_ENABLE) || defined(UNICODEMAP_ENABLE) || defined(UCIS_ENABLE) | |
236 | process_unicode_common(keycode, record) && | |
237 | #endif | |
238 | #ifdef LEADER_ENABLE | |
239 | process_leader(keycode, record) && | |
240 | #endif | |
241 | #ifdef COMBO_ENABLE | |
242 | process_combo(keycode, record) && | |
243 | #endif | |
244 | #ifdef PRINTING_ENABLE | |
245 | process_printer(keycode, record) && | |
246 | #endif | |
247 | #ifdef AUTO_SHIFT_ENABLE | |
248 | process_auto_shift(keycode, record) && | |
249 | #endif | |
250 | #ifdef TERMINAL_ENABLE | |
251 | process_terminal(keycode, record) && | |
252 | #endif | |
253 | #ifdef SPACE_CADET_ENABLE | |
254 | process_space_cadet(keycode, record) && | |
d598f01c JC |
255 | #endif |
256 | #ifdef MAGIC_KEYCODE_ENABLE | |
257 | process_magic(keycode, record) && | |
ae40fc49 | 258 | #endif |
393937b4 JC |
259 | #ifdef GRAVE_ESC_ENABLE |
260 | process_grave_esc(keycode, record) && | |
261 | #endif | |
ae40fc49 JC |
262 | #if defined(RGBLIGHT_ENABLE) || defined(RGB_MATRIX_ENABLE) |
263 | process_rgb(keycode, record) && | |
b624f32f | 264 | #endif |
265 | true)) { | |
db32864c | 266 | return false; |
b624f32f | 267 | } |
8a1e6560 | 268 | |
1604f796 YFL |
269 | if (record->event.pressed) { |
270 | switch (keycode) { | |
271 | case RESET: | |
b624f32f | 272 | reset_keyboard(); |
1604f796 | 273 | return false; |
2048df88 | 274 | #ifndef NO_DEBUG |
1604f796 | 275 | case DEBUG: |
b624f32f | 276 | debug_enable ^= 1; |
277 | if (debug_enable) { | |
278 | print("DEBUG: enabled.\n"); | |
279 | } else { | |
280 | print("DEBUG: disabled.\n"); | |
281 | } | |
2048df88 | 282 | #endif |
1604f796 YFL |
283 | return false; |
284 | case EEPROM_RESET: | |
b624f32f | 285 | eeconfig_init(); |
1604f796 | 286 | return false; |
b624f32f | 287 | #ifdef FAUXCLICKY_ENABLE |
1604f796 | 288 | case FC_TOG: |
b624f32f | 289 | FAUXCLICKY_TOGGLE; |
1604f796 YFL |
290 | return false; |
291 | case FC_ON: | |
b624f32f | 292 | FAUXCLICKY_ON; |
1604f796 YFL |
293 | return false; |
294 | case FC_OFF: | |
b624f32f | 295 | FAUXCLICKY_OFF; |
1604f796 YFL |
296 | return false; |
297 | #endif | |
298 | #ifdef VELOCIKEY_ENABLE | |
299 | case VLK_TOG: | |
300 | velocikey_toggle(); | |
301 | return false; | |
302 | #endif | |
2048df88 | 303 | #ifdef BLUETOOTH_ENABLE |
ae40fc49 | 304 | case OUT_AUTO: |
1604f796 YFL |
305 | set_output(OUTPUT_AUTO); |
306 | return false; | |
ae40fc49 | 307 | case OUT_USB: |
1604f796 YFL |
308 | set_output(OUTPUT_USB); |
309 | return false; | |
ae40fc49 | 310 | case OUT_BT: |
1604f796 YFL |
311 | set_output(OUTPUT_BLUETOOTH); |
312 | return false; | |
de4eb79c JC |
313 | #endif |
314 | #if defined(BACKLIGHT_ENABLE) && defined(BACKLIGHT_BREATHING) | |
ae40fc49 | 315 | case BL_BRTG: |
de4eb79c JC |
316 | backlight_toggle_breathing(); |
317 | return false; | |
b624f32f | 318 | #endif |
1604f796 YFL |
319 | } |
320 | } | |
321 | ||
b624f32f | 322 | return process_action_kb(record); |
fdc2e805 SH |
323 | } |
324 | ||
b624f32f | 325 | __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, |
326 | ||
327 | 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}; | |
328 | ||
329 | __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, | |
330 | ||
331 | 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}; | |
332 | ||
667045b4 | 333 | // clang-format off |
b624f32f | 334 | __attribute__((weak)) const uint8_t ascii_to_keycode_lut[128] PROGMEM = {// NUL SOH STX ETX EOT ENQ ACK BEL |
335 | XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, | |
336 | // BS TAB LF VT FF CR SO SI | |
337 | KC_BSPC, KC_TAB, KC_ENT, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, | |
338 | // DLE DC1 DC2 DC3 DC4 NAK SYN ETB | |
339 | XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, | |
340 | // CAN EM SUB ESC FS GS RS US | |
341 | XXXXXXX, XXXXXXX, XXXXXXX, KC_ESC, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, | |
342 | ||
343 | // ! " # $ % & ' | |
344 | KC_SPC, KC_1, KC_QUOT, KC_3, KC_4, KC_5, KC_7, KC_QUOT, | |
345 | // ( ) * + , - . / | |
346 | KC_9, KC_0, KC_8, KC_EQL, KC_COMM, KC_MINS, KC_DOT, KC_SLSH, | |
347 | // 0 1 2 3 4 5 6 7 | |
348 | KC_0, KC_1, KC_2, KC_3, KC_4, KC_5, KC_6, KC_7, | |
349 | // 8 9 : ; < = > ? | |
350 | KC_8, KC_9, KC_SCLN, KC_SCLN, KC_COMM, KC_EQL, KC_DOT, KC_SLSH, | |
351 | // @ A B C D E F G | |
352 | KC_2, KC_A, KC_B, KC_C, KC_D, KC_E, KC_F, KC_G, | |
353 | // H I J K L M N O | |
354 | KC_H, KC_I, KC_J, KC_K, KC_L, KC_M, KC_N, KC_O, | |
355 | // P Q R S T U V W | |
356 | KC_P, KC_Q, KC_R, KC_S, KC_T, KC_U, KC_V, KC_W, | |
357 | // X Y Z [ \ ] ^ _ | |
358 | KC_X, KC_Y, KC_Z, KC_LBRC, KC_BSLS, KC_RBRC, KC_6, KC_MINS, | |
359 | // ` a b c d e f g | |
360 | KC_GRV, KC_A, KC_B, KC_C, KC_D, KC_E, KC_F, KC_G, | |
361 | // h i j k l m n o | |
362 | KC_H, KC_I, KC_J, KC_K, KC_L, KC_M, KC_N, KC_O, | |
363 | // p q r s t u v w | |
364 | KC_P, KC_Q, KC_R, KC_S, KC_T, KC_U, KC_V, KC_W, | |
365 | // x y z { | } ~ DEL | |
366 | KC_X, KC_Y, KC_Z, KC_LBRC, KC_BSLS, KC_RBRC, KC_GRV, KC_DEL}; | |
667045b4 | 367 | // clang-format on |
b624f32f | 368 | |
369 | void send_string(const char *str) { send_string_with_delay(str, 0); } | |
370 | ||
371 | void send_string_P(const char *str) { send_string_with_delay_P(str, 0); } | |
7ad924ba | 372 | |
fdc2e805 | 373 | void send_string_with_delay(const char *str, uint8_t interval) { |
5dae013f | 374 | while (1) { |
7ad924ba | 375 | char ascii_code = *str; |
5dae013f | 376 | if (!ascii_code) break; |
d15bb05c | 377 | if (ascii_code == SS_TAP_CODE) { |
b624f32f | 378 | // tap |
379 | uint8_t keycode = *(++str); | |
380 | register_code(keycode); | |
381 | unregister_code(keycode); | |
d15bb05c | 382 | } else if (ascii_code == SS_DOWN_CODE) { |
b624f32f | 383 | // down |
384 | uint8_t keycode = *(++str); | |
385 | register_code(keycode); | |
d15bb05c | 386 | } else if (ascii_code == SS_UP_CODE) { |
b624f32f | 387 | // up |
388 | uint8_t keycode = *(++str); | |
389 | unregister_code(keycode); | |
7ad924ba | 390 | } else { |
b624f32f | 391 | send_char(ascii_code); |
5dae013f | 392 | } |
7ad924ba JH |
393 | ++str; |
394 | // interval | |
b624f32f | 395 | { |
396 | uint8_t ms = interval; | |
397 | while (ms--) wait_ms(1); | |
398 | } | |
7ad924ba JH |
399 | } |
400 | } | |
401 | ||
402 | void send_string_with_delay_P(const char *str, uint8_t interval) { | |
403 | while (1) { | |
404 | char ascii_code = pgm_read_byte(str); | |
405 | if (!ascii_code) break; | |
d15bb05c | 406 | if (ascii_code == SS_TAP_CODE) { |
b624f32f | 407 | // tap |
408 | uint8_t keycode = pgm_read_byte(++str); | |
409 | register_code(keycode); | |
410 | unregister_code(keycode); | |
d15bb05c | 411 | } else if (ascii_code == SS_DOWN_CODE) { |
b624f32f | 412 | // down |
413 | uint8_t keycode = pgm_read_byte(++str); | |
414 | register_code(keycode); | |
d15bb05c | 415 | } else if (ascii_code == SS_UP_CODE) { |
b624f32f | 416 | // up |
417 | uint8_t keycode = pgm_read_byte(++str); | |
418 | unregister_code(keycode); | |
7ad924ba | 419 | } else { |
b624f32f | 420 | send_char(ascii_code); |
5dae013f | 421 | } |
422 | ++str; | |
fdc2e805 | 423 | // interval |
b624f32f | 424 | { |
425 | uint8_t ms = interval; | |
426 | while (ms--) wait_ms(1); | |
427 | } | |
5dae013f | 428 | } |
429 | } | |
430 | ||
7ad924ba | 431 | void send_char(char ascii_code) { |
e5501d48 | 432 | #if defined(AUDIO_ENABLE) && defined(SENDSTRING_BELL) |
667045b4 | 433 | if (ascii_code == '\a') { // BEL |
e5501d48 | 434 | PLAY_SONG(bell_song); |
435 | return; | |
436 | } | |
437 | #endif | |
438 | ||
b624f32f | 439 | uint8_t keycode = pgm_read_byte(&ascii_to_keycode_lut[(uint8_t)ascii_code]); |
440 | bool is_shifted = pgm_read_byte(&ascii_to_shift_lut[(uint8_t)ascii_code]); | |
441 | bool is_altgred = pgm_read_byte(&ascii_to_altgr_lut[(uint8_t)ascii_code]); | |
442 | ||
443 | if (is_shifted) { | |
444 | register_code(KC_LSFT); | |
445 | } | |
446 | if (is_altgred) { | |
447 | register_code(KC_RALT); | |
448 | } | |
449 | tap_code(keycode); | |
450 | if (is_altgred) { | |
451 | unregister_code(KC_RALT); | |
452 | } | |
453 | if (is_shifted) { | |
454 | unregister_code(KC_LSFT); | |
455 | } | |
7ad924ba JH |
456 | } |
457 | ||
6a3c6677 | 458 | void set_single_persistent_default_layer(uint8_t default_layer) { |
b624f32f | 459 | #if defined(AUDIO_ENABLE) && defined(DEFAULT_LAYER_SONGS) |
6a3c6677 | 460 | PLAY_SONG(default_layer_songs[default_layer]); |
b624f32f | 461 | #endif |
462 | eeconfig_update_default_layer(1U << default_layer); | |
463 | default_layer_set(1U << default_layer); | |
6a3c6677 JH |
464 | } |
465 | ||
b62e160a | 466 | layer_state_t update_tri_layer_state(layer_state_t state, uint8_t layer1, uint8_t layer2, uint8_t layer3) { |
b624f32f | 467 | layer_state_t mask12 = (1UL << layer1) | (1UL << layer2); |
468 | layer_state_t mask3 = 1UL << layer3; | |
469 | return (state & mask12) == mask12 ? (state | mask3) : (state & ~mask3); | |
66e40529 MS |
470 | } |
471 | ||
b624f32f | 472 | 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)); } |
1c9f33c0 | 473 | |
197f152d | 474 | void tap_random_base64(void) { |
b624f32f | 475 | #if defined(__AVR_ATmega32U4__) |
60fd885a | 476 | uint8_t key = (TCNT0 + TCNT1 + TCNT3 + TCNT4) % 64; |
b624f32f | 477 | #else |
60fd885a | 478 | uint8_t key = rand() % 64; |
b624f32f | 479 | #endif |
480 | switch (key) { | |
481 | case 0 ... 25: | |
482 | register_code(KC_LSFT); | |
483 | register_code(key + KC_A); | |
484 | unregister_code(key + KC_A); | |
485 | unregister_code(KC_LSFT); | |
486 | break; | |
487 | case 26 ... 51: | |
488 | register_code(key - 26 + KC_A); | |
489 | unregister_code(key - 26 + KC_A); | |
490 | break; | |
491 | case 52: | |
492 | register_code(KC_0); | |
493 | unregister_code(KC_0); | |
494 | break; | |
495 | case 53 ... 61: | |
496 | register_code(key - 53 + KC_1); | |
497 | unregister_code(key - 53 + KC_1); | |
498 | break; | |
499 | case 62: | |
500 | register_code(KC_LSFT); | |
501 | register_code(KC_EQL); | |
502 | unregister_code(KC_EQL); | |
503 | unregister_code(KC_LSFT); | |
504 | break; | |
505 | case 63: | |
506 | register_code(KC_SLSH); | |
507 | unregister_code(KC_SLSH); | |
508 | break; | |
509 | } | |
197f152d JH |
510 | } |
511 | ||
b624f32f | 512 | __attribute__((weak)) void bootmagic_lite(void) { |
513 | // The lite version of TMK's bootmagic based on Wilba. | |
514 | // 100% less potential for accidentally making the | |
515 | // keyboard do stupid things. | |
4ffcacd9 | 516 | |
b624f32f | 517 | // We need multiple scans because debouncing can't be turned off. |
518 | matrix_scan(); | |
320822d7 | 519 | #if defined(DEBOUNCE) && DEBOUNCE > 0 |
4ffcacd9 | 520 | wait_ms(DEBOUNCE * 2); |
b624f32f | 521 | #else |
4ffcacd9 | 522 | wait_ms(30); |
b624f32f | 523 | #endif |
524 | matrix_scan(); | |
525 | ||
526 | // If the Esc and space bar are held down on power up, | |
527 | // reset the EEPROM valid state and jump to bootloader. | |
528 | // Assumes Esc is at [0,0]. | |
529 | // This isn't very generalized, but we need something that doesn't | |
530 | // rely on user's keymaps in firmware or EEPROM. | |
531 | if (matrix_get_row(BOOTMAGIC_LITE_ROW) & (1 << BOOTMAGIC_LITE_COLUMN)) { | |
532 | eeconfig_disable(); | |
533 | // Jump to bootloader. | |
534 | bootloader_jump(); | |
535 | } | |
4ffcacd9 DJ |
536 | } |
537 | ||
1a8c0dd2 | 538 | void matrix_init_quantum() { |
b624f32f | 539 | #ifdef BOOTMAGIC_LITE |
4ffcacd9 | 540 | bootmagic_lite(); |
b624f32f | 541 | #endif |
542 | if (!eeconfig_is_enabled()) { | |
543 | eeconfig_init(); | |
544 | } | |
545 | #ifdef BACKLIGHT_ENABLE | |
546 | # ifdef LED_MATRIX_ENABLE | |
547 | led_matrix_init(); | |
548 | # else | |
549 | backlight_init_ports(); | |
550 | # endif | |
551 | #endif | |
552 | #ifdef AUDIO_ENABLE | |
6a3c6677 | 553 | audio_init(); |
b624f32f | 554 | #endif |
555 | #ifdef RGB_MATRIX_ENABLE | |
bad56a4f | 556 | rgb_matrix_init(); |
b624f32f | 557 | #endif |
558 | #ifdef ENCODER_ENABLE | |
85688e5b | 559 | encoder_init(); |
b624f32f | 560 | #endif |
561 | #if defined(UNICODE_ENABLE) || defined(UNICODEMAP_ENABLE) || defined(UCIS_ENABLE) | |
fdeec296 | 562 | unicode_input_mode_init(); |
b624f32f | 563 | #endif |
564 | #ifdef HAPTIC_ENABLE | |
2cee371b | 565 | haptic_init(); |
b624f32f | 566 | #endif |
567 | #ifdef OUTPUT_AUTO_ENABLE | |
b60413af | 568 | set_output(OUTPUT_AUTO); |
b624f32f | 569 | #endif |
dab4967f DJ |
570 | #ifdef DIP_SWITCH_ENABLE |
571 | dip_switch_init(); | |
572 | #endif | |
573 | ||
b624f32f | 574 | matrix_init_kb(); |
1a8c0dd2 EZ |
575 | } |
576 | ||
577 | void matrix_scan_quantum() { | |
b624f32f | 578 | #if defined(AUDIO_ENABLE) && !defined(NO_MUSIC_MODE) |
65faab3b | 579 | matrix_scan_music(); |
b624f32f | 580 | #endif |
fde477a9 | 581 | |
b624f32f | 582 | #ifdef TAP_DANCE_ENABLE |
65faab3b | 583 | matrix_scan_tap_dance(); |
b624f32f | 584 | #endif |
b6bf4e0d | 585 | |
b624f32f | 586 | #ifdef COMBO_ENABLE |
b6bf4e0d | 587 | matrix_scan_combo(); |
b624f32f | 588 | #endif |
b6bf4e0d | 589 | |
ba628a28 | 590 | #ifdef LED_MATRIX_ENABLE |
b624f32f | 591 | led_matrix_task(); |
b624f32f | 592 | #endif |
8d0fdf10 | 593 | |
b624f32f | 594 | #ifdef RGB_MATRIX_ENABLE |
14b7602a | 595 | rgb_matrix_task(); |
b624f32f | 596 | #endif |
14b7602a | 597 | |
b624f32f | 598 | #ifdef ENCODER_ENABLE |
85688e5b | 599 | encoder_read(); |
b624f32f | 600 | #endif |
85688e5b | 601 | |
b624f32f | 602 | #ifdef HAPTIC_ENABLE |
2cee371b | 603 | haptic_task(); |
b624f32f | 604 | #endif |
2cee371b | 605 | |
dab4967f DJ |
606 | #ifdef DIP_SWITCH_ENABLE |
607 | dip_switch_read(false); | |
608 | #endif | |
609 | ||
b624f32f | 610 | matrix_scan_kb(); |
0428214b | 611 | } |
13bb6b4b | 612 | |
bbea9dad | 613 | #ifdef HD44780_ENABLED |
b624f32f | 614 | # include "hd44780.h" |
bbea9dad MA |
615 | #endif |
616 | ||
664c0a03 JH |
617 | // Functions for spitting out values |
618 | // | |
619 | ||
b624f32f | 620 | void send_dword(uint32_t number) { // this might not actually work |
664c0a03 JH |
621 | uint16_t word = (number >> 16); |
622 | send_word(word); | |
623 | send_word(number & 0xFFFFUL); | |
624 | } | |
625 | ||
626 | void send_word(uint16_t number) { | |
627 | uint8_t byte = number >> 8; | |
628 | send_byte(byte); | |
629 | send_byte(number & 0xFF); | |
630 | } | |
631 | ||
632 | void send_byte(uint8_t number) { | |
633 | uint8_t nibble = number >> 4; | |
634 | send_nibble(nibble); | |
635 | send_nibble(number & 0xF); | |
636 | } | |
637 | ||
638 | void send_nibble(uint8_t number) { | |
639 | switch (number) { | |
640 | case 0: | |
641 | register_code(KC_0); | |
642 | unregister_code(KC_0); | |
643 | break; | |
644 | case 1 ... 9: | |
645 | register_code(KC_1 + (number - 1)); | |
646 | unregister_code(KC_1 + (number - 1)); | |
647 | break; | |
648 | case 0xA ... 0xF: | |
649 | register_code(KC_A + (number - 0xA)); | |
650 | unregister_code(KC_A + (number - 0xA)); | |
651 | break; | |
652 | } | |
653 | } | |
654 | ||
b624f32f | 655 | __attribute__((weak)) uint16_t hex_to_keycode(uint8_t hex) { |
656 | hex = hex & 0xF; | |
657 | if (hex == 0x0) { | |
658 | return KC_0; | |
659 | } else if (hex < 0xA) { | |
660 | return KC_1 + (hex - 0x1); | |
661 | } else { | |
662 | return KC_A + (hex - 0xA); | |
663 | } | |
cbabb4d4 JH |
664 | } |
665 | ||
7edac212 JH |
666 | void api_send_unicode(uint32_t unicode) { |
667 | #ifdef API_ENABLE | |
cefa8468 JH |
668 | uint8_t chunk[4]; |
669 | dword_to_bytes(unicode, chunk); | |
670 | MT_SEND_DATA(DT_UNICODE, chunk, 5); | |
7edac212 | 671 | #endif |
cefa8468 | 672 | } |
13bb6b4b | 673 | |
dfb78d2a | 674 | /** \brief Lock LED set callback - keymap/user level |
675 | * | |
676 | * \deprecated Use led_update_user() instead. | |
677 | */ | |
b624f32f | 678 | __attribute__((weak)) void led_set_user(uint8_t usb_led) {} |
13bb6b4b | 679 | |
dfb78d2a | 680 | /** \brief Lock LED set callback - keyboard level |
681 | * | |
682 | * \deprecated Use led_update_kb() instead. | |
683 | */ | |
b624f32f | 684 | __attribute__((weak)) void led_set_kb(uint8_t usb_led) { led_set_user(usb_led); } |
13bb6b4b | 685 | |
dfb78d2a | 686 | /** \brief Lock LED update callback - keymap/user level |
687 | * | |
688 | * \return True if led_update_kb() should run its own code, false otherwise. | |
689 | */ | |
690 | __attribute__((weak)) bool led_update_user(led_t led_state) { return true; } | |
691 | ||
692 | /** \brief Lock LED update callback - keyboard level | |
693 | * | |
694 | * \return Ignored for now. | |
695 | */ | |
696 | __attribute__((weak)) bool led_update_kb(led_t led_state) { return led_update_user(led_state); } | |
697 | ||
b624f32f | 698 | __attribute__((weak)) void led_init_ports(void) {} |
13bb6b4b | 699 | |
b624f32f | 700 | __attribute__((weak)) void led_set(uint8_t usb_led) { |
df251d7a | 701 | #if defined(BACKLIGHT_CAPS_LOCK) && defined(BACKLIGHT_ENABLE) |
b624f32f | 702 | // Use backlight as Caps Lock indicator |
703 | uint8_t bl_toggle_lvl = 0; | |
704 | ||
705 | if (IS_LED_ON(usb_led, USB_LED_CAPS_LOCK) && !backlight_config.enable) { | |
706 | // Turning Caps Lock ON and backlight is disabled in config | |
707 | // Toggling backlight to the brightest level | |
708 | bl_toggle_lvl = BACKLIGHT_LEVELS; | |
709 | } else if (IS_LED_OFF(usb_led, USB_LED_CAPS_LOCK) && backlight_config.enable) { | |
710 | // Turning Caps Lock OFF and backlight is enabled in config | |
711 | // Toggling backlight and restoring config level | |
712 | bl_toggle_lvl = backlight_config.level; | |
713 | } | |
df251d7a | 714 | |
b624f32f | 715 | // Set level without modify backlight_config to keep ability to restore state |
716 | backlight_set(bl_toggle_lvl); | |
df251d7a R |
717 | #endif |
718 | ||
b624f32f | 719 | led_set_kb(usb_led); |
a91c0c47 | 720 | led_update_kb((led_t)usb_led); |
13bb6b4b JH |
721 | } |
722 | ||
287eb7ad | 723 | //------------------------------------------------------------------------------ |
794aed37 | 724 | // Override these functions in your keymap file to play different tunes on |
287eb7ad JH |
725 | // different events such as startup and bootloader jump |
726 | ||
b624f32f | 727 | __attribute__((weak)) void startup_user() {} |
287eb7ad | 728 | |
b624f32f | 729 | __attribute__((weak)) void shutdown_user() {} |
287eb7ad | 730 | |
12370259 | 731 | //------------------------------------------------------------------------------ |