]> git.donarmstrong.com Git - qmk_firmware.git/blobdiff - quantum/quantum.c
fix for issue #1568
[qmk_firmware.git] / quantum / quantum.c
index 3b5e52ff12579d826b3413b5f28b54bfaaf60b4e..65213eaea7b369f901c4a3679a35077ea892ba21 100644 (file)
@@ -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
@@ -351,6 +387,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 +418,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;
@@ -438,12 +480,25 @@ bool process_record_quantum(keyrecord_t *record) {
       // 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 +510,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 +530,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,12 +551,16 @@ 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_with_delay(const char *str, uint8_t interval) {
     while (1) {
         uint8_t keycode;
         uint8_t ascii_code = pgm_read_byte(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])) {
+        keycode = pgm_read_byte(&ascii_to_keycode_lut[ascii_code]);
+        if (pgm_read_byte(&ascii_to_shift_lut[ascii_code])) {
             register_code(KC_LSFT);
             register_code(keycode);
             unregister_code(keycode);
@@ -606,54 +571,18 @@ void send_string(const char *str) {
             unregister_code(keycode);
         }
         ++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
-};
-
-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
-};
-
-#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 +634,9 @@ void matrix_init_quantum() {
   #ifdef BACKLIGHT_ENABLE
     backlight_init_ports();
   #endif
+  #ifdef AUDIO_ENABLE
+    audio_init();
+  #endif
   matrix_init_kb();
 }
 
@@ -814,14 +746,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 +771,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);