diff options
author | Masahisa Kojima | 2022-04-28 17:09:45 +0900 |
---|---|---|
committer | Heinrich Schuchardt | 2022-05-07 23:17:26 +0200 |
commit | 3ae6cf5400ee004c309f73f358c1043cf6d8eecc (patch) | |
tree | e26fc87f501b266147b4de02149ad1d995a94a44 /common | |
parent | 6ae494831d13e96e5bc82b70c8061f5771219c3c (diff) |
bootmenu: factor out the user input handling
This commit moves the user input handling from cmd/bootmenu.c
to common/menu.c to reuse it from other modules.
Signed-off-by: Masahisa Kojima <masahisa.kojima@linaro.org>
Reviewed-by: Heinrich Schuchardt <heinrich.schuchardt@canonical.com>
Diffstat (limited to 'common')
-rw-r--r-- | common/menu.c | 128 |
1 files changed, 128 insertions, 0 deletions
diff --git a/common/menu.c b/common/menu.c index f5fc6930a2c..3e876b55b34 100644 --- a/common/menu.c +++ b/common/menu.c @@ -4,11 +4,14 @@ * Copyright (c) 2019, NVIDIA CORPORATION. All rights reserved. */ +#include <ansi.h> #include <common.h> #include <cli.h> #include <malloc.h> #include <errno.h> +#include <linux/delay.h> #include <linux/list.h> +#include <watchdog.h> #include "menu.h" @@ -421,3 +424,128 @@ int menu_destroy(struct menu *m) return 1; } + +void bootmenu_autoboot_loop(struct bootmenu_data *menu, + enum bootmenu_key *key, int *esc) +{ + int i, c; + + while (menu->delay > 0) { + printf(ANSI_CURSOR_POSITION, menu->count + 5, 3); + printf("Hit any key to stop autoboot: %d ", menu->delay); + for (i = 0; i < 100; ++i) { + if (!tstc()) { + WATCHDOG_RESET(); + mdelay(10); + continue; + } + + menu->delay = -1; + c = getchar(); + + switch (c) { + case '\e': + *esc = 1; + *key = KEY_NONE; + break; + case '\r': + *key = KEY_SELECT; + break; + case 0x3: /* ^C */ + *key = KEY_QUIT; + break; + default: + *key = KEY_NONE; + break; + } + + break; + } + + if (menu->delay < 0) + break; + + --menu->delay; + } + + printf(ANSI_CURSOR_POSITION ANSI_CLEAR_LINE, menu->count + 5, 1); + + if (menu->delay == 0) + *key = KEY_SELECT; +} + +void bootmenu_loop(struct bootmenu_data *menu, + enum bootmenu_key *key, int *esc) +{ + int c; + + if (*esc == 1) { + if (tstc()) { + c = getchar(); + } else { + WATCHDOG_RESET(); + mdelay(10); + if (tstc()) + c = getchar(); + else + c = '\e'; + } + } else { + while (!tstc()) { + WATCHDOG_RESET(); + mdelay(10); + } + c = getchar(); + } + + switch (*esc) { + case 0: + /* First char of ANSI escape sequence '\e' */ + if (c == '\e') { + *esc = 1; + *key = KEY_NONE; + } + break; + case 1: + /* Second char of ANSI '[' */ + if (c == '[') { + *esc = 2; + *key = KEY_NONE; + } else { + /* Alone ESC key was pressed */ + *key = KEY_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 = KEY_NONE; + break; + } + + *esc = 0; + + /* ANSI 'A' - key up was pressed */ + if (c == 'A') + *key = KEY_UP; + /* ANSI 'B' - key down was pressed */ + else if (c == 'B') + *key = KEY_DOWN; + /* other key was pressed */ + else + *key = KEY_NONE; + + break; + } + + /* enter key was pressed */ + if (c == '\r') + *key = KEY_SELECT; + + /* ^C was pressed */ + if (c == 0x3) + *key = KEY_QUIT; +} |