mirror of
https://github.com/AsahiLinux/u-boot
synced 2024-11-28 15:41:40 +00:00
menu: Make use of CLI character processing
Avoid duplicating some of the escape-sequence processing here and use the CLI function instead. Signed-off-by: Simon Glass <sjg@chromium.org>
This commit is contained in:
parent
86cc3c5215
commit
32bab0eae5
6 changed files with 58 additions and 82 deletions
|
@ -4,6 +4,7 @@
|
|||
*/
|
||||
|
||||
#include <charset.h>
|
||||
#include <cli.h>
|
||||
#include <common.h>
|
||||
#include <command.h>
|
||||
#include <ansi.h>
|
||||
|
@ -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) {
|
||||
|
|
|
@ -6,6 +6,7 @@
|
|||
*/
|
||||
|
||||
#include <ansi.h>
|
||||
#include <cli.h>
|
||||
#include <common.h>
|
||||
#include <charset.h>
|
||||
#include <efi_loader.h>
|
||||
|
@ -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:
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -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 = cli_ch_process(cch, 0);
|
||||
if (!c) {
|
||||
while (!c && !tstc()) {
|
||||
schedule();
|
||||
mdelay(10);
|
||||
c = cli_ch_process(cch, -ETIMEDOUT);
|
||||
}
|
||||
if (!c) {
|
||||
c = getchar();
|
||||
} else {
|
||||
schedule();
|
||||
mdelay(10);
|
||||
if (tstc())
|
||||
c = getchar();
|
||||
else
|
||||
c = '\e';
|
||||
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 '\r':
|
||||
case '\n':
|
||||
/* enter key was pressed */
|
||||
key = BKEY_SELECT;
|
||||
break;
|
||||
case CTL_CH('c'):
|
||||
case '\e':
|
||||
/* ^C was pressed */
|
||||
key = BKEY_QUIT;
|
||||
break;
|
||||
|
|
|
@ -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;
|
||||
};
|
||||
|
||||
/**
|
||||
|
|
|
@ -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__ */
|
||||
|
|
Loading…
Reference in a new issue