summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRyan <fauxpark@gmail.com>2022-01-25 08:22:20 +1100
committerGitHub <noreply@github.com>2022-01-24 21:22:20 +0000
commit1d11ae3087f583c4f4756169802b33adea71ed94 (patch)
tree6a9deedeecec0220c2dccd10e90941956c4d27b7
parent3340ca46e82c8b348d9131de53b73e83d1f2c285 (diff)
Rip out old macro and action_function system (#16025)
* Rip out old macro and action_function system * Update quantum/action_util.c Co-authored-by: Joel Challis <git@zvecr.com>
-rw-r--r--common_features.mk1
-rw-r--r--data/templates/avr/config.h4
-rw-r--r--data/templates/ps2avrgb/config.h4
-rw-r--r--docs/config_options.md5
-rw-r--r--docs/feature_haptic_feedback.md3
-rw-r--r--docs/keymap.md2
-rw-r--r--keyboards/deltasplit75/keymaps/default/keymap.c4
-rw-r--r--keyboards/mechmini/v2/keymaps/via/keymap.c2
-rw-r--r--quantum/action.c26
-rw-r--r--quantum/action.h17
-rw-r--r--quantum/action_code.h32
-rw-r--r--quantum/action_macro.c93
-rw-r--r--quantum/action_macro.h123
-rw-r--r--quantum/action_util.c33
-rw-r--r--quantum/action_util.h7
-rw-r--r--quantum/keycode.h43
-rw-r--r--quantum/keymap.h5
-rw-r--r--quantum/keymap_common.c41
-rw-r--r--quantum/process_keycode/process_haptic.c3
-rw-r--r--quantum/quantum_keycodes.h10
-rw-r--r--tests/basic/test_macro.cpp88
21 files changed, 8 insertions, 538 deletions
diff --git a/common_features.mk b/common_features.mk
index d07c137066..e00f95f8e4 100644
--- a/common_features.mk
+++ b/common_features.mk
@@ -20,7 +20,6 @@ QUANTUM_SRC += \
20 $(QUANTUM_DIR)/led.c \ 20 $(QUANTUM_DIR)/led.c \
21 $(QUANTUM_DIR)/action.c \ 21 $(QUANTUM_DIR)/action.c \
22 $(QUANTUM_DIR)/action_layer.c \ 22 $(QUANTUM_DIR)/action_layer.c \
23 $(QUANTUM_DIR)/action_macro.c \
24 $(QUANTUM_DIR)/action_tapping.c \ 23 $(QUANTUM_DIR)/action_tapping.c \
25 $(QUANTUM_DIR)/action_util.c \ 24 $(QUANTUM_DIR)/action_util.c \
26 $(QUANTUM_DIR)/eeconfig.c \ 25 $(QUANTUM_DIR)/eeconfig.c \
diff --git a/data/templates/avr/config.h b/data/templates/avr/config.h
index 7c15e8e704..97f7bb6fad 100644
--- a/data/templates/avr/config.h
+++ b/data/templates/avr/config.h
@@ -129,10 +129,6 @@
129//#define NO_ACTION_TAPPING 129//#define NO_ACTION_TAPPING
130//#define NO_ACTION_ONESHOT 130//#define NO_ACTION_ONESHOT
131 131
132/* disable these deprecated features by default */
133#define NO_ACTION_MACRO
134#define NO_ACTION_FUNCTION
135
136/* Bootmagic Lite key configuration */ 132/* Bootmagic Lite key configuration */
137//#define BOOTMAGIC_LITE_ROW 0 133//#define BOOTMAGIC_LITE_ROW 0
138//#define BOOTMAGIC_LITE_COLUMN 0 134//#define BOOTMAGIC_LITE_COLUMN 0
diff --git a/data/templates/ps2avrgb/config.h b/data/templates/ps2avrgb/config.h
index 876a60252f..ef29da0de0 100644
--- a/data/templates/ps2avrgb/config.h
+++ b/data/templates/ps2avrgb/config.h
@@ -119,10 +119,6 @@
119//#define NO_ACTION_TAPPING 119//#define NO_ACTION_TAPPING
120//#define NO_ACTION_ONESHOT 120//#define NO_ACTION_ONESHOT
121 121
122/* disable these deprecated features by default */
123#define NO_ACTION_MACRO
124#define NO_ACTION_FUNCTION
125
126/* Bootmagic Lite key configuration */ 122/* Bootmagic Lite key configuration */
127//#define BOOTMAGIC_LITE_ROW 0 123//#define BOOTMAGIC_LITE_ROW 0
128//#define BOOTMAGIC_LITE_COLUMN 0 124//#define BOOTMAGIC_LITE_COLUMN 0
diff --git a/docs/config_options.md b/docs/config_options.md
index b661b55ee0..7657fae02e 100644
--- a/docs/config_options.md
+++ b/docs/config_options.md
@@ -124,10 +124,6 @@ If you define these options you will disable the associated feature, which can s
124 * disable tap dance and other tapping features 124 * disable tap dance and other tapping features
125* `#define NO_ACTION_ONESHOT` 125* `#define NO_ACTION_ONESHOT`
126 * disable one-shot modifiers 126 * disable one-shot modifiers
127* `#define NO_ACTION_MACRO`
128 * disable old-style macro handling using `MACRO()`, `action_get_macro()` _(deprecated)_
129* `#define NO_ACTION_FUNCTION`
130 * disable old-style function handling using `fn_actions`, `action_function()` _(deprecated)_
131 127
132## Features That Can Be Enabled 128## Features That Can Be Enabled
133 129
@@ -383,7 +379,6 @@ This is a [make](https://www.gnu.org/software/make/manual/make.html) file that i
383 * A list of [layouts](feature_layouts.md) this keyboard supports. 379 * A list of [layouts](feature_layouts.md) this keyboard supports.
384* `LTO_ENABLE` 380* `LTO_ENABLE`
385 * Enables Link Time Optimization (LTO) when compiling the keyboard. This makes the process take longer, but it can significantly reduce the compiled size (and since the firmware is small, the added time is not noticeable). 381 * Enables Link Time Optimization (LTO) when compiling the keyboard. This makes the process take longer, but it can significantly reduce the compiled size (and since the firmware is small, the added time is not noticeable).
386However, this will automatically disable the legacy TMK Macros and Functions features, as these break when LTO is enabled. It does this by automatically defining `NO_ACTION_MACRO` and `NO_ACTION_FUNCTION`. (Note: This does not affect QMK [Macros](feature_macros.md) and [Layers](feature_layers.md).)
387 382
388## AVR MCU Options 383## AVR MCU Options
389* `MCU = atmega32u4` 384* `MCU = atmega32u4`
diff --git a/docs/feature_haptic_feedback.md b/docs/feature_haptic_feedback.md
index bbdf7e122c..63ac4305ff 100644
--- a/docs/feature_haptic_feedback.md
+++ b/docs/feature_haptic_feedback.md
@@ -191,9 +191,6 @@ With the entry of `#define NO_HAPTIC_MOD` in config.h, the following keys will n
191* `TT()` layer tap toggle keys, when held to activate a layer. However when tapped `TAPPING_TOGGLE` times to permanently toggle the layer, on the last tap haptic feedback is still triggered. 191* `TT()` layer tap toggle keys, when held to activate a layer. However when tapped `TAPPING_TOGGLE` times to permanently toggle the layer, on the last tap haptic feedback is still triggered.
192* `MT()` mod tap keys, when held to keep a usual modifier key pressed. However when tapped, and the key is quickly released, and sends a keycode, haptic feedback is still triggered. See also [Mod-Tap](mod_tap.md). 192* `MT()` mod tap keys, when held to keep a usual modifier key pressed. However when tapped, and the key is quickly released, and sends a keycode, haptic feedback is still triggered. See also [Mod-Tap](mod_tap.md).
193 193
194### NO_HAPTIC_FN
195With the entry of `#define NO_HAPTIC_FN` in config.h, deprecated `fn_actions` type function keys will not trigger a feedback.
196
197### NO_HAPTIC_ALPHA 194### NO_HAPTIC_ALPHA
198With the entry of `#define NO_HAPTIC_ALPHA` in config.h, none of the alpha keys (A ... Z) will trigger a feedback. 195With the entry of `#define NO_HAPTIC_ALPHA` in config.h, none of the alpha keys (A ... Z) will trigger a feedback.
199 196
diff --git a/docs/keymap.md b/docs/keymap.md
index bec781e684..a7c9c50d74 100644
--- a/docs/keymap.md
+++ b/docs/keymap.md
@@ -136,7 +136,7 @@ After this you'll find a list of LAYOUT() macros. A LAYOUT() is simply a list of
136 136
137`keymaps[][MATRIX_ROWS][MATRIX_COLS]` in QMK holds the 16 bit action code (sometimes referred as the quantum keycode) in it. For the keycode representing typical keys, its high byte is 0 and its low byte is the USB HID usage ID for keyboard. 137`keymaps[][MATRIX_ROWS][MATRIX_COLS]` in QMK holds the 16 bit action code (sometimes referred as the quantum keycode) in it. For the keycode representing typical keys, its high byte is 0 and its low byte is the USB HID usage ID for keyboard.
138 138
139> TMK from which QMK was forked uses `const uint8_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS]` instead and holds the 8 bit keycode. Some keycode values are reserved to induce execution of certain action codes via the `fn_actions[]` array. 139> TMK from which QMK was forked uses `const uint8_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS]` instead and holds the 8 bit keycode.
140 140
141#### Base Layer 141#### Base Layer
142 142
diff --git a/keyboards/deltasplit75/keymaps/default/keymap.c b/keyboards/deltasplit75/keymaps/default/keymap.c
index c13b0627c0..7d698eb329 100644
--- a/keyboards/deltasplit75/keymaps/default/keymap.c
+++ b/keyboards/deltasplit75/keymaps/default/keymap.c
@@ -20,8 +20,8 @@ const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = {
20 _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, RESET, 20 _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, RESET,
21 KC_BSLS, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, 21 KC_BSLS, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______,
22 _______, KC_VOLU, KC_UP, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, 22 _______, KC_VOLU, KC_UP, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______,
23 M(1), KC_LEFT, KC_DOWN, KC_RGHT, KC_PAUS, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, 23 _______, KC_LEFT, KC_DOWN, KC_RGHT, KC_PAUS, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______,
24 _______, _______, KC_VOLD, M(0), KC_PSCR, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, 24 _______, _______, KC_VOLD, _______, KC_PSCR, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______,
25 _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______ 25 _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______
26 ), 26 ),
27 27
diff --git a/keyboards/mechmini/v2/keymaps/via/keymap.c b/keyboards/mechmini/v2/keymaps/via/keymap.c
index 7c7c2103c0..e77d9d8859 100644
--- a/keyboards/mechmini/v2/keymaps/via/keymap.c
+++ b/keyboards/mechmini/v2/keymaps/via/keymap.c
@@ -11,7 +11,7 @@ const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = {
11 [1] = LAYOUT_ortho( 11 [1] = LAYOUT_ortho(
12 KC_GRV, KC_1, KC_2, KC_3, KC_4, KC_5, KC_6, KC_7, KC_8, KC_9, KC_0, KC_BSPC, 12 KC_GRV, KC_1, KC_2, KC_3, KC_4, KC_5, KC_6, KC_7, KC_8, KC_9, KC_0, KC_BSPC,
13 KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_LBRC, KC_RBRC, KC_MINS, KC_EQL, KC_BSLS, KC_DEL, 13 KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_LBRC, KC_RBRC, KC_MINS, KC_EQL, KC_BSLS, KC_DEL,
14 KC_TRNS, KC_TRNS, KC_TRNS, M(1), M(1), KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_HOME, KC_END, KC_TRNS, 14 KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_HOME, KC_END, KC_TRNS,
15 KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_MNXT, KC_VOLD, KC_VOLU, KC_MPLY), 15 KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_MNXT, KC_VOLD, KC_VOLU, KC_MPLY),
16 16
17 [2] = LAYOUT_ortho( 17 [2] = LAYOUT_ortho(
diff --git a/quantum/action.c b/quantum/action.c
index ea2310a4d9..d932c01688 100644
--- a/quantum/action.c
+++ b/quantum/action.c
@@ -23,7 +23,6 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
23#include "led.h" 23#include "led.h"
24#include "action_layer.h" 24#include "action_layer.h"
25#include "action_tapping.h" 25#include "action_tapping.h"
26#include "action_macro.h"
27#include "action_util.h" 26#include "action_util.h"
28#include "action.h" 27#include "action.h"
29#include "wait.h" 28#include "wait.h"
@@ -634,12 +633,7 @@ void process_action(keyrecord_t *record, action_t action) {
634 break; 633 break;
635# endif 634# endif
636#endif 635#endif
637 /* Extentions */ 636
638#ifndef NO_ACTION_MACRO
639 case ACT_MACRO:
640 action_macro_play(action_get_macro(record, action.func.id, action.func.opt));
641 break;
642#endif
643#ifdef SWAP_HANDS_ENABLE 637#ifdef SWAP_HANDS_ENABLE
644 case ACT_SWAP_HANDS: 638 case ACT_SWAP_HANDS:
645 switch (action.swap.code) { 639 switch (action.swap.code) {
@@ -713,11 +707,6 @@ void process_action(keyrecord_t *record, action_t action) {
713# endif 707# endif
714 } 708 }
715#endif 709#endif
716#ifndef NO_ACTION_FUNCTION
717 case ACT_FUNCTION:
718 action_function(record, action.func.id, action.func.opt);
719 break;
720#endif
721 default: 710 default:
722 break; 711 break;
723 } 712 }
@@ -1041,7 +1030,6 @@ void clear_keyboard_but_mods_and_keys() {
1041 host_consumer_send(0); 1030 host_consumer_send(0);
1042#endif 1031#endif
1043 clear_weak_mods(); 1032 clear_weak_mods();
1044 clear_macro_mods();
1045 send_keyboard_report(); 1033 send_keyboard_report();
1046#ifdef MOUSEKEY_ENABLE 1034#ifdef MOUSEKEY_ENABLE
1047 mousekey_clear(); 1035 mousekey_clear();
@@ -1104,12 +1092,6 @@ bool is_tap_action(action_t action) {
1104 return true; 1092 return true;
1105 } 1093 }
1106 return false; 1094 return false;
1107 case ACT_MACRO:
1108 case ACT_FUNCTION:
1109 if (action.func.opt & FUNC_TAP) {
1110 return true;
1111 }
1112 return false;
1113 } 1095 }
1114 return false; 1096 return false;
1115} 1097}
@@ -1166,12 +1148,6 @@ void debug_action(action_t action) {
1166 case ACT_LAYER_TAP_EXT: 1148 case ACT_LAYER_TAP_EXT:
1167 dprint("ACT_LAYER_TAP_EXT"); 1149 dprint("ACT_LAYER_TAP_EXT");
1168 break; 1150 break;
1169 case ACT_MACRO:
1170 dprint("ACT_MACRO");
1171 break;
1172 case ACT_FUNCTION:
1173 dprint("ACT_FUNCTION");
1174 break;
1175 case ACT_SWAP_HANDS: 1151 case ACT_SWAP_HANDS:
1176 dprint("ACT_SWAP_HANDS"); 1152 dprint("ACT_SWAP_HANDS");
1177 break; 1153 break;
diff --git a/quantum/action.h b/quantum/action.h
index b562f18c5b..671a8bc190 100644
--- a/quantum/action.h
+++ b/quantum/action.h
@@ -22,22 +22,11 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
22#include "keyboard.h" 22#include "keyboard.h"
23#include "keycode.h" 23#include "keycode.h"
24#include "action_code.h" 24#include "action_code.h"
25#include "action_macro.h"
26 25
27#ifdef __cplusplus 26#ifdef __cplusplus
28extern "C" { 27extern "C" {
29#endif 28#endif
30 29
31/* Disable macro and function features when LTO is enabled, since they break */
32#ifdef LTO_ENABLE
33# ifndef NO_ACTION_MACRO
34# define NO_ACTION_MACRO
35# endif
36# ifndef NO_ACTION_FUNCTION
37# define NO_ACTION_FUNCTION
38# endif
39#endif
40
41#ifndef TAP_CODE_DELAY 30#ifndef TAP_CODE_DELAY
42# define TAP_CODE_DELAY 0 31# define TAP_CODE_DELAY 0
43#endif 32#endif
@@ -72,12 +61,6 @@ void action_exec(keyevent_t event);
72action_t action_for_key(uint8_t layer, keypos_t key); 61action_t action_for_key(uint8_t layer, keypos_t key);
73action_t action_for_keycode(uint16_t keycode); 62action_t action_for_keycode(uint16_t keycode);
74 63
75/* macro */
76const macro_t *action_get_macro(keyrecord_t *record, uint8_t id, uint8_t opt);
77
78/* user defined special function */
79void action_function(keyrecord_t *record, uint8_t id, uint8_t opt);
80
81/* keyboard-specific key event (pre)processing */ 64/* keyboard-specific key event (pre)processing */
82bool process_record_quantum(keyrecord_t *record); 65bool process_record_quantum(keyrecord_t *record);
83 66
diff --git a/quantum/action_code.h b/quantum/action_code.h
index eb18c36ae8..20b3e459d2 100644
--- a/quantum/action_code.h
+++ b/quantum/action_code.h
@@ -79,19 +79,6 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
79 * 101E|LLLL|1111 0100 One Shot Layer (0xF4) [TAP] 79 * 101E|LLLL|1111 0100 One Shot Layer (0xF4) [TAP]
80 * 101E|LLLL|1111 xxxx Reserved (0xF5-FF) 80 * 101E|LLLL|1111 xxxx Reserved (0xF5-FF)
81 * ELLLL: layer 0-31(E: extra bit for layer 16-31) 81 * ELLLL: layer 0-31(E: extra bit for layer 16-31)
82 *
83 * Extensions(11xx)
84 * ----------------
85 * ACT_MACRO(1100):
86 * 1100|opt | id(8) Macro play?
87 * 1100|1111| id(8) Macro record?
88 *
89 * 1101|xxxx xxxx xxxx (reserved)
90 * 1110|xxxx xxxx xxxx (reserved)
91 *
92 * ACT_FUNCTION(1111):
93 * 1111| address(12) Function?
94 * 1111|opt | id(8) Function?
95 */ 82 */
96enum action_kind_id { 83enum action_kind_id {
97 /* Key Actions */ 84 /* Key Actions */
@@ -111,9 +98,6 @@ enum action_kind_id {
111 ACT_LAYER_MODS = 0b1001, 98 ACT_LAYER_MODS = 0b1001,
112 ACT_LAYER_TAP = 0b1010, /* Layer 0-15 */ 99 ACT_LAYER_TAP = 0b1010, /* Layer 0-15 */
113 ACT_LAYER_TAP_EXT = 0b1011, /* Layer 16-31 */ 100 ACT_LAYER_TAP_EXT = 0b1011, /* Layer 16-31 */
114 /* Extensions */
115 ACT_MACRO = 0b1100,
116 ACT_FUNCTION = 0b1111
117}; 101};
118 102
119/** \brief Action Code Struct 103/** \brief Action Code Struct
@@ -164,11 +148,6 @@ typedef union {
164 uint8_t page : 2; 148 uint8_t page : 2;
165 uint8_t kind : 4; 149 uint8_t kind : 4;
166 } usage; 150 } usage;
167 struct action_function {
168 uint8_t id : 8;
169 uint8_t opt : 4;
170 uint8_t kind : 4;
171 } func;
172 struct action_swap { 151 struct action_swap {
173 uint8_t code : 8; 152 uint8_t code : 8;
174 uint8_t opt : 4; 153 uint8_t opt : 4;
@@ -275,17 +254,6 @@ enum layer_param_tap_op {
275#define ACTION_DEFAULT_LAYER_BIT_XOR(part, bits) ACTION_LAYER_BITOP(OP_BIT_XOR, (part), (bits), 0) 254#define ACTION_DEFAULT_LAYER_BIT_XOR(part, bits) ACTION_LAYER_BITOP(OP_BIT_XOR, (part), (bits), 0)
276#define ACTION_DEFAULT_LAYER_BIT_SET(part, bits) ACTION_LAYER_BITOP(OP_BIT_SET, (part), (bits), 0) 255#define ACTION_DEFAULT_LAYER_BIT_SET(part, bits) ACTION_LAYER_BITOP(OP_BIT_SET, (part), (bits), 0)
277 256
278/* Macro */
279#define ACTION_MACRO(id) ACTION(ACT_MACRO, (id))
280#define ACTION_MACRO_TAP(id) ACTION(ACT_MACRO, FUNC_TAP << 8 | (id))
281#define ACTION_MACRO_OPT(id, opt) ACTION(ACT_MACRO, (opt) << 8 | (id))
282/* Function */
283enum function_opts {
284 FUNC_TAP = 0x8, /* indciates function is tappable */
285};
286#define ACTION_FUNCTION(id) ACTION(ACT_FUNCTION, (id))
287#define ACTION_FUNCTION_TAP(id) ACTION(ACT_FUNCTION, FUNC_TAP << 8 | (id))
288#define ACTION_FUNCTION_OPT(id, opt) ACTION(ACT_FUNCTION, (opt) << 8 | (id))
289/* OneHand Support */ 257/* OneHand Support */
290enum swap_hands_param_tap_op { 258enum swap_hands_param_tap_op {
291 OP_SH_TOGGLE = 0xF0, 259 OP_SH_TOGGLE = 0xF0,
diff --git a/quantum/action_macro.c b/quantum/action_macro.c
deleted file mode 100644
index 92228c0ba8..0000000000
--- a/quantum/action_macro.c
+++ /dev/null
@@ -1,93 +0,0 @@
1/*
2Copyright 2013 Jun Wako <wakojun@gmail.com>
3
4This program is free software: you can redistribute it and/or modify
5it under the terms of the GNU General Public License as published by
6the Free Software Foundation, either version 2 of the License, or
7(at your option) any later version.
8
9This program is distributed in the hope that it will be useful,
10but WITHOUT ANY WARRANTY; without even the implied warranty of
11MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12GNU General Public License for more details.
13
14You should have received a copy of the GNU General Public License
15along with this program. If not, see <http://www.gnu.org/licenses/>.
16*/
17#include "action.h"
18#include "action_util.h"
19#include "action_macro.h"
20#include "wait.h"
21
22#ifdef DEBUG_ACTION
23# include "debug.h"
24#else
25# include "nodebug.h"
26#endif
27
28#ifndef NO_ACTION_MACRO
29
30# define MACRO_READ() (macro = MACRO_GET(macro_p++))
31/** \brief Action Macro Play
32 *
33 * FIXME: Needs doc
34 */
35void action_macro_play(const macro_t *macro_p) {
36 macro_t macro = END;
37 uint8_t interval = 0;
38
39 if (!macro_p) return;
40 while (true) {
41 switch (MACRO_READ()) {
42 case KEY_DOWN:
43 MACRO_READ();
44 dprintf("KEY_DOWN(%02X)\n", macro);
45 if (IS_MOD(macro)) {
46 add_macro_mods(MOD_BIT(macro));
47 send_keyboard_report();
48 } else {
49 register_code(macro);
50 }
51 break;
52 case KEY_UP:
53 MACRO_READ();
54 dprintf("KEY_UP(%02X)\n", macro);
55 if (IS_MOD(macro)) {
56 del_macro_mods(MOD_BIT(macro));
57 send_keyboard_report();
58 } else {
59 unregister_code(macro);
60 }
61 break;
62 case WAIT:
63 MACRO_READ();
64 dprintf("WAIT(%u)\n", macro);
65 {
66 uint8_t ms = macro;
67 while (ms--) wait_ms(1);
68 }
69 break;
70 case INTERVAL:
71 interval = MACRO_READ();
72 dprintf("INTERVAL(%u)\n", interval);
73 break;
74 case 0x04 ... 0x73:
75 dprintf("DOWN(%02X)\n", macro);
76 register_code(macro);
77 break;
78 case 0x84 ... 0xF3:
79 dprintf("UP(%02X)\n", macro);
80 unregister_code(macro & 0x7F);
81 break;
82 case END:
83 default:
84 return;
85 }
86 // interval
87 {
88 uint8_t ms = interval;
89 while (ms--) wait_ms(1);
90 }
91 }
92}
93#endif
diff --git a/quantum/action_macro.h b/quantum/action_macro.h
deleted file mode 100644
index 685e2c6ffc..0000000000
--- a/quantum/action_macro.h
+++ /dev/null
@@ -1,123 +0,0 @@
1/*
2Copyright 2013 Jun Wako <wakojun@gmail.com>
3
4This program is free software: you can redistribute it and/or modify
5it under the terms of the GNU General Public License as published by
6the Free Software Foundation, either version 2 of the License, or
7(at your option) any later version.
8
9This program is distributed in the hope that it will be useful,
10but WITHOUT ANY WARRANTY; without even the implied warranty of
11MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12GNU General Public License for more details.
13
14You should have received a copy of the GNU General Public License
15along with this program. If not, see <http://www.gnu.org/licenses/>.
16*/
17
18#pragma once
19
20#include <stdint.h>
21#include "progmem.h"
22
23typedef uint8_t macro_t;
24
25#define MACRO_NONE (macro_t *)0
26#define MACRO(...) \
27 ({ \
28 static const macro_t __m[] PROGMEM = {__VA_ARGS__}; \
29 &__m[0]; \
30 })
31#define MACRO_GET(p) pgm_read_byte(p)
32
33// Sends press when the macro key is pressed, release when release, or tap_macro when the key has been tapped
34#define MACRO_TAP_HOLD(record, press, release, tap_macro) (((record)->event.pressed) ? (((record)->tap.count <= 0 || (record)->tap.interrupted) ? (press) : MACRO_NONE) : (((record)->tap.count > 0 && !((record)->tap.interrupted)) ? (tap_macro) : (release)))
35
36// Holds down the modifier mod when the macro key is held, or sends macro instead when tapped
37#define MACRO_TAP_HOLD_MOD(record, macro, mod) MACRO_TAP_HOLD(record, (MACRO(D(mod), END)), MACRO(U(mod), END), macro)
38
39// Holds down the modifier mod when the macro key is held, or pressed a shifted key when tapped (eg: shift+3 for #)
40#define MACRO_TAP_SHFT_KEY_HOLD_MOD(record, key, mod) MACRO_TAP_HOLD_MOD(record, (MACRO(I(10), D(LSFT), T(key), U(LSFT), END)), mod)
41
42// Momentary switch layer when held, sends macro if tapped
43#define MACRO_TAP_HOLD_LAYER(record, macro, layer) \
44 (((record)->event.pressed) ? (((record)->tap.count <= 0 || (record)->tap.interrupted) ? ({ \
45 layer_on((layer)); \
46 MACRO_NONE; \
47 }) \
48 : MACRO_NONE) \
49 : (((record)->tap.count > 0 && !((record)->tap.interrupted)) ? (macro) : ({ \
50 layer_off((layer)); \
51 MACRO_NONE; \
52 })))
53
54// Momentary switch layer when held, presses a shifted key when tapped (eg: shift+3 for #)
55#define MACRO_TAP_SHFT_KEY_HOLD_LAYER(record, key, layer) MACRO_TAP_HOLD_LAYER(record, MACRO(I(10), D(LSFT), T(key), U(LSFT), END), layer)
56
57#ifndef NO_ACTION_MACRO
58void action_macro_play(const macro_t *macro_p);
59#else
60# define action_macro_play(macro)
61#endif
62
63/* Macro commands
64 * code(0x04-73) // key down(1byte)
65 * code(0x04-73) | 0x80 // key up(1byte)
66 * { KEY_DOWN, code(0x04-0xff) } // key down(2bytes)
67 * { KEY_UP, code(0x04-0xff) } // key up(2bytes)
68 * WAIT // wait milli-seconds
69 * INTERVAL // set interval between macro commands
70 * END // stop macro execution
71 *
72 * Ideas(Not implemented):
73 * modifiers
74 * system usage
75 * consumer usage
76 * unicode usage
77 * function call
78 * conditionals
79 * loop
80 */
81enum macro_command_id {
82 /* 0x00 - 0x03 */
83 END = 0x00,
84 KEY_DOWN,
85 KEY_UP,
86
87 /* 0x04 - 0x73 (reserved for keycode down) */
88
89 /* 0x74 - 0x83 */
90 WAIT = 0x74,
91 INTERVAL,
92
93 /* 0x84 - 0xf3 (reserved for keycode up) */
94
95 /* 0xf4 - 0xff */
96};
97
98/* TODO: keycode:0x04-0x73 can be handled by 1byte command else 2bytes are needed
99 * if keycode between 0x04 and 0x73
100 * keycode / (keycode|0x80)
101 * else
102 * {KEY_DOWN, keycode} / {KEY_UP, keycode}
103 */
104#define DOWN(key) KEY_DOWN, (key)
105#define UP(key) KEY_UP, (key)
106#define TYPE(key) DOWN(key), UP(key)
107#define WAIT(ms) WAIT, (ms)
108#define INTERVAL(ms) INTERVAL, (ms)
109
110/* key down */
111#define D(key) DOWN(KC_##key)
112/* key up */
113#define U(key) UP(KC_##key)
114/* key type */
115#define T(key) TYPE(KC_##key)
116/* wait */
117#define W(ms) WAIT(ms)
118/* interval */
119#define I(ms) INTERVAL(ms)
120
121/* for backward comaptibility */
122#define MD(key) DOWN(KC_##key)
123#define MU(key) UP(KC_##key)
diff --git a/quantum/action_util.c b/quantum/action_util.c
index 7e30593fb1..9eb2a6d30d 100644
--- a/quantum/action_util.c
+++ b/quantum/action_util.c
@@ -25,9 +25,8 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
25 25
26extern keymap_config_t keymap_config; 26extern keymap_config_t keymap_config;
27 27
28static uint8_t real_mods = 0; 28static uint8_t real_mods = 0;
29static uint8_t weak_mods = 0; 29static uint8_t weak_mods = 0;
30static uint8_t macro_mods = 0;
31#ifdef KEY_OVERRIDE_ENABLE 30#ifdef KEY_OVERRIDE_ENABLE
32static uint8_t weak_override_mods = 0; 31static uint8_t weak_override_mods = 0;
33static uint8_t suppressed_mods = 0; 32static uint8_t suppressed_mods = 0;
@@ -224,7 +223,6 @@ bool is_oneshot_enabled(void) { return keymap_config.oneshot_disable; }
224void send_keyboard_report(void) { 223void send_keyboard_report(void) {
225 keyboard_report->mods = real_mods; 224 keyboard_report->mods = real_mods;
226 keyboard_report->mods |= weak_mods; 225 keyboard_report->mods |= weak_mods;
227 keyboard_report->mods |= macro_mods;
228 226
229#ifndef NO_ACTION_ONESHOT 227#ifndef NO_ACTION_ONESHOT
230 if (oneshot_mods) { 228 if (oneshot_mods) {
@@ -325,33 +323,6 @@ void set_suppressed_override_mods(uint8_t mods) { suppressed_mods = mods; }
325void clear_suppressed_override_mods(void) { suppressed_mods = 0; } 323void clear_suppressed_override_mods(void) { suppressed_mods = 0; }
326#endif 324#endif
327 325
328/* macro modifier */
329/** \brief get macro mods
330 *
331 * FIXME: needs doc
332 */
333uint8_t get_macro_mods(void) { return macro_mods; }
334/** \brief add macro mods
335 *
336 * FIXME: needs doc
337 */
338void add_macro_mods(uint8_t mods) { macro_mods |= mods; }
339/** \brief del macro mods
340 *
341 * FIXME: needs doc
342 */
343void del_macro_mods(uint8_t mods) { macro_mods &= ~mods; }
344/** \brief set macro mods
345 *
346 * FIXME: needs doc
347 */
348void set_macro_mods(uint8_t mods) { macro_mods = mods; }
349/** \brief clear macro mods
350 *
351 * FIXME: needs doc
352 */
353void clear_macro_mods(void) { macro_mods = 0; }
354
355#ifndef NO_ACTION_ONESHOT 326#ifndef NO_ACTION_ONESHOT
356/** \brief get oneshot mods 327/** \brief get oneshot mods
357 * 328 *
diff --git a/quantum/action_util.h b/quantum/action_util.h
index f2b3897ae5..bfd0a6cf95 100644
--- a/quantum/action_util.h
+++ b/quantum/action_util.h
@@ -49,13 +49,6 @@ void del_weak_mods(uint8_t mods);
49void set_weak_mods(uint8_t mods); 49void set_weak_mods(uint8_t mods);
50void clear_weak_mods(void); 50void clear_weak_mods(void);
51 51
52/* macro modifier */
53uint8_t get_macro_mods(void);
54void add_macro_mods(uint8_t mods);
55void del_macro_mods(uint8_t mods);
56void set_macro_mods(uint8_t mods);
57void clear_macro_mods(void);
58
59/* oneshot modifier */ 52/* oneshot modifier */
60uint8_t get_oneshot_mods(void); 53uint8_t get_oneshot_mods(void);
61void add_oneshot_mods(uint8_t mods); 54void add_oneshot_mods(uint8_t mods);
diff --git a/quantum/keycode.h b/quantum/keycode.h
index 38a29b439b..a932550635 100644
--- a/quantum/keycode.h
+++ b/quantum/keycode.h
@@ -35,8 +35,6 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
35#define IS_SYSTEM(code) (KC_PWR <= (code) && (code) <= KC_WAKE) 35#define IS_SYSTEM(code) (KC_PWR <= (code) && (code) <= KC_WAKE)
36#define IS_CONSUMER(code) (KC_MUTE <= (code) && (code) <= KC_BRID) 36#define IS_CONSUMER(code) (KC_MUTE <= (code) && (code) <= KC_BRID)
37 37
38#define IS_FN(code) (KC_FN0 <= (code) && (code) <= KC_FN31)
39
40#define IS_MOUSEKEY(code) (KC_MS_UP <= (code) && (code) <= KC_MS_ACCEL2) 38#define IS_MOUSEKEY(code) (KC_MS_UP <= (code) && (code) <= KC_MS_ACCEL2)
41#define IS_MOUSEKEY_MOVE(code) (KC_MS_UP <= (code) && (code) <= KC_MS_RIGHT) 39#define IS_MOUSEKEY_MOVE(code) (KC_MS_UP <= (code) && (code) <= KC_MS_RIGHT)
42#define IS_MOUSEKEY_BUTTON(code) (KC_MS_BTN1 <= (code) && (code) <= KC_MS_BTN8) 40#define IS_MOUSEKEY_BUTTON(code) (KC_MS_BTN1 <= (code) && (code) <= KC_MS_BTN8)
@@ -62,11 +60,6 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
62#define MOD_MASK_SAG (MOD_MASK_SHIFT | MOD_MASK_ALT | MOD_MASK_GUI) 60#define MOD_MASK_SAG (MOD_MASK_SHIFT | MOD_MASK_ALT | MOD_MASK_GUI)
63#define MOD_MASK_CSAG (MOD_MASK_CTRL | MOD_MASK_SHIFT | MOD_MASK_ALT | MOD_MASK_GUI) 61#define MOD_MASK_CSAG (MOD_MASK_CTRL | MOD_MASK_SHIFT | MOD_MASK_ALT | MOD_MASK_GUI)
64 62
65#define FN_BIT(code) (1 << FN_INDEX(code))
66#define FN_INDEX(code) ((code)-KC_FN0)
67#define FN_MIN KC_FN0
68#define FN_MAX KC_FN31
69
70// clang-format off 63// clang-format off
71 64
72/* 65/*
@@ -509,41 +502,7 @@ enum internal_special_keycodes {
509 KC_MEDIA_FAST_FORWARD, 502 KC_MEDIA_FAST_FORWARD,
510 KC_MEDIA_REWIND, 503 KC_MEDIA_REWIND,
511 KC_BRIGHTNESS_UP, 504 KC_BRIGHTNESS_UP,
512 KC_BRIGHTNESS_DOWN, 505 KC_BRIGHTNESS_DOWN
513
514 /* Fn keys */
515 KC_FN0 = 0xC0,
516 KC_FN1,
517 KC_FN2,
518 KC_FN3,
519 KC_FN4,
520 KC_FN5,
521 KC_FN6,
522 KC_FN7,
523 KC_FN8,
524 KC_FN9,
525 KC_FN10,
526 KC_FN11,
527 KC_FN12,
528 KC_FN13,
529 KC_FN14,
530 KC_FN15,
531 KC_FN16, // 0xD0
532 KC_FN17,
533 KC_FN18,
534 KC_FN19,
535 KC_FN20,
536 KC_FN21,
537 KC_FN22,
538 KC_FN23,
539 KC_FN24,
540 KC_FN25,
541 KC_FN26,
542 KC_FN27,
543 KC_FN28,
544 KC_FN29,
545 KC_FN30,
546 KC_FN31
547}; 506};
548 507
549enum mouse_keys { 508enum mouse_keys {
diff --git a/quantum/keymap.h b/quantum/keymap.h
index 3fc41cafd8..2ee2e1b576 100644
--- a/quantum/keymap.h
+++ b/quantum/keymap.h
@@ -27,7 +27,6 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
27# include <ch.h> 27# include <ch.h>
28#endif 28#endif
29#include "keycode.h" 29#include "keycode.h"
30#include "action_macro.h"
31#include "report.h" 30#include "report.h"
32#include "host.h" 31#include "host.h"
33// #include "print.h" 32// #include "print.h"
@@ -49,8 +48,4 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
49// translates key to keycode 48// translates key to keycode
50uint16_t keymap_key_to_keycode(uint8_t layer, keypos_t key); 49uint16_t keymap_key_to_keycode(uint8_t layer, keypos_t key);
51 50
52// translates function id to action
53uint16_t keymap_function_id_to_action(uint16_t function_id);
54
55extern const uint16_t keymaps[][MATRIX_ROWS][MATRIX_COLS]; 51extern const uint16_t keymaps[][MATRIX_ROWS][MATRIX_COLS];
56extern const uint16_t fn_actions[];
diff --git a/quantum/keymap_common.c b/quantum/keymap_common.c
index 5007f15f11..cd67f71a8f 100644
--- a/quantum/keymap_common.c
+++ b/quantum/keymap_common.c
@@ -20,7 +20,6 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
20#include "keycode.h" 20#include "keycode.h"
21#include "action_layer.h" 21#include "action_layer.h"
22#include "action.h" 22#include "action.h"
23#include "action_macro.h"
24#include "debug.h" 23#include "debug.h"
25#include "quantum.h" 24#include "quantum.h"
26 25
@@ -80,24 +79,6 @@ action_t action_for_keycode(uint16_t keycode) {
80 // Split it up 79 // Split it up
81 action.code = ACTION_MODS_KEY(keycode >> 8, keycode & 0xFF); // adds modifier to key 80 action.code = ACTION_MODS_KEY(keycode >> 8, keycode & 0xFF); // adds modifier to key
82 break; 81 break;
83#ifndef NO_ACTION_FUNCTION
84 case KC_FN0 ... KC_FN31:
85 action.code = keymap_function_id_to_action(FN_INDEX(keycode));
86 break;
87 case QK_FUNCTION ... QK_FUNCTION_MAX:;
88 // Is a shortcut for function action_layer, pull last 12bits
89 // This means we have 4,096 FN macros at our disposal
90 action.code = keymap_function_id_to_action((int)keycode & 0xFFF);
91 break;
92#endif
93#ifndef NO_ACTION_MACRO
94 case QK_MACRO ... QK_MACRO_MAX:
95 if (keycode & 0x800) // tap macros have upper bit set
96 action.code = ACTION_MACRO_TAP(keycode & 0xFF);
97 else
98 action.code = ACTION_MACRO(keycode & 0xFF);
99 break;
100#endif
101#ifndef NO_ACTION_LAYER 82#ifndef NO_ACTION_LAYER
102 case QK_LAYER_TAP ... QK_LAYER_TAP_MAX: 83 case QK_LAYER_TAP ... QK_LAYER_TAP_MAX:
103 action.code = ACTION_LAYER_TAP_KEY((keycode >> 0x8) & 0xF, keycode & 0xFF); 84 action.code = ACTION_LAYER_TAP_KEY((keycode >> 0x8) & 0xF, keycode & 0xFF);
@@ -165,30 +146,8 @@ action_t action_for_keycode(uint16_t keycode) {
165 return action; 146 return action;
166} 147}
167 148
168__attribute__((weak)) const uint16_t PROGMEM fn_actions[] = {
169
170};
171
172/* Macro */
173__attribute__((weak)) const macro_t *action_get_macro(keyrecord_t *record, uint8_t id, uint8_t opt) { return MACRO_NONE; }
174
175/* Function */
176__attribute__((weak)) void action_function(keyrecord_t *record, uint8_t id, uint8_t opt) {}
177
178// translates key to keycode 149// translates key to keycode
179__attribute__((weak)) uint16_t keymap_key_to_keycode(uint8_t layer, keypos_t key) { 150__attribute__((weak)) uint16_t keymap_key_to_keycode(uint8_t layer, keypos_t key) {
180 // Read entire word (16bits) 151 // Read entire word (16bits)
181 return pgm_read_word(&keymaps[(layer)][(key.row)][(key.col)]); 152 return pgm_read_word(&keymaps[(layer)][(key.row)][(key.col)]);
182} 153}
183
184// translates function id to action
185__attribute__((weak)) uint16_t keymap_function_id_to_action(uint16_t function_id) {
186// The compiler sees the empty (weak) fn_actions and generates a warning
187// This function should not be called in that case, so the warning is too strict
188// If this function is called however, the keymap should have overridden fn_actions, and then the compile
189// is comparing against the wrong array
190#pragma GCC diagnostic push
191#pragma GCC diagnostic ignored "-Warray-bounds"
192 return pgm_read_word(&fn_actions[function_id]);
193#pragma GCC diagnostic pop
194}
diff --git a/quantum/process_keycode/process_haptic.c b/quantum/process_keycode/process_haptic.c
index 85b2ffcddd..0f07f9ac75 100644
--- a/quantum/process_keycode/process_haptic.c
+++ b/quantum/process_keycode/process_haptic.c
@@ -35,9 +35,6 @@ __attribute__((weak)) bool get_haptic_enabled_key(uint16_t keycode, keyrecord_t
35 case QK_MOMENTARY ... QK_MOMENTARY_MAX: 35 case QK_MOMENTARY ... QK_MOMENTARY_MAX:
36 case QK_LAYER_MOD ... QK_LAYER_MOD_MAX: 36 case QK_LAYER_MOD ... QK_LAYER_MOD_MAX:
37#endif 37#endif
38#ifdef NO_HAPTIC_FN
39 case KC_FN0 ... KC_FN31:
40#endif
41#ifdef NO_HAPTIC_ALPHA 38#ifdef NO_HAPTIC_ALPHA
42 case KC_A ... KC_Z: 39 case KC_A ... KC_Z:
43#endif 40#endif
diff --git a/quantum/quantum_keycodes.h b/quantum/quantum_keycodes.h
index 15ea0276a7..b5b3566786 100644
--- a/quantum/quantum_keycodes.h
+++ b/quantum/quantum_keycodes.h
@@ -37,10 +37,6 @@ enum quantum_keycodes {
37 QK_RALT = 0x1400, 37 QK_RALT = 0x1400,
38 QK_RGUI = 0x1800, 38 QK_RGUI = 0x1800,
39 QK_MODS_MAX = 0x1FFF, 39 QK_MODS_MAX = 0x1FFF,
40 QK_FUNCTION = 0x2000,
41 QK_FUNCTION_MAX = 0x2FFF,
42 QK_MACRO = 0x3000,
43 QK_MACRO_MAX = 0x3FFF,
44 QK_LAYER_TAP = 0x4000, 40 QK_LAYER_TAP = 0x4000,
45 QK_LAYER_TAP_MAX = 0x4FFF, 41 QK_LAYER_TAP_MAX = 0x4FFF,
46 QK_TO = 0x5000, 42 QK_TO = 0x5000,
@@ -710,12 +706,6 @@ enum quantum_keycodes {
710#define A(kc) LALT(kc) 706#define A(kc) LALT(kc)
711#define G(kc) LGUI(kc) 707#define G(kc) LGUI(kc)
712 708
713// Deprecated - do not use
714#define F(kc) (QK_FUNCTION | (kc))
715#define M(kc) (QK_MACRO | (kc))
716#define MACROTAP(kc) (QK_MACRO | (FUNC_TAP << 8) | (kc))
717#define MACRODOWN(...) (record->event.pressed ? MACRO(__VA_ARGS__) : MACRO_NONE)
718
719#define QK_GESC QK_GRAVE_ESCAPE 709#define QK_GESC QK_GRAVE_ESCAPE
720 710
721#define QK_BOOT QK_BOOTLOADER 711#define QK_BOOT QK_BOOTLOADER
diff --git a/tests/basic/test_macro.cpp b/tests/basic/test_macro.cpp
deleted file mode 100644
index ae2f3b32e3..0000000000
--- a/tests/basic/test_macro.cpp
+++ /dev/null
@@ -1,88 +0,0 @@
1/* Copyright 2017 Fred Sundvik
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
17#include "test_common.hpp"
18#include "time.h"
19
20using testing::InSequence;
21using testing::InvokeWithoutArgs;
22
23class Macro : public TestFixture {};
24
25#define AT_TIME(t) WillOnce(InvokeWithoutArgs([current_time]() { EXPECT_EQ(timer_elapsed32(current_time), t); }))
26
27extern "C" const macro_t *action_get_macro(keyrecord_t *record, uint8_t id, uint8_t opt) {
28 if (record->event.pressed) {
29 switch (id) {
30 case 0:
31 return MACRO(D(LSFT), T(H), U(LSFT), T(E), T(L), T(L), T(O), T(SPACE), W(100), D(LSFT), T(W), U(LSFT), I(10), T(O), T(R), T(L), T(D), D(LSFT), T(1), U(LSFT), END);
32 }
33 }
34 return MACRO_NONE;
35};
36
37TEST_F(Macro, PlayASimpleMacro) {
38 TestDriver driver;
39 InSequence s;
40 auto key_macro = KeymapKey(0, 8, 0, M(0));
41
42 set_keymap({key_macro});
43
44 key_macro.press();
45
46 uint32_t current_time = timer_read32();
47 EXPECT_CALL(driver, send_keyboard_mock(KeyboardReport(KC_LEFT_SHIFT))).AT_TIME(0);
48 EXPECT_CALL(driver, send_keyboard_mock(KeyboardReport(KC_LEFT_SHIFT, KC_H))).AT_TIME(0);
49 EXPECT_CALL(driver, send_keyboard_mock(KeyboardReport(KC_LEFT_SHIFT))).AT_TIME(0);
50 EXPECT_CALL(driver, send_keyboard_mock(KeyboardReport())).AT_TIME(0);
51 EXPECT_CALL(driver, send_keyboard_mock(KeyboardReport(KC_E))).AT_TIME(0);
52 // The macro system could actually skip these empty keyboard reports
53 // it should be enough to just send a report with the next key down
54 EXPECT_CALL(driver, send_keyboard_mock(KeyboardReport())).AT_TIME(0);
55 EXPECT_CALL(driver, send_keyboard_mock(KeyboardReport(KC_L))).AT_TIME(0);
56 EXPECT_CALL(driver, send_keyboard_mock(KeyboardReport())).AT_TIME(0);
57 EXPECT_CALL(driver, send_keyboard_mock(KeyboardReport(KC_L))).AT_TIME(0);
58 EXPECT_CALL(driver, send_keyboard_mock(KeyboardReport())).AT_TIME(0);
59 EXPECT_CALL(driver, send_keyboard_mock(KeyboardReport(KC_O))).AT_TIME(0);
60 EXPECT_CALL(driver, send_keyboard_mock(KeyboardReport())).AT_TIME(0);
61 EXPECT_CALL(driver, send_keyboard_mock(KeyboardReport(KC_SPACE))).AT_TIME(0);
62 EXPECT_CALL(driver, send_keyboard_mock(KeyboardReport())).AT_TIME(0);
63 EXPECT_CALL(driver, send_keyboard_mock(KeyboardReport(KC_LEFT_SHIFT))).AT_TIME(100);
64 EXPECT_CALL(driver, send_keyboard_mock(KeyboardReport(KC_LEFT_SHIFT, KC_W))).AT_TIME(100);
65 EXPECT_CALL(driver, send_keyboard_mock(KeyboardReport(KC_LEFT_SHIFT))).AT_TIME(100);
66 EXPECT_CALL(driver, send_keyboard_mock(KeyboardReport())).AT_TIME(100);
67 EXPECT_CALL(driver, send_keyboard_mock(KeyboardReport(KC_O)))
68 // BUG: The timer should not really have advanced 10 ms here
69 // See issue #1477
70 .AT_TIME(110);
71 EXPECT_CALL(driver, send_keyboard_mock(KeyboardReport()))
72 // BUG: The timer should not advance on both keydown and key-up
73 // See issue #1477
74 .AT_TIME(120);
75 EXPECT_CALL(driver, send_keyboard_mock(KeyboardReport(KC_R))).AT_TIME(130);
76 EXPECT_CALL(driver, send_keyboard_mock(KeyboardReport())).AT_TIME(140);
77 EXPECT_CALL(driver, send_keyboard_mock(KeyboardReport(KC_L))).AT_TIME(150);
78 EXPECT_CALL(driver, send_keyboard_mock(KeyboardReport())).AT_TIME(160);
79 EXPECT_CALL(driver, send_keyboard_mock(KeyboardReport(KC_D))).AT_TIME(170);
80 EXPECT_CALL(driver, send_keyboard_mock(KeyboardReport())).AT_TIME(180);
81 EXPECT_CALL(driver, send_keyboard_mock(KeyboardReport(KC_LEFT_SHIFT))).AT_TIME(190);
82 EXPECT_CALL(driver, send_keyboard_mock(KeyboardReport(KC_LEFT_SHIFT, KC_1))).AT_TIME(200);
83 EXPECT_CALL(driver, send_keyboard_mock(KeyboardReport(KC_LEFT_SHIFT))).AT_TIME(210);
84 EXPECT_CALL(driver, send_keyboard_mock(KeyboardReport())).AT_TIME(220);
85 run_one_scan_loop();
86
87 key_macro.release();
88}