mirror of
https://github.com/AsahiLinux/u-boot
synced 2024-11-24 21:54:01 +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 <charset.h>
|
||||||
|
#include <cli.h>
|
||||||
#include <common.h>
|
#include <common.h>
|
||||||
#include <command.h>
|
#include <command.h>
|
||||||
#include <ansi.h>
|
#include <ansi.h>
|
||||||
|
@ -84,19 +85,21 @@ static void bootmenu_print_entry(void *data)
|
||||||
|
|
||||||
static char *bootmenu_choice_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_data *menu = data;
|
||||||
struct bootmenu_entry *iter;
|
struct bootmenu_entry *iter;
|
||||||
enum bootmenu_key key = BKEY_NONE;
|
enum bootmenu_key key = BKEY_NONE;
|
||||||
int esc = 0;
|
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
|
cli_ch_init(cch);
|
||||||
|
|
||||||
while (1) {
|
while (1) {
|
||||||
if (menu->delay >= 0) {
|
if (menu->delay >= 0) {
|
||||||
/* Autoboot was not stopped */
|
/* Autoboot was not stopped */
|
||||||
key = bootmenu_autoboot_loop(menu, &esc);
|
key = bootmenu_autoboot_loop(menu, cch);
|
||||||
} else {
|
} else {
|
||||||
/* Some key was pressed, so autoboot was stopped */
|
/* Some key was pressed, so autoboot was stopped */
|
||||||
key = bootmenu_loop(menu, &esc);
|
key = bootmenu_loop(menu, cch);
|
||||||
}
|
}
|
||||||
|
|
||||||
switch (key) {
|
switch (key) {
|
||||||
|
|
|
@ -6,6 +6,7 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include <ansi.h>
|
#include <ansi.h>
|
||||||
|
#include <cli.h>
|
||||||
#include <common.h>
|
#include <common.h>
|
||||||
#include <charset.h>
|
#include <charset.h>
|
||||||
#include <efi_loader.h>
|
#include <efi_loader.h>
|
||||||
|
@ -184,14 +185,16 @@ static void eficonfig_display_statusline(struct menu *m)
|
||||||
*/
|
*/
|
||||||
static char *eficonfig_choice_entry(void *data)
|
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 list_head *pos, *n;
|
||||||
struct eficonfig_entry *entry;
|
struct eficonfig_entry *entry;
|
||||||
enum bootmenu_key key = BKEY_NONE;
|
enum bootmenu_key key = BKEY_NONE;
|
||||||
struct efimenu *efi_menu = data;
|
struct efimenu *efi_menu = data;
|
||||||
|
|
||||||
|
cli_ch_init(cch);
|
||||||
|
|
||||||
while (1) {
|
while (1) {
|
||||||
key = bootmenu_loop((struct bootmenu_data *)efi_menu, &esc);
|
key = bootmenu_loop((struct bootmenu_data *)efi_menu, cch);
|
||||||
|
|
||||||
switch (key) {
|
switch (key) {
|
||||||
case BKEY_UP:
|
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)
|
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;
|
struct list_head *pos, *n;
|
||||||
enum bootmenu_key key = BKEY_NONE;
|
enum bootmenu_key key = BKEY_NONE;
|
||||||
struct eficonfig_entry *entry, *tmp;
|
struct eficonfig_entry *entry, *tmp;
|
||||||
|
|
||||||
|
cli_ch_init(cch);
|
||||||
while (1) {
|
while (1) {
|
||||||
key = bootmenu_loop(NULL, &esc);
|
key = bootmenu_loop(NULL, cch);
|
||||||
|
|
||||||
switch (key) {
|
switch (key) {
|
||||||
case BKEY_PLUS:
|
case BKEY_PLUS:
|
||||||
|
|
|
@ -140,10 +140,11 @@ int cli_ch_process(struct cli_ch_state *cch, int ichar)
|
||||||
* sequence
|
* sequence
|
||||||
*/
|
*/
|
||||||
if (!ichar) {
|
if (!ichar) {
|
||||||
if (cch->emit_upto) {
|
if (cch->emitting) {
|
||||||
if (cch->emit_upto < cch->esc_len)
|
if (cch->emit_upto < cch->esc_len)
|
||||||
return cch->esc_save[cch->emit_upto++];
|
return cch->esc_save[cch->emit_upto++];
|
||||||
cch->emit_upto = 0;
|
cch->emit_upto = 0;
|
||||||
|
cch->emitting = false;
|
||||||
}
|
}
|
||||||
return 0;
|
return 0;
|
||||||
} else if (ichar == -ETIMEDOUT) {
|
} else if (ichar == -ETIMEDOUT) {
|
||||||
|
@ -174,18 +175,21 @@ int cli_ch_process(struct cli_ch_state *cch, int ichar)
|
||||||
case ESC_SAVE:
|
case ESC_SAVE:
|
||||||
/* save this character and return nothing */
|
/* save this character and return nothing */
|
||||||
cch->esc_save[cch->esc_len++] = ichar;
|
cch->esc_save[cch->esc_len++] = ichar;
|
||||||
return 0;
|
ichar = 0;
|
||||||
|
break;
|
||||||
case ESC_REJECT:
|
case ESC_REJECT:
|
||||||
/*
|
/*
|
||||||
* invalid escape sequence, start returning the
|
* invalid escape sequence, start returning the
|
||||||
* characters in it
|
* characters in it
|
||||||
*/
|
*/
|
||||||
cch->esc_save[cch->esc_len++] = ichar;
|
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:
|
case ESC_CONVERTED:
|
||||||
/* valid escape sequence, return the resulting char */
|
/* valid escape sequence, return the resulting char */
|
||||||
cch->esc_len = 0;
|
cch->esc_len = 0;
|
||||||
return ichar;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -15,6 +15,8 @@
|
||||||
|
|
||||||
#include "menu.h"
|
#include "menu.h"
|
||||||
|
|
||||||
|
#define ansi 0
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Internally, each item in a menu is represented by a struct menu_item.
|
* 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;
|
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;
|
enum bootmenu_key key = BKEY_NONE;
|
||||||
int i, c;
|
int i, c;
|
||||||
|
|
||||||
while (menu->delay > 0) {
|
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);
|
printf("Hit any key to stop autoboot: %d ", menu->delay);
|
||||||
for (i = 0; i < 100; ++i) {
|
for (i = 0; i < 100; ++i) {
|
||||||
|
int ichar;
|
||||||
|
|
||||||
if (!tstc()) {
|
if (!tstc()) {
|
||||||
schedule();
|
schedule();
|
||||||
mdelay(10);
|
mdelay(10);
|
||||||
|
@ -443,12 +449,13 @@ enum bootmenu_key bootmenu_autoboot_loop(struct bootmenu_data *menu, int *esc)
|
||||||
menu->delay = -1;
|
menu->delay = -1;
|
||||||
c = getchar();
|
c = getchar();
|
||||||
|
|
||||||
switch (c) {
|
ichar = cli_ch_process(cch, c);
|
||||||
case '\e':
|
|
||||||
*esc = 1;
|
switch (ichar) {
|
||||||
|
case '\0':
|
||||||
key = BKEY_NONE;
|
key = BKEY_NONE;
|
||||||
break;
|
break;
|
||||||
case '\r':
|
case '\n':
|
||||||
key = BKEY_SELECT;
|
key = BKEY_SELECT;
|
||||||
break;
|
break;
|
||||||
case 0x3: /* ^C */
|
case 0x3: /* ^C */
|
||||||
|
@ -458,7 +465,6 @@ enum bootmenu_key bootmenu_autoboot_loop(struct bootmenu_data *menu, int *esc)
|
||||||
key = BKEY_NONE;
|
key = BKEY_NONE;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -468,7 +474,8 @@ enum bootmenu_key bootmenu_autoboot_loop(struct bootmenu_data *menu, int *esc)
|
||||||
--menu->delay;
|
--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)
|
if (menu->delay == 0)
|
||||||
key = BKEY_SELECT;
|
key = BKEY_SELECT;
|
||||||
|
@ -476,79 +483,32 @@ enum bootmenu_key bootmenu_autoboot_loop(struct bootmenu_data *menu, int *esc)
|
||||||
return key;
|
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;
|
enum bootmenu_key key = BKEY_NONE;
|
||||||
int c;
|
int c;
|
||||||
|
|
||||||
if (*esc == 1) {
|
c = cli_ch_process(cch, 0);
|
||||||
if (tstc()) {
|
if (!c) {
|
||||||
|
while (!c && !tstc()) {
|
||||||
|
schedule();
|
||||||
|
mdelay(10);
|
||||||
|
c = cli_ch_process(cch, -ETIMEDOUT);
|
||||||
|
}
|
||||||
|
if (!c) {
|
||||||
c = getchar();
|
c = getchar();
|
||||||
} else {
|
c = cli_ch_process(cch, c);
|
||||||
schedule();
|
|
||||||
mdelay(10);
|
|
||||||
if (tstc())
|
|
||||||
c = getchar();
|
|
||||||
else
|
|
||||||
c = '\e';
|
|
||||||
}
|
}
|
||||||
} 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) {
|
switch (c) {
|
||||||
case '\r':
|
case '\n':
|
||||||
/* enter key was pressed */
|
/* enter key was pressed */
|
||||||
key = BKEY_SELECT;
|
key = BKEY_SELECT;
|
||||||
break;
|
break;
|
||||||
case CTL_CH('c'):
|
case CTL_CH('c'):
|
||||||
|
case '\e':
|
||||||
/* ^C was pressed */
|
/* ^C was pressed */
|
||||||
key = BKEY_QUIT;
|
key = BKEY_QUIT;
|
||||||
break;
|
break;
|
||||||
|
|
|
@ -14,12 +14,14 @@
|
||||||
*
|
*
|
||||||
* @esc_len: Number of escape characters read so far
|
* @esc_len: Number of escape characters read so far
|
||||||
* @esc_save: Escape characters collected 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 {
|
struct cli_ch_state {
|
||||||
int esc_len;
|
int esc_len;
|
||||||
char esc_save[8];
|
char esc_save[8];
|
||||||
int emit_upto;
|
int emit_upto;
|
||||||
|
bool emitting;
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -6,6 +6,7 @@
|
||||||
#ifndef __MENU_H__
|
#ifndef __MENU_H__
|
||||||
#define __MENU_H__
|
#define __MENU_H__
|
||||||
|
|
||||||
|
struct cli_ch_state;
|
||||||
struct menu;
|
struct menu;
|
||||||
|
|
||||||
struct menu *menu_create(char *title, int timeout, int prompt,
|
struct menu *menu_create(char *title, int timeout, int prompt,
|
||||||
|
@ -71,7 +72,8 @@ enum bootmenu_key {
|
||||||
* Ctrl-C: KEY_QUIT
|
* Ctrl-C: KEY_QUIT
|
||||||
* anything else: KEY_NONE
|
* 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
|
* 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
|
* Minus: BKEY_MINUS
|
||||||
* Space: BKEY_SPACE
|
* 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__ */
|
#endif /* __MENU_H__ */
|
||||||
|
|
Loading…
Reference in a new issue