Consolidate send_string implementations. (#24817)
This commit is contained in:
		
							parent
							
								
									47575d4af1
								
							
						
					
					
						commit
						a6a0dc8039
					
				
					 4 changed files with 64 additions and 102 deletions
				
			
		| 
						 | 
				
			
			@ -245,6 +245,17 @@ void dynamic_keymap_macro_set_buffer(uint16_t offset, uint16_t size, uint8_t *da
 | 
			
		|||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
typedef struct send_string_eeprom_state_t {
 | 
			
		||||
    const uint8_t *ptr;
 | 
			
		||||
} send_string_eeprom_state_t;
 | 
			
		||||
 | 
			
		||||
char send_string_get_next_eeprom(void *arg) {
 | 
			
		||||
    send_string_eeprom_state_t *state = (send_string_eeprom_state_t *)arg;
 | 
			
		||||
    char                        ret   = eeprom_read_byte(state->ptr);
 | 
			
		||||
    state->ptr++;
 | 
			
		||||
    return ret;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void dynamic_keymap_macro_reset(void) {
 | 
			
		||||
    void *p   = (void *)(DYNAMIC_KEYMAP_MACRO_EEPROM_ADDR);
 | 
			
		||||
    void *end = (void *)(DYNAMIC_KEYMAP_MACRO_EEPROM_ADDR + DYNAMIC_KEYMAP_MACRO_EEPROM_SIZE);
 | 
			
		||||
| 
						 | 
				
			
			@ -284,57 +295,6 @@ void dynamic_keymap_macro_send(uint8_t id) {
 | 
			
		|||
        ++p;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    // Send the macro string by making a temporary string.
 | 
			
		||||
    char data[8] = {0};
 | 
			
		||||
    // We already checked there was a null at the end of
 | 
			
		||||
    // the buffer, so this cannot go past the end
 | 
			
		||||
    while (1) {
 | 
			
		||||
        data[0] = eeprom_read_byte(p++);
 | 
			
		||||
        data[1] = 0;
 | 
			
		||||
        // Stop at the null terminator of this macro string
 | 
			
		||||
        if (data[0] == 0) {
 | 
			
		||||
            break;
 | 
			
		||||
        }
 | 
			
		||||
        if (data[0] == SS_QMK_PREFIX) {
 | 
			
		||||
            // Get the code
 | 
			
		||||
            data[1] = eeprom_read_byte(p++);
 | 
			
		||||
            // Unexpected null, abort.
 | 
			
		||||
            if (data[1] == 0) {
 | 
			
		||||
                return;
 | 
			
		||||
            }
 | 
			
		||||
            if (data[1] == SS_TAP_CODE || data[1] == SS_DOWN_CODE || data[1] == SS_UP_CODE) {
 | 
			
		||||
                // Get the keycode
 | 
			
		||||
                data[2] = eeprom_read_byte(p++);
 | 
			
		||||
                // Unexpected null, abort.
 | 
			
		||||
                if (data[2] == 0) {
 | 
			
		||||
                    return;
 | 
			
		||||
                }
 | 
			
		||||
                // Null terminate
 | 
			
		||||
                data[3] = 0;
 | 
			
		||||
            } else if (data[1] == SS_DELAY_CODE) {
 | 
			
		||||
                // Get the number and '|'
 | 
			
		||||
                // At most this is 4 digits plus '|'
 | 
			
		||||
                uint8_t i = 2;
 | 
			
		||||
                while (1) {
 | 
			
		||||
                    data[i] = eeprom_read_byte(p++);
 | 
			
		||||
                    // Unexpected null, abort
 | 
			
		||||
                    if (data[i] == 0) {
 | 
			
		||||
                        return;
 | 
			
		||||
                    }
 | 
			
		||||
                    // Found '|', send it
 | 
			
		||||
                    if (data[i] == '|') {
 | 
			
		||||
                        data[i + 1] = 0;
 | 
			
		||||
                        break;
 | 
			
		||||
                    }
 | 
			
		||||
                    // If haven't found '|' by i==6 then
 | 
			
		||||
                    // number too big, abort
 | 
			
		||||
                    if (i == 6) {
 | 
			
		||||
                        return;
 | 
			
		||||
                    }
 | 
			
		||||
                    ++i;
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
        send_string_with_delay(data, DYNAMIC_KEYMAP_MACRO_DELAY);
 | 
			
		||||
    }
 | 
			
		||||
    send_string_eeprom_state_t state = {p};
 | 
			
		||||
    send_string_with_delay_impl(send_string_get_next_eeprom, &state, DYNAMIC_KEYMAP_MACRO_DELAY);
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -150,48 +150,65 @@ void send_string(const char *string) {
 | 
			
		|||
    send_string_with_delay(string, TAP_CODE_DELAY);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void send_string_with_delay(const char *string, uint8_t interval) {
 | 
			
		||||
void send_string_with_delay_impl(char (*getter)(void *), void *arg, uint8_t interval) {
 | 
			
		||||
    while (1) {
 | 
			
		||||
        char ascii_code = *string;
 | 
			
		||||
        char ascii_code = getter(arg);
 | 
			
		||||
        if (!ascii_code) break;
 | 
			
		||||
        if (ascii_code == SS_QMK_PREFIX) {
 | 
			
		||||
            ascii_code = *(++string);
 | 
			
		||||
            ascii_code = getter(arg);
 | 
			
		||||
 | 
			
		||||
            if (ascii_code == SS_TAP_CODE) {
 | 
			
		||||
                // tap
 | 
			
		||||
                uint8_t keycode = *(++string);
 | 
			
		||||
                uint8_t keycode = getter(arg);
 | 
			
		||||
                tap_code(keycode);
 | 
			
		||||
            } else if (ascii_code == SS_DOWN_CODE) {
 | 
			
		||||
                // down
 | 
			
		||||
                uint8_t keycode = *(++string);
 | 
			
		||||
                uint8_t keycode = getter(arg);
 | 
			
		||||
                register_code(keycode);
 | 
			
		||||
            } else if (ascii_code == SS_UP_CODE) {
 | 
			
		||||
                // up
 | 
			
		||||
                uint8_t keycode = *(++string);
 | 
			
		||||
                uint8_t keycode = getter(arg);
 | 
			
		||||
                unregister_code(keycode);
 | 
			
		||||
            } else if (ascii_code == SS_DELAY_CODE) {
 | 
			
		||||
                // delay
 | 
			
		||||
                int     ms      = 0;
 | 
			
		||||
                uint8_t keycode = *(++string);
 | 
			
		||||
                int ms     = 0;
 | 
			
		||||
                ascii_code = getter(arg);
 | 
			
		||||
 | 
			
		||||
                while (isdigit(keycode)) {
 | 
			
		||||
                while (isdigit(ascii_code)) {
 | 
			
		||||
                    ms *= 10;
 | 
			
		||||
                    ms += keycode - '0';
 | 
			
		||||
                    keycode = *(++string);
 | 
			
		||||
                    ms += ascii_code - '0';
 | 
			
		||||
                    ascii_code = getter(arg);
 | 
			
		||||
                }
 | 
			
		||||
 | 
			
		||||
                wait_ms(ms);
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            wait_ms(interval);
 | 
			
		||||
 | 
			
		||||
            // if we had a delay that terminated with a null, we're done
 | 
			
		||||
            if (ascii_code == 0) break;
 | 
			
		||||
        } else {
 | 
			
		||||
            send_char_with_delay(ascii_code, interval);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        ++string;
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
typedef struct send_string_memory_state_t {
 | 
			
		||||
    const char *string;
 | 
			
		||||
} send_string_memory_state_t;
 | 
			
		||||
 | 
			
		||||
char send_string_get_next_ram(void *arg) {
 | 
			
		||||
    send_string_memory_state_t *state = (send_string_memory_state_t *)arg;
 | 
			
		||||
    char                        ret   = *state->string;
 | 
			
		||||
    state->string++;
 | 
			
		||||
    return ret;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void send_string_with_delay(const char *string, uint8_t interval) {
 | 
			
		||||
    send_string_memory_state_t state = {string};
 | 
			
		||||
    send_string_with_delay_impl(send_string_get_next_ram, &state, interval);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void send_char(char ascii_code) {
 | 
			
		||||
    send_char_with_delay(ascii_code, TAP_CODE_DELAY);
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			@ -297,42 +314,15 @@ void send_string_P(const char *string) {
 | 
			
		|||
    send_string_with_delay_P(string, TAP_CODE_DELAY);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
char send_string_get_next_progmem(void *arg) {
 | 
			
		||||
    send_string_memory_state_t *state = (send_string_memory_state_t *)arg;
 | 
			
		||||
    char                        ret   = pgm_read_byte(state->string);
 | 
			
		||||
    state->string++;
 | 
			
		||||
    return ret;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void send_string_with_delay_P(const char *string, uint8_t interval) {
 | 
			
		||||
    while (1) {
 | 
			
		||||
        char ascii_code = pgm_read_byte(string);
 | 
			
		||||
        if (!ascii_code) break;
 | 
			
		||||
        if (ascii_code == SS_QMK_PREFIX) {
 | 
			
		||||
            ascii_code = pgm_read_byte(++string);
 | 
			
		||||
 | 
			
		||||
            if (ascii_code == SS_TAP_CODE) {
 | 
			
		||||
                // tap
 | 
			
		||||
                uint8_t keycode = pgm_read_byte(++string);
 | 
			
		||||
                tap_code(keycode);
 | 
			
		||||
            } else if (ascii_code == SS_DOWN_CODE) {
 | 
			
		||||
                // down
 | 
			
		||||
                uint8_t keycode = pgm_read_byte(++string);
 | 
			
		||||
                register_code(keycode);
 | 
			
		||||
            } else if (ascii_code == SS_UP_CODE) {
 | 
			
		||||
                // up
 | 
			
		||||
                uint8_t keycode = pgm_read_byte(++string);
 | 
			
		||||
                unregister_code(keycode);
 | 
			
		||||
            } else if (ascii_code == SS_DELAY_CODE) {
 | 
			
		||||
                // delay
 | 
			
		||||
                int     ms      = 0;
 | 
			
		||||
                uint8_t keycode = pgm_read_byte(++string);
 | 
			
		||||
 | 
			
		||||
                while (isdigit(keycode)) {
 | 
			
		||||
                    ms *= 10;
 | 
			
		||||
                    ms += keycode - '0';
 | 
			
		||||
                    keycode = pgm_read_byte(++string);
 | 
			
		||||
                }
 | 
			
		||||
                wait_ms(ms);
 | 
			
		||||
            }
 | 
			
		||||
        } else {
 | 
			
		||||
            send_char_with_delay(ascii_code, interval);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        ++string;
 | 
			
		||||
    }
 | 
			
		||||
    send_string_memory_state_t state = {string};
 | 
			
		||||
    send_string_with_delay_impl(send_string_get_next_progmem, &state, interval);
 | 
			
		||||
}
 | 
			
		||||
#endif
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -161,4 +161,12 @@ void send_string_with_delay_P(const char *string, uint8_t interval);
 | 
			
		|||
 */
 | 
			
		||||
#define SEND_STRING_DELAY(string, interval) send_string_with_delay_P(PSTR(string), interval)
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * \brief Actual implementation function that iterates and sends the string returned by the getter function.
 | 
			
		||||
 *
 | 
			
		||||
 * The getter assumes that the next byte is available to be read, and returns it. `arg` is passed in and can be whatever
 | 
			
		||||
 * makes most sense for the getter -- each invocation of `getter` must advance its position in the source.
 | 
			
		||||
 */
 | 
			
		||||
void send_string_with_delay_impl(char (*getter)(void *), void *arg, uint8_t interval);
 | 
			
		||||
 | 
			
		||||
/** \} */
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue