This reverts commit 32bab0eae51b55898d1e2804e6614d9143840581. Signed-off-by: Pali Rohár <p...@kernel.org> --- 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, 80 insertions(+), 56 deletions(-)
diff --git a/cmd/bootmenu.c b/cmd/bootmenu.c index 6baeedc69f91..c02dc6269283 100644 --- a/cmd/bootmenu.c +++ b/cmd/bootmenu.c @@ -4,7 +4,6 @@ */ #include <charset.h> -#include <cli.h> #include <common.h> #include <command.h> #include <ansi.h> @@ -85,21 +84,19 @@ 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, cch); + key = bootmenu_autoboot_loop(menu, &esc); } else { /* Some key was pressed, so autoboot was stopped */ - key = bootmenu_loop(menu, cch); + key = bootmenu_loop(menu, &esc); } switch (key) { diff --git a/cmd/eficonfig.c b/cmd/eficonfig.c index 720f52b48b8c..5c3ed76e78f5 100644 --- a/cmd/eficonfig.c +++ b/cmd/eficonfig.c @@ -6,7 +6,6 @@ */ #include <ansi.h> -#include <cli.h> #include <common.h> #include <charset.h> #include <efi_loader.h> @@ -230,16 +229,14 @@ void eficonfig_display_statusline(struct menu *m) */ char *eficonfig_choice_entry(void *data) { - struct cli_ch_state s_cch, *cch = &s_cch; + int esc = 0; 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, cch); + key = bootmenu_loop((struct bootmenu_data *)efi_menu, &esc); switch (key) { case BKEY_UP: @@ -1929,15 +1926,14 @@ static void eficonfig_print_change_boot_order_entry(void *data) */ char *eficonfig_choice_change_boot_order(void *data) { - struct cli_ch_state s_cch, *cch = &s_cch; + int esc = 0; struct list_head *pos, *n; struct efimenu *efi_menu = data; enum bootmenu_key key = BKEY_NONE; struct eficonfig_entry *entry, *tmp; - cli_ch_init(cch); while (1) { - key = bootmenu_loop(NULL, cch); + key = bootmenu_loop(NULL, &esc); switch (key) { case BKEY_PLUS: diff --git a/common/cli_getch.c b/common/cli_getch.c index 61d4cb261b81..8080ff814eff 100644 --- a/common/cli_getch.c +++ b/common/cli_getch.c @@ -140,11 +140,10 @@ int cli_ch_process(struct cli_ch_state *cch, int ichar) * sequence */ if (!ichar) { - if (cch->emitting) { + if (cch->emit_upto) { if (cch->emit_upto < cch->esc_len) return cch->esc_save[cch->emit_upto++]; cch->emit_upto = 0; - cch->emitting = false; cch->esc_len = 0; } return 0; @@ -176,21 +175,18 @@ 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; - ichar = 0; - break; + return 0; case ESC_REJECT: /* * invalid escape sequence, start returning the * characters in it */ cch->esc_save[cch->esc_len++] = ichar; - ichar = cch->esc_save[cch->emit_upto++]; - cch->emitting = true; - return ichar; + return cch->esc_save[cch->emit_upto++]; case ESC_CONVERTED: /* valid escape sequence, return the resulting char */ cch->esc_len = 0; - break; + return ichar; } } diff --git a/common/menu.c b/common/menu.c index b6ec2e9c616c..5b614eafa413 100644 --- a/common/menu.c +++ b/common/menu.c @@ -15,8 +15,6 @@ #include "menu.h" -#define ansi 0 - /* * Internally, each item in a menu is represented by a struct menu_item. * @@ -427,19 +425,15 @@ int menu_destroy(struct menu *m) return 1; } -enum bootmenu_key bootmenu_autoboot_loop(struct bootmenu_data *menu, - struct cli_ch_state *cch) +enum bootmenu_key bootmenu_autoboot_loop(struct bootmenu_data *menu, int *esc) { enum bootmenu_key key = BKEY_NONE; int i, c; while (menu->delay > 0) { - if (ansi) - printf(ANSI_CURSOR_POSITION, menu->count + 5, 3); + 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); @@ -449,13 +443,12 @@ enum bootmenu_key bootmenu_autoboot_loop(struct bootmenu_data *menu, menu->delay = -1; c = getchar(); - ichar = cli_ch_process(cch, c); - - switch (ichar) { - case '\0': + switch (c) { + case '\e': + *esc = 1; key = BKEY_NONE; break; - case '\n': + case '\r': key = BKEY_SELECT; break; case 0x3: /* ^C */ @@ -465,6 +458,7 @@ enum bootmenu_key bootmenu_autoboot_loop(struct bootmenu_data *menu, key = BKEY_NONE; break; } + break; } @@ -474,8 +468,7 @@ enum bootmenu_key bootmenu_autoboot_loop(struct bootmenu_data *menu, --menu->delay; } - if (ansi) - printf(ANSI_CURSOR_POSITION ANSI_CLEAR_LINE, menu->count + 5, 1); + printf(ANSI_CURSOR_POSITION ANSI_CLEAR_LINE, menu->count + 5, 1); if (menu->delay == 0) key = BKEY_SELECT; @@ -483,32 +476,79 @@ enum bootmenu_key bootmenu_autoboot_loop(struct bootmenu_data *menu, return key; } -enum bootmenu_key bootmenu_loop(struct bootmenu_data *menu, - struct cli_ch_state *cch) +enum bootmenu_key bootmenu_loop(struct bootmenu_data *menu, int *esc) { enum bootmenu_key key = BKEY_NONE; int c; - c = cli_ch_process(cch, 0); - if (!c) { - while (!c && !tstc()) { + if (*esc == 1) { + if (tstc()) { + c = getchar(); + } else { schedule(); mdelay(10); - c = cli_ch_process(cch, -ETIMEDOUT); + if (tstc()) + c = getchar(); + else + c = '\e'; } - if (!c) { - c = getchar(); - c = cli_ch_process(cch, c); + } 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; + } + + *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 '\n': + case '\r': /* 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 094a6602d70e..0c7995fb90a4 100644 --- a/include/cli.h +++ b/include/cli.h @@ -14,14 +14,12 @@ * * @esc_len: Number of escape characters read so far * @esc_save: Escape characters collected so far - * @emit_upto: Next index to emit from esc_save - * @emitting: true if emitting from esc_save + * @emit_upto: Next character to emit from esc_save (0 if not emitting) */ 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 5e54f033dfa4..e4fae283f74f 100644 --- a/include/menu.h +++ b/include/menu.h @@ -6,7 +6,6 @@ #ifndef __MENU_H__ #define __MENU_H__ -struct cli_ch_state; struct menu; struct menu *menu_create(char *title, int timeout, int prompt, @@ -73,8 +72,7 @@ enum bootmenu_key { * Ctrl-C: KEY_QUIT * anything else: KEY_NONE */ -enum bootmenu_key bootmenu_autoboot_loop(struct bootmenu_data *menu, - struct cli_ch_state *cch); +enum bootmenu_key bootmenu_autoboot_loop(struct bootmenu_data *menu, int *esc); /** * bootmenu_loop() - handle waiting for a keypress when autoboot is disabled @@ -99,7 +97,6 @@ enum bootmenu_key bootmenu_autoboot_loop(struct bootmenu_data *menu, * Minus: BKEY_MINUS * Space: BKEY_SPACE */ -enum bootmenu_key bootmenu_loop(struct bootmenu_data *menu, - struct cli_ch_state *cch); +enum bootmenu_key bootmenu_loop(struct bootmenu_data *menu, int *esc); #endif /* __MENU_H__ */ -- 2.20.1