···635635 TRI_LAYER_ENABLE := yes
636636endif
637637638638+ifeq ($(strip $(DYNAMIC_KEYMAP_ENABLE)), yes)
639639+ SEND_STRING_ENABLE := yes
640640+endif
641641+638642VALID_CUSTOM_MATRIX_TYPES:= yes lite no
639643640644CUSTOM_MATRIX ?= no
+13-53
quantum/dynamic_keymap.c
···245245 }
246246}
247247248248+typedef struct send_string_eeprom_state_t {
249249+ const uint8_t *ptr;
250250+} send_string_eeprom_state_t;
251251+252252+char send_string_get_next_eeprom(void *arg) {
253253+ send_string_eeprom_state_t *state = (send_string_eeprom_state_t *)arg;
254254+ char ret = eeprom_read_byte(state->ptr);
255255+ state->ptr++;
256256+ return ret;
257257+}
258258+248259void dynamic_keymap_macro_reset(void) {
249260 void *p = (void *)(DYNAMIC_KEYMAP_MACRO_EEPROM_ADDR);
250261 void *end = (void *)(DYNAMIC_KEYMAP_MACRO_EEPROM_ADDR + DYNAMIC_KEYMAP_MACRO_EEPROM_SIZE);
···284295 ++p;
285296 }
286297287287- // Send the macro string by making a temporary string.
288288- char data[8] = {0};
289289- // We already checked there was a null at the end of
290290- // the buffer, so this cannot go past the end
291291- while (1) {
292292- data[0] = eeprom_read_byte(p++);
293293- data[1] = 0;
294294- // Stop at the null terminator of this macro string
295295- if (data[0] == 0) {
296296- break;
297297- }
298298- if (data[0] == SS_QMK_PREFIX) {
299299- // Get the code
300300- data[1] = eeprom_read_byte(p++);
301301- // Unexpected null, abort.
302302- if (data[1] == 0) {
303303- return;
304304- }
305305- if (data[1] == SS_TAP_CODE || data[1] == SS_DOWN_CODE || data[1] == SS_UP_CODE) {
306306- // Get the keycode
307307- data[2] = eeprom_read_byte(p++);
308308- // Unexpected null, abort.
309309- if (data[2] == 0) {
310310- return;
311311- }
312312- // Null terminate
313313- data[3] = 0;
314314- } else if (data[1] == SS_DELAY_CODE) {
315315- // Get the number and '|'
316316- // At most this is 4 digits plus '|'
317317- uint8_t i = 2;
318318- while (1) {
319319- data[i] = eeprom_read_byte(p++);
320320- // Unexpected null, abort
321321- if (data[i] == 0) {
322322- return;
323323- }
324324- // Found '|', send it
325325- if (data[i] == '|') {
326326- data[i + 1] = 0;
327327- break;
328328- }
329329- // If haven't found '|' by i==6 then
330330- // number too big, abort
331331- if (i == 6) {
332332- return;
333333- }
334334- ++i;
335335- }
336336- }
337337- }
338338- send_string_with_delay(data, DYNAMIC_KEYMAP_MACRO_DELAY);
339339- }
298298+ send_string_eeprom_state_t state = {p};
299299+ send_string_with_delay_impl(send_string_get_next_eeprom, &state, DYNAMIC_KEYMAP_MACRO_DELAY);
340300}
+39-49
quantum/send_string/send_string.c
···150150 send_string_with_delay(string, TAP_CODE_DELAY);
151151}
152152153153-void send_string_with_delay(const char *string, uint8_t interval) {
153153+void send_string_with_delay_impl(char (*getter)(void *), void *arg, uint8_t interval) {
154154 while (1) {
155155- char ascii_code = *string;
155155+ char ascii_code = getter(arg);
156156 if (!ascii_code) break;
157157 if (ascii_code == SS_QMK_PREFIX) {
158158- ascii_code = *(++string);
158158+ ascii_code = getter(arg);
159159160160 if (ascii_code == SS_TAP_CODE) {
161161 // tap
162162- uint8_t keycode = *(++string);
162162+ uint8_t keycode = getter(arg);
163163 tap_code(keycode);
164164 } else if (ascii_code == SS_DOWN_CODE) {
165165 // down
166166- uint8_t keycode = *(++string);
166166+ uint8_t keycode = getter(arg);
167167 register_code(keycode);
168168 } else if (ascii_code == SS_UP_CODE) {
169169 // up
170170- uint8_t keycode = *(++string);
170170+ uint8_t keycode = getter(arg);
171171 unregister_code(keycode);
172172 } else if (ascii_code == SS_DELAY_CODE) {
173173 // delay
174174- int ms = 0;
175175- uint8_t keycode = *(++string);
174174+ int ms = 0;
175175+ ascii_code = getter(arg);
176176177177- while (isdigit(keycode)) {
177177+ while (isdigit(ascii_code)) {
178178 ms *= 10;
179179- ms += keycode - '0';
180180- keycode = *(++string);
179179+ ms += ascii_code - '0';
180180+ ascii_code = getter(arg);
181181 }
182182183183 wait_ms(ms);
184184 }
185185186186 wait_ms(interval);
187187+188188+ // if we had a delay that terminated with a null, we're done
189189+ if (ascii_code == 0) break;
187190 } else {
188191 send_char_with_delay(ascii_code, interval);
189192 }
193193+ }
194194+}
190195191191- ++string;
192192- }
196196+typedef struct send_string_memory_state_t {
197197+ const char *string;
198198+} send_string_memory_state_t;
199199+200200+char send_string_get_next_ram(void *arg) {
201201+ send_string_memory_state_t *state = (send_string_memory_state_t *)arg;
202202+ char ret = *state->string;
203203+ state->string++;
204204+ return ret;
205205+}
206206+207207+void send_string_with_delay(const char *string, uint8_t interval) {
208208+ send_string_memory_state_t state = {string};
209209+ send_string_with_delay_impl(send_string_get_next_ram, &state, interval);
193210}
194211195212void send_char(char ascii_code) {
···297314 send_string_with_delay_P(string, TAP_CODE_DELAY);
298315}
299316317317+char send_string_get_next_progmem(void *arg) {
318318+ send_string_memory_state_t *state = (send_string_memory_state_t *)arg;
319319+ char ret = pgm_read_byte(state->string);
320320+ state->string++;
321321+ return ret;
322322+}
323323+300324void send_string_with_delay_P(const char *string, uint8_t interval) {
301301- while (1) {
302302- char ascii_code = pgm_read_byte(string);
303303- if (!ascii_code) break;
304304- if (ascii_code == SS_QMK_PREFIX) {
305305- ascii_code = pgm_read_byte(++string);
306306-307307- if (ascii_code == SS_TAP_CODE) {
308308- // tap
309309- uint8_t keycode = pgm_read_byte(++string);
310310- tap_code(keycode);
311311- } else if (ascii_code == SS_DOWN_CODE) {
312312- // down
313313- uint8_t keycode = pgm_read_byte(++string);
314314- register_code(keycode);
315315- } else if (ascii_code == SS_UP_CODE) {
316316- // up
317317- uint8_t keycode = pgm_read_byte(++string);
318318- unregister_code(keycode);
319319- } else if (ascii_code == SS_DELAY_CODE) {
320320- // delay
321321- int ms = 0;
322322- uint8_t keycode = pgm_read_byte(++string);
323323-324324- while (isdigit(keycode)) {
325325- ms *= 10;
326326- ms += keycode - '0';
327327- keycode = pgm_read_byte(++string);
328328- }
329329- wait_ms(ms);
330330- }
331331- } else {
332332- send_char_with_delay(ascii_code, interval);
333333- }
334334-335335- ++string;
336336- }
325325+ send_string_memory_state_t state = {string};
326326+ send_string_with_delay_impl(send_string_get_next_progmem, &state, interval);
337327}
338328#endif
+8
quantum/send_string/send_string.h
···161161 */
162162#define SEND_STRING_DELAY(string, interval) send_string_with_delay_P(PSTR(string), interval)
163163164164+/**
165165+ * \brief Actual implementation function that iterates and sends the string returned by the getter function.
166166+ *
167167+ * The getter assumes that the next byte is available to be read, and returns it. `arg` is passed in and can be whatever
168168+ * makes most sense for the getter -- each invocation of `getter` must advance its position in the source.
169169+ */
170170+void send_string_with_delay_impl(char (*getter)(void *), void *arg, uint8_t interval);
171171+164172/** \} */