aboutsummaryrefslogtreecommitdiff
path: root/quantum
diff options
context:
space:
mode:
Diffstat (limited to 'quantum')
-rw-r--r--quantum/backlight/backlight_avr.c2
-rw-r--r--quantum/config_common.h39
-rw-r--r--quantum/dip_switch.c37
-rw-r--r--quantum/dynamic_macro.h20
-rw-r--r--quantum/encoder.c46
-rw-r--r--quantum/keymap_common.c14
-rw-r--r--quantum/keymap_extras/keymap_italian.h54
-rw-r--r--quantum/keymap_extras/keymap_italian_osx_ansi.h60
-rw-r--r--quantum/keymap_extras/keymap_italian_osx_iso.h60
-rw-r--r--quantum/mcu_selection.mk17
-rw-r--r--quantum/process_keycode/process_dynamic_macro.c257
-rw-r--r--quantum/process_keycode/process_dynamic_macro.h41
-rw-r--r--quantum/process_keycode/process_magic.c178
-rw-r--r--quantum/process_keycode/process_magic.h20
-rw-r--r--quantum/process_keycode/process_tap_dance.h6
-rw-r--r--quantum/process_keycode/process_terminal.c2
-rw-r--r--quantum/quantum.c504
-rw-r--r--quantum/quantum.h35
-rw-r--r--quantum/quantum_keycodes.h49
-rw-r--r--quantum/rgb_matrix_animations/rainbow_pinwheels_anim.h6
-rw-r--r--quantum/rgb_matrix_drivers.c3
-rw-r--r--quantum/rgblight.c29
-rw-r--r--quantum/send_string_keycodes.h575
-rw-r--r--quantum/split_common/post_config.h2
-rw-r--r--quantum/split_common/split_util.c6
-rw-r--r--quantum/split_common/transport.c2
-rw-r--r--quantum/stm32/chconf.h39
-rw-r--r--quantum/stm32/proton_c.mk2
-rw-r--r--quantum/template/avr/config.h7
-rw-r--r--quantum/template/base/keyboard.c4
-rw-r--r--quantum/template/base/keymaps/default/keymap.c6
-rw-r--r--quantum/template/ps2avrgb/config.h8
-rw-r--r--quantum/template/ps2avrgb/usbconfig.h12
33 files changed, 1346 insertions, 796 deletions
diff --git a/quantum/backlight/backlight_avr.c b/quantum/backlight/backlight_avr.c
index 648a37adf..edda6ea0b 100644
--- a/quantum/backlight/backlight_avr.c
+++ b/quantum/backlight/backlight_avr.c
@@ -191,7 +191,7 @@ void backlight_off(pin_t backlight_pin) {
191 191
192# define FOR_EACH_LED(x) \ 192# define FOR_EACH_LED(x) \
193 for (uint8_t i = 0; i < BACKLIGHT_LED_COUNT; i++) { \ 193 for (uint8_t i = 0; i < BACKLIGHT_LED_COUNT; i++) { \
194 pin_t backlight_pin = backlight_pins[i]; \ 194 pin_t backlight_pin = backlight_pins[i]; \
195 { x } \ 195 { x } \
196 } 196 }
197 197
diff --git a/quantum/config_common.h b/quantum/config_common.h
index f42df6357..c1c1d4bd4 100644
--- a/quantum/config_common.h
+++ b/quantum/config_common.h
@@ -303,25 +303,26 @@
303 UCSR1C = _BV(UCSZ11) | _BV(UCSZ10); \ 303 UCSR1C = _BV(UCSZ11) | _BV(UCSZ10); \
304 sei(); \ 304 sei(); \
305 } while (0) 305 } while (0)
306# elif (defined(__AVR_AT90USB646__) || defined(__AVR_AT90USB1286__)) 306# elif (defined(__AVR_AT90USB646__) || defined(__AVR_AT90USB1286__))
307# define SERIAL_UART_BAUD 115200 307# define SERIAL_UART_BAUD 115200
308# define SERIAL_UART_DATA UDR1 308# define SERIAL_UART_DATA UDR1
309 /* UBRR should result in ~16 and set UCSR1A = _BV(U2X1) as per rn42 documentation. HC05 needs baudrate configured accordingly */ 309/* UBRR should result in ~16 and set UCSR1A = _BV(U2X1) as per rn42 documentation. HC05 needs baudrate configured accordingly */
310# define SERIAL_UART_UBRR (F_CPU / (8UL * SERIAL_UART_BAUD) - 1) 310# define SERIAL_UART_UBRR (F_CPU / (8UL * SERIAL_UART_BAUD) - 1)
311# define SERIAL_UART_RXD_VECT USART1_RX_vect 311# define SERIAL_UART_RXD_VECT USART1_RX_vect
312# define SERIAL_UART_TXD_READY (UCSR1A & _BV(UDRE1)) 312# define SERIAL_UART_TXD_READY (UCSR1A & _BV(UDRE1))
313# define SERIAL_UART_INIT() do { \ 313# define SERIAL_UART_INIT() \
314 UCSR1A = _BV(U2X1); \ 314 do { \
315 /* baud rate */ \ 315 UCSR1A = _BV(U2X1); \
316 UBRR1L = SERIAL_UART_UBRR; \ 316 /* baud rate */ \
317 /* baud rate */ \ 317 UBRR1L = SERIAL_UART_UBRR; \
318 UBRR1H = SERIAL_UART_UBRR >> 8; \ 318 /* baud rate */ \
319 /* enable TX */ \ 319 UBRR1H = SERIAL_UART_UBRR >> 8; \
320 UCSR1B = _BV(TXEN1); \ 320 /* enable TX */ \
321 /* 8-bit data */ \ 321 UCSR1B = _BV(TXEN1); \
322 UCSR1C = _BV(UCSZ11) | _BV(UCSZ10); \ 322 /* 8-bit data */ \
323 sei(); \ 323 UCSR1C = _BV(UCSZ11) | _BV(UCSZ10); \
324 } while(0) 324 sei(); \
325 } while (0)
325# else 326# else
326# error "USART configuration is needed." 327# error "USART configuration is needed."
327# endif 328# endif
diff --git a/quantum/dip_switch.c b/quantum/dip_switch.c
index 3b5a8dadc..ab74222d1 100644
--- a/quantum/dip_switch.c
+++ b/quantum/dip_switch.c
@@ -21,40 +21,33 @@
21// for memcpy 21// for memcpy
22#include <string.h> 22#include <string.h>
23 23
24
25#if !defined(DIP_SWITCH_PINS) 24#if !defined(DIP_SWITCH_PINS)
26# error "No DIP switch pads defined by DIP_SWITCH_PINS" 25# error "No DIP switch pads defined by DIP_SWITCH_PINS"
27#endif 26#endif
28 27
29#define NUMBER_OF_DIP_SWITCHES (sizeof(dip_switch_pad)/sizeof(pin_t)) 28#define NUMBER_OF_DIP_SWITCHES (sizeof(dip_switch_pad) / sizeof(pin_t))
30static pin_t dip_switch_pad[] = DIP_SWITCH_PINS; 29static pin_t dip_switch_pad[] = DIP_SWITCH_PINS;
31static bool dip_switch_state[NUMBER_OF_DIP_SWITCHES] = { 0 }; 30static bool dip_switch_state[NUMBER_OF_DIP_SWITCHES] = {0};
32static bool last_dip_switch_state[NUMBER_OF_DIP_SWITCHES] = { 0 }; 31static bool last_dip_switch_state[NUMBER_OF_DIP_SWITCHES] = {0};
33
34 32
35__attribute__((weak)) 33__attribute__((weak)) void dip_switch_update_user(uint8_t index, bool active) {}
36void dip_switch_update_user(uint8_t index, bool active) {}
37 34
38__attribute__((weak)) 35__attribute__((weak)) void dip_switch_update_kb(uint8_t index, bool active) { dip_switch_update_user(index, active); }
39void dip_switch_update_kb(uint8_t index, bool active) { dip_switch_update_user(index, active); }
40 36
41__attribute__((weak)) 37__attribute__((weak)) void dip_switch_update_mask_user(uint32_t state) {}
42void dip_switch_update_mask_user(uint32_t state) {}
43 38
44__attribute__((weak)) 39__attribute__((weak)) void dip_switch_update_mask_kb(uint32_t state) { dip_switch_update_mask_user(state); }
45void dip_switch_update_mask_kb(uint32_t state) { dip_switch_update_mask_user(state); }
46 40
47void dip_switch_init(void) { 41void dip_switch_init(void) {
48 for (uint8_t i = 0; i < NUMBER_OF_DIP_SWITCHES; i++) { 42 for (uint8_t i = 0; i < NUMBER_OF_DIP_SWITCHES; i++) {
49 setPinInputHigh(dip_switch_pad[i]); 43 setPinInputHigh(dip_switch_pad[i]);
50 } 44 }
51 dip_switch_read(true); 45 dip_switch_read(true);
52} 46}
53 47
54
55void dip_switch_read(bool forced) { 48void dip_switch_read(bool forced) {
56 bool has_dip_state_changed = false; 49 bool has_dip_state_changed = false;
57 uint32_t dip_switch_mask = 0; 50 uint32_t dip_switch_mask = 0;
58 51
59 for (uint8_t i = 0; i < NUMBER_OF_DIP_SWITCHES; i++) { 52 for (uint8_t i = 0; i < NUMBER_OF_DIP_SWITCHES; i++) {
60 dip_switch_state[i] = !readPin(dip_switch_pad[i]); 53 dip_switch_state[i] = !readPin(dip_switch_pad[i]);
diff --git a/quantum/dynamic_macro.h b/quantum/dynamic_macro.h
index c7632c004..fe9de6fa6 100644
--- a/quantum/dynamic_macro.h
+++ b/quantum/dynamic_macro.h
@@ -15,8 +15,10 @@
15 */ 15 */
16 16
17/* Author: Wojciech Siewierski < wojciech dot siewierski at onet dot pl > */ 17/* Author: Wojciech Siewierski < wojciech dot siewierski at onet dot pl > */
18#ifndef DYNAMIC_MACROS_H 18#pragma once
19#define DYNAMIC_MACROS_H 19
20/* Warn users that this is now deprecated and they should use the core feature instead. */
21#pragma message "Dynamic Macros is now a core feature. See updated documentation to see how to configure it: https://docs.qmk.fm/#/feature_dynamic_macros"
20 22
21#include "action_layer.h" 23#include "action_layer.h"
22 24
@@ -33,18 +35,6 @@
33# define DYNAMIC_MACRO_SIZE 128 35# define DYNAMIC_MACRO_SIZE 128
34#endif 36#endif
35 37
36/* DYNAMIC_MACRO_RANGE must be set as the last element of user's
37 * "planck_keycodes" enum prior to including this header. This allows
38 * us to 'extend' it.
39 */
40enum dynamic_macro_keycodes {
41 DYN_REC_START1 = DYNAMIC_MACRO_RANGE,
42 DYN_REC_START2,
43 DYN_REC_STOP,
44 DYN_MACRO_PLAY1,
45 DYN_MACRO_PLAY2,
46};
47
48/* Blink the LEDs to notify the user about some event. */ 38/* Blink the LEDs to notify the user about some event. */
49void dynamic_macro_led_blink(void) { 39void dynamic_macro_led_blink(void) {
50#ifdef BACKLIGHT_ENABLE 40#ifdef BACKLIGHT_ENABLE
@@ -272,5 +262,3 @@ bool process_record_dynamic_macro(uint16_t keycode, keyrecord_t *record) {
272#undef DYNAMIC_MACRO_CURRENT_SLOT 262#undef DYNAMIC_MACRO_CURRENT_SLOT
273#undef DYNAMIC_MACRO_CURRENT_LENGTH 263#undef DYNAMIC_MACRO_CURRENT_LENGTH
274#undef DYNAMIC_MACRO_CURRENT_CAPACITY 264#undef DYNAMIC_MACRO_CURRENT_CAPACITY
275
276#endif
diff --git a/quantum/encoder.c b/quantum/encoder.c
index 36a6403b3..c41b89f49 100644
--- a/quantum/encoder.c
+++ b/quantum/encoder.c
@@ -38,14 +38,15 @@ static pin_t encoders_pad_b[] = ENCODERS_PAD_B;
38static int8_t encoder_LUT[] = {0, -1, 1, 0, 1, 0, 0, -1, -1, 0, 0, 1, 0, 1, -1, 0}; 38static int8_t encoder_LUT[] = {0, -1, 1, 0, 1, 0, 0, -1, -1, 0, 0, 1, 0, 1, -1, 0};
39 39
40static uint8_t encoder_state[NUMBER_OF_ENCODERS] = {0}; 40static uint8_t encoder_state[NUMBER_OF_ENCODERS] = {0};
41static int8_t encoder_pulses[NUMBER_OF_ENCODERS] = {0};
41 42
42#ifdef SPLIT_KEYBOARD 43#ifdef SPLIT_KEYBOARD
43// right half encoders come over as second set of encoders 44// right half encoders come over as second set of encoders
44static int8_t encoder_value[NUMBER_OF_ENCODERS * 2] = {0}; 45static uint8_t encoder_value[NUMBER_OF_ENCODERS * 2] = {0};
45// row offsets for each hand 46// row offsets for each hand
46static uint8_t thisHand, thatHand; 47static uint8_t thisHand, thatHand;
47#else 48#else
48static int8_t encoder_value[NUMBER_OF_ENCODERS] = {0}; 49static uint8_t encoder_value[NUMBER_OF_ENCODERS] = {0};
49#endif 50#endif
50 51
51__attribute__((weak)) void encoder_update_user(int8_t index, bool clockwise) {} 52__attribute__((weak)) void encoder_update_user(int8_t index, bool clockwise) {}
@@ -78,34 +79,47 @@ void encoder_init(void) {
78} 79}
79 80
80static void encoder_update(int8_t index, uint8_t state) { 81static void encoder_update(int8_t index, uint8_t state) {
81 encoder_value[index] += encoder_LUT[state & 0xF]; 82 uint8_t i = index;
82 if (encoder_value[index] >= ENCODER_RESOLUTION) { 83#ifdef SPLIT_KEYBOARD
83 encoder_update_kb(index, false); 84 index += thisHand;
84 } 85#endif
85 if (encoder_value[index] <= -ENCODER_RESOLUTION) { // direction is arbitrary here, but this clockwise 86 encoder_pulses[i] += encoder_LUT[state & 0xF];
87 if (encoder_pulses[i] >= ENCODER_RESOLUTION) {
88 encoder_value[index]++;
86 encoder_update_kb(index, true); 89 encoder_update_kb(index, true);
87 } 90 }
88 encoder_value[index] %= ENCODER_RESOLUTION; 91 if (encoder_pulses[i] <= -ENCODER_RESOLUTION) { // direction is arbitrary here, but this clockwise
92 encoder_value[index]--;
93 encoder_update_kb(index, false);
94 }
95 encoder_pulses[i] %= ENCODER_RESOLUTION;
89} 96}
90 97
91void encoder_read(void) { 98void encoder_read(void) {
92 for (int i = 0; i < NUMBER_OF_ENCODERS; i++) { 99 for (uint8_t i = 0; i < NUMBER_OF_ENCODERS; i++) {
93 encoder_state[i] <<= 2; 100 encoder_state[i] <<= 2;
94 encoder_state[i] |= (readPin(encoders_pad_a[i]) << 0) | (readPin(encoders_pad_b[i]) << 1); 101 encoder_state[i] |= (readPin(encoders_pad_a[i]) << 0) | (readPin(encoders_pad_b[i]) << 1);
95#if SPLIT_KEYBOARD
96 encoder_update(i + thisHand, encoder_state[i]);
97#else
98 encoder_update(i, encoder_state[i]); 102 encoder_update(i, encoder_state[i]);
99#endif
100 } 103 }
101} 104}
102 105
103#ifdef SPLIT_KEYBOARD 106#ifdef SPLIT_KEYBOARD
104void encoder_state_raw(uint8_t* slave_state) { memcpy(slave_state, encoder_state, sizeof(encoder_state)); } 107void encoder_state_raw(uint8_t* slave_state) { memcpy(slave_state, &encoder_value[thisHand], sizeof(uint8_t) * NUMBER_OF_ENCODERS); }
105 108
106void encoder_update_raw(uint8_t* slave_state) { 109void encoder_update_raw(uint8_t* slave_state) {
107 for (int i = 0; i < NUMBER_OF_ENCODERS; i++) { 110 for (uint8_t i = 0; i < NUMBER_OF_ENCODERS; i++) {
108 encoder_update(i + thatHand, slave_state[i]); 111 uint8_t index = i + thatHand;
112 int8_t delta = slave_state[i] - encoder_value[index];
113 while (delta > 0) {
114 delta--;
115 encoder_value[index]++;
116 encoder_update_kb(index, true);
117 }
118 while (delta < 0) {
119 delta++;
120 encoder_value[index]--;
121 encoder_update_kb(index, false);
122 }
109 } 123 }
110} 124}
111#endif 125#endif
diff --git a/quantum/keymap_common.c b/quantum/keymap_common.c
index 4fa45ac37..c82c44639 100644
--- a/quantum/keymap_common.c
+++ b/quantum/keymap_common.c
@@ -48,13 +48,10 @@ action_t action_for_key(uint8_t layer, keypos_t key) {
48 // keycode remapping 48 // keycode remapping
49 keycode = keycode_config(keycode); 49 keycode = keycode_config(keycode);
50 50
51 action_t action; 51 action_t action = {};
52 uint8_t action_layer, when, mod; 52 uint8_t action_layer, when, mod;
53 53
54 switch (keycode) { 54 switch (keycode) {
55 case KC_FN0 ... KC_FN31:
56 action.code = keymap_function_id_to_action(FN_INDEX(keycode));
57 break;
58 case KC_A ... KC_EXSEL: 55 case KC_A ... KC_EXSEL:
59 case KC_LCTRL ... KC_RGUI: 56 case KC_LCTRL ... KC_RGUI:
60 action.code = ACTION_KEY(keycode); 57 action.code = ACTION_KEY(keycode);
@@ -65,9 +62,11 @@ action_t action_for_key(uint8_t layer, keypos_t key) {
65 case KC_AUDIO_MUTE ... KC_BRIGHTNESS_DOWN: 62 case KC_AUDIO_MUTE ... KC_BRIGHTNESS_DOWN:
66 action.code = ACTION_USAGE_CONSUMER(KEYCODE2CONSUMER(keycode)); 63 action.code = ACTION_USAGE_CONSUMER(KEYCODE2CONSUMER(keycode));
67 break; 64 break;
65#ifdef MOUSEKEY_ENABLE
68 case KC_MS_UP ... KC_MS_ACCEL2: 66 case KC_MS_UP ... KC_MS_ACCEL2:
69 action.code = ACTION_MOUSEKEY(keycode); 67 action.code = ACTION_MOUSEKEY(keycode);
70 break; 68 break;
69#endif
71 case KC_TRNS: 70 case KC_TRNS:
72 action.code = ACTION_TRANSPARENT; 71 action.code = ACTION_TRANSPARENT;
73 break; 72 break;
@@ -76,17 +75,24 @@ action_t action_for_key(uint8_t layer, keypos_t key) {
76 // Split it up 75 // Split it up
77 action.code = ACTION_MODS_KEY(keycode >> 8, keycode & 0xFF); // adds modifier to key 76 action.code = ACTION_MODS_KEY(keycode >> 8, keycode & 0xFF); // adds modifier to key
78 break; 77 break;
78#ifndef NO_ACTION_FUNCTION
79 case KC_FN0 ... KC_FN31:
80 action.code = keymap_function_id_to_action(FN_INDEX(keycode));
81 break;
79 case QK_FUNCTION ... QK_FUNCTION_MAX:; 82 case QK_FUNCTION ... QK_FUNCTION_MAX:;
80 // Is a shortcut for function action_layer, pull last 12bits 83 // Is a shortcut for function action_layer, pull last 12bits
81 // This means we have 4,096 FN macros at our disposal 84 // This means we have 4,096 FN macros at our disposal
82 action.code = keymap_function_id_to_action((int)keycode & 0xFFF); 85 action.code = keymap_function_id_to_action((int)keycode & 0xFFF);
83 break; 86 break;
87#endif
88#ifndef NO_ACTION_MACRO
84 case QK_MACRO ... QK_MACRO_MAX: 89 case QK_MACRO ... QK_MACRO_MAX:
85 if (keycode & 0x800) // tap macros have upper bit set 90 if (keycode & 0x800) // tap macros have upper bit set
86 action.code = ACTION_MACRO_TAP(keycode & 0xFF); 91 action.code = ACTION_MACRO_TAP(keycode & 0xFF);
87 else 92 else
88 action.code = ACTION_MACRO(keycode & 0xFF); 93 action.code = ACTION_MACRO(keycode & 0xFF);
89 break; 94 break;
95#endif
90 case QK_LAYER_TAP ... QK_LAYER_TAP_MAX: 96 case QK_LAYER_TAP ... QK_LAYER_TAP_MAX:
91 action.code = ACTION_LAYER_TAP_KEY((keycode >> 0x8) & 0xF, keycode & 0xFF); 97 action.code = ACTION_LAYER_TAP_KEY((keycode >> 0x8) & 0xF, keycode & 0xFF);
92 break; 98 break;
diff --git a/quantum/keymap_extras/keymap_italian.h b/quantum/keymap_extras/keymap_italian.h
index a8c03b884..063700aa0 100644
--- a/quantum/keymap_extras/keymap_italian.h
+++ b/quantum/keymap_extras/keymap_italian.h
@@ -78,36 +78,36 @@
78#define IT_MINS KC_SLSH // - and _ 78#define IT_MINS KC_SLSH // - and _
79 79
80// shifted characters 80// shifted characters
81#define IT_DEGR LSFT(IT_AACC) // ° 81#define IT_DEGR LSFT(IT_AACC) // °
82#define IT_EXLM LSFT(KC_1) // ! 82#define IT_EXLM LSFT(KC_1) // !
83#define IT_DQOT LSFT(KC_2) // " 83#define IT_DQOT LSFT(KC_2) // "
84#define IT_STRL LSFT(KC_3) // £ 84#define IT_STRL LSFT(KC_3) // £
85#define IT_DLR LSFT(KC_4) // $ 85#define IT_DLR LSFT(KC_4) // $
86#define IT_PERC LSFT(KC_5) // % 86#define IT_PERC LSFT(KC_5) // %
87#define IT_AMPR LSFT(KC_6) // & 87#define IT_AMPR LSFT(KC_6) // &
88#define IT_SLSH LSFT(KC_7) // / 88#define IT_SLSH LSFT(KC_7) // /
89#define IT_LPRN LSFT(KC_8) // ( 89#define IT_LPRN LSFT(KC_8) // (
90#define IT_RPRN LSFT(KC_9) // ) 90#define IT_RPRN LSFT(KC_9) // )
91#define IT_EQL LSFT(KC_0) // = 91#define IT_EQL LSFT(KC_0) // =
92#define IT_QST LSFT(IT_APOS) // ? 92#define IT_QST LSFT(IT_APOS) // ?
93#define IT_CRC LSFT(IT_IACC) // ^ 93#define IT_CRC LSFT(IT_IACC) // ^
94#define IT_ASTR LSFT(IT_PLUS) // * 94#define IT_ASTR LSFT(IT_PLUS) // *
95#define IT_MORE LSFT(IT_LESS) // > 95#define IT_MORE LSFT(IT_LESS) // >
96#define IT_COLN LSFT(IT_DOT) // : 96#define IT_COLN LSFT(IT_DOT) // :
97#define IT_SCLN LSFT(IT_COMM) // ; 97#define IT_SCLN LSFT(IT_COMM) // ;
98#define IT_UNDS LSFT(IT_MINS) // _ 98#define IT_UNDS LSFT(IT_MINS) // _
99 99
100// Alt Gr-ed characters 100// Alt Gr-ed characters
101#define IT_LCBR ALGR(KC_7) // { 101#define IT_LCBR ALGR(KC_7) // {
102#define IT_LBRC ALGR(IT_EACC) // [ 102#define IT_LBRC ALGR(IT_EACC) // [
103#define IT_RBRC ALGR(IT_PLUS) // ] 103#define IT_RBRC ALGR(IT_PLUS) // ]
104#define IT_RCBR ALGR(KC_0) // } 104#define IT_RCBR ALGR(KC_0) // }
105#define IT_AT ALGR(IT_OACC) // @ 105#define IT_AT ALGR(IT_OACC) // @
106#define IT_EURO ALGR(KC_E) // € 106#define IT_EURO ALGR(KC_E) // €
107#define IT_PIPE LSFT(IT_BSLS) // | 107#define IT_PIPE LSFT(IT_BSLS) // |
108#define IT_SHRP ALGR(IT_AACC) // # 108#define IT_SHRP ALGR(IT_AACC) // #
109 109
110// Deprecated 110// Deprecated
111#define IT_X_PLUS X_RBRACKET // # 111#define IT_X_PLUS X_RBRACKET // #
112 112
113#endif 113#endif
diff --git a/quantum/keymap_extras/keymap_italian_osx_ansi.h b/quantum/keymap_extras/keymap_italian_osx_ansi.h
index 2b7160ff3..fa12d05dc 100644
--- a/quantum/keymap_extras/keymap_italian_osx_ansi.h
+++ b/quantum/keymap_extras/keymap_italian_osx_ansi.h
@@ -65,7 +65,7 @@
65#define IT_COMM KC_COMM // , and ; 65#define IT_COMM KC_COMM // , and ;
66#define IT_APOS KC_MINS // ' and ? 66#define IT_APOS KC_MINS // ' and ?
67#define IT_BSLS KC_NUBS // \ and | 67#define IT_BSLS KC_NUBS // \ and |
68#define IT_LESS KC_GRV // < and > 68#define IT_LESS KC_GRV // < and >
69#define IT_MINS KC_SLSH // - and _ 69#define IT_MINS KC_SLSH // - and _
70 70
71// accented vowels (regular, with shift, with option, with option and shift) 71// accented vowels (regular, with shift, with option, with option and shift)
@@ -77,37 +77,37 @@
77#define IT_IACC KC_EQL // ì, ^, ˆ, ± 77#define IT_IACC KC_EQL // ì, ^, ˆ, ±
78 78
79// shifted characters 79// shifted characters
80#define IT_EXLM LSFT(KC_1) // ! 80#define IT_EXLM LSFT(KC_1) // !
81#define IT_DQOT LSFT(KC_2) // " 81#define IT_DQOT LSFT(KC_2) // "
82#define IT_STRL LSFT(KC_3) // £ 82#define IT_STRL LSFT(KC_3) // £
83#define IT_DLR LSFT(KC_4) // $ 83#define IT_DLR LSFT(KC_4) // $
84#define IT_PERC LSFT(KC_5) // % 84#define IT_PERC LSFT(KC_5) // %
85#define IT_AMPR LSFT(KC_6) // & 85#define IT_AMPR LSFT(KC_6) // &
86#define IT_SLSH LSFT(KC_7) // / 86#define IT_SLSH LSFT(KC_7) // /
87#define IT_LPRN LSFT(KC_8) // ( 87#define IT_LPRN LSFT(KC_8) // (
88#define IT_RPRN LSFT(KC_9) // ) 88#define IT_RPRN LSFT(KC_9) // )
89#define IT_EQL LSFT(KC_0) // = 89#define IT_EQL LSFT(KC_0) // =
90#define IT_DEGR LSFT(IT_AACC) // ° 90#define IT_DEGR LSFT(IT_AACC) // °
91#define IT_QST LSFT(IT_APOS) // ? 91#define IT_QST LSFT(IT_APOS) // ?
92#define IT_CRC LSFT(IT_IACC) // ^ 92#define IT_CRC LSFT(IT_IACC) // ^
93#define IT_ASTR LSFT(IT_PLUS) // * 93#define IT_ASTR LSFT(IT_PLUS) // *
94#define IT_MORE LSFT(IT_LESS) // > 94#define IT_MORE LSFT(IT_LESS) // >
95#define IT_COLN LSFT(IT_DOT) // : 95#define IT_COLN LSFT(IT_DOT) // :
96#define IT_SCLN LSFT(IT_COMM) // ; 96#define IT_SCLN LSFT(IT_COMM) // ;
97#define IT_UNDS LSFT(IT_MINS) // _ 97#define IT_UNDS LSFT(IT_MINS) // _
98#define IT_LCBR LSFT(IT_LBRC) // { 98#define IT_LCBR LSFT(IT_LBRC) // {
99#define IT_RCBR LSFT(IT_RBRC) // } 99#define IT_RCBR LSFT(IT_RBRC) // }
100#define IT_PIPE LSFT(IT_BSLS) // | 100#define IT_PIPE LSFT(IT_BSLS) // |
101 101
102// Alt -ed characters 102// Alt -ed characters
103#define IT_LBRC LALT(IT_EACC) // [ 103#define IT_LBRC LALT(IT_EACC) // [
104#define IT_RBRC LALT(IT_PLUS) // ] 104#define IT_RBRC LALT(IT_PLUS) // ]
105#define IT_AT LALT(IT_OACC) // @ 105#define IT_AT LALT(IT_OACC) // @
106#define IT_EURO LALT(KC_E) // € 106#define IT_EURO LALT(KC_E) // €
107#define IT_SHRP LALT(IT_AACC ) // # 107#define IT_SHRP LALT(IT_AACC) // #
108#define IT_ACUT LALT(KC_8) // ´ 108#define IT_ACUT LALT(KC_8) // ´
109#define IT_GRAVE LALT(KC_9) // ` 109#define IT_GRAVE LALT(KC_9) // `
110#define IT_TILDE LALT(KC_5) // ~ 110#define IT_TILDE LALT(KC_5) // ~
111#define IT_PLMN LALT(LSFT(IT_IACC)) // ± 111#define IT_PLMN LALT(LSFT(IT_IACC)) // ±
112 112
113#endif 113#endif
diff --git a/quantum/keymap_extras/keymap_italian_osx_iso.h b/quantum/keymap_extras/keymap_italian_osx_iso.h
index 5c920014a..a9b36f16e 100644
--- a/quantum/keymap_extras/keymap_italian_osx_iso.h
+++ b/quantum/keymap_extras/keymap_italian_osx_iso.h
@@ -65,7 +65,7 @@
65#define IT_COMM KC_COMM // , and ; 65#define IT_COMM KC_COMM // , and ;
66#define IT_APOS KC_MINS // ' and ? 66#define IT_APOS KC_MINS // ' and ?
67#define IT_BSLS KC_GRV // \ and | 67#define IT_BSLS KC_GRV // \ and |
68#define IT_LESS KC_NUBS// < and > 68#define IT_LESS KC_NUBS // < and >
69#define IT_MINS KC_SLSH // - and _ 69#define IT_MINS KC_SLSH // - and _
70 70
71// accented vowels (regular, with shift, with option, with option and shift) 71// accented vowels (regular, with shift, with option, with option and shift)
@@ -77,37 +77,37 @@
77#define IT_IACC KC_EQL // ì, ^, ˆ, ± 77#define IT_IACC KC_EQL // ì, ^, ˆ, ±
78 78
79// shifted characters 79// shifted characters
80#define IT_EXLM LSFT(KC_1) // ! 80#define IT_EXLM LSFT(KC_1) // !
81#define IT_DQOT LSFT(KC_2) // " 81#define IT_DQOT LSFT(KC_2) // "
82#define IT_STRL LSFT(KC_3) // £ 82#define IT_STRL LSFT(KC_3) // £
83#define IT_DLR LSFT(KC_4) // $ 83#define IT_DLR LSFT(KC_4) // $
84#define IT_PERC LSFT(KC_5) // % 84#define IT_PERC LSFT(KC_5) // %
85#define IT_AMPR LSFT(KC_6) // & 85#define IT_AMPR LSFT(KC_6) // &
86#define IT_SLSH LSFT(KC_7) // / 86#define IT_SLSH LSFT(KC_7) // /
87#define IT_LPRN LSFT(KC_8) // ( 87#define IT_LPRN LSFT(KC_8) // (
88#define IT_RPRN LSFT(KC_9) // ) 88#define IT_RPRN LSFT(KC_9) // )
89#define IT_EQL LSFT(KC_0) // = 89#define IT_EQL LSFT(KC_0) // =
90#define IT_DEGR LSFT(IT_AACC) // ° 90#define IT_DEGR LSFT(IT_AACC) // °
91#define IT_QST LSFT(IT_APOS) // ? 91#define IT_QST LSFT(IT_APOS) // ?
92#define IT_CRC LSFT(IT_IACC) // ^ 92#define IT_CRC LSFT(IT_IACC) // ^
93#define IT_ASTR LSFT(IT_PLUS) // * 93#define IT_ASTR LSFT(IT_PLUS) // *
94#define IT_MORE LSFT(IT_LESS) // > 94#define IT_MORE LSFT(IT_LESS) // >
95#define IT_COLN LSFT(IT_DOT) // : 95#define IT_COLN LSFT(IT_DOT) // :
96#define IT_SCLN LSFT(IT_COMM) // ; 96#define IT_SCLN LSFT(IT_COMM) // ;
97#define IT_UNDS LSFT(IT_MINS) // _ 97#define IT_UNDS LSFT(IT_MINS) // _
98#define IT_LCBR LSFT(IT_LBRC) // { 98#define IT_LCBR LSFT(IT_LBRC) // {
99#define IT_RCBR LSFT(IT_RBRC) // } 99#define IT_RCBR LSFT(IT_RBRC) // }
100#define IT_PIPE LSFT(IT_BSLS) // | 100#define IT_PIPE LSFT(IT_BSLS) // |
101 101
102// Alt -ed characters 102// Alt -ed characters
103#define IT_LBRC LALT(IT_EACC) // [ 103#define IT_LBRC LALT(IT_EACC) // [
104#define IT_RBRC LALT(IT_PLUS) // ] 104#define IT_RBRC LALT(IT_PLUS) // ]
105#define IT_AT LALT(IT_OACC) // @ 105#define IT_AT LALT(IT_OACC) // @
106#define IT_EURO LALT(KC_E) // € 106#define IT_EURO LALT(KC_E) // €
107#define IT_SHRP LALT(IT_AACC ) // # 107#define IT_SHRP LALT(IT_AACC) // #
108#define IT_ACUT LALT(KC_8) // ´ 108#define IT_ACUT LALT(KC_8) // ´
109#define IT_GRAVE LALT(KC_9) // ` 109#define IT_GRAVE LALT(KC_9) // `
110#define IT_TILDE LALT(KC_5) // ~ 110#define IT_TILDE LALT(KC_5) // ~
111#define IT_PLMN LALT(LSFT(IT_IACC)) // ± 111#define IT_PLMN LALT(LSFT(IT_IACC)) // ±
112 112
113#endif 113#endif
diff --git a/quantum/mcu_selection.mk b/quantum/mcu_selection.mk
index 5102010c7..24b2b2abd 100644
--- a/quantum/mcu_selection.mk
+++ b/quantum/mcu_selection.mk
@@ -7,15 +7,15 @@ ifneq ($(findstring STM32F303, $(MCU)),)
7 7
8 # Linker script to use 8 # Linker script to use
9 # - it should exist either in <chibios>/os/common/ports/ARMCMx/compilers/GCC/ld/ 9 # - it should exist either in <chibios>/os/common/ports/ARMCMx/compilers/GCC/ld/
10 # or <this_dir>/ld/ 10 # or <keyboard_dir>/ld/
11 MCU_LDSCRIPT ?= STM32F303xC 11 MCU_LDSCRIPT ?= STM32F303xC
12 12
13 # Startup code to use 13 # Startup code to use
14 # - it should exist in <chibios>/os/common/startup/ARMCMx/compilers/GCC/mk/ 14 # - it should exist in <chibios>/os/common/startup/ARMCMx/compilers/GCC/mk/
15 MCU_STARTUP ?= stm32f3xx 15 MCU_STARTUP ?= stm32f3xx
16 16
17 # Board: it should exist either in <chibios>/os/hal/boards/ 17 # Board: it should exist either in <chibios>/os/hal/boards/,
18 # or <this_dir>/boards 18 # <keyboard_dir>/boards/, or drivers/boards/
19 BOARD ?= GENERIC_STM32_F303XC 19 BOARD ?= GENERIC_STM32_F303XC
20 20
21 # Cortex version 21 # Cortex version
@@ -27,7 +27,7 @@ ifneq ($(findstring STM32F303, $(MCU)),)
27 USE_FPU = yes 27 USE_FPU = yes
28 28
29 # Vector table for application 29 # Vector table for application
30 # 0x00000000-0x00001000 area is occupied by bootlaoder.*/ 30 # 0x00000000-0x00001000 area is occupied by bootloader.*/
31 # The CORTEX_VTOR... is needed only for MCHCK/Infinity KB 31 # The CORTEX_VTOR... is needed only for MCHCK/Infinity KB
32 # OPT_DEFS = -DCORTEX_VTOR_INIT=0x08005000 32 # OPT_DEFS = -DCORTEX_VTOR_INIT=0x08005000
33 33
@@ -75,6 +75,9 @@ ifneq (,$(filter $(MCU),atmega16u2 atmega32u2 atmega16u4 atmega32u4 at90usb646 a
75endif 75endif
76 76
77ifneq (,$(filter $(MCU),atmega32a)) 77ifneq (,$(filter $(MCU),atmega32a))
78 # MCU name for avrdude
79 AVRDUDE_MCU = m32
80
78 PROTOCOL = VUSB 81 PROTOCOL = VUSB
79 82
80 # Processor frequency. 83 # Processor frequency.
@@ -87,12 +90,12 @@ ifneq (,$(filter $(MCU),atmega32a))
87 # unsupported features for now 90 # unsupported features for now
88 NO_UART ?= yes 91 NO_UART ?= yes
89 NO_SUSPEND_POWER_DOWN ?= yes 92 NO_SUSPEND_POWER_DOWN ?= yes
90
91 # Programming options
92 PROGRAM_CMD ?= ./util/atmega32a_program.py $(TARGET).hex
93endif 93endif
94 94
95ifneq (,$(filter $(MCU),atmega328p)) 95ifneq (,$(filter $(MCU),atmega328p))
96 # MCU name for avrdude
97 AVRDUDE_MCU = m328p
98
96 PROTOCOL = VUSB 99 PROTOCOL = VUSB
97 100
98 # Processor frequency. 101 # Processor frequency.
diff --git a/quantum/process_keycode/process_dynamic_macro.c b/quantum/process_keycode/process_dynamic_macro.c
new file mode 100644
index 000000000..2065f242d
--- /dev/null
+++ b/quantum/process_keycode/process_dynamic_macro.c
@@ -0,0 +1,257 @@
1/* Copyright 2016 Jack Humbert
2 * Copyright 2019 Drashna Jael're (@drashna, aka Christopher Courtney)
3 *
4 * This program is free software: you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License as published by
6 * the Free Software Foundation, either version 2 of the License, or
7 * (at your option) any later version.
8 *
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
13 *
14 * You should have received a copy of the GNU General Public License
15 * along with this program. If not, see <http://www.gnu.org/licenses/>.
16 */
17
18/* Author: Wojciech Siewierski < wojciech dot siewierski at onet dot pl > */
19#include "process_dynamic_macro.h"
20
21// default feedback method
22void dynamic_macro_led_blink(void) {
23#ifdef BACKLIGHT_ENABLE
24 backlight_toggle();
25 wait_ms(100);
26 backlight_toggle();
27#endif
28}
29
30/* User hooks for Dynamic Macros */
31
32__attribute__((weak)) void dynamic_macro_record_start_user(void) { dynamic_macro_led_blink(); }
33
34__attribute__((weak)) void dynamic_macro_play_user(int8_t direction) { dynamic_macro_led_blink(); }
35
36__attribute__((weak)) void dynamic_macro_record_key_user(int8_t direction, keyrecord_t *record) { dynamic_macro_led_blink(); }
37
38__attribute__((weak)) void dynamic_macro_record_end_user(int8_t direction) { dynamic_macro_led_blink(); }
39
40/* Convenience macros used for retrieving the debug info. All of them
41 * need a `direction` variable accessible at the call site.
42 */
43#define DYNAMIC_MACRO_CURRENT_SLOT() (direction > 0 ? 1 : 2)
44#define DYNAMIC_MACRO_CURRENT_LENGTH(BEGIN, POINTER) ((int)(direction * ((POINTER) - (BEGIN))))
45#define DYNAMIC_MACRO_CURRENT_CAPACITY(BEGIN, END2) ((int)(direction * ((END2) - (BEGIN)) + 1))
46
47/**
48 * Start recording of the dynamic macro.
49 *
50 * @param[out] macro_pointer The new macro buffer iterator.
51 * @param[in] macro_buffer The macro buffer used to initialize macro_pointer.
52 */
53void dynamic_macro_record_start(keyrecord_t **macro_pointer, keyrecord_t *macro_buffer) {
54 dprintln("dynamic macro recording: started");
55
56 dynamic_macro_record_start_user();
57
58 clear_keyboard();
59 layer_clear();
60 *macro_pointer = macro_buffer;
61}
62
63/**
64 * Play the dynamic macro.
65 *
66 * @param macro_buffer[in] The beginning of the macro buffer being played.
67 * @param macro_end[in] The element after the last macro buffer element.
68 * @param direction[in] Either +1 or -1, which way to iterate the buffer.
69 */
70void dynamic_macro_play(keyrecord_t *macro_buffer, keyrecord_t *macro_end, int8_t direction) {
71 dprintf("dynamic macro: slot %d playback\n", DYNAMIC_MACRO_CURRENT_SLOT());
72
73 layer_state_t saved_layer_state = layer_state;
74
75 clear_keyboard();
76 layer_clear();
77
78 while (macro_buffer != macro_end) {
79 process_record(macro_buffer);
80 macro_buffer += direction;
81 }
82
83 clear_keyboard();
84
85 layer_state = saved_layer_state;
86
87 dynamic_macro_play_user(direction);
88}
89
90/**
91 * Record a single key in a dynamic macro.
92 *
93 * @param macro_buffer[in] The start of the used macro buffer.
94 * @param macro_pointer[in,out] The current buffer position.
95 * @param macro2_end[in] The end of the other macro.
96 * @param direction[in] Either +1 or -1, which way to iterate the buffer.
97 * @param record[in] The current keypress.
98 */
99void dynamic_macro_record_key(keyrecord_t *macro_buffer, keyrecord_t **macro_pointer, keyrecord_t *macro2_end, int8_t direction, keyrecord_t *record) {
100 /* If we've just started recording, ignore all the key releases. */
101 if (!record->event.pressed && *macro_pointer == macro_buffer) {
102 dprintln("dynamic macro: ignoring a leading key-up event");
103 return;
104 }
105
106 /* The other end of the other macro is the last buffer element it
107 * is safe to use before overwriting the other macro.
108 */
109 if (*macro_pointer - direction != macro2_end) {
110 **macro_pointer = *record;
111 *macro_pointer += direction;
112 } else {
113 dynamic_macro_record_key_user(direction, record);
114 }
115
116 dprintf("dynamic macro: slot %d length: %d/%d\n", DYNAMIC_MACRO_CURRENT_SLOT(), DYNAMIC_MACRO_CURRENT_LENGTH(macro_buffer, *macro_pointer), DYNAMIC_MACRO_CURRENT_CAPACITY(macro_buffer, macro2_end));
117}
118
119/**
120 * End recording of the dynamic macro. Essentially just update the
121 * pointer to the end of the macro.
122 */
123void dynamic_macro_record_end(keyrecord_t *macro_buffer, keyrecord_t *macro_pointer, int8_t direction, keyrecord_t **macro_end) {
124 dynamic_macro_record_end_user(direction);
125
126 /* Do not save the keys being held when stopping the recording,
127 * i.e. the keys used to access the layer DYN_REC_STOP is on.
128 */
129 while (macro_pointer != macro_buffer && (macro_pointer - direction)->event.pressed) {
130 dprintln("dynamic macro: trimming a trailing key-down event");
131 macro_pointer -= direction;
132 }
133
134 dprintf("dynamic macro: slot %d saved, length: %d\n", DYNAMIC_MACRO_CURRENT_SLOT(), DYNAMIC_MACRO_CURRENT_LENGTH(macro_buffer, macro_pointer));
135
136 *macro_end = macro_pointer;
137}
138
139/* Handle the key events related to the dynamic macros. Should be
140 * called from process_record_user() like this:
141 *
142 * bool process_record_user(uint16_t keycode, keyrecord_t *record) {
143 * if (!process_record_dynamic_macro(keycode, record)) {
144 * return false;
145 * }
146 * <...THE REST OF THE FUNCTION...>
147 * }
148 */
149bool process_dynamic_macro(uint16_t keycode, keyrecord_t *record) {
150 /* Both macros use the same buffer but read/write on different
151 * ends of it.
152 *
153 * Macro1 is written left-to-right starting from the beginning of
154 * the buffer.
155 *
156 * Macro2 is written right-to-left starting from the end of the
157 * buffer.
158 *
159 * &macro_buffer macro_end
160 * v v
161 * +------------------------------------------------------------+
162 * |>>>>>> MACRO1 >>>>>> <<<<<<<<<<<<< MACRO2 <<<<<<<<<<<<<|
163 * +------------------------------------------------------------+
164 * ^ ^
165 * r_macro_end r_macro_buffer
166 *
167 * During the recording when one macro encounters the end of the
168 * other macro, the recording is stopped. Apart from this, there
169 * are no arbitrary limits for the macros' length in relation to
170 * each other: for example one can either have two medium sized
171 * macros or one long macro and one short macro. Or even one empty
172 * and one using the whole buffer.
173 */
174 static keyrecord_t macro_buffer[DYNAMIC_MACRO_SIZE];
175
176 /* Pointer to the first buffer element after the first macro.
177 * Initially points to the very beginning of the buffer since the
178 * macro is empty. */
179 static keyrecord_t *macro_end = macro_buffer;
180
181 /* The other end of the macro buffer. Serves as the beginning of
182 * the second macro. */
183 static keyrecord_t *const r_macro_buffer = macro_buffer + DYNAMIC_MACRO_SIZE - 1;
184
185 /* Like macro_end but for the second macro. */
186 static keyrecord_t *r_macro_end = r_macro_buffer;
187
188 /* A persistent pointer to the current macro position (iterator)
189 * used during the recording. */
190 static keyrecord_t *macro_pointer = NULL;
191
192 /* 0 - no macro is being recorded right now
193 * 1,2 - either macro 1 or 2 is being recorded */
194 static uint8_t macro_id = 0;
195
196 if (macro_id == 0) {
197 /* No macro recording in progress. */
198 if (!record->event.pressed) {
199 switch (keycode) {
200 case DYN_REC_START1:
201 dynamic_macro_record_start(&macro_pointer, macro_buffer);
202 macro_id = 1;
203 return false;
204 case DYN_REC_START2:
205 dynamic_macro_record_start(&macro_pointer, r_macro_buffer);
206 macro_id = 2;
207 return false;
208 case DYN_MACRO_PLAY1:
209 dynamic_macro_play(macro_buffer, macro_end, +1);
210 return false;
211 case DYN_MACRO_PLAY2:
212 dynamic_macro_play(r_macro_buffer, r_macro_end, -1);
213 return false;
214 }
215 }
216 } else {
217 /* A macro is being recorded right now. */
218 switch (keycode) {
219 case DYN_REC_STOP:
220 /* Stop the macro recording. */
221 if (record->event.pressed) { /* Ignore the initial release
222 * just after the recoding
223 * starts. */
224 switch (macro_id) {
225 case 1:
226 dynamic_macro_record_end(macro_buffer, macro_pointer, +1, &macro_end);
227 break;
228 case 2:
229 dynamic_macro_record_end(r_macro_buffer, macro_pointer, -1, &r_macro_end);
230 break;
231 }
232 macro_id = 0;
233 }
234 return false;
235#ifdef DYNAMIC_MACRO_NO_NESTING
236 case DYN_MACRO_PLAY1:
237 case DYN_MACRO_PLAY2:
238 dprintln("dynamic macro: ignoring macro play key while recording");
239 return false;
240#endif
241 default:
242 /* Store the key in the macro buffer and process it normally. */
243 switch (macro_id) {
244 case 1:
245 dynamic_macro_record_key(macro_buffer, &macro_pointer, r_macro_end, +1, record);
246 break;
247 case 2:
248 dynamic_macro_record_key(r_macro_buffer, &macro_pointer, macro_end, -1, record);
249 break;
250 }
251 return true;
252 break;
253 }
254 }
255
256 return true;
257}
diff --git a/quantum/process_keycode/process_dynamic_macro.h b/quantum/process_keycode/process_dynamic_macro.h
new file mode 100644
index 000000000..39036541b
--- /dev/null
+++ b/quantum/process_keycode/process_dynamic_macro.h
@@ -0,0 +1,41 @@
1/* Copyright 2016 Jack Humbert
2 * Copyright 2019 Drashna Jael're (@drashna, aka Christopher Courtney)
3 *
4 * This program is free software: you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License as published by
6 * the Free Software Foundation, either version 2 of the License, or
7 * (at your option) any later version.
8 *
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
13 *
14 * You should have received a copy of the GNU General Public License
15 * along with this program. If not, see <http://www.gnu.org/licenses/>.
16 */
17
18/* Author: Wojciech Siewierski < wojciech dot siewierski at onet dot pl > */
19#pragma once
20
21#include "quantum.h"
22
23/* May be overridden with a custom value. Be aware that the effective
24 * macro length is half of this value: each keypress is recorded twice
25 * because of the down-event and up-event. This is not a bug, it's the
26 * intended behavior.
27 *
28 * Usually it should be fine to set the macro size to at least 256 but
29 * there have been reports of it being too much in some users' cases,
30 * so 128 is considered a safe default.
31 */
32#ifndef DYNAMIC_MACRO_SIZE
33# define DYNAMIC_MACRO_SIZE 128
34#endif
35
36void dynamic_macro_led_blink(void);
37bool process_dynamic_macro(uint16_t keycode, keyrecord_t *record);
38void dynamic_macro_record_start_user(void);
39void dynamic_macro_play_user(int8_t direction);
40void dynamic_macro_record_key_user(int8_t direction, keyrecord_t *record);
41void dynamic_macro_record_end_user(int8_t direction);
diff --git a/quantum/process_keycode/process_magic.c b/quantum/process_keycode/process_magic.c
new file mode 100644
index 000000000..44dd5f057
--- /dev/null
+++ b/quantum/process_keycode/process_magic.c
@@ -0,0 +1,178 @@
1/* Copyright 2019 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#include "process_magic.h"
17
18#ifdef AUDIO_ENABLE
19# ifndef AG_NORM_SONG
20# define AG_NORM_SONG SONG(AG_NORM_SOUND)
21# endif
22# ifndef AG_SWAP_SONG
23# define AG_SWAP_SONG SONG(AG_SWAP_SOUND)
24# endif
25# ifndef CG_NORM_SONG
26# define CG_NORM_SONG SONG(AG_NORM_SOUND)
27# endif
28# ifndef CG_SWAP_SONG
29# define CG_SWAP_SONG SONG(AG_SWAP_SOUND)
30# endif
31float ag_norm_song[][2] = AG_NORM_SONG;
32float ag_swap_song[][2] = AG_SWAP_SONG;
33float cg_norm_song[][2] = CG_NORM_SONG;
34float cg_swap_song[][2] = CG_SWAP_SONG;
35#endif
36
37/**
38 * MAGIC actions (BOOTMAGIC without the boot)
39 */
40bool process_magic(uint16_t keycode, keyrecord_t *record) {
41 // skip anything that isn't a keyup
42 if (record->event.pressed) {
43 switch (keycode) {
44 case MAGIC_SWAP_CONTROL_CAPSLOCK ... MAGIC_TOGGLE_ALT_GUI:
45 case MAGIC_SWAP_LCTL_LGUI ... MAGIC_EE_HANDS_RIGHT:
46 /* keymap config */
47 keymap_config.raw = eeconfig_read_keymap();
48 switch (keycode) {
49 case MAGIC_SWAP_CONTROL_CAPSLOCK:
50 keymap_config.swap_control_capslock = true;
51 break;
52 case MAGIC_CAPSLOCK_TO_CONTROL:
53 keymap_config.capslock_to_control = true;
54 break;
55 case MAGIC_SWAP_LALT_LGUI:
56 keymap_config.swap_lalt_lgui = true;
57 break;
58 case MAGIC_SWAP_RALT_RGUI:
59 keymap_config.swap_ralt_rgui = true;
60 break;
61 case MAGIC_SWAP_LCTL_LGUI:
62 keymap_config.swap_lctl_lgui = true;
63 break;
64 case MAGIC_SWAP_RCTL_RGUI:
65 keymap_config.swap_rctl_rgui = true;
66 break;
67 case MAGIC_NO_GUI:
68 keymap_config.no_gui = true;
69 break;
70 case MAGIC_SWAP_GRAVE_ESC:
71 keymap_config.swap_grave_esc = true;
72 break;
73 case MAGIC_SWAP_BACKSLASH_BACKSPACE:
74 keymap_config.swap_backslash_backspace = true;
75 break;
76 case MAGIC_HOST_NKRO:
77 clear_keyboard(); // clear first buffer to prevent stuck keys
78 keymap_config.nkro = true;
79 break;
80 case MAGIC_SWAP_ALT_GUI:
81 keymap_config.swap_lalt_lgui = keymap_config.swap_ralt_rgui = true;
82#ifdef AUDIO_ENABLE
83 PLAY_SONG(ag_swap_song);
84#endif
85 break;
86 case MAGIC_SWAP_CTL_GUI:
87 keymap_config.swap_lctl_lgui = keymap_config.swap_rctl_rgui = true;
88#ifdef AUDIO_ENABLE
89 PLAY_SONG(cg_swap_song);
90#endif
91 break;
92 case MAGIC_UNSWAP_CONTROL_CAPSLOCK:
93 keymap_config.swap_control_capslock = false;
94 break;
95 case MAGIC_UNCAPSLOCK_TO_CONTROL:
96 keymap_config.capslock_to_control = false;
97 break;
98 case MAGIC_UNSWAP_LALT_LGUI:
99 keymap_config.swap_lalt_lgui = false;
100 break;
101 case MAGIC_UNSWAP_RALT_RGUI:
102 keymap_config.swap_ralt_rgui = false;
103 break;
104 case MAGIC_UNSWAP_LCTL_LGUI:
105 keymap_config.swap_lctl_lgui = false;
106 break;
107 case MAGIC_UNSWAP_RCTL_RGUI:
108 keymap_config.swap_rctl_rgui = false;
109 break;
110 case MAGIC_UNNO_GUI:
111 keymap_config.no_gui = false;
112 break;
113 case MAGIC_UNSWAP_GRAVE_ESC:
114 keymap_config.swap_grave_esc = false;
115 break;
116 case MAGIC_UNSWAP_BACKSLASH_BACKSPACE:
117 keymap_config.swap_backslash_backspace = false;
118 break;
119 case MAGIC_UNHOST_NKRO:
120 clear_keyboard(); // clear first buffer to prevent stuck keys
121 keymap_config.nkro = false;
122 break;
123 case MAGIC_UNSWAP_ALT_GUI:
124 keymap_config.swap_lalt_lgui = keymap_config.swap_ralt_rgui = false;
125#ifdef AUDIO_ENABLE
126 PLAY_SONG(ag_norm_song);
127#endif
128 break;
129 case MAGIC_UNSWAP_CTL_GUI:
130 keymap_config.swap_lctl_lgui = keymap_config.swap_rctl_rgui = false;
131#ifdef AUDIO_ENABLE
132 PLAY_SONG(cg_norm_song);
133#endif
134 break;
135 case MAGIC_TOGGLE_ALT_GUI:
136 keymap_config.swap_lalt_lgui = !keymap_config.swap_lalt_lgui;
137 keymap_config.swap_ralt_rgui = keymap_config.swap_lalt_lgui;
138#ifdef AUDIO_ENABLE
139 if (keymap_config.swap_ralt_rgui) {
140 PLAY_SONG(ag_swap_song);
141 } else {
142 PLAY_SONG(ag_norm_song);
143 }
144#endif
145 break;
146 case MAGIC_TOGGLE_CTL_GUI:
147 keymap_config.swap_lctl_lgui = !keymap_config.swap_lctl_lgui;
148 keymap_config.swap_rctl_rgui = keymap_config.swap_lctl_lgui;
149#ifdef AUDIO_ENABLE
150 if (keymap_config.swap_rctl_rgui) {
151 PLAY_SONG(cg_swap_song);
152 } else {
153 PLAY_SONG(cg_norm_song);
154 }
155#endif
156 break;
157 case MAGIC_TOGGLE_NKRO:
158 clear_keyboard(); // clear first buffer to prevent stuck keys
159 keymap_config.nkro = !keymap_config.nkro;
160 break;
161 case MAGIC_EE_HANDS_LEFT:
162 eeconfig_update_handedness(true);
163 break;
164 case MAGIC_EE_HANDS_RIGHT:
165 eeconfig_update_handedness(false);
166 break;
167 }
168
169 eeconfig_update_keymap(keymap_config.raw);
170 clear_keyboard(); // clear to prevent stuck keys
171
172 return false;
173 }
174 }
175
176 // Not a magic keycode so continue processing
177 return true;
178}
diff --git a/quantum/process_keycode/process_magic.h b/quantum/process_keycode/process_magic.h
new file mode 100644
index 000000000..1eb39f145
--- /dev/null
+++ b/quantum/process_keycode/process_magic.h
@@ -0,0 +1,20 @@
1/* Copyright 2019
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#pragma once
17
18#include "quantum.h"
19
20bool process_magic(uint16_t keycode, keyrecord_t *record);
diff --git a/quantum/process_keycode/process_tap_dance.h b/quantum/process_keycode/process_tap_dance.h
index 8f3f3ff3c..09ceef74d 100644
--- a/quantum/process_keycode/process_tap_dance.h
+++ b/quantum/process_keycode/process_tap_dance.h
@@ -63,10 +63,10 @@ typedef struct {
63 { .fn = {qk_tap_dance_pair_on_each_tap, qk_tap_dance_pair_finished, qk_tap_dance_pair_reset}, .user_data = (void *)&((qk_tap_dance_pair_t){kc1, kc2}), } 63 { .fn = {qk_tap_dance_pair_on_each_tap, qk_tap_dance_pair_finished, qk_tap_dance_pair_reset}, .user_data = (void *)&((qk_tap_dance_pair_t){kc1, kc2}), }
64 64
65# define ACTION_TAP_DANCE_DUAL_ROLE(kc, layer) \ 65# define ACTION_TAP_DANCE_DUAL_ROLE(kc, layer) \
66 { .fn = { qk_tap_dance_dual_role_on_each_tap, qk_tap_dance_dual_role_finished, qk_tap_dance_dual_role_reset }, .user_data = (void *)&((qk_tap_dance_dual_role_t) { kc, layer, layer_move }), } 66 { .fn = {qk_tap_dance_dual_role_on_each_tap, qk_tap_dance_dual_role_finished, qk_tap_dance_dual_role_reset}, .user_data = (void *)&((qk_tap_dance_dual_role_t){kc, layer, layer_move}), }
67 67
68# define ACTION_TAP_DANCE_LAYER_TOGGLE(kc, layer) \ 68# define ACTION_TAP_DANCE_LAYER_TOGGLE(kc, layer) \
69 { .fn = { NULL, qk_tap_dance_dual_role_finished, qk_tap_dance_dual_role_reset }, .user_data = (void *)&((qk_tap_dance_dual_role_t) { kc, layer, layer_invert }), } 69 { .fn = {NULL, qk_tap_dance_dual_role_finished, qk_tap_dance_dual_role_reset}, .user_data = (void *)&((qk_tap_dance_dual_role_t){kc, layer, layer_invert}), }
70 70
71# define ACTION_TAP_DANCE_LAYER_MOVE(kc, layer) ACTION_TAP_DANCE_DUAL_ROLE(kc, layer) 71# define ACTION_TAP_DANCE_LAYER_MOVE(kc, layer) ACTION_TAP_DANCE_DUAL_ROLE(kc, layer)
72 72
@@ -79,8 +79,6 @@ typedef struct {
79# define ACTION_TAP_DANCE_FN_ADVANCED_TIME(user_fn_on_each_tap, user_fn_on_dance_finished, user_fn_on_dance_reset, tap_specific_tapping_term) \ 79# define ACTION_TAP_DANCE_FN_ADVANCED_TIME(user_fn_on_each_tap, user_fn_on_dance_finished, user_fn_on_dance_reset, tap_specific_tapping_term) \
80 { .fn = {user_fn_on_each_tap, user_fn_on_dance_finished, user_fn_on_dance_reset}, .user_data = NULL, .custom_tapping_term = tap_specific_tapping_term, } 80 { .fn = {user_fn_on_each_tap, user_fn_on_dance_finished, user_fn_on_dance_reset}, .user_data = NULL, .custom_tapping_term = tap_specific_tapping_term, }
81 81
82
83
84extern qk_tap_dance_action_t tap_dance_actions[]; 82extern qk_tap_dance_action_t tap_dance_actions[];
85 83
86/* To be used internally */ 84/* To be used internally */
diff --git a/quantum/process_keycode/process_terminal.c b/quantum/process_keycode/process_terminal.c
index f48f3d702..7d1eefa9e 100644
--- a/quantum/process_keycode/process_terminal.c
+++ b/quantum/process_keycode/process_terminal.c
@@ -61,7 +61,7 @@ void enable_terminal(void) {
61 memset(cmd_buffer, 0, CMD_BUFF_SIZE * 80); 61 memset(cmd_buffer, 0, CMD_BUFF_SIZE * 80);
62 for (int i = 0; i < 6; i++) strcpy(arguments[i], ""); 62 for (int i = 0; i < 6; i++) strcpy(arguments[i], "");
63 // select all text to start over 63 // select all text to start over
64 // SEND_STRING(SS_LCTRL("a")); 64 // SEND_STRING(SS_LCTL("a"));
65 send_string(terminal_prompt); 65 send_string(terminal_prompt);
66} 66}
67 67
diff --git a/quantum/quantum.c b/quantum/quantum.c
index 571dda4c5..2def99ac8 100644
--- a/quantum/quantum.c
+++ b/quantum/quantum.c
@@ -26,7 +26,7 @@
26 26
27#ifdef BACKLIGHT_ENABLE 27#ifdef BACKLIGHT_ENABLE
28# include "backlight.h" 28# include "backlight.h"
29 extern backlight_config_t backlight_config; 29extern backlight_config_t backlight_config;
30#endif 30#endif
31 31
32#ifdef FAUXCLICKY_ENABLE 32#ifdef FAUXCLICKY_ENABLE
@@ -57,23 +57,7 @@
57# ifndef GOODBYE_SONG 57# ifndef GOODBYE_SONG
58# define GOODBYE_SONG SONG(GOODBYE_SOUND) 58# define GOODBYE_SONG SONG(GOODBYE_SOUND)
59# endif 59# endif
60# ifndef AG_NORM_SONG
61# define AG_NORM_SONG SONG(AG_NORM_SOUND)
62# endif
63# ifndef AG_SWAP_SONG
64# define AG_SWAP_SONG SONG(AG_SWAP_SOUND)
65# endif
66# ifndef CG_NORM_SONG
67# define CG_NORM_SONG SONG(AG_NORM_SOUND)
68# endif
69# ifndef CG_SWAP_SONG
70# define CG_SWAP_SONG SONG(AG_SWAP_SOUND)
71# endif
72float goodbye_song[][2] = GOODBYE_SONG; 60float goodbye_song[][2] = GOODBYE_SONG;
73float ag_norm_song[][2] = AG_NORM_SONG;
74float ag_swap_song[][2] = AG_SWAP_SONG;
75float cg_norm_song[][2] = CG_NORM_SONG;
76float cg_swap_song[][2] = CG_SWAP_SONG;
77# ifdef DEFAULT_LAYER_SONGS 61# ifdef DEFAULT_LAYER_SONGS
78float default_layer_songs[][16][2] = DEFAULT_LAYER_SONGS; 62float default_layer_songs[][16][2] = DEFAULT_LAYER_SONGS;
79# endif 63# endif
@@ -89,7 +73,7 @@ static void do_code16(uint16_t code, void (*f)(uint8_t)) {
89 73
90 uint8_t mods_to_send = 0; 74 uint8_t mods_to_send = 0;
91 75
92 if (code & QK_RMODS_MIN) { // Right mod flag is set 76 if (code & QK_RMODS_MIN) { // Right mod flag is set
93 if (code & QK_LCTL) mods_to_send |= MOD_BIT(KC_RCTL); 77 if (code & QK_LCTL) mods_to_send |= MOD_BIT(KC_RCTL);
94 if (code & QK_LSFT) mods_to_send |= MOD_BIT(KC_RSFT); 78 if (code & QK_LSFT) mods_to_send |= MOD_BIT(KC_RSFT);
95 if (code & QK_LALT) mods_to_send |= MOD_BIT(KC_RALT); 79 if (code & QK_LALT) mods_to_send |= MOD_BIT(KC_RALT);
@@ -164,11 +148,6 @@ void reset_keyboard(void) {
164 bootloader_jump(); 148 bootloader_jump();
165} 149}
166 150
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.
169 */
170static bool grave_esc_was_shifted = false;
171
172/* Convert record into usable keycode via the contained event. */ 151/* Convert record into usable keycode via the contained event. */
173uint16_t get_record_keycode(keyrecord_t *record) { return get_event_keycode(record->event); } 152uint16_t get_record_keycode(keyrecord_t *record) { return get_event_keycode(record->event); }
174 153
@@ -222,6 +201,10 @@ bool process_record_quantum(keyrecord_t *record) {
222 // Must run first to be able to mask key_up events. 201 // Must run first to be able to mask key_up events.
223 process_key_lock(&keycode, record) && 202 process_key_lock(&keycode, record) &&
224#endif 203#endif
204#if defined(DYNAMIC_MACRO_ENABLE) && !defined(DYNAMIC_MACRO_USER_CALL)
205 // Must run asap to ensure all keypresses are recorded.
206 process_dynamic_macro(keycode, record) &&
207#endif
225#if defined(AUDIO_ENABLE) && defined(AUDIO_CLICKY) 208#if defined(AUDIO_ENABLE) && defined(AUDIO_CLICKY)
226 process_clicky(keycode, record) && 209 process_clicky(keycode, record) &&
227#endif // AUDIO_CLICKY 210#endif // AUDIO_CLICKY
@@ -268,402 +251,226 @@ bool process_record_quantum(keyrecord_t *record) {
268#ifdef SPACE_CADET_ENABLE 251#ifdef SPACE_CADET_ENABLE
269 process_space_cadet(keycode, record) && 252 process_space_cadet(keycode, record) &&
270#endif 253#endif
254#ifdef MAGIC_KEYCODE_ENABLE
255 process_magic(keycode, record) &&
256#endif
271 true)) { 257 true)) {
272 return false; 258 return false;
273 } 259 }
274 260
275 // Shift / paren setup 261 if (record->event.pressed) {
276 262 switch (keycode) {
277 switch (keycode) { 263 case RESET:
278 case RESET:
279 if (record->event.pressed) {
280 reset_keyboard(); 264 reset_keyboard();
281 } 265 return false;
282 return false; 266#ifndef NO_DEBUG
283 case DEBUG: 267 case DEBUG:
284 if (record->event.pressed) {
285 debug_enable ^= 1; 268 debug_enable ^= 1;
286 if (debug_enable) { 269 if (debug_enable) {
287 print("DEBUG: enabled.\n"); 270 print("DEBUG: enabled.\n");
288 } else { 271 } else {
289 print("DEBUG: disabled.\n"); 272 print("DEBUG: disabled.\n");
290 } 273 }
291 } 274#endif
292 return false; 275 return false;
293 case EEPROM_RESET: 276 case EEPROM_RESET:
294 if (record->event.pressed) {
295 eeconfig_init(); 277 eeconfig_init();
296 } 278 return false;
297 return false;
298#ifdef FAUXCLICKY_ENABLE 279#ifdef FAUXCLICKY_ENABLE
299 case FC_TOG: 280 case FC_TOG:
300 if (record->event.pressed) {
301 FAUXCLICKY_TOGGLE; 281 FAUXCLICKY_TOGGLE;
302 } 282 return false;
303 return false; 283 case FC_ON:
304 case FC_ON:
305 if (record->event.pressed) {
306 FAUXCLICKY_ON; 284 FAUXCLICKY_ON;
307 } 285 return false;
308 return false; 286 case FC_OFF:
309 case FC_OFF:
310 if (record->event.pressed) {
311 FAUXCLICKY_OFF; 287 FAUXCLICKY_OFF;
312 } 288 return false;
313 return false; 289#endif
290#ifdef VELOCIKEY_ENABLE
291 case VLK_TOG:
292 velocikey_toggle();
293 return false;
294#endif
295#ifdef BLUETOOTH_ENABLE
296 case OUT_AUTO:
297 set_output(OUTPUT_AUTO);
298 return false;
299 case OUT_USB:
300 set_output(OUTPUT_USB);
301 return false;
302 case OUT_BT:
303 set_output(OUTPUT_BLUETOOTH);
304 return false;
305#endif
306#if defined(BACKLIGHT_ENABLE) && defined(BACKLIGHT_BREATHING)
307 case BL_BRTG:
308 backlight_toggle_breathing();
309 return false;
314#endif 310#endif
311 }
312 }
313
315#if defined(RGBLIGHT_ENABLE) || defined(RGB_MATRIX_ENABLE) 314#if defined(RGBLIGHT_ENABLE) || defined(RGB_MATRIX_ENABLE)
316 case RGB_TOG:
317// Split keyboards need to trigger on key-up for edge-case issue
318# ifndef SPLIT_KEYBOARD 315# ifndef SPLIT_KEYBOARD
319 if (record->event.pressed) { 316 if (record->event.pressed) {
320# else 317# else
321 if (!record->event.pressed) { 318 // Split keyboards need to trigger on key-up for edge-case issue
319 if (!record->event.pressed) {
322# endif 320# endif
321 uint8_t shifted = get_mods() & (MOD_BIT(KC_LSHIFT) | MOD_BIT(KC_RSHIFT));
322 switch (keycode) {
323 case RGB_TOG:
323 rgblight_toggle(); 324 rgblight_toggle();
324 } 325 return false;
325 return false; 326 case RGB_MODE_FORWARD:
326 case RGB_MODE_FORWARD:
327 if (record->event.pressed) {
328 uint8_t shifted = get_mods() & (MOD_BIT(KC_LSHIFT) | MOD_BIT(KC_RSHIFT));
329 if (shifted) { 327 if (shifted) {
330 rgblight_step_reverse(); 328 rgblight_step_reverse();
331 } else { 329 } else {
332 rgblight_step(); 330 rgblight_step();
333 } 331 }
334 } 332 return false;
335 return false; 333 case RGB_MODE_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));
339 if (shifted) { 334 if (shifted) {
340 rgblight_step(); 335 rgblight_step();
341 } else { 336 } else {
342 rgblight_step_reverse(); 337 rgblight_step_reverse();
343 } 338 }
344 } 339 return false;
345 return false; 340 case RGB_HUI:
346 case RGB_HUI: 341 if (shifted) {
347// Split keyboards need to trigger on key-up for edge-case issue 342 rgblight_decrease_hue();
348# ifndef SPLIT_KEYBOARD 343 } else {
349 if (record->event.pressed) { 344 rgblight_increase_hue();
350# else 345 }
351 if (!record->event.pressed) { 346 return false;
352# endif 347 case RGB_HUD:
353 rgblight_increase_hue(); 348 if (shifted) {
354 } 349 rgblight_increase_hue();
355 return false; 350 } else {
356 case RGB_HUD: 351 rgblight_decrease_hue();
357// Split keyboards need to trigger on key-up for edge-case issue 352 }
358# ifndef SPLIT_KEYBOARD 353 return false;
359 if (record->event.pressed) { 354 case RGB_SAI:
360# else 355 if (shifted) {
361 if (!record->event.pressed) { 356 rgblight_decrease_sat();
362# endif 357 } else {
363 rgblight_decrease_hue(); 358 rgblight_increase_sat();
364 } 359 }
365 return false; 360 return false;
366 case RGB_SAI: 361 case RGB_SAD:
367// Split keyboards need to trigger on key-up for edge-case issue 362 if (shifted) {
368# ifndef SPLIT_KEYBOARD 363 rgblight_increase_sat();
369 if (record->event.pressed) { 364 } else {
370# else 365 rgblight_decrease_sat();
371 if (!record->event.pressed) { 366 }
372# endif 367 return false;
373 rgblight_increase_sat(); 368 case RGB_VAI:
374 } 369 if (shifted) {
375 return false; 370 rgblight_decrease_val();
376 case RGB_SAD: 371 } else {
377// Split keyboards need to trigger on key-up for edge-case issue 372 rgblight_increase_val();
378# ifndef SPLIT_KEYBOARD 373 }
379 if (record->event.pressed) { 374 return false;
380# else 375 case RGB_VAD:
381 if (!record->event.pressed) { 376 if (shifted) {
382# endif 377 rgblight_increase_val();
383 rgblight_decrease_sat(); 378 } else {
384 } 379 rgblight_decrease_val();
385 return false; 380 }
386 case RGB_VAI: 381 return false;
387// Split keyboards need to trigger on key-up for edge-case issue 382 case RGB_SPI:
388# ifndef SPLIT_KEYBOARD 383 if (shifted) {
389 if (record->event.pressed) { 384 rgblight_decrease_speed();
390# else 385 } else {
391 if (!record->event.pressed) { 386 rgblight_increase_speed();
392# endif 387 }
393 rgblight_increase_val(); 388 return false;
394 } 389 case RGB_SPD:
395 return false; 390 if (shifted) {
396 case RGB_VAD: 391 rgblight_increase_speed();
397// Split keyboards need to trigger on key-up for edge-case issue 392 } else {
398# ifndef SPLIT_KEYBOARD 393 rgblight_decrease_speed();
399 if (record->event.pressed) { 394 }
400# else 395 return false;
401 if (!record->event.pressed) { 396 case RGB_MODE_PLAIN:
402# endif
403 rgblight_decrease_val();
404 }
405 return false;
406 case RGB_SPI:
407 if (record->event.pressed) {
408 rgblight_increase_speed();
409 }
410 return false;
411 case RGB_SPD:
412 if (record->event.pressed) {
413 rgblight_decrease_speed();
414 }
415 return false;
416 case RGB_MODE_PLAIN:
417 if (record->event.pressed) {
418 rgblight_mode(RGBLIGHT_MODE_STATIC_LIGHT); 397 rgblight_mode(RGBLIGHT_MODE_STATIC_LIGHT);
419 } 398 return false;
420 return false; 399 case RGB_MODE_BREATHE:
421 case RGB_MODE_BREATHE:
422# ifdef RGBLIGHT_EFFECT_BREATHING 400# ifdef RGBLIGHT_EFFECT_BREATHING
423 if (record->event.pressed) {
424 if ((RGBLIGHT_MODE_BREATHING <= rgblight_get_mode()) && (rgblight_get_mode() < RGBLIGHT_MODE_BREATHING_end)) { 401 if ((RGBLIGHT_MODE_BREATHING <= rgblight_get_mode()) && (rgblight_get_mode() < RGBLIGHT_MODE_BREATHING_end)) {
425 rgblight_step(); 402 rgblight_step();
426 } else { 403 } else {
427 rgblight_mode(RGBLIGHT_MODE_BREATHING); 404 rgblight_mode(RGBLIGHT_MODE_BREATHING);
428 } 405 }
429 }
430# endif 406# endif
431 return false; 407 return false;
432 case RGB_MODE_RAINBOW: 408 case RGB_MODE_RAINBOW:
433# ifdef RGBLIGHT_EFFECT_RAINBOW_MOOD 409# 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)) { 410 if ((RGBLIGHT_MODE_RAINBOW_MOOD <= rgblight_get_mode()) && (rgblight_get_mode() < RGBLIGHT_MODE_RAINBOW_MOOD_end)) {
436 rgblight_step(); 411 rgblight_step();
437 } else { 412 } else {
438 rgblight_mode(RGBLIGHT_MODE_RAINBOW_MOOD); 413 rgblight_mode(RGBLIGHT_MODE_RAINBOW_MOOD);
439 } 414 }
440 }
441# endif 415# endif
442 return false; 416 case RGB_MODE_SWIRL:
443 case RGB_MODE_SWIRL:
444# ifdef RGBLIGHT_EFFECT_RAINBOW_SWIRL 417# 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)) { 418 if ((RGBLIGHT_MODE_RAINBOW_SWIRL <= rgblight_get_mode()) && (rgblight_get_mode() < RGBLIGHT_MODE_RAINBOW_SWIRL_end)) {
447 rgblight_step(); 419 rgblight_step();
448 } else { 420 } else {
449 rgblight_mode(RGBLIGHT_MODE_RAINBOW_SWIRL); 421 rgblight_mode(RGBLIGHT_MODE_RAINBOW_SWIRL);
450 } 422 }
451 }
452# endif 423# endif
453 return false; 424 return false;
454 case RGB_MODE_SNAKE: 425 case RGB_MODE_SNAKE:
455# ifdef RGBLIGHT_EFFECT_SNAKE 426# ifdef RGBLIGHT_EFFECT_SNAKE
456 if (record->event.pressed) {
457 if ((RGBLIGHT_MODE_SNAKE <= rgblight_get_mode()) && (rgblight_get_mode() < RGBLIGHT_MODE_SNAKE_end)) { 427 if ((RGBLIGHT_MODE_SNAKE <= rgblight_get_mode()) && (rgblight_get_mode() < RGBLIGHT_MODE_SNAKE_end)) {
458 rgblight_step(); 428 rgblight_step();
459 } else { 429 } else {
460 rgblight_mode(RGBLIGHT_MODE_SNAKE); 430 rgblight_mode(RGBLIGHT_MODE_SNAKE);
461 } 431 }
462 }
463# endif 432# endif
464 return false; 433 return false;
465 case RGB_MODE_KNIGHT: 434 case RGB_MODE_KNIGHT:
466# ifdef RGBLIGHT_EFFECT_KNIGHT 435# ifdef RGBLIGHT_EFFECT_KNIGHT
467 if (record->event.pressed) {
468 if ((RGBLIGHT_MODE_KNIGHT <= rgblight_get_mode()) && (rgblight_get_mode() < RGBLIGHT_MODE_KNIGHT_end)) { 436 if ((RGBLIGHT_MODE_KNIGHT <= rgblight_get_mode()) && (rgblight_get_mode() < RGBLIGHT_MODE_KNIGHT_end)) {
469 rgblight_step(); 437 rgblight_step();
470 } else { 438 } else {
471 rgblight_mode(RGBLIGHT_MODE_KNIGHT); 439 rgblight_mode(RGBLIGHT_MODE_KNIGHT);
472 } 440 }
473 }
474# endif 441# endif
475 return false; 442 return false;
476 case RGB_MODE_XMAS: 443 case RGB_MODE_XMAS:
477# ifdef RGBLIGHT_EFFECT_CHRISTMAS 444# ifdef RGBLIGHT_EFFECT_CHRISTMAS
478 if (record->event.pressed) {
479 rgblight_mode(RGBLIGHT_MODE_CHRISTMAS); 445 rgblight_mode(RGBLIGHT_MODE_CHRISTMAS);
480 }
481# endif 446# endif
482 return false; 447 return false;
483 case RGB_MODE_GRADIENT: 448 case RGB_MODE_GRADIENT:
484# ifdef RGBLIGHT_EFFECT_STATIC_GRADIENT 449# 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)) { 450 if ((RGBLIGHT_MODE_STATIC_GRADIENT <= rgblight_get_mode()) && (rgblight_get_mode() < RGBLIGHT_MODE_STATIC_GRADIENT_end)) {
487 rgblight_step(); 451 rgblight_step();
488 } else { 452 } else {
489 rgblight_mode(RGBLIGHT_MODE_STATIC_GRADIENT); 453 rgblight_mode(RGBLIGHT_MODE_STATIC_GRADIENT);
490 } 454 }
491 }
492# endif 455# endif
493 return false; 456 return false;
494 case RGB_MODE_RGBTEST: 457 case RGB_MODE_RGBTEST:
495# ifdef RGBLIGHT_EFFECT_RGB_TEST 458# ifdef RGBLIGHT_EFFECT_RGB_TEST
496 if (record->event.pressed) {
497 rgblight_mode(RGBLIGHT_MODE_RGB_TEST); 459 rgblight_mode(RGBLIGHT_MODE_RGB_TEST);
498 }
499# endif
500 return false;
501#endif // defined(RGBLIGHT_ENABLE) || defined(RGB_MATRIX_ENABLE)
502#ifdef VELOCIKEY_ENABLE
503 case VLK_TOG:
504 if (record->event.pressed) {
505 velocikey_toggle();
506 }
507 return false;
508#endif
509#ifdef PROTOCOL_LUFA
510 case OUT_AUTO:
511 if (record->event.pressed) {
512 set_output(OUTPUT_AUTO);
513 }
514 return false;
515 case OUT_USB:
516 if (record->event.pressed) {
517 set_output(OUTPUT_USB);
518 }
519 return false;
520# ifdef BLUETOOTH_ENABLE
521 case OUT_BT:
522 if (record->event.pressed) {
523 set_output(OUTPUT_BLUETOOTH);
524 }
525 return false;
526# endif 460# endif
527#endif
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()) {
533 eeconfig_init();
534 }
535 /* keymap config */
536 keymap_config.raw = eeconfig_read_keymap();
537 switch (keycode) {
538 case MAGIC_SWAP_CONTROL_CAPSLOCK:
539 keymap_config.swap_control_capslock = true;
540 break;
541 case MAGIC_CAPSLOCK_TO_CONTROL:
542 keymap_config.capslock_to_control = true;
543 break;
544 case MAGIC_SWAP_LALT_LGUI:
545 keymap_config.swap_lalt_lgui = true;
546 break;
547 case MAGIC_SWAP_RALT_RGUI:
548 keymap_config.swap_ralt_rgui = true;
549 break;
550 case MAGIC_SWAP_LCTL_LGUI:
551 keymap_config.swap_lctl_lgui = true;
552 break;
553 case MAGIC_SWAP_RCTL_RGUI:
554 keymap_config.swap_rctl_rgui = true;
555 break;
556 case MAGIC_NO_GUI:
557 keymap_config.no_gui = true;
558 break;
559 case MAGIC_SWAP_GRAVE_ESC:
560 keymap_config.swap_grave_esc = true;
561 break;
562 case MAGIC_SWAP_BACKSLASH_BACKSPACE:
563 keymap_config.swap_backslash_backspace = true;
564 break;
565 case MAGIC_HOST_NKRO:
566 clear_keyboard(); // clear first buffer to prevent stuck keys
567 keymap_config.nkro = true;
568 break;
569 case MAGIC_SWAP_ALT_GUI:
570 keymap_config.swap_lalt_lgui = keymap_config.swap_ralt_rgui = true;
571#ifdef AUDIO_ENABLE
572 PLAY_SONG(ag_swap_song);
573#endif
574 break;
575 case MAGIC_SWAP_CTL_GUI:
576 keymap_config.swap_lctl_lgui = keymap_config.swap_rctl_rgui = true;
577#ifdef AUDIO_ENABLE
578 PLAY_SONG(cg_swap_song);
579#endif
580 break;
581 case MAGIC_UNSWAP_CONTROL_CAPSLOCK:
582 keymap_config.swap_control_capslock = false;
583 break;
584 case MAGIC_UNCAPSLOCK_TO_CONTROL:
585 keymap_config.capslock_to_control = false;
586 break;
587 case MAGIC_UNSWAP_LALT_LGUI:
588 keymap_config.swap_lalt_lgui = false;
589 break;
590 case MAGIC_UNSWAP_RALT_RGUI:
591 keymap_config.swap_ralt_rgui = false;
592 break;
593 case MAGIC_UNSWAP_LCTL_LGUI:
594 keymap_config.swap_lctl_lgui = false;
595 break;
596 case MAGIC_UNSWAP_RCTL_RGUI:
597 keymap_config.swap_rctl_rgui = false;
598 break;
599 case MAGIC_UNNO_GUI:
600 keymap_config.no_gui = false;
601 break;
602 case MAGIC_UNSWAP_GRAVE_ESC:
603 keymap_config.swap_grave_esc = false;
604 break;
605 case MAGIC_UNSWAP_BACKSLASH_BACKSPACE:
606 keymap_config.swap_backslash_backspace = false;
607 break;
608 case MAGIC_UNHOST_NKRO:
609 clear_keyboard(); // clear first buffer to prevent stuck keys
610 keymap_config.nkro = false;
611 break;
612 case MAGIC_UNSWAP_ALT_GUI:
613 keymap_config.swap_lalt_lgui = keymap_config.swap_ralt_rgui = false;
614#ifdef AUDIO_ENABLE
615 PLAY_SONG(ag_norm_song);
616#endif
617 break;
618 case MAGIC_UNSWAP_CTL_GUI:
619 keymap_config.swap_lctl_lgui = keymap_config.swap_rctl_rgui = false;
620#ifdef AUDIO_ENABLE
621 PLAY_SONG(cg_norm_song);
622#endif
623 break;
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;
627#ifdef AUDIO_ENABLE
628 if (keymap_config.swap_ralt_rgui) {
629 PLAY_SONG(ag_swap_song);
630 } else {
631 PLAY_SONG(ag_norm_song);
632 }
633#endif
634 break;
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;
638#ifdef AUDIO_ENABLE
639 if (keymap_config.swap_rctl_rgui) {
640 PLAY_SONG(cg_swap_song);
641 } else {
642 PLAY_SONG(cg_norm_song);
643 }
644#endif
645 break;
646 case MAGIC_TOGGLE_NKRO:
647 clear_keyboard(); // clear first buffer to prevent stuck keys
648 keymap_config.nkro = !keymap_config.nkro;
649 break;
650 case MAGIC_EE_HANDS_LEFT:
651 eeconfig_update_handedness(true);
652 break;
653 case MAGIC_EE_HANDS_RIGHT:
654 eeconfig_update_handedness(false);
655 break;
656 default:
657 break;
658 }
659 eeconfig_update_keymap(keymap_config.raw);
660 clear_keyboard(); // clear to prevent stuck keys
661
662 return false; 461 return false;
663 } 462 }
664 break; 463 }
464#endif
665 465
466 // keycodes that depend on both pressed and non-pressed state
467 switch (keycode) {
666 case GRAVE_ESC: { 468 case GRAVE_ESC: {
469 /* true if the last press of GRAVE_ESC was shifted (i.e. GUI or SHIFT were pressed), false otherwise.
470 * Used to ensure that the correct keycode is released if the key is released.
471 */
472 static bool grave_esc_was_shifted = false;
473
667 uint8_t shifted = get_mods() & ((MOD_BIT(KC_LSHIFT) | MOD_BIT(KC_RSHIFT) | MOD_BIT(KC_LGUI) | MOD_BIT(KC_RGUI))); 474 uint8_t shifted = get_mods() & ((MOD_BIT(KC_LSHIFT) | MOD_BIT(KC_RSHIFT) | MOD_BIT(KC_LGUI) | MOD_BIT(KC_RGUI)));
668 475
669#ifdef GRAVE_ESC_ALT_OVERRIDE 476#ifdef GRAVE_ESC_ALT_OVERRIDE
@@ -707,14 +514,6 @@ bool process_record_quantum(keyrecord_t *record) {
707 return false; 514 return false;
708 } 515 }
709 516
710#if defined(BACKLIGHT_ENABLE) && defined(BACKLIGHT_BREATHING)
711 case BL_BRTG: {
712 if (record->event.pressed) {
713 backlight_toggle_breathing();
714 }
715 return false;
716 }
717#endif
718 } 517 }
719 518
720 return process_action_kb(record); 519 return process_action_kb(record);
@@ -1066,10 +865,30 @@ void api_send_unicode(uint32_t unicode) {
1066#endif 865#endif
1067} 866}
1068 867
868/** \brief Lock LED set callback - keymap/user level
869 *
870 * \deprecated Use led_update_user() instead.
871 */
1069__attribute__((weak)) void led_set_user(uint8_t usb_led) {} 872__attribute__((weak)) void led_set_user(uint8_t usb_led) {}
1070 873
874/** \brief Lock LED set callback - keyboard level
875 *
876 * \deprecated Use led_update_kb() instead.
877 */
1071__attribute__((weak)) void led_set_kb(uint8_t usb_led) { led_set_user(usb_led); } 878__attribute__((weak)) void led_set_kb(uint8_t usb_led) { led_set_user(usb_led); }
1072 879
880/** \brief Lock LED update callback - keymap/user level
881 *
882 * \return True if led_update_kb() should run its own code, false otherwise.
883 */
884__attribute__((weak)) bool led_update_user(led_t led_state) { return true; }
885
886/** \brief Lock LED update callback - keyboard level
887 *
888 * \return Ignored for now.
889 */
890__attribute__((weak)) bool led_update_kb(led_t led_state) { return led_update_user(led_state); }
891
1073__attribute__((weak)) void led_init_ports(void) {} 892__attribute__((weak)) void led_init_ports(void) {}
1074 893
1075__attribute__((weak)) void led_set(uint8_t usb_led) { 894__attribute__((weak)) void led_set(uint8_t usb_led) {
@@ -1092,6 +911,7 @@ __attribute__((weak)) void led_set(uint8_t usb_led) {
1092#endif 911#endif
1093 912
1094 led_set_kb(usb_led); 913 led_set_kb(usb_led);
914 led_update_kb((led_t)usb_led);
1095} 915}
1096 916
1097//------------------------------------------------------------------------------ 917//------------------------------------------------------------------------------
diff --git a/quantum/quantum.h b/quantum/quantum.h
index 01abe1c0a..2ee261e60 100644
--- a/quantum/quantum.h
+++ b/quantum/quantum.h
@@ -133,6 +133,10 @@ extern layer_state_t layer_state;
133# include "process_space_cadet.h" 133# include "process_space_cadet.h"
134#endif 134#endif
135 135
136#ifdef MAGIC_KEYCODE_ENABLE
137# include "process_magic.h"
138#endif
139
136#ifdef HD44780_ENABLE 140#ifdef HD44780_ENABLE
137# include "hd44780.h" 141# include "hd44780.h"
138#endif 142#endif
@@ -146,9 +150,12 @@ extern layer_state_t layer_state;
146#endif 150#endif
147 151
148#ifdef DIP_SWITCH_ENABLE 152#ifdef DIP_SWITCH_ENABLE
149 #include "dip_switch.h" 153# include "dip_switch.h"
150#endif 154#endif
151 155
156#ifdef DYNAMIC_MACRO_ENABLE
157# include "process_dynamic_macro.h"
158#endif
152 159
153// Function substitutions to ease GPIO manipulation 160// Function substitutions to ease GPIO manipulation
154#if defined(__AVR__) 161#if defined(__AVR__)
@@ -179,30 +186,8 @@ typedef ioline_t pin_t;
179# define readPin(pin) palReadLine(pin) 186# define readPin(pin) palReadLine(pin)
180#endif 187#endif
181 188
182// Send string macros
183#define STRINGIZE(z) #z
184#define ADD_SLASH_X(y) STRINGIZE(\x##y)
185#define SYMBOL_STR(x) ADD_SLASH_X(x)
186
187#define SS_TAP_CODE 1
188#define SS_DOWN_CODE 2
189#define SS_UP_CODE 3
190
191#define SS_TAP(keycode) "\1" SYMBOL_STR(keycode)
192#define SS_DOWN(keycode) "\2" SYMBOL_STR(keycode)
193#define SS_UP(keycode) "\3" SYMBOL_STR(keycode)
194
195// `string` arguments must not be parenthesized
196#define SS_LCTRL(string) SS_DOWN(X_LCTRL) string SS_UP(X_LCTRL)
197#define SS_LGUI(string) SS_DOWN(X_LGUI) string SS_UP(X_LGUI)
198#define SS_LCMD(string) SS_LGUI(string)
199#define SS_LWIN(string) SS_LGUI(string)
200#define SS_LALT(string) SS_DOWN(X_LALT) string SS_UP(X_LALT)
201#define SS_LSFT(string) SS_DOWN(X_LSHIFT) string SS_UP(X_LSHIFT)
202#define SS_RALT(string) SS_DOWN(X_RALT) string SS_UP(X_RALT)
203#define SS_ALGR(string) SS_RALT(string)
204
205#define SEND_STRING(string) send_string_P(PSTR(string)) 189#define SEND_STRING(string) send_string_P(PSTR(string))
190#define SEND_STRING_DELAY(string, interval) send_string_with_delay_P(PSTR(string), interval)
206 191
207extern const bool ascii_to_shift_lut[128]; 192extern const bool ascii_to_shift_lut[128];
208extern const bool ascii_to_altgr_lut[128]; 193extern const bool ascii_to_altgr_lut[128];
@@ -285,5 +270,7 @@ uint16_t hex_to_keycode(uint8_t hex);
285 270
286void led_set_user(uint8_t usb_led); 271void led_set_user(uint8_t usb_led);
287void led_set_kb(uint8_t usb_led); 272void led_set_kb(uint8_t usb_led);
273bool led_update_user(led_t led_state);
274bool led_update_kb(led_t led_state);
288 275
289void api_send_unicode(uint32_t unicode); 276void api_send_unicode(uint32_t unicode);
diff --git a/quantum/quantum_keycodes.h b/quantum/quantum_keycodes.h
index 5fac6a5ca..c8d0e354b 100644
--- a/quantum/quantum_keycodes.h
+++ b/quantum/quantum_keycodes.h
@@ -505,6 +505,13 @@ enum quantum_keycodes {
505 MAGIC_EE_HANDS_LEFT, 505 MAGIC_EE_HANDS_LEFT,
506 MAGIC_EE_HANDS_RIGHT, 506 MAGIC_EE_HANDS_RIGHT,
507 507
508 // Dynamic Macros
509 DYN_REC_START1,
510 DYN_REC_START2,
511 DYN_REC_STOP,
512 DYN_MACRO_PLAY1,
513 DYN_MACRO_PLAY2,
514
508 // always leave at the end 515 // always leave at the end
509 SAFE_RANGE 516 SAFE_RANGE
510}; 517};
@@ -648,14 +655,43 @@ enum quantum_keycodes {
648// L-ayer, T-ap - 256 keycode max, 16 layer max 655// L-ayer, T-ap - 256 keycode max, 16 layer max
649#define LT(layer, kc) (QK_LAYER_TAP | (((layer)&0xF) << 8) | ((kc)&0xFF)) 656#define LT(layer, kc) (QK_LAYER_TAP | (((layer)&0xF) << 8) | ((kc)&0xFF))
650 657
651#define AG_SWAP MAGIC_SWAP_ALT_GUI 658#define CL_SWAP MAGIC_SWAP_CONTROL_CAPSLOCK
652#define AG_NORM MAGIC_UNSWAP_ALT_GUI 659#define CL_NORM MAGIC_UNSWAP_CONTROL_CAPSLOCK
653#define AG_TOGG MAGIC_TOGGLE_ALT_GUI 660#define CL_CTRL MAGIC_CAPSLOCK_TO_CONTROL
661#define CL_CAPS MAGIC_UNCAPSLOCK_TO_CONTROL
654 662
663#define LCG_SWP MAGIC_SWAP_LCTL_LGUI
664#define LCG_NRM MAGIC_UNSWAP_LCTL_LGUI
665#define RCG_SWP MAGIC_SWAP_RCTL_RGUI
666#define RCG_NRM MAGIC_UNSWAP_RCTL_RGUI
655#define CG_SWAP MAGIC_SWAP_CTL_GUI 667#define CG_SWAP MAGIC_SWAP_CTL_GUI
656#define CG_NORM MAGIC_UNSWAP_CTL_GUI 668#define CG_NORM MAGIC_UNSWAP_CTL_GUI
657#define CG_TOGG MAGIC_TOGGLE_CTL_GUI 669#define CG_TOGG MAGIC_TOGGLE_CTL_GUI
658 670
671#define LAG_SWP MAGIC_SWAP_LALT_LGUI
672#define LAG_NRM MAGIC_UNSWAP_LALT_LGUI
673#define RAG_SWP MAGIC_SWAP_RALT_RGUI
674#define RAG_NRM MAGIC_UNSWAP_RALT_RGUI
675#define AG_SWAP MAGIC_SWAP_ALT_GUI
676#define AG_NORM MAGIC_UNSWAP_ALT_GUI
677#define AG_TOGG MAGIC_TOGGLE_ALT_GUI
678
679#define GUI_OFF MAGIC_NO_GUI
680#define GUI_ON MAGIC_UNNO_GUI
681
682#define GE_SWAP MAGIC_SWAP_GRAVE_ESC
683#define GE_NORM MAGIC_UNSWAP_GRAVE_ESC
684
685#define BS_SWAP MAGIC_SWAP_BACKSLASH_BACKSPACE
686#define BS_NORM MAGIC_UNSWAP_BACKSLASH_BACKSPACE
687
688#define NK_ON MAGIC_HOST_NKRO
689#define NK_OFF MAGIC_UNHOST_NKRO
690#define NK_TOGG MAGIC_TOGGLE_NKRO
691
692#define EH_LEFT MAGIC_EE_HANDS_LEFT
693#define EH_RGHT MAGIC_EE_HANDS_RIGHT
694
659// GOTO layer - 16 layers max 695// GOTO layer - 16 layers max
660// when: 696// when:
661// ON_PRESS = 1 697// ON_PRESS = 1
@@ -757,4 +793,11 @@ enum quantum_keycodes {
757# define SH_OFF (QK_SWAP_HANDS | OP_SH_OFF) 793# define SH_OFF (QK_SWAP_HANDS | OP_SH_OFF)
758#endif 794#endif
759 795
796// Dynamic Macros aliases
797#define DM_REC1 DYN_REC_START1
798#define DM_REC2 DYN_REC_START2
799#define DM_RSTP DYN_REC_STOP
800#define DM_PLY1 DYN_MACRO_PLAY1
801#define DM_PLY2 DYN_MACRO_PLAY2
802
760#endif // QUANTUM_KEYCODES_H 803#endif // QUANTUM_KEYCODES_H
diff --git a/quantum/rgb_matrix_animations/rainbow_pinwheels_anim.h b/quantum/rgb_matrix_animations/rainbow_pinwheels_anim.h
index 4f69456c3..1cd4ed2ac 100644
--- a/quantum/rgb_matrix_animations/rainbow_pinwheels_anim.h
+++ b/quantum/rgb_matrix_animations/rainbow_pinwheels_anim.h
@@ -1,13 +1,13 @@
1#ifndef DISABLE_RGB_MATRIX_RAINBOW_PINWHEELS 1#ifndef DISABLE_RGB_MATRIX_RAINBOW_PINWHEELS
2RGB_MATRIX_EFFECT(PINWHEELS) 2RGB_MATRIX_EFFECT(RAINBOW_PINWHEELS)
3# ifdef RGB_MATRIX_CUSTOM_EFFECT_IMPLS 3# ifdef RGB_MATRIX_CUSTOM_EFFECT_IMPLS
4 4
5static HSV PINWHEELS_math(HSV hsv, int8_t sin, int8_t cos, uint8_t i, uint8_t time) { 5static HSV RAINBOW_PINWHEELS_math(HSV hsv, int8_t sin, int8_t cos, uint8_t i, uint8_t time) {
6 hsv.h += ((g_led_config.point[i].y - k_rgb_matrix_center.y) * 3 * cos + (56 - abs8(g_led_config.point[i].x - k_rgb_matrix_center.x)) * 3 * sin) / 128; 6 hsv.h += ((g_led_config.point[i].y - k_rgb_matrix_center.y) * 3 * cos + (56 - abs8(g_led_config.point[i].x - k_rgb_matrix_center.x)) * 3 * sin) / 128;
7 return hsv; 7 return hsv;
8} 8}
9 9
10bool PINWHEELS(effect_params_t* params) { return effect_runner_sin_cos_i(params, &PINWHEELS_math); } 10bool RAINBOW_PINWHEELS(effect_params_t* params) { return effect_runner_sin_cos_i(params, &RAINBOW_PINWHEELS_math); }
11 11
12# endif // RGB_MATRIX_CUSTOM_EFFECT_IMPLS 12# endif // RGB_MATRIX_CUSTOM_EFFECT_IMPLS
13#endif // DISABLE_RGB_MATRIX_RAINBOW_PINWHEELS 13#endif // DISABLE_RGB_MATRIX_RAINBOW_PINWHEELS
diff --git a/quantum/rgb_matrix_drivers.c b/quantum/rgb_matrix_drivers.c
index 503f97014..9729a3064 100644
--- a/quantum/rgb_matrix_drivers.c
+++ b/quantum/rgb_matrix_drivers.c
@@ -112,6 +112,9 @@ static inline void setled(int i, uint8_t r, uint8_t g, uint8_t b) {
112 led[i].r = r; 112 led[i].r = r;
113 led[i].g = g; 113 led[i].g = g;
114 led[i].b = b; 114 led[i].b = b;
115# ifdef RGBW
116 led[i].w = 0;
117# endif
115} 118}
116 119
117static void setled_all(uint8_t r, uint8_t g, uint8_t b) { 120static void setled_all(uint8_t r, uint8_t g, uint8_t b) {
diff --git a/quantum/rgblight.c b/quantum/rgblight.c
index 1c197827f..7949bb688 100644
--- a/quantum/rgblight.c
+++ b/quantum/rgblight.c
@@ -126,6 +126,9 @@ void setrgb(uint8_t r, uint8_t g, uint8_t b, LED_TYPE *led1) {
126 (*led1).r = r; 126 (*led1).r = r;
127 (*led1).g = g; 127 (*led1).g = g;
128 (*led1).b = b; 128 (*led1).b = b;
129#ifdef RGBW
130 (*led1).w = 0;
131#endif
129} 132}
130 133
131void rgblight_check_config(void) { 134void rgblight_check_config(void) {
@@ -186,7 +189,6 @@ void rgblight_init(void) {
186 return; 189 return;
187 } 190 }
188 191
189 debug_enable = 1; // Debug ON!
190 dprintf("rgblight_init called.\n"); 192 dprintf("rgblight_init called.\n");
191 dprintf("rgblight_init start!\n"); 193 dprintf("rgblight_init start!\n");
192 if (!eeconfig_is_enabled()) { 194 if (!eeconfig_is_enabled()) {
@@ -514,6 +516,9 @@ void rgblight_setrgb(uint8_t r, uint8_t g, uint8_t b) {
514 led[i].r = r; 516 led[i].r = r;
515 led[i].g = g; 517 led[i].g = g;
516 led[i].b = b; 518 led[i].b = b;
519#ifdef RGBW
520 led[i].w = 0;
521#endif
517 } 522 }
518 rgblight_set(); 523 rgblight_set();
519} 524}
@@ -526,6 +531,9 @@ void rgblight_setrgb_at(uint8_t r, uint8_t g, uint8_t b, uint8_t index) {
526 led[index].r = r; 531 led[index].r = r;
527 led[index].g = g; 532 led[index].g = g;
528 led[index].b = b; 533 led[index].b = b;
534#ifdef RGBW
535 led[index].w = 0;
536#endif
529 rgblight_set(); 537 rgblight_set();
530} 538}
531 539
@@ -560,6 +568,9 @@ void rgblight_setrgb_range(uint8_t r, uint8_t g, uint8_t b, uint8_t start, uint8
560 led[i].r = r; 568 led[i].r = r;
561 led[i].g = g; 569 led[i].g = g;
562 led[i].b = b; 570 led[i].b = b;
571#ifdef RGBW
572 led[i].w = 0;
573#endif
563 } 574 }
564 rgblight_set(); 575 rgblight_set();
565 wait_ms(1); 576 wait_ms(1);
@@ -595,6 +606,9 @@ void rgblight_set(void) {
595 led[i].r = 0; 606 led[i].r = 0;
596 led[i].g = 0; 607 led[i].g = 0;
597 led[i].b = 0; 608 led[i].b = 0;
609# ifdef RGBW
610 led[i].w = 0;
611# endif
598 } 612 }
599 } 613 }
600# ifdef RGBLIGHT_LED_MAP 614# ifdef RGBLIGHT_LED_MAP
@@ -606,11 +620,7 @@ void rgblight_set(void) {
606# else 620# else
607 start_led = led + clipping_start_pos; 621 start_led = led + clipping_start_pos;
608# endif 622# endif
609# ifdef RGBW
610 ws2812_setleds_rgbw(start_led, num_leds);
611# else
612 ws2812_setleds(start_led, num_leds); 623 ws2812_setleds(start_led, num_leds);
613# endif
614} 624}
615#endif 625#endif
616 626
@@ -908,6 +918,9 @@ void rgblight_effect_snake(animation_status_t *anim) {
908 ledp->r = 0; 918 ledp->r = 0;
909 ledp->g = 0; 919 ledp->g = 0;
910 ledp->b = 0; 920 ledp->b = 0;
921# ifdef RGBW
922 ledp->w = 0;
923# endif
911 for (j = 0; j < RGBLIGHT_EFFECT_SNAKE_LENGTH; j++) { 924 for (j = 0; j < RGBLIGHT_EFFECT_SNAKE_LENGTH; j++) {
912 k = pos + j * increment; 925 k = pos + j * increment;
913 if (k > RGBLED_NUM) { 926 if (k > RGBLED_NUM) {
@@ -965,6 +978,9 @@ void rgblight_effect_knight(animation_status_t *anim) {
965 led[i].r = 0; 978 led[i].r = 0;
966 led[i].g = 0; 979 led[i].g = 0;
967 led[i].b = 0; 980 led[i].b = 0;
981# ifdef RGBW
982 led[i].w = 0;
983# endif
968 } 984 }
969 // Determine which LEDs should be lit up 985 // Determine which LEDs should be lit up
970 for (i = 0; i < RGBLIGHT_EFFECT_KNIGHT_LED_NUM; i++) { 986 for (i = 0; i < RGBLIGHT_EFFECT_KNIGHT_LED_NUM; i++) {
@@ -976,6 +992,9 @@ void rgblight_effect_knight(animation_status_t *anim) {
976 led[cur].r = 0; 992 led[cur].r = 0;
977 led[cur].g = 0; 993 led[cur].g = 0;
978 led[cur].b = 0; 994 led[cur].b = 0;
995# ifdef RGBW
996 led[cur].w = 0;
997# endif
979 } 998 }
980 } 999 }
981 rgblight_set(); 1000 rgblight_set();
diff --git a/quantum/send_string_keycodes.h b/quantum/send_string_keycodes.h
index e71790a1d..fc6467a74 100644
--- a/quantum/send_string_keycodes.h
+++ b/quantum/send_string_keycodes.h
@@ -1,207 +1,374 @@
1#ifndef SEND_STRING_KEYCODES 1/* Copyright 2019
2#define SEND_STRING_KEYCODES 2 *
3 3 * This program is free software: you can redistribute it and/or modify
4#define X_NO 00 4 * it under the terms of the GNU General Public License as published by
5#define X_ROLL_OVER 01 5 * the Free Software Foundation, either version 2 of the License, or
6#define X_POST_FAIL 02 6 * (at your option) any later version.
7#define X_UNDEFINED 03 7 *
8#define X_A 04 8 * This program is distributed in the hope that it will be useful,
9#define X_B 05 9 * but WITHOUT ANY WARRANTY; without even the implied warranty of
10#define X_C 06 10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11#define X_D 07 11 * GNU General Public License for more details.
12#define X_E 08 12 *
13#define X_F 09 13 * You should have received a copy of the GNU General Public License
14#define X_G 0a 14 * along with this program. If not, see <http://www.gnu.org/licenses/>.
15#define X_H 0b 15 */
16#define X_I 0c 16
17#define X_J 0d 17#pragma once
18#define X_K 0e 18
19#define X_L 0f 19// clang-format off
20#define X_M 10 20
21#define X_N 11 21/* Punctuation */
22#define X_O 12 22#define X_ENT X_ENTER
23#define X_P 13 23#define X_ESC X_ESCAPE
24#define X_Q 14 24#define X_BSPC X_BSPACE
25#define X_R 15 25#define X_SPC X_SPACE
26#define X_S 16 26#define X_MINS X_MINUS
27#define X_T 17 27#define X_EQL X_EQUAL
28#define X_U 18 28#define X_LBRC X_LBRACKET
29#define X_V 19 29#define X_RBRC X_RBRACKET
30#define X_W 1a 30#define X_BSLS X_BSLASH
31#define X_X 1b 31#define X_NUHS X_NONUS_HASH
32#define X_Y 1c 32#define X_SCLN X_SCOLON
33#define X_Z 1d 33#define X_QUOT X_QUOTE
34#define X_1 1e 34#define X_GRV X_GRAVE
35#define X_2 1f 35#define X_COMM X_COMMA
36#define X_3 20 36#define X_SLSH X_SLASH
37#define X_4 21 37#define X_NUBS X_NONUS_BSLASH
38#define X_5 22 38
39#define X_6 23 39/* Lock Keys */
40#define X_7 24 40#define X_CLCK X_CAPSLOCK
41#define X_8 25 41#define X_CAPS X_CAPSLOCK
42#define X_9 26 42#define X_SLCK X_SCROLLLOCK
43#define X_0 27 43#define X_NLCK X_NUMLOCK
44#define X_ENTER 28 44#define X_LCAP X_LOCKING_CAPS
45#define X_ESCAPE 29 45#define X_LNUM X_LOCKING_NUM
46#define X_BSPACE 2a 46#define X_LSCR X_LOCKING_SCROLL
47#define X_TAB 2b 47
48#define X_SPACE 2c 48/* Commands */
49#define X_MINUS 2d 49#define X_PSCR X_PSCREEN
50#define X_EQUAL 2e 50#define X_PAUS X_PAUSE
51#define X_LBRACKET 2f 51#define X_BRK X_PAUSE
52#define X_RBRACKET 30 52#define X_INS X_INSERT
53#define X_BSLASH 31 53#define X_DEL X_DELETE
54#define X_NONUS_HASH 32 54#define X_PGDN X_PGDOWN
55#define X_SCOLON 33 55#define X_RGHT X_RIGHT
56#define X_QUOTE 34 56#define X_APP X_APPLICATION
57#define X_GRAVE 35 57#define X_EXEC X_EXECUTE
58#define X_COMMA 36 58#define X_SLCT X_SELECT
59#define X_DOT 37 59#define X_AGIN X_AGAIN
60#define X_SLASH 38 60#define X_PSTE X_PASTE
61#define X_CAPSLOCK 39 61#define X_ERAS X_ALT_ERASE
62#define X_F1 3a 62#define X_CLR X_CLEAR
63#define X_F2 3b 63
64#define X_F3 3c 64/* Keypad */
65#define X_F4 3d 65#define X_PSLS X_KP_SLASH
66#define X_F5 3e 66#define X_PAST X_KP_ASTERISK
67#define X_F6 3f 67#define X_PMNS X_KP_MINUS
68#define X_F7 40 68#define X_PPLS X_KP_PLUS
69#define X_F8 41 69#define X_PENT X_KP_ENTER
70#define X_F9 42 70#define X_P1 X_KP_1
71#define X_F10 43 71#define X_P2 X_KP_2
72#define X_F11 44 72#define X_P3 X_KP_3
73#define X_F12 45 73#define X_P4 X_KP_4
74#define X_PSCREEN 46 74#define X_P5 X_KP_5
75#define X_SCROLLLOCK 47 75#define X_P6 X_KP_6
76#define X_PAUSE 48 76#define X_P7 X_KP_7
77#define X_INSERT 49 77#define X_P8 X_KP_8
78#define X_HOME 4a 78#define X_P9 X_KP_9
79#define X_PGUP 4b 79#define X_P0 X_KP_0
80#define X_DELETE 4c 80#define X_PDOT X_KP_DOT
81#define X_END 4d 81#define X_PEQL X_KP_EQUAL
82#define X_PGDOWN 4e 82#define X_PCMM X_KP_COMMA
83#define X_RIGHT 4f 83
84#define X_LEFT 50 84/* Japanese specific */
85#define X_DOWN 51 85#define X_ZKHK X_GRAVE
86#define X_UP 52 86#define X_RO X_INT1
87#define X_NUMLOCK 53 87#define X_KANA X_INT2
88#define X_KP_SLASH 54 88#define X_JYEN X_INT3
89#define X_KP_ASTERISK 55 89#define X_HENK X_INT4
90#define X_KP_MINUS 56 90#define X_MHEN X_INT5
91#define X_KP_PLUS 57 91
92#define X_KP_ENTER 58 92/* Korean specific */
93#define X_KP_1 59 93#define X_HAEN X_LANG1
94#define X_KP_2 5a 94#define X_HANJ X_LANG2
95#define X_KP_3 5b 95
96#define X_KP_4 5c 96/* Modifiers */
97#define X_KP_5 5d 97#define X_LCTL X_LCTRL
98#define X_KP_6 5e 98#define X_LSFT X_LSHIFT
99#define X_KP_7 5f 99#define X_LCMD X_LGUI
100#define X_KP_8 60 100#define X_LWIN X_LGUI
101#define X_KP_9 61 101#define X_RCTL X_RCTRL
102#define X_KP_0 62 102#define X_RSFT X_RSHIFT
103#define X_KP_DOT 63 103#define X_ALGR X_RALT
104#define X_NONUS_BSLASH 64 104#define X_RCMD X_RGUI
105#define X_APPLICATION 65 105#define X_RWIN X_RGUI
106#define X_POWER 66 106
107#define X_KP_EQUAL 67 107/* Generic Desktop Page (0x01) */
108#define X_F13 68 108#define X_PWR X_SYSTEM_POWER
109#define X_F14 69 109#define X_SLEP X_SYSTEM_SLEEP
110#define X_F15 6a 110#define X_WAKE X_SYSTEM_WAKE
111#define X_F16 6b 111
112#define X_F17 6c 112/* Consumer Page (0x0C) */
113#define X_F18 6d 113#define X_MUTE X_AUDIO_MUTE
114#define X_F19 6e 114#define X_VOLU X_AUDIO_VOL_UP
115#define X_F20 6f 115#define X_VOLD X_AUDIO_VOL_DOWN
116#define X_F21 70 116#define X_MNXT X_MEDIA_NEXT_TRACK
117#define X_F22 71 117#define X_MPRV X_MEDIA_PREV_TRACK
118#define X_F23 72 118#define X_MSTP X_MEDIA_STOP
119#define X_F24 73 119#define X_MPLY X_MEDIA_PLAY_PAUSE
120#define X_EXECUTE 74 120#define X_MSEL X_MEDIA_SELECT
121#define X_HELP 75 121#define X_EJCT X_MEDIA_EJECT
122#define X_MENU 76 122#define X_CALC X_CALCULATOR
123#define X_SELECT 77 123#define X_MYCM X_MY_COMPUTER
124#define X_STOP 78 124#define X_WSCH X_WWW_SEARCH
125#define X_AGAIN 79 125#define X_WHOM X_WWW_HOME
126#define X_UNDO 7a 126#define X_WBAK X_WWW_BACK
127#define X_CUT 7b 127#define X_WFWD X_WWW_FORWARD
128#define X_COPY 7c 128#define X_WSTP X_WWW_STOP
129#define X_PASTE 7d 129#define X_WREF X_WWW_REFRESH
130#define X_FIND 7e 130#define X_WFAV X_WWW_FAVORITES
131#define X__MUTE 7f 131#define X_MFFD X_MEDIA_FAST_FORWARD
132#define X__VOLUP 80 132#define X_MRWD X_MEDIA_REWIND
133#define X__VOLDOWN 81 133#define X_BRIU X_BRIGHTNESS_UP
134#define X_LOCKING_CAPS 82 134#define X_BRID X_BRIGHTNESS_DOWN
135#define X_LOCKING_NUM 83 135
136#define X_LOCKING_SCROLL 84 136/* System Specific */
137#define X_KP_COMMA 85 137#define X_BRMU X_PAUSE
138#define X_KP_EQUAL_AS400 86 138#define X_BRMD X_SCROLLLOCK
139#define X_INT1 87 139
140#define X_INT2 88 140/* Keyboard/Keypad Page (0x07) */
141#define X_INT3 89 141#define X_A 04
142#define X_INT4 8a 142#define X_B 05
143#define X_INT5 8b 143#define X_C 06
144#define X_INT6 8c 144#define X_D 07
145#define X_INT7 8d 145#define X_E 08
146#define X_INT8 8e 146#define X_F 09
147#define X_INT9 8f 147#define X_G 0a
148#define X_LANG1 90 148#define X_H 0b
149#define X_LANG2 91 149#define X_I 0c
150#define X_LANG3 92 150#define X_J 0d
151#define X_LANG4 93 151#define X_K 0e
152#define X_LANG5 94 152#define X_L 0f
153#define X_LANG6 95 153#define X_M 10
154#define X_LANG7 96 154#define X_N 11
155#define X_LANG8 97 155#define X_O 12
156#define X_LANG9 98 156#define X_P 13
157#define X_ALT_ERASE 99 157#define X_Q 14
158#define X_SYSREQ 9a 158#define X_R 15
159#define X_CANCEL 9b 159#define X_S 16
160#define X_CLEAR 9c 160#define X_T 17
161#define X_PRIOR 9d 161#define X_U 18
162#define X_RETURN 9e 162#define X_V 19
163#define X_SEPARATOR 9f 163#define X_W 1a
164#define X_OUT a0 164#define X_X 1b
165#define X_OPER a1 165#define X_Y 1c
166#define X_CLEAR_AGAIN a2 166#define X_Z 1d
167#define X_CRSEL a3 167#define X_1 1e
168#define X_EXSEL a4 168#define X_2 1f
169#define X_3 20
170#define X_4 21
171#define X_5 22
172#define X_6 23
173#define X_7 24
174#define X_8 25
175#define X_9 26
176#define X_0 27
177#define X_ENTER 28
178#define X_ESCAPE 29
179#define X_BSPACE 2a
180#define X_TAB 2b
181#define X_SPACE 2c
182#define X_MINUS 2d
183#define X_EQUAL 2e
184#define X_LBRACKET 2f
185#define X_RBRACKET 30
186#define X_BSLASH 31
187#define X_NONUS_HASH 32
188#define X_SCOLON 33
189#define X_QUOTE 34
190#define X_GRAVE 35
191#define X_COMMA 36
192#define X_DOT 37
193#define X_SLASH 38
194#define X_CAPSLOCK 39
195#define X_F1 3a
196#define X_F2 3b
197#define X_F3 3c
198#define X_F4 3d
199#define X_F5 3e
200#define X_F6 3f
201#define X_F7 40
202#define X_F8 41
203#define X_F9 42
204#define X_F10 43
205#define X_F11 44
206#define X_F12 45
207#define X_PSCREEN 46
208#define X_SCROLLLOCK 47
209#define X_PAUSE 48
210#define X_INSERT 49
211#define X_HOME 4a
212#define X_PGUP 4b
213#define X_DELETE 4c
214#define X_END 4d
215#define X_PGDOWN 4e
216#define X_RIGHT 4f
217#define X_LEFT 50
218#define X_DOWN 51
219#define X_UP 52
220#define X_NUMLOCK 53
221#define X_KP_SLASH 54
222#define X_KP_ASTERISK 55
223#define X_KP_MINUS 56
224#define X_KP_PLUS 57
225#define X_KP_ENTER 58
226#define X_KP_1 59
227#define X_KP_2 5a
228#define X_KP_3 5b
229#define X_KP_4 5c
230#define X_KP_5 5d
231#define X_KP_6 5e
232#define X_KP_7 5f
233#define X_KP_8 60
234#define X_KP_9 61
235#define X_KP_0 62
236#define X_KP_DOT 63
237#define X_NONUS_BSLASH 64
238#define X_APPLICATION 65
239#define X_POWER 66
240#define X_KP_EQUAL 67
241#define X_F13 68
242#define X_F14 69
243#define X_F15 6a
244#define X_F16 6b
245#define X_F17 6c
246#define X_F18 6d
247#define X_F19 6e
248#define X_F20 6f
249#define X_F21 70
250#define X_F22 71
251#define X_F23 72
252#define X_F24 73
253#define X_EXECUTE 74
254#define X_HELP 75
255#define X_MENU 76
256#define X_SELECT 77
257#define X_STOP 78
258#define X_AGAIN 79
259#define X_UNDO 7a
260#define X_CUT 7b
261#define X_COPY 7c
262#define X_PASTE 7d
263#define X_FIND 7e
264#define X__MUTE 7f
265#define X__VOLUP 80
266#define X__VOLDOWN 81
267#define X_LOCKING_CAPS 82
268#define X_LOCKING_NUM 83
269#define X_LOCKING_SCROLL 84
270#define X_KP_COMMA 85
271#define X_KP_EQUAL_AS400 86
272#define X_INT1 87
273#define X_INT2 88
274#define X_INT3 89
275#define X_INT4 8a
276#define X_INT5 8b
277#define X_INT6 8c
278#define X_INT7 8d
279#define X_INT8 8e
280#define X_INT9 8f
281#define X_LANG1 90
282#define X_LANG2 91
283#define X_LANG3 92
284#define X_LANG4 93
285#define X_LANG5 94
286#define X_LANG6 95
287#define X_LANG7 96
288#define X_LANG8 97
289#define X_LANG9 98
290#define X_ALT_ERASE 99
291#define X_SYSREQ 9a
292#define X_CANCEL 9b
293#define X_CLEAR 9c
294#define X_PRIOR 9d
295#define X_RETURN 9e
296#define X_SEPARATOR 9f
297#define X_OUT a0
298#define X_OPER a1
299#define X_CLEAR_AGAIN a2
300#define X_CRSEL a3
301#define X_EXSEL a4
169 302
170/* Modifiers */ 303/* Modifiers */
171#define X_LCTRL e0 304#define X_LCTRL e0
172#define X_LSHIFT e1 305#define X_LSHIFT e1
173#define X_LALT e2 306#define X_LALT e2
174#define X_LGUI e3 307#define X_LGUI e3
175#define X_RCTRL e4 308#define X_RCTRL e4
176#define X_RSHIFT e5 309#define X_RSHIFT e5
177#define X_RALT e6 310#define X_RALT e6
178#define X_RGUI e7 311#define X_RGUI e7
179 312
180/* System Control */ 313/* Media and Function keys */
181#define X_SYSTEM_POWER a5 314/* Generic Desktop Page (0x01) */
182#define X_SYSTEM_SLEEP a6 315#define X_SYSTEM_POWER a5
183#define X_SYSTEM_WAKE a7 316#define X_SYSTEM_SLEEP a6
184 317#define X_SYSTEM_WAKE a7
185/* Media Control */ 318
186#define X_AUDIO_MUTE a8 319/* Consumer Page (0x0C) */
187#define X_AUDIO_VOL_UP a9 320#define X_AUDIO_MUTE a8
188#define X_AUDIO_VOL_DOWN aa 321#define X_AUDIO_VOL_UP a9
189#define X_MEDIA_NEXT_TRACK ab 322#define X_AUDIO_VOL_DOWN aa
190#define X_MEDIA_PREV_TRACK ac 323#define X_MEDIA_NEXT_TRACK ab
191#define X_MEDIA_STOP ad 324#define X_MEDIA_PREV_TRACK ac
192#define X_MEDIA_PLAY_PAUSE ae 325#define X_MEDIA_STOP ad
193#define X_MEDIA_SELECT af 326#define X_MEDIA_PLAY_PAUSE ae
194#define X_MEDIA_EJECT b0 327#define X_MEDIA_SELECT af
195#define X_MAIL b1 328#define X_MEDIA_EJECT b0
196#define X_CALCULATOR b2 329#define X_MAIL b1
197#define X_MY_COMPUTER b3 330#define X_CALCULATOR b2
198#define X_WWW_SEARCH b4 331#define X_MY_COMPUTER b3
199#define X_WWW_HOME b5 332#define X_WWW_SEARCH b4
200#define X_WWW_BACK b6 333#define X_WWW_HOME b5
201#define X_WWW_FORWARD b7 334#define X_WWW_BACK b6
202#define X_WWW_STOP b8 335#define X_WWW_FORWARD b7
203#define X_WWW_REFRESH b9 336#define X_WWW_STOP b8
204#define X_WWW_FAVORITES ba 337#define X_WWW_REFRESH b9
338#define X_WWW_FAVORITES ba
205#define X_MEDIA_FAST_FORWARD bb 339#define X_MEDIA_FAST_FORWARD bb
206#define X_MEDIA_REWIND bc 340#define X_MEDIA_REWIND bc
207#endif 341#define X_BRIGHTNESS_UP bd
342#define X_BRIGHTNESS_DOWN be
343
344// Send string macros
345#define STRINGIZE(z) #z
346#define ADD_SLASH_X(y) STRINGIZE(\x##y)
347#define SYMBOL_STR(x) ADD_SLASH_X(x)
348
349#define SS_TAP_CODE 1
350#define SS_DOWN_CODE 2
351#define SS_UP_CODE 3
352
353#define SS_TAP(keycode) "\1" SYMBOL_STR(keycode)
354#define SS_DOWN(keycode) "\2" SYMBOL_STR(keycode)
355#define SS_UP(keycode) "\3" SYMBOL_STR(keycode)
356
357// `string` arguments must not be parenthesized
358#define SS_LCTL(string) SS_DOWN(X_LCTL) string SS_UP(X_LCTL)
359#define SS_LSFT(string) SS_DOWN(X_LSFT) string SS_UP(X_LSFT)
360#define SS_LALT(string) SS_DOWN(X_LALT) string SS_UP(X_LALT)
361#define SS_LGUI(string) SS_DOWN(X_LGUI) string SS_UP(X_LGUI)
362#define SS_LCMD(string) SS_LGUI(string)
363#define SS_LWIN(string) SS_LGUI(string)
364
365#define SS_RCTL(string) SS_DOWN(X_RCTL) string SS_UP(X_RCTL)
366#define SS_RSFT(string) SS_DOWN(X_RSFT) string SS_UP(X_RSFT)
367#define SS_RALT(string) SS_DOWN(X_RALT) string SS_UP(X_RALT)
368#define SS_RGUI(string) SS_DOWN(X_RGUI) string SS_UP(X_RGUI)
369#define SS_ALGR(string) SS_RALT(string)
370#define SS_RCMD(string) SS_RGUI(string)
371#define SS_RWIN(string) SS_RGUI(string)
372
373// DEPRECATED
374#define SS_LCTRL(string) SS_LCTL(string)
diff --git a/quantum/split_common/post_config.h b/quantum/split_common/post_config.h
index 5c0b414fb..4ae1d5273 100644
--- a/quantum/split_common/post_config.h
+++ b/quantum/split_common/post_config.h
@@ -1,4 +1,4 @@
1#if defined(USE_I2C) || defined(EH) 1#if defined(USE_I2C)
2// When using I2C, using rgblight implicitly involves split support. 2// When using I2C, using rgblight implicitly involves split support.
3# if defined(RGBLIGHT_ENABLE) && !defined(RGBLIGHT_SPLIT) 3# if defined(RGBLIGHT_ENABLE) && !defined(RGBLIGHT_SPLIT)
4# define RGBLIGHT_SPLIT 4# define RGBLIGHT_SPLIT
diff --git a/quantum/split_common/split_util.c b/quantum/split_common/split_util.c
index 5c548de05..076f18664 100644
--- a/quantum/split_common/split_util.c
+++ b/quantum/split_common/split_util.c
@@ -33,9 +33,11 @@ bool waitForUsb(void) {
33 wait_ms(100); 33 wait_ms(100);
34 } 34 }
35 35
36#if defined(__AVR__)
37 // Avoid NO_USB_STARTUP_CHECK - Disable USB as the previous checks seem to enable it somehow 36 // Avoid NO_USB_STARTUP_CHECK - Disable USB as the previous checks seem to enable it somehow
37#if defined(__AVR__)
38 (USBCON &= ~(_BV(USBE) | _BV(OTGPADE))); 38 (USBCON &= ~(_BV(USBE) | _BV(OTGPADE)));
39#else
40 usbStop(&USBD1);
39#endif 41#endif
40 42
41 return false; 43 return false;
@@ -76,7 +78,7 @@ __attribute__((weak)) bool is_keyboard_master(void) {
76} 78}
77 79
78static void keyboard_master_setup(void) { 80static void keyboard_master_setup(void) {
79#if defined(USE_I2C) || defined(EH) 81#if defined(USE_I2C)
80# ifdef SSD1306OLED 82# ifdef SSD1306OLED
81 matrix_master_OLED_init(); 83 matrix_master_OLED_init();
82# endif 84# endif
diff --git a/quantum/split_common/transport.c b/quantum/split_common/transport.c
index 3c783dc56..ab421adc4 100644
--- a/quantum/split_common/transport.c
+++ b/quantum/split_common/transport.c
@@ -21,7 +21,7 @@ static pin_t encoders_pad[] = ENCODERS_PAD_A;
21# define NUMBER_OF_ENCODERS (sizeof(encoders_pad) / sizeof(pin_t)) 21# define NUMBER_OF_ENCODERS (sizeof(encoders_pad) / sizeof(pin_t))
22#endif 22#endif
23 23
24#if defined(USE_I2C) || defined(EH) 24#if defined(USE_I2C)
25 25
26# include "i2c_master.h" 26# include "i2c_master.h"
27# include "i2c_slave.h" 27# include "i2c_slave.h"
diff --git a/quantum/stm32/chconf.h b/quantum/stm32/chconf.h
index f7b1b077d..6b691950a 100644
--- a/quantum/stm32/chconf.h
+++ b/quantum/stm32/chconf.h
@@ -419,34 +419,39 @@
419 * @note It is invoked from within @p chThdInit() and implicitly from all 419 * @note It is invoked from within @p chThdInit() and implicitly from all
420 * the threads creation APIs. 420 * the threads creation APIs.
421 */ 421 */
422# define CH_CFG_THREAD_INIT_HOOK(tp) \ 422# define CH_CFG_THREAD_INIT_HOOK(tp) \
423 { /* Add threads initialization code here.*/ } 423 { /* Add threads initialization code here.*/ \
424 }
424 425
425/** 426/**
426 * @brief Threads finalization hook. 427 * @brief Threads finalization hook.
427 * @details User finalization code added to the @p chThdExit() API. 428 * @details User finalization code added to the @p chThdExit() API.
428 */ 429 */
429# define CH_CFG_THREAD_EXIT_HOOK(tp) \ 430# define CH_CFG_THREAD_EXIT_HOOK(tp) \
430 { /* Add threads finalization code here.*/ } 431 { /* Add threads finalization code here.*/ \
432 }
431 433
432/** 434/**
433 * @brief Context switch hook. 435 * @brief Context switch hook.
434 * @details This hook is invoked just before switching between threads. 436 * @details This hook is invoked just before switching between threads.
435 */ 437 */
436# define CH_CFG_CONTEXT_SWITCH_HOOK(ntp, otp) \ 438# define CH_CFG_CONTEXT_SWITCH_HOOK(ntp, otp) \
437 { /* Context switch code here.*/ } 439 { /* Context switch code here.*/ \
440 }
438 441
439/** 442/**
440 * @brief ISR enter hook. 443 * @brief ISR enter hook.
441 */ 444 */
442# define CH_CFG_IRQ_PROLOGUE_HOOK() \ 445# define CH_CFG_IRQ_PROLOGUE_HOOK() \
443 { /* IRQ prologue code here.*/ } 446 { /* IRQ prologue code here.*/ \
447 }
444 448
445/** 449/**
446 * @brief ISR exit hook. 450 * @brief ISR exit hook.
447 */ 451 */
448# define CH_CFG_IRQ_EPILOGUE_HOOK() \ 452# define CH_CFG_IRQ_EPILOGUE_HOOK() \
449 { /* IRQ epilogue code here.*/ } 453 { /* IRQ epilogue code here.*/ \
454 }
450 455
451/** 456/**
452 * @brief Idle thread enter hook. 457 * @brief Idle thread enter hook.
@@ -455,7 +460,8 @@
455 * @note This macro can be used to activate a power saving mode. 460 * @note This macro can be used to activate a power saving mode.
456 */ 461 */
457# define CH_CFG_IDLE_ENTER_HOOK() \ 462# define CH_CFG_IDLE_ENTER_HOOK() \
458 { /* Idle-enter code here.*/ } 463 { /* Idle-enter code here.*/ \
464 }
459 465
460/** 466/**
461 * @brief Idle thread leave hook. 467 * @brief Idle thread leave hook.
@@ -464,22 +470,25 @@
464 * @note This macro can be used to deactivate a power saving mode. 470 * @note This macro can be used to deactivate a power saving mode.
465 */ 471 */
466# define CH_CFG_IDLE_LEAVE_HOOK() \ 472# define CH_CFG_IDLE_LEAVE_HOOK() \
467 { /* Idle-leave code here.*/ } 473 { /* Idle-leave code here.*/ \
474 }
468 475
469/** 476/**
470 * @brief Idle Loop hook. 477 * @brief Idle Loop hook.
471 * @details This hook is continuously invoked by the idle thread loop. 478 * @details This hook is continuously invoked by the idle thread loop.
472 */ 479 */
473# define CH_CFG_IDLE_LOOP_HOOK() \ 480# define CH_CFG_IDLE_LOOP_HOOK() \
474 { /* Idle loop code here.*/ } 481 { /* Idle loop code here.*/ \
482 }
475 483
476/** 484/**
477 * @brief System tick event hook. 485 * @brief System tick event hook.
478 * @details This hook is invoked in the system tick handler immediately 486 * @details This hook is invoked in the system tick handler immediately
479 * after processing the virtual timers queue. 487 * after processing the virtual timers queue.
480 */ 488 */
481# define CH_CFG_SYSTEM_TICK_HOOK() \ 489# define CH_CFG_SYSTEM_TICK_HOOK() \
482 { /* System tick event code here.*/ } 490 { /* System tick event code here.*/ \
491 }
483 492
484/** 493/**
485 * @brief System halt hook. 494 * @brief System halt hook.
@@ -487,7 +496,8 @@
487 * the system is halted. 496 * the system is halted.
488 */ 497 */
489# define CH_CFG_SYSTEM_HALT_HOOK(reason) \ 498# define CH_CFG_SYSTEM_HALT_HOOK(reason) \
490 { /* System halt code here.*/ } 499 { /* System halt code here.*/ \
500 }
491 501
492/** 502/**
493 * @brief Trace hook. 503 * @brief Trace hook.
@@ -495,7 +505,8 @@
495 * trace buffer. 505 * trace buffer.
496 */ 506 */
497# define CH_CFG_TRACE_HOOK(tep) \ 507# define CH_CFG_TRACE_HOOK(tep) \
498 { /* Trace code here.*/ } 508 { /* Trace code here.*/ \
509 }
499 510
500/** @} */ 511/** @} */
501 512
diff --git a/quantum/stm32/proton_c.mk b/quantum/stm32/proton_c.mk
index 193e09ca1..ff28a4cb5 100644
--- a/quantum/stm32/proton_c.mk
+++ b/quantum/stm32/proton_c.mk
@@ -2,7 +2,7 @@
2 2
3# These are defaults based on what has been implemented for ARM boards 3# These are defaults based on what has been implemented for ARM boards
4AUDIO_ENABLE = yes 4AUDIO_ENABLE = yes
5RGBLIGHT_ENABLE = no 5WS2812_DRIVER = bitbang
6 6
7# Force task driven PWM until ARM can provide automatic configuration 7# Force task driven PWM until ARM can provide automatic configuration
8ifneq ($(strip $(BACKLIGHT_ENABLE)), no) 8ifneq ($(strip $(BACKLIGHT_ENABLE)), no)
diff --git a/quantum/template/avr/config.h b/quantum/template/avr/config.h
index 304a54ae5..7e4a01449 100644
--- a/quantum/template/avr/config.h
+++ b/quantum/template/avr/config.h
@@ -190,9 +190,12 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
190//#define NO_ACTION_LAYER 190//#define NO_ACTION_LAYER
191//#define NO_ACTION_TAPPING 191//#define NO_ACTION_TAPPING
192//#define NO_ACTION_ONESHOT 192//#define NO_ACTION_ONESHOT
193//#define NO_ACTION_MACRO
194//#define NO_ACTION_FUNCTION
195 193
194/* disable these deprecated features by default */
195#ifndef LINK_TIME_OPTIMIZATION_ENABLE
196 #define NO_ACTION_MACRO
197 #define NO_ACTION_FUNCTION
198#endif
196/* 199/*
197 * MIDI options 200 * MIDI options
198 */ 201 */
diff --git a/quantum/template/base/keyboard.c b/quantum/template/base/keyboard.c
index 55e4fffd3..fc31c294a 100644
--- a/quantum/template/base/keyboard.c
+++ b/quantum/template/base/keyboard.c
@@ -42,9 +42,9 @@ bool process_record_kb(uint16_t keycode, keyrecord_t *record) {
42 return process_record_user(keycode, record); 42 return process_record_user(keycode, record);
43} 43}
44 44
45void led_set_kb(uint8_t usb_led) { 45bool led_update_kb(led_t led_state) {
46 // put your keyboard LED indicator (ex: Caps Lock LED) toggling code here 46 // put your keyboard LED indicator (ex: Caps Lock LED) toggling code here
47 47
48 led_set_user(usb_led); 48 return led_update_user(led_state);
49} 49}
50*/ 50*/
diff --git a/quantum/template/base/keymaps/default/keymap.c b/quantum/template/base/keymaps/default/keymap.c
index 4d5bac7b2..af35ccec1 100644
--- a/quantum/template/base/keymaps/default/keymap.c
+++ b/quantum/template/base/keymaps/default/keymap.c
@@ -52,7 +52,7 @@ bool process_record_user(uint16_t keycode, keyrecord_t *record) {
52 case QMKURL: 52 case QMKURL:
53 if (record->event.pressed) { 53 if (record->event.pressed) {
54 // when keycode QMKURL is pressed 54 // when keycode QMKURL is pressed
55 SEND_STRING("https://qmk.fm/" SS_TAP(X_ENTER)); 55 SEND_STRING("https://qmk.fm/\n");
56 } else { 56 } else {
57 // when keycode QMKURL is released 57 // when keycode QMKURL is released
58 } 58 }
@@ -70,7 +70,7 @@ void matrix_scan_user(void) {
70 70
71} 71}
72 72
73void led_set_user(uint8_t usb_led) { 73bool led_update_user(led_t led_state) {
74 74 return true;
75} 75}
76*/ 76*/
diff --git a/quantum/template/ps2avrgb/config.h b/quantum/template/ps2avrgb/config.h
index f6d7c25e0..d93512bca 100644
--- a/quantum/template/ps2avrgb/config.h
+++ b/quantum/template/ps2avrgb/config.h
@@ -22,7 +22,7 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
22#define VENDOR_ID 0x20A0 22#define VENDOR_ID 0x20A0
23#define PRODUCT_ID 0x422D 23#define PRODUCT_ID 0x422D
24#define DEVICE_VER 0x0001 24#define DEVICE_VER 0x0001
25#define MANUFACTURER You 25#define MANUFACTURER %YOUR_NAME%
26#define PRODUCT %KEYBOARD% 26#define PRODUCT %KEYBOARD%
27#define DESCRIPTION A custom keyboard 27#define DESCRIPTION A custom keyboard
28 28
@@ -44,6 +44,12 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
44 44
45#define NO_UART 1 45#define NO_UART 1
46 46
47/* disable these deprecated features by default */
48#ifndef LINK_TIME_OPTIMIZATION_ENABLE
49 #define NO_ACTION_MACRO
50 #define NO_ACTION_FUNCTION
51#endif
52
47/* key combination for magic key command */ 53/* key combination for magic key command */
48/* defined by default; to change, uncomment and set to the combination you want */ 54/* defined by default; to change, uncomment and set to the combination you want */
49// #define IS_COMMAND() (get_mods() == MOD_MASK_SHIFT) 55// #define IS_COMMAND() (get_mods() == MOD_MASK_SHIFT)
diff --git a/quantum/template/ps2avrgb/usbconfig.h b/quantum/template/ps2avrgb/usbconfig.h
index 9ef232f04..83ad06544 100644
--- a/quantum/template/ps2avrgb/usbconfig.h
+++ b/quantum/template/ps2avrgb/usbconfig.h
@@ -98,20 +98,10 @@ section at the end of this file).
98 * (e.g. HID), but never want to send any data. This option saves a couple 98 * (e.g. HID), but never want to send any data. This option saves a couple
99 * of bytes in flash memory and the transmit buffers in RAM. 99 * of bytes in flash memory and the transmit buffers in RAM.
100 */ 100 */
101#define USB_CFG_INTR_POLL_INTERVAL 1
102/* If you compile a version with endpoint 1 (interrupt-in), this is the poll
103 * interval. The value is in milliseconds and must not be less than 10 ms for
104 * low speed devices.
105 */
106#define USB_CFG_IS_SELF_POWERED 0 101#define USB_CFG_IS_SELF_POWERED 0
107/* Define this to 1 if the device has its own power supply. Set it to 0 if the 102/* Define this to 1 if the device has its own power supply. Set it to 0 if the
108 * device is powered from the USB bus. 103 * device is powered from the USB bus.
109 */ 104 */
110#define USB_CFG_MAX_BUS_POWER 500
111/* Set this variable to the maximum USB bus power consumption of your device.
112 * The value is in milliamperes. [It will be divided by two since USB
113 * communicates power requirements in units of 2 mA.]
114 */
115#define USB_CFG_IMPLEMENT_FN_WRITE 1 105#define USB_CFG_IMPLEMENT_FN_WRITE 1
116/* Set this to 1 if you want usbFunctionWrite() to be called for control-out 106/* Set this to 1 if you want usbFunctionWrite() to be called for control-out
117 * transfers. Set it to 0 if you don't need it and want to save a couple of 107 * transfers. Set it to 0 if you don't need it and want to save a couple of
@@ -227,7 +217,7 @@ section at the end of this file).
227 * with libusb: 0x16c0/0x5dc. Use this VID/PID pair ONLY if you understand 217 * with libusb: 0x16c0/0x5dc. Use this VID/PID pair ONLY if you understand
228 * the implications! 218 * the implications!
229 */ 219 */
230#define USB_CFG_DEVICE_VERSION 0x00, 0x02 220#define USB_CFG_DEVICE_VERSION (DEVICE_VER & 0xFF), ((DEVICE_VER >> 8) & 0xFF)
231/* Version number of the device: Minor number first, then major number. 221/* Version number of the device: Minor number first, then major number.
232 */ 222 */
233#define USB_CFG_VENDOR_NAME 'w', 'i', 'n', 'k', 'e', 'y', 'l', 'e', 's', 's', '.', 'k', 'r' 223#define USB_CFG_VENDOR_NAME 'w', 'i', 'n', 'k', 'e', 'y', 'l', 'e', 's', 's', '.', 'k', 'r'