[PATCH 1/2] efi_loader: efi_console: support editable input fields
Ilias Apalodimas
ilias.apalodimas at linaro.org
Fri Oct 24 13:58:32 CEST 2025
On Thu, 23 Oct 2025 at 17:26, Casey Connolly <casey.connolly at linaro.org> wrote:
>
> When editing eficonfig "optional data" (typically cmdline arguments)
> it's useful to be able to edit the string rather than having to re-type
> the entire thing. Implement support for editing buffers to make this a
> whole lot nicer. Specifically, add support for moving the cursor with
> the arrow keys and End key as well as deleting backwards with the delete
> key.
>
> Signed-off-by: Casey Connolly <casey.connolly at linaro.org>
> ---
> cmd/eficonfig.c | 2 ++
> lib/efi_loader/efi_console.c | 52 ++++++++++++++++++++++++++++++++++++--------
> 2 files changed, 45 insertions(+), 9 deletions(-)
>
> diff --git a/cmd/eficonfig.c b/cmd/eficonfig.c
> index 8ac0fb98e02e..d8d946c87ac8 100644
> --- a/cmd/eficonfig.c
> +++ b/cmd/eficonfig.c
> @@ -973,8 +973,10 @@ static efi_status_t handle_user_input(u16 *buf, int buf_size,
> tmp = calloc(1, buf_size * sizeof(u16));
> if (!tmp)
> return EFI_OUT_OF_RESOURCES;
>
> + /* Populate tmp so user can edit existing string */
> + u16_strcpy(tmp, buf);
> ret = efi_console_get_u16_string(cin, tmp, buf_size, NULL, 4, cursor_col);
> if (ret == EFI_SUCCESS)
> u16_strcpy(buf, tmp);
>
> diff --git a/lib/efi_loader/efi_console.c b/lib/efi_loader/efi_console.c
> index 953f6831466e..7bfd18233feb 100644
> --- a/lib/efi_loader/efi_console.c
> +++ b/lib/efi_loader/efi_console.c
> @@ -1383,36 +1383,61 @@ efi_status_t efi_console_get_u16_string(struct efi_simple_text_input_protocol *c
> efi_console_filter_func filter_func,
> int row, int col)
> {
> efi_status_t ret;
> - efi_uintn_t len = 0;
> + efi_uintn_t len;
> + efi_uintn_t cursor;
> + efi_uintn_t i;
> struct efi_input_key key;
>
> printf(ANSI_CURSOR_POSITION
> ANSI_CLEAR_LINE_TO_END
> ANSI_CURSOR_SHOW, row, col);
>
> efi_cin_empty_buffer();
>
> + len = u16_strlen(buf);
> + cursor = len;
> for (;;) {
> + printf(ANSI_CURSOR_POSITION "%ls"
> + ANSI_CLEAR_LINE_TO_END ANSI_CURSOR_POSITION,
> + row, col, buf, row, col + (int)cursor);
> do {
> ret = EFI_CALL(cin->read_key_stroke(cin, &key));
> mdelay(10);
> } while (ret == EFI_NOT_READY);
>
> if (key.unicode_char == u'\b') {
> - if (len > 0)
> - buf[--len] = u'\0';
> -
> - printf(ANSI_CURSOR_POSITION
> - "%ls"
> - ANSI_CLEAR_LINE_TO_END, row, col, buf);
> + if (cursor > 0) {
> + if (cursor == len) {
> + buf[--cursor] = u'\0';
> + } else {
> + for (i = cursor - 1; i < len; i++)
> + buf[i] = buf[i + 1];
> + cursor--;
> + }
> + len--;
> + }
> + continue;
> + } else if (key.scan_code == 8) { /* delete */
> + for (i = cursor; i <= len; i++)
> + buf[i] = buf[i + 1];
> + len--;
> continue;
> } else if (key.unicode_char == u'\r') {
> buf[len] = u'\0';
> return EFI_SUCCESS;
> } else if (key.unicode_char == 0x3 || key.scan_code == 23) {
> return EFI_ABORTED;
> + } else if (key.scan_code == 3) { /* Right arrow */
> + cursor += (cursor < len) ? 1 : 0;
> + continue;
> + } else if (key.scan_code == 4) { /* Left arrow */
> + cursor -= (cursor > 0) ? 1 : 0;
> + continue;
> + } else if (key.scan_code == 6) { /* End */
> + cursor = len;
> + continue;
> } else if (key.unicode_char < 0x20) {
> /* ignore control codes other than Ctrl+C, '\r' and '\b' */
> continue;
> } else if (key.scan_code != 0) {
> @@ -1427,9 +1452,18 @@ efi_status_t efi_console_get_u16_string(struct efi_simple_text_input_protocol *c
>
> if (len >= (count - 1))
> continue;
>
> - buf[len] = key.unicode_char;
> + /*
> + * Insert the character into the middle of the buffer, shift the
> + * characters after the cursor along. The check above ensures we
> + * will never overflow the buffer.
> + * If the cursor is at the end of the string then this will
> + * do nothing.
> + */
> + for (i = len + 1; i > cursor; i--)
> + buf[i] = buf[i - 1];
> + buf[cursor] = key.unicode_char;
> + cursor++;
> len++;
> - printf(ANSI_CURSOR_POSITION "%ls", row, col, buf);
> }
> }
>
> --
> 2.51.0
>
Acked-by: Ilias Apalodimas <ilias.apalodimas at linaro.org>
Tested-by: Ilias Apalodimas <ilias.apalodimas at linaro.org>
More information about the U-Boot
mailing list