From d534c72a544454132b3c6c05af85c821f6a93d65 Mon Sep 17 00:00:00 2001 From: Stephen Wanhella Date: Wed, 21 Aug 2019 17:07:08 -0700 Subject: Added keycodes for swapping and unswapping the Control and OS keys (#6110) * Add MAGIC_SWAP_CONTROL_LGUI and MAGIC_UNSWAP_CONTROL_LGUI keycodes Key codes to swap and unswap the control and windows/cmd keys * Fix issues with pull request #6110 Renamed swap/unswap lctl and lgui key codes, added key codes to swap/unswap rctl and rgui, and moved new bool inside keycode_config.h struct to the end * Move new keycodes to the end of the enum (#6110) * add cases for swapped control and OS keys to mod_config (#6110) * Add new keycodes to feature_bootmagic.md (#6110) * Add R+L swap codes to keep in parity with AG_* codes * Extend Magic range check to include new magic codes * Update audio docs * Combine 2 byte ranges into 1 word for EECONFG Fix names for Keymap config EEPROM * Update docs/feature_bootmagic.md Co-Authored-By: noroadsleft <18669334+noroadsleft@users.noreply.github.com> * Update docs/feature_bootmagic.md Co-Authored-By: noroadsleft <18669334+noroadsleft@users.noreply.github.com> * Update docs/feature_bootmagic.md Co-Authored-By: noroadsleft <18669334+noroadsleft@users.noreply.github.com> * Update docs/feature_bootmagic.md Co-Authored-By: noroadsleft <18669334+noroadsleft@users.noreply.github.com> --- docs/keycodes.md | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) (limited to 'docs/keycodes.md') diff --git a/docs/keycodes.md b/docs/keycodes.md index bd4dd61a5..e17fef6fd 100644 --- a/docs/keycodes.md +++ b/docs/keycodes.md @@ -261,6 +261,8 @@ This is a reference only. Each group of keys links to the page documenting their |----------------------------------|---------|------------------------------------| |`MAGIC_SWAP_CONTROL_CAPSLOCK` | |Swap Caps Lock and Left Control | |`MAGIC_CAPSLOCK_TO_CONTROL` | |Treat Caps Lock as Control | +|`MAGIC_SWAP_LCTL_LGUI` | |Swap Left Control and GUI | +|`MAGIC_SWAP_RCTL_RGUI` | |Swap Right Control and GUI | |`MAGIC_SWAP_LALT_LGUI` | |Swap Left Alt and GUI | |`MAGIC_SWAP_RALT_RGUI` | |Swap Right Alt and GUI | |`MAGIC_NO_GUI` | |Disable the GUI key | @@ -268,8 +270,11 @@ This is a reference only. Each group of keys links to the page documenting their |`MAGIC_SWAP_BACKSLASH_BACKSPACE` | |Swap `\` and Backspace | |`MAGIC_HOST_NKRO` | |Force NKRO on | |`MAGIC_SWAP_ALT_GUI` |`AG_SWAP`|Swap Alt and GUI on both sides | +|`MAGIC_SWAP_CTL_GUI` |`CG_SWAP`|Swap Ctrl and GUI on both sides (for macOS)| |`MAGIC_UNSWAP_CONTROL_CAPSLOCK` | |Unswap Caps Lock and Left Control | |`MAGIC_UNCAPSLOCK_TO_CONTROL` | |Stop treating Caps Lock as Control | +|`MAGIC_UNSWAP_LCTL_LGUI` | |Unswap Left Control and GUI | +|`MAGIC_UNSWAP_RCTL_RGUI` | |Unswap Right Control and GUI | |`MAGIC_UNSWAP_LALT_LGUI` | |Unswap Left Alt and GUI | |`MAGIC_UNSWAP_RALT_RGUI` | |Unswap Right Alt and GUI | |`MAGIC_UNNO_GUI` | |Enable the GUI key | @@ -277,8 +282,10 @@ This is a reference only. Each group of keys links to the page documenting their |`MAGIC_UNSWAP_BACKSLASH_BACKSPACE`| |Unswap `\` and Backspace | |`MAGIC_UNHOST_NKRO` | |Force NKRO off | |`MAGIC_UNSWAP_ALT_GUI` |`AG_NORM`|Unswap Alt and GUI on both sides | -|`MAGIC_TOGGLE_ALT_GUI` |`AG_TOGG`|Toggle Alt and GUI swap on both sides| -|`MAGIC_TOGGLE_NKRO` | |Turn NKRO on or off | +|`MAGIC_UNSWAP_CTL_GUI` |`CG_NORM`|Unswap Ctrl and GUI on both sides | +|`MAGIC_TOGGLE_ALT_GUI` |`AG_TOGG`|Toggle Alt and GUI swap on both sides | +|`MAGIC_TOGGLE_CTL_GUI` |`CG_TOGG`|Toggle Ctrl and GUI swap on both sides | +|`MAGIC_TOGGLE_NKRO` | |Turn NKRO on or off | ## [Bluetooth](feature_bluetooth.md) -- cgit v1.2.3-70-g09d2 From ad8dbd5ca5390ad9e441943b705684fce521bc15 Mon Sep 17 00:00:00 2001 From: Joel Challis Date: Tue, 24 Sep 2019 15:24:12 +0100 Subject: ARM split - Add bootmagic/magic keycodes for setting handedness (#6545) * Add docs on bootmagic/magic keycodes for setting handedness * Clang format fixes * Maintain backwards compatibility * Maintain backwards compatibility --- docs/feature_bootmagic.md | 6 ++++ docs/keycodes.md | 58 ++++++++++++++++++++------------------- quantum/quantum.c | 8 +++++- quantum/quantum_keycodes.h | 2 ++ quantum/split_common/split_util.c | 3 +- tmk_core/common/bootmagic.c | 8 ++++++ tmk_core/common/bootmagic.h | 6 ++++ tmk_core/common/eeconfig.c | 19 +++++++++++-- tmk_core/common/eeconfig.h | 3 ++ 9 files changed, 80 insertions(+), 33 deletions(-) (limited to 'docs/keycodes.md') diff --git a/docs/feature_bootmagic.md b/docs/feature_bootmagic.md index fc37a3302..ed00d5129 100644 --- a/docs/feature_bootmagic.md +++ b/docs/feature_bootmagic.md @@ -34,6 +34,8 @@ Hold down the Bootmagic key (Space by default) and the desired hotkey while plug |`X` |Toggle key matrix debugging | |`K` |Toggle keyboard debugging | |`M` |Toggle mouse debugging | +|`L` |Set "Left Hand" for EE_HANDS handedness | +|`R` |Set "Right Hand" for EE_HANDS handedness | |Backspace |Clear the EEPROM | |Caps Lock |Toggle treating Caps Lock as Left Control | |Left Control |Toggle swapping Caps Lock and Left Control | @@ -83,6 +85,8 @@ Hold down the Bootmagic key (Space by default) and the desired hotkey while plug |`MAGIC_UNSWAP_LCTL_LGUI` | |Unswap Left Control and Left GUI | |`MAGIC_SWAP_RCTL_RGUI` | |Swap Right Control and Right GUI | |`MAGIC_UNSWAP_RCTL_RGUI` | |Unswap Right Control and Right GUI | +|`MAGIC_EE_HANDS_LEFT` | |Set "Left Hand" for EE_HANDS handedness | +|`MAGIC_EE_HANDS_RIGHT` | |Set "Right Hand" for EE_HANDS handedness | ## Configuration @@ -98,6 +102,8 @@ If you would like to change the hotkey assignments for Bootmagic, `#define` thes |`BOOTMAGIC_KEY_DEBUG_MATRIX` |`KC_X` |Toggle matrix debugging | |`BOOTMAGIC_KEY_DEBUG_KEYBOARD` |`KC_K` |Toggle keyboard debugging | |`BOOTMAGIC_KEY_DEBUG_MOUSE` |`KC_M` |Toggle mouse debugging | +|`BOOTMAGIC_KEY_EE_HANDS_LEFT` |`KC_L` |Set "Left Hand" for EE_HANDS handedness | +|`BOOTMAGIC_KEY_EE_HANDS_RIGHT` |`KC_R` |Set "Right Hand" for EE_HANDS handedness | |`BOOTMAGIC_KEY_SWAP_CONTROL_CAPSLOCK` |`KC_LCTRL` |Swap Left Control and Caps Lock | |`BOOTMAGIC_KEY_CAPSLOCK_TO_CONTROL` |`KC_CAPSLOCK`|Toggle treating Caps Lock as Left Control | |`BOOTMAGIC_KEY_SWAP_LALT_LGUI` |`KC_LALT` |Toggle swapping Left Alt and Left GUI (for macOS) | diff --git a/docs/keycodes.md b/docs/keycodes.md index e17fef6fd..dfbab148b 100644 --- a/docs/keycodes.md +++ b/docs/keycodes.md @@ -257,35 +257,37 @@ This is a reference only. Each group of keys links to the page documenting their ## [Bootmagic](feature_bootmagic.md) -|Key |Aliases |Description | -|----------------------------------|---------|------------------------------------| -|`MAGIC_SWAP_CONTROL_CAPSLOCK` | |Swap Caps Lock and Left Control | -|`MAGIC_CAPSLOCK_TO_CONTROL` | |Treat Caps Lock as Control | -|`MAGIC_SWAP_LCTL_LGUI` | |Swap Left Control and GUI | -|`MAGIC_SWAP_RCTL_RGUI` | |Swap Right Control and GUI | -|`MAGIC_SWAP_LALT_LGUI` | |Swap Left Alt and GUI | -|`MAGIC_SWAP_RALT_RGUI` | |Swap Right Alt and GUI | -|`MAGIC_NO_GUI` | |Disable the GUI key | -|`MAGIC_SWAP_GRAVE_ESC` | |Swap ` and Escape | -|`MAGIC_SWAP_BACKSLASH_BACKSPACE` | |Swap `\` and Backspace | -|`MAGIC_HOST_NKRO` | |Force NKRO on | -|`MAGIC_SWAP_ALT_GUI` |`AG_SWAP`|Swap Alt and GUI on both sides | +|Key |Aliases |Description | +|----------------------------------|---------|-------------------------------------------| +|`MAGIC_SWAP_CONTROL_CAPSLOCK` | |Swap Caps Lock and Left Control | +|`MAGIC_CAPSLOCK_TO_CONTROL` | |Treat Caps Lock as Control | +|`MAGIC_SWAP_LCTL_LGUI` | |Swap Left Control and GUI | +|`MAGIC_SWAP_RCTL_RGUI` | |Swap Right Control and GUI | +|`MAGIC_SWAP_LALT_LGUI` | |Swap Left Alt and GUI | +|`MAGIC_SWAP_RALT_RGUI` | |Swap Right Alt and GUI | +|`MAGIC_NO_GUI` | |Disable the GUI key | +|`MAGIC_SWAP_GRAVE_ESC` | |Swap ` and Escape | +|`MAGIC_SWAP_BACKSLASH_BACKSPACE` | |Swap `\` and Backspace | +|`MAGIC_HOST_NKRO` | |Force NKRO on | +|`MAGIC_SWAP_ALT_GUI` |`AG_SWAP`|Swap Alt and GUI on both sides | |`MAGIC_SWAP_CTL_GUI` |`CG_SWAP`|Swap Ctrl and GUI on both sides (for macOS)| -|`MAGIC_UNSWAP_CONTROL_CAPSLOCK` | |Unswap Caps Lock and Left Control | -|`MAGIC_UNCAPSLOCK_TO_CONTROL` | |Stop treating Caps Lock as Control | -|`MAGIC_UNSWAP_LCTL_LGUI` | |Unswap Left Control and GUI | -|`MAGIC_UNSWAP_RCTL_RGUI` | |Unswap Right Control and GUI | -|`MAGIC_UNSWAP_LALT_LGUI` | |Unswap Left Alt and GUI | -|`MAGIC_UNSWAP_RALT_RGUI` | |Unswap Right Alt and GUI | -|`MAGIC_UNNO_GUI` | |Enable the GUI key | -|`MAGIC_UNSWAP_GRAVE_ESC` | |Unswap ` and Escape| -|`MAGIC_UNSWAP_BACKSLASH_BACKSPACE`| |Unswap `\` and Backspace | -|`MAGIC_UNHOST_NKRO` | |Force NKRO off | -|`MAGIC_UNSWAP_ALT_GUI` |`AG_NORM`|Unswap Alt and GUI on both sides | -|`MAGIC_UNSWAP_CTL_GUI` |`CG_NORM`|Unswap Ctrl and GUI on both sides | -|`MAGIC_TOGGLE_ALT_GUI` |`AG_TOGG`|Toggle Alt and GUI swap on both sides | -|`MAGIC_TOGGLE_CTL_GUI` |`CG_TOGG`|Toggle Ctrl and GUI swap on both sides | -|`MAGIC_TOGGLE_NKRO` | |Turn NKRO on or off | +|`MAGIC_UNSWAP_CONTROL_CAPSLOCK` | |Unswap Caps Lock and Left Control | +|`MAGIC_UNCAPSLOCK_TO_CONTROL` | |Stop treating Caps Lock as Control | +|`MAGIC_UNSWAP_LCTL_LGUI` | |Unswap Left Control and GUI | +|`MAGIC_UNSWAP_RCTL_RGUI` | |Unswap Right Control and GUI | +|`MAGIC_UNSWAP_LALT_LGUI` | |Unswap Left Alt and GUI | +|`MAGIC_UNSWAP_RALT_RGUI` | |Unswap Right Alt and GUI | +|`MAGIC_UNNO_GUI` | |Enable the GUI key | +|`MAGIC_UNSWAP_GRAVE_ESC` | |Unswap ` and Escape | +|`MAGIC_UNSWAP_BACKSLASH_BACKSPACE`| |Unswap `\` and Backspace | +|`MAGIC_UNHOST_NKRO` | |Force NKRO off | +|`MAGIC_UNSWAP_ALT_GUI` |`AG_NORM`|Unswap Alt and GUI on both sides | +|`MAGIC_UNSWAP_CTL_GUI` |`CG_NORM`|Unswap Ctrl and GUI on both sides | +|`MAGIC_TOGGLE_ALT_GUI` |`AG_TOGG`|Toggle Alt and GUI swap on both sides | +|`MAGIC_TOGGLE_CTL_GUI` |`CG_TOGG`|Toggle Ctrl and GUI swap on both sides | +|`MAGIC_TOGGLE_NKRO` | |Turn NKRO on or off | +|`MAGIC_EE_HANDS_LEFT` | |Set "Left Hand" for EE_HANDS handedness | +|`MAGIC_EE_HANDS_RIGHT` | |Set "Right Hand" for EE_HANDS handedness | ## [Bluetooth](feature_bluetooth.md) diff --git a/quantum/quantum.c b/quantum/quantum.c index ec80fa557..16922dd01 100644 --- a/quantum/quantum.c +++ b/quantum/quantum.c @@ -544,7 +544,7 @@ bool process_record_quantum(keyrecord_t *record) { # endif #endif case MAGIC_SWAP_CONTROL_CAPSLOCK ... MAGIC_TOGGLE_ALT_GUI: - case MAGIC_SWAP_LCTL_LGUI ... MAGIC_TOGGLE_CTL_GUI: + case MAGIC_SWAP_LCTL_LGUI ... MAGIC_EE_HANDS_RIGHT: if (record->event.pressed) { // MAGIC actions (BOOTMAGIC without the boot) if (!eeconfig_is_enabled()) { @@ -662,6 +662,12 @@ bool process_record_quantum(keyrecord_t *record) { case MAGIC_TOGGLE_NKRO: keymap_config.nkro = !keymap_config.nkro; break; + case MAGIC_EE_HANDS_LEFT: + eeconfig_update_handedness(true); + break; + case MAGIC_EE_HANDS_RIGHT: + eeconfig_update_handedness(false); + break; default: break; } diff --git a/quantum/quantum_keycodes.h b/quantum/quantum_keycodes.h index af984a7cd..5fac6a5ca 100644 --- a/quantum/quantum_keycodes.h +++ b/quantum/quantum_keycodes.h @@ -502,6 +502,8 @@ enum quantum_keycodes { MAGIC_SWAP_CTL_GUI, MAGIC_UNSWAP_CTL_GUI, MAGIC_TOGGLE_CTL_GUI, + MAGIC_EE_HANDS_LEFT, + MAGIC_EE_HANDS_RIGHT, // always leave at the end SAFE_RANGE diff --git a/quantum/split_common/split_util.c b/quantum/split_common/split_util.c index 5114b188e..d16a98977 100644 --- a/quantum/split_common/split_util.c +++ b/quantum/split_common/split_util.c @@ -7,7 +7,6 @@ #include "quantum.h" #ifdef EE_HANDS -# include "tmk_core/common/eeprom.h" # include "eeconfig.h" #endif @@ -23,7 +22,7 @@ __attribute__((weak)) bool is_keyboard_left(void) { setPinInput(SPLIT_HAND_PIN); return readPin(SPLIT_HAND_PIN); #elif defined(EE_HANDS) - return eeprom_read_byte(EECONFIG_HANDEDNESS); + return eeconfig_read_handedness(); #elif defined(MASTER_RIGHT) return !is_keyboard_master(); #endif diff --git a/tmk_core/common/bootmagic.c b/tmk_core/common/bootmagic.c index 09b1664c9..bb2aa0db8 100644 --- a/tmk_core/common/bootmagic.c +++ b/tmk_core/common/bootmagic.c @@ -122,6 +122,14 @@ void bootmagic(void) { default_layer = eeconfig_read_default_layer(); default_layer_set((layer_state_t)default_layer); } + + /* EE_HANDS handedness */ + if (bootmagic_scan_keycode(BOOTMAGIC_KEY_EE_HANDS_LEFT)) { + eeconfig_update_handedness(true); + } + if (bootmagic_scan_keycode(BOOTMAGIC_KEY_EE_HANDS_RIGHT)) { + eeconfig_update_handedness(false); + } } /** \brief Scan Keycode diff --git a/tmk_core/common/bootmagic.h b/tmk_core/common/bootmagic.h index fb7647257..c64dc1785 100644 --- a/tmk_core/common/bootmagic.h +++ b/tmk_core/common/bootmagic.h @@ -36,6 +36,12 @@ #ifndef BOOTMAGIC_KEY_DEBUG_MOUSE # define BOOTMAGIC_KEY_DEBUG_MOUSE KC_M #endif +#ifndef BOOTMAGIC_KEY_EE_HANDS_LEFT +# define BOOTMAGIC_KEY_EE_HANDS_LEFT KC_L +#endif +#ifndef BOOTMAGIC_KEY_EE_HANDS_RIGHT +# define BOOTMAGIC_KEY_EE_HANDS_RIGHT KC_R +#endif /* * keymap config diff --git a/tmk_core/common/eeconfig.c b/tmk_core/common/eeconfig.c index 61aaec205..933ac42bd 100644 --- a/tmk_core/common/eeconfig.c +++ b/tmk_core/common/eeconfig.c @@ -153,8 +153,8 @@ uint32_t eeconfig_read_kb(void) { return eeprom_read_dword(EECONFIG_KEYBOARD); } * * FIXME: needs doc */ - void eeconfig_update_kb(uint32_t val) { eeprom_update_dword(EECONFIG_KEYBOARD, val); } + /** \brief eeconfig read user * * FIXME: needs doc @@ -166,9 +166,24 @@ uint32_t eeconfig_read_user(void) { return eeprom_read_dword(EECONFIG_USER); } */ void eeconfig_update_user(uint32_t val) { eeprom_update_dword(EECONFIG_USER, val); } +/** \brief eeconfig read haptic + * + * FIXME: needs doc + */ uint32_t eeconfig_read_haptic(void) { return eeprom_read_dword(EECONFIG_HAPTIC); } -/** \brief eeconfig update user +/** \brief eeconfig update haptic * * FIXME: needs doc */ void eeconfig_update_haptic(uint32_t val) { eeprom_update_dword(EECONFIG_HAPTIC, val); } + +/** \brief eeconfig read split handedness + * + * FIXME: needs doc + */ +bool eeconfig_read_handedness(void) { return !!eeprom_read_byte(EECONFIG_HANDEDNESS); } +/** \brief eeconfig update split handedness + * + * FIXME: needs doc + */ +void eeconfig_update_handedness(bool val) { eeprom_update_byte(EECONFIG_HANDEDNESS, !!val); } diff --git a/tmk_core/common/eeconfig.h b/tmk_core/common/eeconfig.h index aea4eff9f..308f865e1 100644 --- a/tmk_core/common/eeconfig.h +++ b/tmk_core/common/eeconfig.h @@ -107,4 +107,7 @@ uint32_t eeconfig_read_haptic(void); void eeconfig_update_haptic(uint32_t val); #endif +bool eeconfig_read_handedness(void); +void eeconfig_update_handedness(bool val); + #endif -- cgit v1.2.3-70-g09d2 From 40de65eac4e8d039470b91a678cd1f7fc83fc929 Mon Sep 17 00:00:00 2001 From: fauxpark Date: Sat, 26 Oct 2019 16:10:03 +1100 Subject: Backslash-escape pipe character in keycode lists (#7157) --- docs/keycodes.md | 52 ++++++++++++++++++++-------------------- docs/keycodes_basic.md | 44 +++++++++++++++++----------------- docs/keycodes_us_ansi_shifted.md | 46 +++++++++++++++++------------------ 3 files changed, 71 insertions(+), 71 deletions(-) (limited to 'docs/keycodes.md') diff --git a/docs/keycodes.md b/docs/keycodes.md index dfbab148b..60f14844c 100644 --- a/docs/keycodes.md +++ b/docs/keycodes.md @@ -55,7 +55,7 @@ This is a reference only. Each group of keys links to the page documenting their |`KC_EQUAL` |`KC_EQL` |`=` and `+` | |`KC_LBRACKET` |`KC_LBRC` |`[` and `{` | |`KC_RBRACKET` |`KC_RBRC` |`]` and `}` | -|`KC_BSLASH` |`KC_BSLS` |`\` and | | +|`KC_BSLASH` |`KC_BSLS` |`\` and `\|` | |`KC_NONUS_HASH` |`KC_NUHS` |Non-US `#` and `~` | |`KC_SCOLON` |`KC_SCLN` |`;` and `:` | |`KC_QUOTE` |`KC_QUOT` |`'` and `"` | @@ -106,7 +106,7 @@ This is a reference only. Each group of keys links to the page documenting their |`KC_KP_9` |`KC_P9` |Keypad `9` and Page Up | |`KC_KP_0` |`KC_P0` |Keypad `0` and Insert | |`KC_KP_DOT` |`KC_PDOT` |Keypad `.` and Delete | -|`KC_NONUS_BSLASH` |`KC_NUBS` |Non-US `\` and | | +|`KC_NONUS_BSLASH` |`KC_NUBS` |Non-US `\` and `\|` | |`KC_APPLICATION` |`KC_APP` |Application (Windows Menu Key) | |`KC_POWER` | |System Power (macOS) | |`KC_KP_EQUAL` |`KC_PEQL` |Keypad `=` | @@ -143,7 +143,7 @@ This is a reference only. Each group of keys links to the page documenting their |`KC_KP_EQUAL_AS400` | |Keypad `=` on AS/400 keyboards | |`KC_INT1` |`KC_RO` |JIS `\` and `_` | |`KC_INT2` |`KC_KANA` |JIS Katakana/Hiragana | -|`KC_INT3` |`KC_JYEN` |JIS `¥` and | | +|`KC_INT3` |`KC_JYEN` |JIS `¥` and `\|` | |`KC_INT4` |`KC_HENK` |JIS Henkan | |`KC_INT5` |`KC_MHEN` |JIS Muhenkan | |`KC_INT6` | |JIS Numpad `,` | @@ -420,29 +420,29 @@ This is a reference only. Each group of keys links to the page documenting their ## [US ANSI Shifted Symbols](keycodes_us_ansi_shifted.md) -|Key |Aliases |Description | -|------------------------|-------------------|-------------------| -|`KC_TILDE` |`KC_TILD` |`~` | -|`KC_EXCLAIM` |`KC_EXLM` |`!` | -|`KC_AT` | |`@` | -|`KC_HASH` | |`#` | -|`KC_DOLLAR` |`KC_DLR` |`$` | -|`KC_PERCENT` |`KC_PERC` |`%` | -|`KC_CIRCUMFLEX` |`KC_CIRC` |`^` | -|`KC_AMPERSAND` |`KC_AMPR` |`&` | -|`KC_ASTERISK` |`KC_ASTR` |`*` | -|`KC_LEFT_PAREN` |`KC_LPRN` |`(` | -|`KC_RIGHT_PAREN` |`KC_RPRN` |`)` | -|`KC_UNDERSCORE` |`KC_UNDS` |`_` | -|`KC_PLUS` | |`+` | -|`KC_LEFT_CURLY_BRACE` |`KC_LCBR` |`{` | -|`KC_RIGHT_CURLY_BRACE` |`KC_RCBR` |`}` | -|`KC_PIPE` | ||| -|`KC_COLON` |`KC_COLN` |`:` | -|`KC_DOUBLE_QUOTE` |`KC_DQUO`, `KC_DQT`|`"` | -|`KC_LEFT_ANGLE_BRACKET` |`KC_LABK`, `KC_LT` |`<` | -|`KC_RIGHT_ANGLE_BRACKET`|`KC_RABK`, `KC_GT` |`>` | -|`KC_QUESTION` |`KC_QUES` |`?` | +|Key |Aliases |Description| +|------------------------|-------------------|-----------| +|`KC_TILDE` |`KC_TILD` |`~` | +|`KC_EXCLAIM` |`KC_EXLM` |`!` | +|`KC_AT` | |`@` | +|`KC_HASH` | |`#` | +|`KC_DOLLAR` |`KC_DLR` |`$` | +|`KC_PERCENT` |`KC_PERC` |`%` | +|`KC_CIRCUMFLEX` |`KC_CIRC` |`^` | +|`KC_AMPERSAND` |`KC_AMPR` |`&` | +|`KC_ASTERISK` |`KC_ASTR` |`*` | +|`KC_LEFT_PAREN` |`KC_LPRN` |`(` | +|`KC_RIGHT_PAREN` |`KC_RPRN` |`)` | +|`KC_UNDERSCORE` |`KC_UNDS` |`_` | +|`KC_PLUS` | |`+` | +|`KC_LEFT_CURLY_BRACE` |`KC_LCBR` |`{` | +|`KC_RIGHT_CURLY_BRACE` |`KC_RCBR` |`}` | +|`KC_PIPE` | |`\|` | +|`KC_COLON` |`KC_COLN` |`:` | +|`KC_DOUBLE_QUOTE` |`KC_DQUO`, `KC_DQT`|`"` | +|`KC_LEFT_ANGLE_BRACKET` |`KC_LABK`, `KC_LT` |`<` | +|`KC_RIGHT_ANGLE_BRACKET`|`KC_RABK`, `KC_GT` |`>` | +|`KC_QUESTION` |`KC_QUES` |`?` | ## [One Shot Keys](feature_advanced_keycodes.md#one-shot-keys) diff --git a/docs/keycodes_basic.md b/docs/keycodes_basic.md index 6f21cabd2..8b1b52e19 100644 --- a/docs/keycodes_basic.md +++ b/docs/keycodes_basic.md @@ -85,7 +85,7 @@ The basic set of keycodes are based on the [HID Keyboard/Keypad Usage Page (0x07 |`KC_EQUAL` |`KC_EQL` |`=` and `+` | |`KC_LBRACKET` |`KC_LBRC` |`[` and `{` | |`KC_RBRACKET` |`KC_RBRC` |`]` and `}` | -|`KC_BSLASH` |`KC_BSLS` |`\` and | | +|`KC_BSLASH` |`KC_BSLS` |`\` and `\|` | |`KC_NONUS_HASH` |`KC_NUHS` |Non-US `#` and `~` | |`KC_SCOLON` |`KC_SCLN` |`;` and `:` | |`KC_QUOTE` |`KC_QUOT` |`'` and `"` | @@ -93,7 +93,7 @@ The basic set of keycodes are based on the [HID Keyboard/Keypad Usage Page (0x07 |`KC_COMMA` |`KC_COMM` |`,` and `<` | |`KC_DOT` | |`.` and `>` | |`KC_SLASH` |`KC_SLSH` |`/` and `?` | -|`KC_NONUS_BSLASH`|`KC_NUBS` |Non-US `\` and | | +|`KC_NONUS_BSLASH`|`KC_NUBS` |Non-US `\` and `\|` | ## Lock Keys @@ -121,26 +121,26 @@ The basic set of keycodes are based on the [HID Keyboard/Keypad Usage Page (0x07 ## International -|Key |Aliases |Description | -|----------|---------|-------------------------------| -|`KC_INT1` |`KC_RO` |JIS `\` and `_` | -|`KC_INT2` |`KC_KANA`|JIS Katakana/Hiragana | -|`KC_INT3` |`KC_JYEN`|JIS `¥` and || -|`KC_INT4` |`KC_HENK`|JIS Henkan | -|`KC_INT5` |`KC_MHEN`|JIS Muhenkan | -|`KC_INT6` | |JIS Numpad `,` | -|`KC_INT7` | |International 7 | -|`KC_INT8` | |International 8 | -|`KC_INT9` | |International 9 | -|`KC_LANG1`|`KC_HAEN`|Hangul/English | -|`KC_LANG2`|`KC_HANJ`|Hanja | -|`KC_LANG3`| |JIS Katakana | -|`KC_LANG4`| |JIS Hiragana | -|`KC_LANG5`| |JIS Zenkaku/Hankaku | -|`KC_LANG6`| |Language 6 | -|`KC_LANG7`| |Language 7 | -|`KC_LANG8`| |Language 8 | -|`KC_LANG9`| |Language 9 | +|Key |Aliases |Description | +|----------|---------|---------------------| +|`KC_INT1` |`KC_RO` |JIS `\` and `_` | +|`KC_INT2` |`KC_KANA`|JIS Katakana/Hiragana| +|`KC_INT3` |`KC_JYEN`|JIS `¥` and `\|` | +|`KC_INT4` |`KC_HENK`|JIS Henkan | +|`KC_INT5` |`KC_MHEN`|JIS Muhenkan | +|`KC_INT6` | |JIS Numpad `,` | +|`KC_INT7` | |International 7 | +|`KC_INT8` | |International 8 | +|`KC_INT9` | |International 9 | +|`KC_LANG1`|`KC_HAEN`|Hangul/English | +|`KC_LANG2`|`KC_HANJ`|Hanja | +|`KC_LANG3`| |JIS Katakana | +|`KC_LANG4`| |JIS Hiragana | +|`KC_LANG5`| |JIS Zenkaku/Hankaku | +|`KC_LANG6`| |Language 6 | +|`KC_LANG7`| |Language 7 | +|`KC_LANG8`| |Language 8 | +|`KC_LANG9`| |Language 9 | ## Commands diff --git a/docs/keycodes_us_ansi_shifted.md b/docs/keycodes_us_ansi_shifted.md index 41d603592..85dd61759 100644 --- a/docs/keycodes_us_ansi_shifted.md +++ b/docs/keycodes_us_ansi_shifted.md @@ -12,26 +12,26 @@ To fix this, open Remote Desktop Connection, click on "Show Options", open the t ## Keycodes -|Key |Aliases |Description | -|------------------------|-------------------|-------------------| -|`KC_TILDE` |`KC_TILD` |`~` | -|`KC_EXCLAIM` |`KC_EXLM` |`!` | -|`KC_AT` | |`@` | -|`KC_HASH` | |`#` | -|`KC_DOLLAR` |`KC_DLR` |`$` | -|`KC_PERCENT` |`KC_PERC` |`%` | -|`KC_CIRCUMFLEX` |`KC_CIRC` |`^` | -|`KC_AMPERSAND` |`KC_AMPR` |`&` | -|`KC_ASTERISK` |`KC_ASTR` |`*` | -|`KC_LEFT_PAREN` |`KC_LPRN` |`(` | -|`KC_RIGHT_PAREN` |`KC_RPRN` |`)` | -|`KC_UNDERSCORE` |`KC_UNDS` |`_` | -|`KC_PLUS` | |`+` | -|`KC_LEFT_CURLY_BRACE` |`KC_LCBR` |`{` | -|`KC_RIGHT_CURLY_BRACE` |`KC_RCBR` |`}` | -|`KC_PIPE` | ||| -|`KC_COLON` |`KC_COLN` |`:` | -|`KC_DOUBLE_QUOTE` |`KC_DQUO`, `KC_DQT`|`"` | -|`KC_LEFT_ANGLE_BRACKET` |`KC_LABK`, `KC_LT` |`<` | -|`KC_RIGHT_ANGLE_BRACKET`|`KC_RABK`, `KC_GT` |`>` | -|`KC_QUESTION` |`KC_QUES` |`?` | +|Key |Aliases |Description| +|------------------------|-------------------|-----------| +|`KC_TILDE` |`KC_TILD` |`~` | +|`KC_EXCLAIM` |`KC_EXLM` |`!` | +|`KC_AT` | |`@` | +|`KC_HASH` | |`#` | +|`KC_DOLLAR` |`KC_DLR` |`$` | +|`KC_PERCENT` |`KC_PERC` |`%` | +|`KC_CIRCUMFLEX` |`KC_CIRC` |`^` | +|`KC_AMPERSAND` |`KC_AMPR` |`&` | +|`KC_ASTERISK` |`KC_ASTR` |`*` | +|`KC_LEFT_PAREN` |`KC_LPRN` |`(` | +|`KC_RIGHT_PAREN` |`KC_RPRN` |`)` | +|`KC_UNDERSCORE` |`KC_UNDS` |`_` | +|`KC_PLUS` | |`+` | +|`KC_LEFT_CURLY_BRACE` |`KC_LCBR` |`{` | +|`KC_RIGHT_CURLY_BRACE` |`KC_RCBR` |`}` | +|`KC_PIPE` | |`\|` | +|`KC_COLON` |`KC_COLN` |`:` | +|`KC_DOUBLE_QUOTE` |`KC_DQUO`, `KC_DQT`|`"` | +|`KC_LEFT_ANGLE_BRACKET` |`KC_LABK`, `KC_LT` |`<` | +|`KC_RIGHT_ANGLE_BRACKET`|`KC_RABK`, `KC_GT` |`>` | +|`KC_QUESTION` |`KC_QUES` |`?` | -- cgit v1.2.3-70-g09d2 From 606813b72dc8645d59afb51775e6554b6c97769d Mon Sep 17 00:00:00 2001 From: Steve Purcell Date: Wed, 30 Oct 2019 12:39:38 +1300 Subject: Remove obsolete note about media keys in MacOS (#6631) * Remove obsolete note about media keys in MacOS KC_MNXT and KC_MPRV work fine on MacOS, so this note is obsolete. * Document behaviour of MEDIA_FAST_FORWARD/MEDIA_REWIND codes on MacOS * Small typo fix, and make OS-dependent keycode claim less absolute * Update docs/keycodes_basic.md Co-Authored-By: fauxpark --- docs/faq_keymap.md | 7 ------- docs/keycodes.md | 4 ++-- docs/keycodes_basic.md | 6 +++--- 3 files changed, 5 insertions(+), 12 deletions(-) (limited to 'docs/keycodes.md') diff --git a/docs/faq_keymap.md b/docs/faq_keymap.md index 0a627469e..84d8548d4 100644 --- a/docs/faq_keymap.md +++ b/docs/faq_keymap.md @@ -95,13 +95,6 @@ Even worse, it is not recognized unless the keyboard's VID and PID match that of See [this issue](https://github.com/qmk/qmk_firmware/issues/2179) for detailed information. - -## Media Control Keys in Mac OSX -#### KC_MNXT and KC_MPRV Does Not Work on Mac -Use `KC_MFFD`(`KC_MEDIA_FAST_FORWARD`) and `KC_MRWD`(`KC_MEDIA_REWIND`) instead of `KC_MNXT` and `KC_MPRV`. -See https://github.com/tmk/tmk_keyboard/issues/195 - - ## Keys Supported in Mac OSX? You can know which keycodes are supported in OSX from this source code. diff --git a/docs/keycodes.md b/docs/keycodes.md index 60f14844c..7dcff03fd 100644 --- a/docs/keycodes.md +++ b/docs/keycodes.md @@ -185,8 +185,8 @@ This is a reference only. Each group of keys links to the page documenting their |`KC_AUDIO_MUTE` |`KC_MUTE` |Mute | |`KC_AUDIO_VOL_UP` |`KC_VOLU` |Volume Up | |`KC_AUDIO_VOL_DOWN` |`KC_VOLD` |Volume Down | -|`KC_MEDIA_NEXT_TRACK` |`KC_MNXT` |Next Track (Windows) | -|`KC_MEDIA_PREV_TRACK` |`KC_MPRV` |Previous Track (Windows) | +|`KC_MEDIA_NEXT_TRACK` |`KC_MNXT` |Next Track | +|`KC_MEDIA_PREV_TRACK` |`KC_MPRV` |Previous Track | |`KC_MEDIA_STOP` |`KC_MSTP` |Stop Track (Windows) | |`KC_MEDIA_PLAY_PAUSE` |`KC_MPLY` |Play/Pause Track | |`KC_MEDIA_SELECT` |`KC_MSEL` |Launch Media Player (Windows) | diff --git a/docs/keycodes_basic.md b/docs/keycodes_basic.md index 8b1b52e19..75d58c1f1 100644 --- a/docs/keycodes_basic.md +++ b/docs/keycodes_basic.md @@ -191,7 +191,7 @@ The basic set of keycodes are based on the [HID Keyboard/Keypad Usage Page (0x07 These keycodes are not part of the Keyboard/Keypad usage page. The `SYSTEM_` keycodes are found in the Generic Desktop page, and the rest are located in the Consumer page. -Windows and macOS use different keycodes for "next track" and "previous track". Make sure you choose the keycode that corresponds to your OS. +?> Some of these keycodes may behave differently depending on the OS. For example, on macOS, the keycodes `KC_MEDIA_FAST_FORWARD`, `KC_MEDIA_REWIND`, `KC_MEDIA_NEXT_TRACK` and `KC_MEDIA_PREV_TRACK` skip within the current track when held, but skip the entire track when tapped. |Key |Aliases |Description | |-----------------------|---------|-----------------------------| @@ -201,8 +201,8 @@ Windows and macOS use different keycodes for "next track" and "previous track". |`KC_AUDIO_MUTE` |`KC_MUTE`|Mute | |`KC_AUDIO_VOL_UP` |`KC_VOLU`|Volume Up | |`KC_AUDIO_VOL_DOWN` |`KC_VOLD`|Volume Down | -|`KC_MEDIA_NEXT_TRACK` |`KC_MNXT`|Next Track (Windows) | -|`KC_MEDIA_PREV_TRACK` |`KC_MPRV`|Previous Track (Windows) | +|`KC_MEDIA_NEXT_TRACK` |`KC_MNXT`|Next Track | +|`KC_MEDIA_PREV_TRACK` |`KC_MPRV`|Previous Track | |`KC_MEDIA_STOP` |`KC_MSTP`|Stop Track (Windows) | |`KC_MEDIA_PLAY_PAUSE` |`KC_MPLY`|Play/Pause Track | |`KC_MEDIA_SELECT` |`KC_MSEL`|Launch Media Player (Windows)| -- cgit v1.2.3-70-g09d2 From 542cb0a8ce3f324c6bd46751d733daf86384a8f6 Mon Sep 17 00:00:00 2001 From: Drashna Jaelre Date: Mon, 4 Nov 2019 22:59:13 -0800 Subject: [Core] Convert Dynamic Macro to a Core Feature (#5948) * Convert Dynamic Macro to a Core Feature This imports the code from Dynamic Macro into the core code, and handles it, as such. This deprecates the old method but does not remove it, for legacy support. This way, no existing user files need to be touched. Additionally, this reorganizes the documentation to better reflect the changes. Also, it adds user hooks to the feature so users can customize the existing functionality. Based heavily on and closes #2976 * Apply suggestions from code review Co-Authored-By: fauxpark Co-Authored-By: noroadsleft <18669334+noroadsleft@users.noreply.github.com> * Cleanup based on feedback * Add short-form keycodes and document them - add short-form keycodes to quantum/quantum_keycodes.h - document the new aliases in docs/feature_dynamic_macros.md * Add Dynamic Macros section and keycodes to docs/keycodes.md * Make anti-nesting optional * Add documentation for DYNAMIC_MACRO_NO_NESTING option * Fix Merge artifacts * Fix formatting typo in docs Co-Authored-By: James Young <18669334+noroadsleft@users.noreply.github.com> * Remove DYNAMIC_MACRO_RANGE as it's not needed * Fix includes and layer var type --- common_features.mk | 6 +- docs/feature_dynamic_macros.md | 75 +++---- docs/keycodes.md | 10 + quantum/dynamic_macro.h | 20 +- quantum/process_keycode/process_dynamic_macro.c | 257 ++++++++++++++++++++++++ quantum/process_keycode/process_dynamic_macro.h | 41 ++++ quantum/quantum.c | 14 +- quantum/quantum.h | 4 + quantum/quantum_keycodes.h | 16 +- 9 files changed, 384 insertions(+), 59 deletions(-) create mode 100644 quantum/process_keycode/process_dynamic_macro.c create mode 100644 quantum/process_keycode/process_dynamic_macro.h (limited to 'docs/keycodes.md') diff --git a/common_features.mk b/common_features.mk index a1f95955a..e50207b0b 100644 --- a/common_features.mk +++ b/common_features.mk @@ -407,8 +407,12 @@ ifeq ($(strip $(SPACE_CADET_ENABLE)), yes) OPT_DEFS += -DSPACE_CADET_ENABLE endif - ifeq ($(strip $(DIP_SWITCH_ENABLE)), yes) SRC += $(QUANTUM_DIR)/dip_switch.c OPT_DEFS += -DDIP_SWITCH_ENABLE endif + +ifeq ($(strip $(DYNAMIC_MACRO_ENABLE)), yes) + SRC += $(QUANTUM_DIR)/process_keycode/process_dynamic_macro.c + OPT_DEFS += -DDYNAMIC_MACRO_ENABLE +endif diff --git a/docs/feature_dynamic_macros.md b/docs/feature_dynamic_macros.md index 0d11a2864..b86df6c60 100644 --- a/docs/feature_dynamic_macros.md +++ b/docs/feature_dynamic_macros.md @@ -4,51 +4,45 @@ QMK supports temporary macros created on the fly. We call these Dynamic Macros. You can store one or two macros and they may have a combined total of 128 keypresses. You can increase this size at the cost of RAM. -To enable them, first add a new element to the end of your `keycodes` enum — `DYNAMIC_MACRO_RANGE`: +To enable them, first include `DYNAMIC_MACRO_ENABLE = yes` in your `rules.mk`. Then, add the following keys to your keymap: -```c -enum keycodes { - QWERTY = SAFE_RANGE, - COLEMAK, - DVORAK, - PLOVER, - LOWER, - RAISE, - BACKLIT, - EXT_PLV, - DYNAMIC_MACRO_RANGE, -}; -``` +|Key |Alias |Description | +|------------------|----------|---------------------------------------------------| +|`DYN_REC_START1` |`DM_REC1` |Start recording Macro 1 | +|`DYN_REC_START2` |`DM_REC2` |Start recording Macro 2 | +|`DYN_MACRO_PLAY1` |`DM_PLY1` |Replay Macro 1 | +|`DYN_MACRO_PLAY2` |`DM_PLY2` |Replay Macro 2 | +|`DYN_REC_STOP` |`DM_RSTP` |Finish the macro that is currently being recorded. | -Your `keycodes` enum may have a slightly different name. You must add `DYNAMIC_MACRO_RANGE` as the last element because `dynamic_macros.h` will add some more keycodes after it. +That should be everything necessary. -Below it, include the `dynamic_macro.h` header: +To start recording the macro, press either `DYN_REC_START1` or `DYN_REC_START2`. -```c - #include "dynamic_macro.h"` -``` +To finish the recording, press the `DYN_REC_STOP` layer button. -Add the following keys to your keymap: +To replay the macro, press either `DYN_MACRO_PLAY1` or `DYN_MACRO_PLAY2`. -* `DYN_REC_START1` — start recording the macro 1, -* `DYN_REC_START2` — start recording the macro 2, -* `DYN_MACRO_PLAY1` — replay the macro 1, -* `DYN_MACRO_PLAY2` — replay the macro 2, -* `DYN_REC_STOP` — finish the macro that is currently being recorded. +It is possible to replay a macro as part of a macro. It's ok to replay macro 2 while recording macro 1 and vice versa but never create recursive macros i.e. macro 1 that replays macro 1. If you do so and the keyboard will get unresponsive, unplug the keyboard and plug it again. You can disable this completly by defining `DYNAMIC_MACRO_NO_NESTING` in your `config.h` file. -Add the following code to the very beginning of your `process_record_user()` function: +?> For the details about the internals of the dynamic macros, please read the comments in the `process_dynamic_macro.h` and `process_dynamic_macro.c` files. -```c - if (!process_record_dynamic_macro(keycode, record)) { - return false; - } -``` +## Customization -That should be everything necessary. To start recording the macro, press either `DYN_REC_START1` or `DYN_REC_START2`. To finish the recording, press the `DYN_REC_STOP` layer button. To replay the macro, press either `DYN_MACRO_PLAY1` or `DYN_MACRO_PLAY2`. +There are a number of options added that should allow some additional degree of customization -Note that it's possible to replay a macro as part of a macro. It's ok to replay macro 2 while recording macro 1 and vice versa but never create recursive macros i.e. macro 1 that replays macro 1. If you do so and the keyboard will get unresponsive, unplug the keyboard and plug it again. +|Define |Default |Description | +|----------------------------|----------------|-----------------------------------------------------------------------------------------------------------------| +|`DYNAMIC_MACRO_SIZE` |128 |Sets the amount of memory that Dynamic Macros can use. This is a limited resource, dependent on the controller. | +|`DYNAMIC_MACRO_USER_CALL` |*Not defined* |Defining this falls back to using the user `keymap.c` file to trigger the macro behavior. | +|`DYNAMIC_MACRO_NO_NESTING` |*Not Defined* |Defining this disables the ability to call a macro from another macro (nested macros). | -For users of the earlier versions of dynamic macros: It is still possible to finish the macro recording using just the layer modifier used to access the dynamic macro keys, without a dedicated `DYN_REC_STOP` key. If you want this behavior back, use the following snippet instead of the one above: + +If the LEDs start blinking during the recording with each keypress, it means there is no more space for the macro in the macro buffer. To fit the macro in, either make the other macro shorter (they share the same buffer) or increase the buffer size by adding the `DYNAMIC_MACRO_SIZE` define in your `config.h` (default value: 128; please read the comments for it in the header). + + +### DYNAMIC_MACRO_USER_CALL + +For users of the earlier versions of dynamic macros: It is still possible to finish the macro recording using just the layer modifier used to access the dynamic macro keys, without a dedicated `DYN_REC_STOP` key. If you want this behavior back, add `#define DYNAMIC_MACRO_USER_CALL` to your `config.h` and insert the following snippet at the beginning of your `process_record_user()` function: ```c uint16_t macro_kc = (keycode == MO(_DYN) ? DYN_REC_STOP : keycode); @@ -58,6 +52,15 @@ For users of the earlier versions of dynamic macros: It is still possible to fin } ``` -If the LEDs start blinking during the recording with each keypress, it means there is no more space for the macro in the macro buffer. To fit the macro in, either make the other macro shorter (they share the same buffer) or increase the buffer size by setting the `DYNAMIC_MACRO_SIZE` preprocessor macro (default value: 128; please read the comments for it in the header). +### User Hooks + +There are a number of hooks that you can use to add custom functionality and feedback options to Dynamic Macro feature. This allows for some additional degree of customization. + +Note, that direction indicates which macro it is, with `1` being Macro 1, `-1` being Macro 2, and 0 being no macro. + +* `dynamic_macro_record_start_user(void)` - Triggered when you start recording a macro. +* `dynamic_macro_play_user(int8_t direction)` - Triggered when you play back a macro. +* `dynamic_macro_record_key_user(int8_t direction, keyrecord_t *record)` - Triggered on each keypress while recording a macro. +* `dynamic_macro_record_end_user(int8_t direction)` - Triggered when the macro recording is stopped. -For the details about the internals of the dynamic macros, please read the comments in the `dynamic_macro.h` header. +Additionally, you can call `dynamic_macro_led_blink()` to flash the backlights if that feature is enabled. diff --git a/docs/keycodes.md b/docs/keycodes.md index 7dcff03fd..fa01df63d 100644 --- a/docs/keycodes.md +++ b/docs/keycodes.md @@ -297,6 +297,16 @@ This is a reference only. Each group of keys links to the page documenting their |`OUT_USB` |USB only | |`OUT_BT` |Bluetooth only | +## [Dynamic Macros](feature_dynamic_macros.md) + +|Key |Alias |Description | +|-----------------|---------|--------------------------------------------------| +|`DYN_REC_START1` |`DM_REC1`|Start recording Macro 1 | +|`DYN_REC_START2` |`DM_REC2`|Start recording Macro 2 | +|`DYN_MACRO_PLAY1`|`DM_PLY1`|Replay Macro 1 | +|`DYN_MACRO_PLAY2`|`DM_PLY2`|Replay Macro 2 | +|`DYN_REC_STOP` |`DM_RSTP`|Finish the macro that is currently being recorded.| + ## [Layer Switching](feature_advanced_keycodes.md#switching-and-toggling-layers) |Key |Description | 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 @@ */ /* Author: Wojciech Siewierski < wojciech dot siewierski at onet dot pl > */ -#ifndef DYNAMIC_MACROS_H -#define DYNAMIC_MACROS_H +#pragma once + +/* Warn users that this is now deprecated and they should use the core feature instead. */ +#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" #include "action_layer.h" @@ -33,18 +35,6 @@ # define DYNAMIC_MACRO_SIZE 128 #endif -/* DYNAMIC_MACRO_RANGE must be set as the last element of user's - * "planck_keycodes" enum prior to including this header. This allows - * us to 'extend' it. - */ -enum dynamic_macro_keycodes { - DYN_REC_START1 = DYNAMIC_MACRO_RANGE, - DYN_REC_START2, - DYN_REC_STOP, - DYN_MACRO_PLAY1, - DYN_MACRO_PLAY2, -}; - /* Blink the LEDs to notify the user about some event. */ void dynamic_macro_led_blink(void) { #ifdef BACKLIGHT_ENABLE @@ -272,5 +262,3 @@ bool process_record_dynamic_macro(uint16_t keycode, keyrecord_t *record) { #undef DYNAMIC_MACRO_CURRENT_SLOT #undef DYNAMIC_MACRO_CURRENT_LENGTH #undef DYNAMIC_MACRO_CURRENT_CAPACITY - -#endif 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 @@ +/* Copyright 2016 Jack Humbert + * Copyright 2019 Drashna Jael're (@drashna, aka Christopher Courtney) + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +/* Author: Wojciech Siewierski < wojciech dot siewierski at onet dot pl > */ +#include "process_dynamic_macro.h" + +// default feedback method +void dynamic_macro_led_blink(void) { +#ifdef BACKLIGHT_ENABLE + backlight_toggle(); + wait_ms(100); + backlight_toggle(); +#endif +} + +/* User hooks for Dynamic Macros */ + +__attribute__((weak)) void dynamic_macro_record_start_user(void) { dynamic_macro_led_blink(); } + +__attribute__((weak)) void dynamic_macro_play_user(int8_t direction) { dynamic_macro_led_blink(); } + +__attribute__((weak)) void dynamic_macro_record_key_user(int8_t direction, keyrecord_t *record) { dynamic_macro_led_blink(); } + +__attribute__((weak)) void dynamic_macro_record_end_user(int8_t direction) { dynamic_macro_led_blink(); } + +/* Convenience macros used for retrieving the debug info. All of them + * need a `direction` variable accessible at the call site. + */ +#define DYNAMIC_MACRO_CURRENT_SLOT() (direction > 0 ? 1 : 2) +#define DYNAMIC_MACRO_CURRENT_LENGTH(BEGIN, POINTER) ((int)(direction * ((POINTER) - (BEGIN)))) +#define DYNAMIC_MACRO_CURRENT_CAPACITY(BEGIN, END2) ((int)(direction * ((END2) - (BEGIN)) + 1)) + +/** + * Start recording of the dynamic macro. + * + * @param[out] macro_pointer The new macro buffer iterator. + * @param[in] macro_buffer The macro buffer used to initialize macro_pointer. + */ +void dynamic_macro_record_start(keyrecord_t **macro_pointer, keyrecord_t *macro_buffer) { + dprintln("dynamic macro recording: started"); + + dynamic_macro_record_start_user(); + + clear_keyboard(); + layer_clear(); + *macro_pointer = macro_buffer; +} + +/** + * Play the dynamic macro. + * + * @param macro_buffer[in] The beginning of the macro buffer being played. + * @param macro_end[in] The element after the last macro buffer element. + * @param direction[in] Either +1 or -1, which way to iterate the buffer. + */ +void dynamic_macro_play(keyrecord_t *macro_buffer, keyrecord_t *macro_end, int8_t direction) { + dprintf("dynamic macro: slot %d playback\n", DYNAMIC_MACRO_CURRENT_SLOT()); + + layer_state_t saved_layer_state = layer_state; + + clear_keyboard(); + layer_clear(); + + while (macro_buffer != macro_end) { + process_record(macro_buffer); + macro_buffer += direction; + } + + clear_keyboard(); + + layer_state = saved_layer_state; + + dynamic_macro_play_user(direction); +} + +/** + * Record a single key in a dynamic macro. + * + * @param macro_buffer[in] The start of the used macro buffer. + * @param macro_pointer[in,out] The current buffer position. + * @param macro2_end[in] The end of the other macro. + * @param direction[in] Either +1 or -1, which way to iterate the buffer. + * @param record[in] The current keypress. + */ +void dynamic_macro_record_key(keyrecord_t *macro_buffer, keyrecord_t **macro_pointer, keyrecord_t *macro2_end, int8_t direction, keyrecord_t *record) { + /* If we've just started recording, ignore all the key releases. */ + if (!record->event.pressed && *macro_pointer == macro_buffer) { + dprintln("dynamic macro: ignoring a leading key-up event"); + return; + } + + /* The other end of the other macro is the last buffer element it + * is safe to use before overwriting the other macro. + */ + if (*macro_pointer - direction != macro2_end) { + **macro_pointer = *record; + *macro_pointer += direction; + } else { + dynamic_macro_record_key_user(direction, record); + } + + 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)); +} + +/** + * End recording of the dynamic macro. Essentially just update the + * pointer to the end of the macro. + */ +void dynamic_macro_record_end(keyrecord_t *macro_buffer, keyrecord_t *macro_pointer, int8_t direction, keyrecord_t **macro_end) { + dynamic_macro_record_end_user(direction); + + /* Do not save the keys being held when stopping the recording, + * i.e. the keys used to access the layer DYN_REC_STOP is on. + */ + while (macro_pointer != macro_buffer && (macro_pointer - direction)->event.pressed) { + dprintln("dynamic macro: trimming a trailing key-down event"); + macro_pointer -= direction; + } + + dprintf("dynamic macro: slot %d saved, length: %d\n", DYNAMIC_MACRO_CURRENT_SLOT(), DYNAMIC_MACRO_CURRENT_LENGTH(macro_buffer, macro_pointer)); + + *macro_end = macro_pointer; +} + +/* Handle the key events related to the dynamic macros. Should be + * called from process_record_user() like this: + * + * bool process_record_user(uint16_t keycode, keyrecord_t *record) { + * if (!process_record_dynamic_macro(keycode, record)) { + * return false; + * } + * <...THE REST OF THE FUNCTION...> + * } + */ +bool process_dynamic_macro(uint16_t keycode, keyrecord_t *record) { + /* Both macros use the same buffer but read/write on different + * ends of it. + * + * Macro1 is written left-to-right starting from the beginning of + * the buffer. + * + * Macro2 is written right-to-left starting from the end of the + * buffer. + * + * ¯o_buffer macro_end + * v v + * +------------------------------------------------------------+ + * |>>>>>> MACRO1 >>>>>> <<<<<<<<<<<<< MACRO2 <<<<<<<<<<<<<| + * +------------------------------------------------------------+ + * ^ ^ + * r_macro_end r_macro_buffer + * + * During the recording when one macro encounters the end of the + * other macro, the recording is stopped. Apart from this, there + * are no arbitrary limits for the macros' length in relation to + * each other: for example one can either have two medium sized + * macros or one long macro and one short macro. Or even one empty + * and one using the whole buffer. + */ + static keyrecord_t macro_buffer[DYNAMIC_MACRO_SIZE]; + + /* Pointer to the first buffer element after the first macro. + * Initially points to the very beginning of the buffer since the + * macro is empty. */ + static keyrecord_t *macro_end = macro_buffer; + + /* The other end of the macro buffer. Serves as the beginning of + * the second macro. */ + static keyrecord_t *const r_macro_buffer = macro_buffer + DYNAMIC_MACRO_SIZE - 1; + + /* Like macro_end but for the second macro. */ + static keyrecord_t *r_macro_end = r_macro_buffer; + + /* A persistent pointer to the current macro position (iterator) + * used during the recording. */ + static keyrecord_t *macro_pointer = NULL; + + /* 0 - no macro is being recorded right now + * 1,2 - either macro 1 or 2 is being recorded */ + static uint8_t macro_id = 0; + + if (macro_id == 0) { + /* No macro recording in progress. */ + if (!record->event.pressed) { + switch (keycode) { + case DYN_REC_START1: + dynamic_macro_record_start(¯o_pointer, macro_buffer); + macro_id = 1; + return false; + case DYN_REC_START2: + dynamic_macro_record_start(¯o_pointer, r_macro_buffer); + macro_id = 2; + return false; + case DYN_MACRO_PLAY1: + dynamic_macro_play(macro_buffer, macro_end, +1); + return false; + case DYN_MACRO_PLAY2: + dynamic_macro_play(r_macro_buffer, r_macro_end, -1); + return false; + } + } + } else { + /* A macro is being recorded right now. */ + switch (keycode) { + case DYN_REC_STOP: + /* Stop the macro recording. */ + if (record->event.pressed) { /* Ignore the initial release + * just after the recoding + * starts. */ + switch (macro_id) { + case 1: + dynamic_macro_record_end(macro_buffer, macro_pointer, +1, ¯o_end); + break; + case 2: + dynamic_macro_record_end(r_macro_buffer, macro_pointer, -1, &r_macro_end); + break; + } + macro_id = 0; + } + return false; +#ifdef DYNAMIC_MACRO_NO_NESTING + case DYN_MACRO_PLAY1: + case DYN_MACRO_PLAY2: + dprintln("dynamic macro: ignoring macro play key while recording"); + return false; +#endif + default: + /* Store the key in the macro buffer and process it normally. */ + switch (macro_id) { + case 1: + dynamic_macro_record_key(macro_buffer, ¯o_pointer, r_macro_end, +1, record); + break; + case 2: + dynamic_macro_record_key(r_macro_buffer, ¯o_pointer, macro_end, -1, record); + break; + } + return true; + break; + } + } + + return true; +} 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 @@ +/* Copyright 2016 Jack Humbert + * Copyright 2019 Drashna Jael're (@drashna, aka Christopher Courtney) + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +/* Author: Wojciech Siewierski < wojciech dot siewierski at onet dot pl > */ +#pragma once + +#include "quantum.h" + +/* May be overridden with a custom value. Be aware that the effective + * macro length is half of this value: each keypress is recorded twice + * because of the down-event and up-event. This is not a bug, it's the + * intended behavior. + * + * Usually it should be fine to set the macro size to at least 256 but + * there have been reports of it being too much in some users' cases, + * so 128 is considered a safe default. + */ +#ifndef DYNAMIC_MACRO_SIZE +# define DYNAMIC_MACRO_SIZE 128 +#endif + +void dynamic_macro_led_blink(void); +bool process_dynamic_macro(uint16_t keycode, keyrecord_t *record); +void dynamic_macro_record_start_user(void); +void dynamic_macro_play_user(int8_t direction); +void dynamic_macro_record_key_user(int8_t direction, keyrecord_t *record); +void dynamic_macro_record_end_user(int8_t direction); diff --git a/quantum/quantum.c b/quantum/quantum.c index 571dda4c5..1f17c6ff7 100644 --- a/quantum/quantum.c +++ b/quantum/quantum.c @@ -26,7 +26,7 @@ #ifdef BACKLIGHT_ENABLE # include "backlight.h" - extern backlight_config_t backlight_config; +extern backlight_config_t backlight_config; #endif #ifdef FAUXCLICKY_ENABLE @@ -89,7 +89,7 @@ static void do_code16(uint16_t code, void (*f)(uint8_t)) { uint8_t mods_to_send = 0; - if (code & QK_RMODS_MIN) { // Right mod flag is set + if (code & QK_RMODS_MIN) { // Right mod flag is set if (code & QK_LCTL) mods_to_send |= MOD_BIT(KC_RCTL); if (code & QK_LSFT) mods_to_send |= MOD_BIT(KC_RSFT); if (code & QK_LALT) mods_to_send |= MOD_BIT(KC_RALT); @@ -222,6 +222,10 @@ bool process_record_quantum(keyrecord_t *record) { // Must run first to be able to mask key_up events. process_key_lock(&keycode, record) && #endif +#if defined(DYNAMIC_MACRO_ENABLE) && !defined(DYNAMIC_MACRO_USER_CALL) + // Must run asap to ensure all keypresses are recorded. + process_dynamic_macro(keycode, record) && +#endif #if defined(AUDIO_ENABLE) && defined(AUDIO_CLICKY) process_clicky(keycode, record) && #endif // AUDIO_CLICKY @@ -563,7 +567,7 @@ bool process_record_quantum(keyrecord_t *record) { keymap_config.swap_backslash_backspace = true; break; case MAGIC_HOST_NKRO: - clear_keyboard(); // clear first buffer to prevent stuck keys + clear_keyboard(); // clear first buffer to prevent stuck keys keymap_config.nkro = true; break; case MAGIC_SWAP_ALT_GUI: @@ -606,7 +610,7 @@ bool process_record_quantum(keyrecord_t *record) { keymap_config.swap_backslash_backspace = false; break; case MAGIC_UNHOST_NKRO: - clear_keyboard(); // clear first buffer to prevent stuck keys + clear_keyboard(); // clear first buffer to prevent stuck keys keymap_config.nkro = false; break; case MAGIC_UNSWAP_ALT_GUI: @@ -644,7 +648,7 @@ bool process_record_quantum(keyrecord_t *record) { #endif break; case MAGIC_TOGGLE_NKRO: - clear_keyboard(); // clear first buffer to prevent stuck keys + clear_keyboard(); // clear first buffer to prevent stuck keys keymap_config.nkro = !keymap_config.nkro; break; case MAGIC_EE_HANDS_LEFT: diff --git a/quantum/quantum.h b/quantum/quantum.h index 01abe1c0a..87343a15d 100644 --- a/quantum/quantum.h +++ b/quantum/quantum.h @@ -149,6 +149,10 @@ extern layer_state_t layer_state; #include "dip_switch.h" #endif +#ifdef DYNAMIC_MACRO_ENABLE + #include "process_dynamic_macro.h" +#endif + // Function substitutions to ease GPIO manipulation #if defined(__AVR__) diff --git a/quantum/quantum_keycodes.h b/quantum/quantum_keycodes.h index 5fac6a5ca..51a7e290f 100644 --- a/quantum/quantum_keycodes.h +++ b/quantum/quantum_keycodes.h @@ -505,6 +505,13 @@ enum quantum_keycodes { MAGIC_EE_HANDS_LEFT, MAGIC_EE_HANDS_RIGHT, + // Dynamic Macros + DYN_REC_START1, + DYN_REC_START2, + DYN_REC_STOP, + DYN_MACRO_PLAY1, + DYN_MACRO_PLAY2, + // always leave at the end SAFE_RANGE }; @@ -757,4 +764,11 @@ enum quantum_keycodes { # define SH_OFF (QK_SWAP_HANDS | OP_SH_OFF) #endif -#endif // QUANTUM_KEYCODES_H +// Dynamic Macros aliases +#define DM_REC1 DYN_REC_START1 +#define DM_REC2 DYN_REC_START2 +#define DM_RSTP DYN_REC_STOP +#define DM_PLY1 DYN_MACRO_PLAY1 +#define DM_PLY2 DYN_MACRO_PLAY2 + +#endif // QUANTUM_KEYCODES_H -- cgit v1.2.3-70-g09d2