summaryrefslogtreecommitdiffstats
path: root/quantum/quantum.c
diff options
context:
space:
mode:
Diffstat (limited to 'quantum/quantum.c')
-rw-r--r--quantum/quantum.c463
1 files changed, 246 insertions, 217 deletions
diff --git a/quantum/quantum.c b/quantum/quantum.c
index 5bb7b04d5..1fccaa7d5 100644
--- a/quantum/quantum.c
+++ b/quantum/quantum.c
@@ -30,6 +30,24 @@ extern backlight_config_t backlight_config;
#include "fauxclicky.h"
#endif
+#ifdef AUDIO_ENABLE
+ #ifndef GOODBYE_SONG
+ #define GOODBYE_SONG SONG(GOODBYE_SOUND)
+ #endif
+ #ifndef AG_NORM_SONG
+ #define AG_NORM_SONG SONG(AG_NORM_SOUND)
+ #endif
+ #ifndef AG_SWAP_SONG
+ #define AG_SWAP_SONG SONG(AG_SWAP_SOUND)
+ #endif
+ float goodbye_song[][2] = GOODBYE_SONG;
+ float ag_norm_song[][2] = AG_NORM_SONG;
+ float ag_swap_song[][2] = AG_SWAP_SONG;
+ #ifdef DEFAULT_LAYER_SONGS
+ float default_layer_songs[][16][2] = DEFAULT_LAYER_SONGS;
+ #endif
+#endif
+
static void do_code16 (uint16_t code, void (*f) (uint8_t)) {
switch (code) {
case QK_MODS ... QK_MODS_MAX:
@@ -116,9 +134,15 @@ void reset_keyboard(void) {
clear_keyboard();
#if defined(AUDIO_ENABLE) || (defined(MIDI_ENABLE) && defined(MIDI_ENABLE_BASIC))
music_all_notes_off();
+ uint16_t timer_start = timer_read();
+ PLAY_SONG(goodbye_song);
shutdown_user();
-#endif
+ while(timer_elapsed(timer_start) < 250)
+ wait_ms(1);
+ stop_all_notes();
+#else
wait_ms(250);
+#endif
#ifdef CATERINA_BOOTLOADER
*(uint16_t *)0x0800 = 0x7777; // these two are a-star-specific
#endif
@@ -137,6 +161,11 @@ void reset_keyboard(void) {
static bool shift_interrupted[2] = {0, 0};
static uint16_t scs_timer[2] = {0, 0};
+/* true if the last press of GRAVE_ESC was shifted (i.e. GUI or SHIFT were pressed), false otherwise.
+ * Used to ensure that the correct keycode is released if the key is released.
+ */
+static bool grave_esc_was_shifted = false;
+
bool process_record_quantum(keyrecord_t *record) {
/* This gets the keycode from the key pressed */
@@ -168,6 +197,10 @@ bool process_record_quantum(keyrecord_t *record) {
// }
if (!(
+ #if defined(KEY_LOCK_ENABLE)
+ // Must run first to be able to mask key_up events.
+ process_key_lock(&keycode, record) &&
+ #endif
process_record_kb(keycode, record) &&
#if defined(MIDI_ENABLE) && defined(MIDI_ADVANCED)
process_midi(keycode, record) &&
@@ -175,6 +208,9 @@ bool process_record_quantum(keyrecord_t *record) {
#ifdef AUDIO_ENABLE
process_audio(keycode, record) &&
#endif
+ #ifdef STENO_ENABLE
+ process_steno(keycode, record) &&
+ #endif
#if defined(AUDIO_ENABLE) || (defined(MIDI_ENABLE) && defined(MIDI_BASIC))
process_music(keycode, record) &&
#endif
@@ -202,6 +238,9 @@ bool process_record_quantum(keyrecord_t *record) {
#ifdef UNICODEMAP_ENABLE
process_unicode_map(keycode, record) &&
#endif
+ #ifdef TERMINAL_ENABLE
+ process_terminal(keycode, record) &&
+ #endif
true)) {
return false;
}
@@ -213,105 +252,153 @@ bool process_record_quantum(keyrecord_t *record) {
if (record->event.pressed) {
reset_keyboard();
}
- return false;
- break;
+ return false;
case DEBUG:
if (record->event.pressed) {
- print("\nDEBUG: enabled.\n");
debug_enable = true;
+ print("DEBUG: enabled.\n");
}
- return false;
- break;
+ return false;
#ifdef FAUXCLICKY_ENABLE
case FC_TOG:
if (record->event.pressed) {
FAUXCLICKY_TOGGLE;
}
return false;
- break;
case FC_ON:
if (record->event.pressed) {
FAUXCLICKY_ON;
}
return false;
- break;
case FC_OFF:
if (record->event.pressed) {
FAUXCLICKY_OFF;
}
return false;
- break;
#endif
- #ifdef RGBLIGHT_ENABLE
- case RGB_TOG:
- if (record->event.pressed) {
- rgblight_toggle();
- }
- return false;
- break;
- case RGB_MOD:
- if (record->event.pressed) {
- rgblight_step();
- }
- return false;
- break;
- case RGB_HUI:
- if (record->event.pressed) {
- rgblight_increase_hue();
+ #ifdef RGBLIGHT_ENABLE
+ case RGB_TOG:
+ if (record->event.pressed) {
+ rgblight_toggle();
+ }
+ return false;
+ case RGB_MOD:
+ if (record->event.pressed) {
+ rgblight_step();
+ }
+ return false;
+ case RGB_HUI:
+ if (record->event.pressed) {
+ rgblight_increase_hue();
+ }
+ return false;
+ case RGB_HUD:
+ if (record->event.pressed) {
+ rgblight_decrease_hue();
+ }
+ return false;
+ case RGB_SAI:
+ if (record->event.pressed) {
+ rgblight_increase_sat();
+ }
+ return false;
+ case RGB_SAD:
+ if (record->event.pressed) {
+ rgblight_decrease_sat();
+ }
+ return false;
+ case RGB_VAI:
+ if (record->event.pressed) {
+ rgblight_increase_val();
+ }
+ return false;
+ case RGB_VAD:
+ if (record->event.pressed) {
+ rgblight_decrease_val();
+ }
+ return false;
+ case RGB_MODE_PLAIN:
+ if (record->event.pressed) {
+ rgblight_mode(1);
+ }
+ return false;
+ case RGB_MODE_BREATHE:
+ if (record->event.pressed) {
+ if ((2 <= rgblight_get_mode()) && (rgblight_get_mode() < 5)) {
+ rgblight_step();
+ } else {
+ rgblight_mode(2);
}
- return false;
- break;
- case RGB_HUD:
- if (record->event.pressed) {
- rgblight_decrease_hue();
+ }
+ return false;
+ case RGB_MODE_RAINBOW:
+ if (record->event.pressed) {
+ if ((6 <= rgblight_get_mode()) && (rgblight_get_mode() < 8)) {
+ rgblight_step();
+ } else {
+ rgblight_mode(6);
}
- return false;
- break;
- case RGB_SAI:
- if (record->event.pressed) {
- rgblight_increase_sat();
+ }
+ return false;
+ case RGB_MODE_SWIRL:
+ if (record->event.pressed) {
+ if ((9 <= rgblight_get_mode()) && (rgblight_get_mode() < 14)) {
+ rgblight_step();
+ } else {
+ rgblight_mode(9);
}
- return false;
- break;
- case RGB_SAD:
- if (record->event.pressed) {
- rgblight_decrease_sat();
+ }
+ return false;
+ case RGB_MODE_SNAKE:
+ if (record->event.pressed) {
+ if ((15 <= rgblight_get_mode()) && (rgblight_get_mode() < 20)) {
+ rgblight_step();
+ } else {
+ rgblight_mode(15);
}
- return false;
- break;
- case RGB_VAI:
- if (record->event.pressed) {
- rgblight_increase_val();
+ }
+ return false;
+ case RGB_MODE_KNIGHT:
+ if (record->event.pressed) {
+ if ((21 <= rgblight_get_mode()) && (rgblight_get_mode() < 23)) {
+ rgblight_step();
+ } else {
+ rgblight_mode(21);
}
- return false;
- break;
- case RGB_VAD:
- if (record->event.pressed) {
- rgblight_decrease_val();
+ }
+ return false;
+ case RGB_MODE_XMAS:
+ if (record->event.pressed) {
+ rgblight_mode(24);
+ }
+ return false;
+ case RGB_MODE_GRADIENT:
+ if (record->event.pressed) {
+ if ((25 <= rgblight_get_mode()) && (rgblight_get_mode() < 34)) {
+ rgblight_step();
+ } else {
+ rgblight_mode(25);
}
- return false;
- break;
- #endif
+ }
+ return false;
+ #endif
#ifdef PROTOCOL_LUFA
case OUT_AUTO:
if (record->event.pressed) {
set_output(OUTPUT_AUTO);
}
return false;
- break;
case OUT_USB:
if (record->event.pressed) {
set_output(OUTPUT_USB);
}
return false;
- break;
#ifdef BLUETOOTH_ENABLE
case OUT_BT:
if (record->event.pressed) {
set_output(OUTPUT_BLUETOOTH);
}
return false;
- break;
#endif
#endif
case MAGIC_SWAP_CONTROL_CAPSLOCK ... MAGIC_TOGGLE_NKRO:
@@ -351,6 +438,9 @@ bool process_record_quantum(keyrecord_t *record) {
case MAGIC_SWAP_ALT_GUI:
keymap_config.swap_lalt_lgui = true;
keymap_config.swap_ralt_rgui = true;
+ #ifdef AUDIO_ENABLE
+ PLAY_SONG(ag_swap_song);
+ #endif
break;
case MAGIC_UNSWAP_CONTROL_CAPSLOCK:
keymap_config.swap_control_capslock = false;
@@ -379,6 +469,9 @@ bool process_record_quantum(keyrecord_t *record) {
case MAGIC_UNSWAP_ALT_GUI:
keymap_config.swap_lalt_lgui = false;
keymap_config.swap_ralt_rgui = false;
+ #ifdef AUDIO_ENABLE
+ PLAY_SONG(ag_norm_song);
+ #endif
break;
case MAGIC_TOGGLE_NKRO:
keymap_config.nkro = !keymap_config.nkro;
@@ -412,7 +505,6 @@ bool process_record_quantum(keyrecord_t *record) {
unregister_mods(MOD_BIT(KC_LSFT));
}
return false;
- // break;
}
case KC_RSPC: {
@@ -435,15 +527,27 @@ bool process_record_quantum(keyrecord_t *record) {
unregister_mods(MOD_BIT(KC_RSFT));
}
return false;
- // break;
}
case GRAVE_ESC: {
- void (*method)(uint8_t) = (record->event.pressed) ? &add_key : &del_key;
uint8_t shifted = get_mods() & ((MOD_BIT(KC_LSHIFT)|MOD_BIT(KC_RSHIFT)
|MOD_BIT(KC_LGUI)|MOD_BIT(KC_RGUI)));
- method(shifted ? KC_GRAVE : KC_ESCAPE);
- send_keyboard_report();
+#ifdef GRAVE_ESC_CTRL_OVERRIDE
+ // if CTRL is pressed, ESC is always read as ESC, even if SHIFT or GUI is pressed.
+ // this is handy for the ctrl+shift+esc shortcut on windows, among other things.
+ if (get_mods() & (MOD_BIT(KC_LCTL) | MOD_BIT(KC_RCTL)))
+ shifted = 0;
+#endif
+
+ if (record->event.pressed) {
+ grave_esc_was_shifted = shifted;
+ add_key(shifted ? KC_GRAVE : KC_ESCAPE);
+ }
+ else {
+ del_key(grave_esc_was_shifted ? KC_GRAVE : KC_ESCAPE);
+ }
+
+ send_keyboard_report();
}
default: {
shift_interrupted[0] = true;
@@ -455,103 +559,8 @@ bool process_record_quantum(keyrecord_t *record) {
return process_action_kb(record);
}
-#ifdef JIS_KEYCODE
-static const uint16_t ascii_to_shift_lut[8] PROGMEM = {
- 0x0000, /*0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0,*/
- 0x0000, /*0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0,*/
- 0x7ff0, /*0, 1, 1, 1, 1, 1, 1, 1,
- 1, 1, 1, 1, 0, 0, 0, 0,*/
- 0x000f, /*0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 1, 1, 1, 1,*/
- 0x7fff, /*0, 1, 1, 1, 1, 1, 1, 1,
- 1, 1, 1, 1, 1, 1, 1, 1,*/
- 0xffe1, /*1, 1, 1, 1, 1, 1, 1, 1,
- 1, 1, 1, 0, 0, 0, 0, 1,*/
- 0x8000, /*1, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0,*/
- 0x001e, /*0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 1, 1, 1, 1, 0*/
-};
-
-static const struct {
- uint8_t controls_0[16],
- controls_1[16],
- numerics[16],
- alphabets_0[16],
- alphabets_1[16];
-} lower_to_keycode PROGMEM = {
- .controls_0 = {
- 0, 0, 0, 0, 0, 0, 0, 0,
- KC_BSPC, KC_TAB, KC_ENT, 0, 0, 0, 0, 0,
- },
- .controls_1 = {
- 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, KC_ESC, 0, 0, 0, 0,
- },
- .numerics = {
- KC_0, KC_1, KC_2, KC_3, KC_4, KC_5, KC_6, KC_7,
- KC_8, KC_9, KC_QUOT, KC_SCLN, KC_COMM, KC_MINS, KC_DOT, KC_SLSH,
- },
- .alphabets_0 = {
- KC_LBRC, KC_A, KC_B, KC_C, KC_D, KC_E, KC_F, KC_G,
- KC_H, KC_I, KC_J, KC_K, KC_L, KC_M, KC_N, KC_O,
- },
- .alphabets_1 = {
- KC_P, KC_Q, KC_R, KC_S, KC_T, KC_U, KC_V, KC_W,
- KC_X, KC_Y, KC_Z, KC_RBRC, KC_JYEN, KC_BSLS, KC_EQL, KC_RO,
- },
-};
-static const uint8_t* ascii_to_keycode_lut[8] = {
- lower_to_keycode.controls_0,
- lower_to_keycode.controls_1,
- lower_to_keycode.numerics,
- lower_to_keycode.numerics,
- lower_to_keycode.alphabets_0,
- lower_to_keycode.alphabets_1,
- lower_to_keycode.alphabets_0,
- lower_to_keycode.alphabets_1
-};
-
-void send_string(const char *str) {
- while (1) {
- uint8_t keycode;
- bool shift;
- uint8_t ascii_code = pgm_read_byte(str);
-
- if ( ascii_code == 0x00u ){ break; }
- else if (ascii_code == 0x20u) {
- keycode = KC_SPC;
- shift = false;
- }
- else if (ascii_code == 0x7Fu) {
- keycode = KC_DEL;
- shift = false;
- }
- else {
- int hi = ascii_code>>4 & 0x0f,
- lo = ascii_code & 0x0f;
- keycode = pgm_read_byte(&ascii_to_keycode_lut[hi][lo]);
- shift = !!( pgm_read_word(&ascii_to_shift_lut[hi]) & (0x8000u>>lo) );
- }
-
- if (shift) {
- register_code(KC_LSFT);
- register_code(keycode);
- unregister_code(keycode);
- unregister_code(KC_LSFT);
- }
- else {
- register_code(keycode);
- unregister_code(keycode);
- }
- ++str;
- }
-}
-
-#else
-static const bool ascii_to_qwerty_shift_lut[0x80] PROGMEM = {
+__attribute__ ((weak))
+const bool ascii_to_shift_lut[0x80] 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,
@@ -570,7 +579,8 @@ static const bool ascii_to_qwerty_shift_lut[0x80] PROGMEM = {
0, 0, 0, 1, 1, 1, 1, 0
};
-static const uint8_t ascii_to_qwerty_keycode_lut[0x80] PROGMEM = {
+__attribute__ ((weak))
+const uint8_t ascii_to_keycode_lut[0x80] PROGMEM = {
0, 0, 0, 0, 0, 0, 0, 0,
KC_BSPC, KC_TAB, KC_ENT, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
@@ -590,70 +600,86 @@ static const uint8_t ascii_to_qwerty_keycode_lut[0x80] PROGMEM = {
};
void send_string(const char *str) {
+ send_string_with_delay(str, 0);
+}
+
+void send_string_P(const char *str) {
+ send_string_with_delay_P(str, 0);
+}
+
+void send_string_with_delay(const char *str, uint8_t interval) {
while (1) {
- uint8_t keycode;
- uint8_t ascii_code = pgm_read_byte(str);
+ char ascii_code = *str;
if (!ascii_code) break;
- keycode = pgm_read_byte(&ascii_to_qwerty_keycode_lut[ascii_code]);
- if (pgm_read_byte(&ascii_to_qwerty_shift_lut[ascii_code])) {
- register_code(KC_LSFT);
- register_code(keycode);
- unregister_code(keycode);
- unregister_code(KC_LSFT);
- }
- else {
- register_code(keycode);
- unregister_code(keycode);
+ if (ascii_code == 1) {
+ // tap
+ uint8_t keycode = *(++str);
+ register_code(keycode);
+ unregister_code(keycode);
+ } else if (ascii_code == 2) {
+ // down
+ uint8_t keycode = *(++str);
+ register_code(keycode);
+ } else if (ascii_code == 3) {
+ // up
+ uint8_t keycode = *(++str);
+ unregister_code(keycode);
+ } else {
+ send_char(ascii_code);
}
++str;
+ // interval
+ { uint8_t ms = interval; while (ms--) wait_ms(1); }
}
}
-#endif
-
-/* for users whose OSes are set to Colemak */
-#if 0
-#include "keymap_colemak.h"
-
-const bool ascii_to_colemak_shift_lut[0x80] 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,
- 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
-};
+void send_string_with_delay_P(const char *str, uint8_t interval) {
+ while (1) {
+ char ascii_code = pgm_read_byte(str);
+ if (!ascii_code) break;
+ if (ascii_code == 1) {
+ // tap
+ uint8_t keycode = pgm_read_byte(++str);
+ register_code(keycode);
+ unregister_code(keycode);
+ } else if (ascii_code == 2) {
+ // down
+ uint8_t keycode = pgm_read_byte(++str);
+ register_code(keycode);
+ } else if (ascii_code == 3) {
+ // up
+ uint8_t keycode = pgm_read_byte(++str);
+ unregister_code(keycode);
+ } else {
+ send_char(ascii_code);
+ }
+ ++str;
+ // interval
+ { uint8_t ms = interval; while (ms--) wait_ms(1); }
+ }
+}
-const uint8_t ascii_to_colemak_keycode_lut[0x80] PROGMEM = {
- 0, 0, 0, 0, 0, 0, 0, 0,
- KC_BSPC, KC_TAB, KC_ENT, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, KC_ESC, 0, 0, 0, 0,
- KC_SPC, KC_1, KC_QUOT, KC_3, KC_4, KC_5, KC_7, KC_QUOT,
- KC_9, KC_0, KC_8, KC_EQL, KC_COMM, KC_MINS, KC_DOT, KC_SLSH,
- KC_0, KC_1, KC_2, KC_3, KC_4, KC_5, KC_6, KC_7,
- KC_8, KC_9, CM_SCLN, CM_SCLN, KC_COMM, KC_EQL, KC_DOT, KC_SLSH,
- KC_2, CM_A, CM_B, CM_C, CM_D, CM_E, CM_F, CM_G,
- CM_H, CM_I, CM_J, CM_K, CM_L, CM_M, CM_N, CM_O,
- CM_P, CM_Q, CM_R, CM_S, CM_T, CM_U, CM_V, CM_W,
- CM_X, CM_Y, CM_Z, KC_LBRC, KC_BSLS, KC_RBRC, KC_6, KC_MINS,
- KC_GRV, CM_A, CM_B, CM_C, CM_D, CM_E, CM_F, CM_G,
- CM_H, CM_I, CM_J, CM_K, CM_L, CM_M, CM_N, CM_O,
- CM_P, CM_Q, CM_R, CM_S, CM_T, CM_U, CM_V, CM_W,
- CM_X, CM_Y, CM_Z, KC_LBRC, KC_BSLS, KC_RBRC, KC_GRV, KC_DEL
-};
+void send_char(char ascii_code) {
+ uint8_t keycode;
+ keycode = pgm_read_byte(&ascii_to_keycode_lut[(uint8_t)ascii_code]);
+ if (pgm_read_byte(&ascii_to_shift_lut[(uint8_t)ascii_code])) {
+ register_code(KC_LSFT);
+ register_code(keycode);
+ unregister_code(keycode);
+ unregister_code(KC_LSFT);
+ } else {
+ register_code(keycode);
+ unregister_code(keycode);
+ }
+}
-#endif
+void set_single_persistent_default_layer(uint8_t default_layer) {
+ #if defined(AUDIO_ENABLE) && defined(DEFAULT_LAYER_SONGS)
+ PLAY_SONG(default_layer_songs[default_layer]);
+ #endif
+ eeconfig_update_default_layer(1U<<default_layer);
+ default_layer_set(1U<<default_layer);
+}
void update_tri_layer(uint8_t layer1, uint8_t layer2, uint8_t layer3) {
if (IS_LAYER_ON(layer1) && IS_LAYER_ON(layer2)) {
@@ -705,6 +731,9 @@ void matrix_init_quantum() {
#ifdef BACKLIGHT_ENABLE
backlight_init_ports();
#endif
+ #ifdef AUDIO_ENABLE
+ audio_init();
+ #endif
matrix_init_kb();
}
@@ -814,14 +843,14 @@ void backlight_set(uint8_t level)
// _SFR_IO8((backlight_pin >> 4) + 2) &= ~_BV(backlight_pin & 0xF);
// #endif
#endif
- }
+ }
#ifndef NO_BACKLIGHT_CLOCK
else if ( level == BACKLIGHT_LEVELS ) {
// Turn on PWM control of backlight pin
TCCR1A |= _BV(COM1x1);
// Set the brightness
OCR1x = 0xFFFF;
- }
+ }
else {
// Turn on PWM control of backlight pin
TCCR1A |= _BV(COM1x1);
@@ -839,7 +868,7 @@ uint8_t backlight_tick = 0;
void backlight_task(void) {
#ifdef NO_BACKLIGHT_CLOCK
- if ((0xFFFF >> ((BACKLIGHT_LEVELS - backlight_config.level) * ((BACKLIGHT_LEVELS + 1) / 2))) & (1 << backlight_tick)) {
+ if ((0xFFFF >> ((BACKLIGHT_LEVELS - backlight_config.level) * ((BACKLIGHT_LEVELS + 1) / 2))) & (1 << backlight_tick)) {
#if BACKLIGHT_ON_STATE == 0
// PORTx &= ~n
_SFR_IO8((backlight_pin >> 4) + 2) &= ~_BV(backlight_pin & 0xF);