From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from phobos.denx.de (phobos.denx.de [85.214.62.61]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by smtp.lore.kernel.org (Postfix) with ESMTPS id 28AF1C4708D for ; Fri, 6 Jan 2023 15:03:47 +0000 (UTC) Received: from h2850616.stratoserver.net (localhost [IPv6:::1]) by phobos.denx.de (Postfix) with ESMTP id 6F5A7853C5; Fri, 6 Jan 2023 16:03:44 +0100 (CET) Authentication-Results: phobos.denx.de; dmarc=pass (p=none dis=none) header.from=chromium.org Authentication-Results: phobos.denx.de; spf=pass smtp.mailfrom=u-boot-bounces@lists.denx.de Authentication-Results: phobos.denx.de; dkim=pass (1024-bit key; unprotected) header.d=chromium.org header.i=@chromium.org header.b="eSQhS4Ie"; dkim-atps=neutral Received: by phobos.denx.de (Postfix, from userid 109) id 7131D8561B; Fri, 6 Jan 2023 15:53:33 +0100 (CET) Received: from mail-il1-x12e.google.com (mail-il1-x12e.google.com [IPv6:2607:f8b0:4864:20::12e]) (using TLSv1.3 with cipher TLS_AES_128_GCM_SHA256 (128/128 bits)) (No client certificate requested) by phobos.denx.de (Postfix) with ESMTPS id BAB8985608 for ; Fri, 6 Jan 2023 15:52:58 +0100 (CET) Authentication-Results: phobos.denx.de; dmarc=pass (p=none dis=none) header.from=chromium.org Authentication-Results: phobos.denx.de; spf=pass smtp.mailfrom=sjg@chromium.org Received: by mail-il1-x12e.google.com with SMTP id bp26so1091760ilb.3 for ; Fri, 06 Jan 2023 06:52:58 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=chromium.org; s=google; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to; bh=Iui7ID6Sk1nI9rZFkOeAHMQGew29q5CMlV2FJBPIp9o=; b=eSQhS4Ie8V6hw5ed2MaeSW6es+UmgYKIb4RiOb6cb3dGYuJnDOCun5XejjLL6xrw7G YM3gn6yjgoKKd92rILNKQJtxhsl4yJkzKqi2VLPBgdf+ffGuOkR1sY0W/4Cyg7cnB5Ae P+oxxeMqc35yE5/7Qmn3a3Zp5ia9kyEC8n6N4= X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=Iui7ID6Sk1nI9rZFkOeAHMQGew29q5CMlV2FJBPIp9o=; b=NqmR3/1Q3G4NJ4mS9FWVY0QVqBDZ/i4DF5HDDL/6YnhhgboygzSMjh6Zm/V/E6ntAj xvQr9RYpjY841ciQVy3b3kNLY0X7N6BbuLYskB/GyGmc6gZZoMqQ9kAtyjLogm9mR4jy 8ACo02qiQYWYQZtZAwrLmi2FlKPWBgOkJUfa92MA7j0dok7jFiuddbh29sIcm5FZQkUZ Zj/xpYq+IFQK6dYyY/Nr54n8MaVjxZW2N+v7eM06zMksB6/mqvXRehhG8qQu1CS2dAOk uRFw+Sza/CCZQJYiJowkjr43Ujnaqiq40CANwE1Ok2N0uamieYYhu8+nb1HY8m2bq+QC Y3Iw== X-Gm-Message-State: AFqh2krePARRG7BZ3BP1UIkvc/BJfdrhVOEG65JsXB3/G4eZxq4JgQeE r3WXDSPRZRSqBrMezoGecr67oRloyp11OzpospI= X-Google-Smtp-Source: AMrXdXsQbTZqPij+HceMJPbFGFRKfm/spaWorwu4Ou85FKrrKQOl3gSYSKpi2nvwc77f5hsO32/UhA== X-Received: by 2002:a05:6e02:1ca2:b0:30d:851c:d939 with SMTP id x2-20020a056e021ca200b0030d851cd939mr4866608ill.30.1673016777206; Fri, 06 Jan 2023 06:52:57 -0800 (PST) Received: from sjg1.lan (c-71-56-217-229.hsd1.co.comcast.net. [71.56.217.229]) by smtp.gmail.com with ESMTPSA id w20-20020a05663800d400b00375783003fcsm360273jao.136.2023.01.06.06.52.56 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Fri, 06 Jan 2023 06:52:57 -0800 (PST) From: Simon Glass To: U-Boot Mailing List Cc: Anatolij Gustschin , Tom Rini , Heinrich Schuchardt , Simon Glass Subject: [PATCH v3 08/25] menu: Make use of CLI character processing Date: Fri, 6 Jan 2023 08:52:26 -0600 Message-Id: <20230106145243.411626-9-sjg@chromium.org> X-Mailer: git-send-email 2.39.0.314.g84b9a713c41-goog In-Reply-To: <20230106145243.411626-1-sjg@chromium.org> References: <20230106145243.411626-1-sjg@chromium.org> MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-BeenThere: u-boot@lists.denx.de X-Mailman-Version: 2.1.39 Precedence: list List-Id: U-Boot discussion List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: u-boot-bounces@lists.denx.de Sender: "U-Boot" X-Virus-Scanned: clamav-milter 0.103.6 at phobos.denx.de X-Virus-Status: Clean Avoid duplicating some of the escape-sequence processing here and use the CLI function instead. Signed-off-by: Simon Glass --- (no changes since v2) Changes in v2: - Rebase to master cmd/bootmenu.c | 9 +++-- cmd/eficonfig.c | 12 ++++-- common/cli_getch.c | 12 ++++-- common/menu.c | 92 +++++++++++++--------------------------------- include/cli.h | 4 +- include/menu.h | 7 +++- 6 files changed, 56 insertions(+), 80 deletions(-) diff --git a/cmd/bootmenu.c b/cmd/bootmenu.c index 573afe16609..52d8c2f266d 100644 --- a/cmd/bootmenu.c +++ b/cmd/bootmenu.c @@ -4,6 +4,7 @@ */ #include +#include #include #include #include @@ -84,19 +85,21 @@ static void bootmenu_print_entry(void *data) static char *bootmenu_choice_entry(void *data) { + struct cli_ch_state s_cch, *cch = &s_cch; struct bootmenu_data *menu = data; struct bootmenu_entry *iter; enum bootmenu_key key = BKEY_NONE; - int esc = 0; int i; + cli_ch_init(cch); + while (1) { if (menu->delay >= 0) { /* Autoboot was not stopped */ - key = bootmenu_autoboot_loop(menu, &esc); + key = bootmenu_autoboot_loop(menu, cch); } else { /* Some key was pressed, so autoboot was stopped */ - key = bootmenu_loop(menu, &esc); + key = bootmenu_loop(menu, cch); } switch (key) { diff --git a/cmd/eficonfig.c b/cmd/eficonfig.c index 96cb1a367f3..d830e4af53b 100644 --- a/cmd/eficonfig.c +++ b/cmd/eficonfig.c @@ -6,6 +6,7 @@ */ #include +#include #include #include #include @@ -184,14 +185,16 @@ static void eficonfig_display_statusline(struct menu *m) */ static char *eficonfig_choice_entry(void *data) { - int esc = 0; + struct cli_ch_state s_cch, *cch = &s_cch; struct list_head *pos, *n; struct eficonfig_entry *entry; enum bootmenu_key key = BKEY_NONE; struct efimenu *efi_menu = data; + cli_ch_init(cch); + while (1) { - key = bootmenu_loop((struct bootmenu_data *)efi_menu, &esc); + key = bootmenu_loop((struct bootmenu_data *)efi_menu, cch); switch (key) { case BKEY_UP: @@ -1862,13 +1865,14 @@ static void eficonfig_display_change_boot_order(struct efimenu *efi_menu) */ static efi_status_t eficonfig_choice_change_boot_order(struct efimenu *efi_menu) { - int esc = 0; + struct cli_ch_state s_cch, *cch = &s_cch; struct list_head *pos, *n; enum bootmenu_key key = BKEY_NONE; struct eficonfig_entry *entry, *tmp; + cli_ch_init(cch); while (1) { - key = bootmenu_loop(NULL, &esc); + key = bootmenu_loop(NULL, cch); switch (key) { case BKEY_PLUS: diff --git a/common/cli_getch.c b/common/cli_getch.c index 9eeea7fef29..87c23edcf4b 100644 --- a/common/cli_getch.c +++ b/common/cli_getch.c @@ -140,10 +140,11 @@ int cli_ch_process(struct cli_ch_state *cch, int ichar) * sequence */ if (!ichar) { - if (cch->emit_upto) { + if (cch->emitting) { if (cch->emit_upto < cch->esc_len) return cch->esc_save[cch->emit_upto++]; cch->emit_upto = 0; + cch->emitting = false; } return 0; } else if (ichar == -ETIMEDOUT) { @@ -174,18 +175,21 @@ int cli_ch_process(struct cli_ch_state *cch, int ichar) case ESC_SAVE: /* save this character and return nothing */ cch->esc_save[cch->esc_len++] = ichar; - return 0; + ichar = 0; + break; case ESC_REJECT: /* * invalid escape sequence, start returning the * characters in it */ cch->esc_save[cch->esc_len++] = ichar; - return cch->esc_save[cch->emit_upto++]; + ichar = cch->esc_save[cch->emit_upto++]; + cch->emitting = true; + break; case ESC_CONVERTED: /* valid escape sequence, return the resulting char */ cch->esc_len = 0; - return ichar; + break; } } diff --git a/common/menu.c b/common/menu.c index 7db98942a61..45f36ae3ede 100644 --- a/common/menu.c +++ b/common/menu.c @@ -15,6 +15,8 @@ #include "menu.h" +#define ansi 0 + /* * Internally, each item in a menu is represented by a struct menu_item. * @@ -425,15 +427,19 @@ int menu_destroy(struct menu *m) return 1; } -enum bootmenu_key bootmenu_autoboot_loop(struct bootmenu_data *menu, int *esc) +enum bootmenu_key bootmenu_autoboot_loop(struct bootmenu_data *menu, + struct cli_ch_state *cch) { enum bootmenu_key key = BKEY_NONE; int i, c; while (menu->delay > 0) { - printf(ANSI_CURSOR_POSITION, menu->count + 5, 3); + if (ansi) + printf(ANSI_CURSOR_POSITION, menu->count + 5, 3); printf("Hit any key to stop autoboot: %d ", menu->delay); for (i = 0; i < 100; ++i) { + int ichar; + if (!tstc()) { schedule(); mdelay(10); @@ -443,12 +449,13 @@ enum bootmenu_key bootmenu_autoboot_loop(struct bootmenu_data *menu, int *esc) menu->delay = -1; c = getchar(); - switch (c) { - case '\e': - *esc = 1; + ichar = cli_ch_process(cch, c); + + switch (ichar) { + case '\0': key = BKEY_NONE; break; - case '\r': + case '\n': key = BKEY_SELECT; break; case 0x3: /* ^C */ @@ -458,7 +465,6 @@ enum bootmenu_key bootmenu_autoboot_loop(struct bootmenu_data *menu, int *esc) key = BKEY_NONE; break; } - break; } @@ -468,7 +474,8 @@ enum bootmenu_key bootmenu_autoboot_loop(struct bootmenu_data *menu, int *esc) --menu->delay; } - printf(ANSI_CURSOR_POSITION ANSI_CLEAR_LINE, menu->count + 5, 1); + if (ansi) + printf(ANSI_CURSOR_POSITION ANSI_CLEAR_LINE, menu->count + 5, 1); if (menu->delay == 0) key = BKEY_SELECT; @@ -476,79 +483,32 @@ enum bootmenu_key bootmenu_autoboot_loop(struct bootmenu_data *menu, int *esc) return key; } -enum bootmenu_key bootmenu_loop(struct bootmenu_data *menu, int *esc) +enum bootmenu_key bootmenu_loop(struct bootmenu_data *menu, + struct cli_ch_state *cch) { enum bootmenu_key key = BKEY_NONE; int c; - if (*esc == 1) { - if (tstc()) { - c = getchar(); - } else { + c = cli_ch_process(cch, 0); + if (!c) { + while (!c && !tstc()) { schedule(); mdelay(10); - if (tstc()) - c = getchar(); - else - c = '\e'; + c = cli_ch_process(cch, -ETIMEDOUT); } - } else { - while (!tstc()) { - schedule(); - mdelay(10); - } - c = getchar(); - } - - switch (*esc) { - case 0: - /* First char of ANSI escape sequence '\e' */ - if (c == '\e') { - *esc = 1; - key = BKEY_NONE; - } - break; - case 1: - /* Second char of ANSI '[' */ - if (c == '[') { - *esc = 2; - key = BKEY_NONE; - } else { - /* Alone ESC key was pressed */ - key = BKEY_QUIT; - *esc = (c == '\e') ? 1 : 0; - } - break; - case 2: - case 3: - /* Third char of ANSI (number '1') - optional */ - if (*esc == 2 && c == '1') { - *esc = 3; - key = BKEY_NONE; - break; + if (!c) { + c = getchar(); + c = cli_ch_process(cch, c); } - - *esc = 0; - - /* ANSI 'A' - key up was pressed */ - if (c == 'A') - key = BKEY_UP; - /* ANSI 'B' - key down was pressed */ - else if (c == 'B') - key = BKEY_DOWN; - /* other key was pressed */ - else - key = BKEY_NONE; - - break; } switch (c) { - case '\r': + case '\n': /* enter key was pressed */ key = BKEY_SELECT; break; case CTL_CH('c'): + case '\e': /* ^C was pressed */ key = BKEY_QUIT; break; diff --git a/include/cli.h b/include/cli.h index 863519e4b13..c777c90313f 100644 --- a/include/cli.h +++ b/include/cli.h @@ -14,12 +14,14 @@ * * @esc_len: Number of escape characters read so far * @esc_save: Escape characters collected so far - * @emit_upto: Next character to emit from esc_save (0 if not emitting) + * @emit_upto: Next index to emit from esc_save + * @emitting: true if emitting from esc_save */ struct cli_ch_state { int esc_len; char esc_save[8]; int emit_upto; + bool emitting; }; /** diff --git a/include/menu.h b/include/menu.h index 8b9b36214f7..3996075a337 100644 --- a/include/menu.h +++ b/include/menu.h @@ -6,6 +6,7 @@ #ifndef __MENU_H__ #define __MENU_H__ +struct cli_ch_state; struct menu; struct menu *menu_create(char *title, int timeout, int prompt, @@ -71,7 +72,8 @@ enum bootmenu_key { * Ctrl-C: KEY_QUIT * anything else: KEY_NONE */ -enum bootmenu_key bootmenu_autoboot_loop(struct bootmenu_data *menu, int *esc); +enum bootmenu_key bootmenu_autoboot_loop(struct bootmenu_data *menu, + struct cli_ch_state *cch); /** * bootmenu_loop() - handle waiting for a keypress when autoboot is disabled @@ -96,6 +98,7 @@ enum bootmenu_key bootmenu_autoboot_loop(struct bootmenu_data *menu, int *esc); * Minus: BKEY_MINUS * Space: BKEY_SPACE */ -enum bootmenu_key bootmenu_loop(struct bootmenu_data *menu, int *esc); +enum bootmenu_key bootmenu_loop(struct bootmenu_data *menu, + struct cli_ch_state *cch); #endif /* __MENU_H__ */ -- 2.39.0.314.g84b9a713c41-goog