On Tue, 27 Dec 2022 at 23:55, Ilias Apalodimas <ilias.apalodi...@linaro.org> wrote: > > > This looks correct to me. > Heinrich can you check if that solves your scrolling issues? > > On Sat, Dec 24, 2022 at 07:57:44AM +0900, Masahisa Kojima wrote: > > The current eficonfig menu does not support vertical scroll, > > so it can not display the menu entries greater than > > the console row size. > > > > This commit add the vertial scroll support. > > The console size is retrieved by > > SIMPLE_TEXT_OUTPUT_PROTOCOL.QueryMode() service, then > > calculates the row size for menu entry by subtracting > > menu header and description row size from the console row size. > > "start" and "end" are added in the efimenu structure. > > "start" keeps the menu entry index at the top, "end" keeps > > the bottom menu entry index. item_data_print() menu function > > only draws the menu entry between "start" and "end". > > > > Signed-off-by: Masahisa Kojima <masahisa.koj...@linaro.org> > > --- > > No update since v1 > > > > cmd/eficonfig.c | 79 ++++++++++++++++++++++++++++++++++++-------- > > include/efi_config.h | 4 +++ > > include/efi_loader.h | 1 + > > 3 files changed, 70 insertions(+), 14 deletions(-) > > > > diff --git a/cmd/eficonfig.c b/cmd/eficonfig.c > > index 13929cb003..e289d95589 100644 > > --- a/cmd/eficonfig.c > > +++ b/cmd/eficonfig.c > > @@ -29,8 +29,13 @@ static const char *eficonfig_change_boot_order_desc = > > " Press SPACE to activate or deactivate the entry\n" > > " Select [Save] to complete, ESC/CTRL+C to quit"; > > > > +static struct efi_simple_text_output_protocol *cout; > > +static int avail_row; > > + > > #define EFICONFIG_DESCRIPTION_MAX 32 > > #define EFICONFIG_OPTIONAL_DATA_MAX 64 > > +#define EFICONFIG_MENU_HEADER_ROW_NUM 3 > > +#define EFICONFIG_MENU_DESC_ROW_NUM 5 > > > > /** > > * struct eficonfig_filepath_info - structure to be used to store file path > > @@ -156,18 +161,16 @@ void eficonfig_print_entry(void *data) > > struct eficonfig_entry *entry = data; > > int reverse = (entry->efi_menu->active == entry->num); > > > > - /* TODO: support scroll or page for many entries */ > > + if (entry->efi_menu->start > entry->num || entry->efi_menu->end < > > entry->num) > > + return; > > > > - /* > > - * Move cursor to line where the entry will be drawn (entry->num) > > - * First 3 lines(menu header) + 1 empty line > > - */ > > - printf(ANSI_CURSOR_POSITION, entry->num + 4, 7); > > + printf(ANSI_CURSOR_POSITION, (entry->num - entry->efi_menu->start) + > > + EFICONFIG_MENU_HEADER_ROW_NUM + 1, 7); > > > > if (reverse) > > puts(ANSI_COLOR_REVERSE); > > > > - printf("%s", entry->title); > > + printf(ANSI_CLEAR_LINE "%s", entry->title); > > > > if (reverse) > > puts(ANSI_COLOR_RESET); > > @@ -190,8 +193,8 @@ void eficonfig_display_statusline(struct menu *m) > > ANSI_CURSOR_POSITION ANSI_CLEAR_LINE ANSI_CURSOR_POSITION > > "%s" > > ANSI_CLEAR_LINE_TO_END, > > - 1, 1, entry->efi_menu->menu_header, entry->efi_menu->count + > > 5, 1, > > - entry->efi_menu->count + 6, 1, entry->efi_menu->menu_desc); > > + 1, 1, entry->efi_menu->menu_header, avail_row + 4, 1, > > + avail_row + 5, 1, entry->efi_menu->menu_desc); > > } > > > > /** > > @@ -213,13 +216,23 @@ char *eficonfig_choice_entry(void *data) > > > > switch (key) { > > case KEY_UP: > > - if (efi_menu->active > 0) > > + if (efi_menu->active > 0) { > > --efi_menu->active; > > + if (efi_menu->start > efi_menu->active) { > > + efi_menu->start--; > > + efi_menu->end--; > > + } > > + } > > /* no menu key selected, regenerate menu */ > > return NULL; > > case KEY_DOWN: > > - if (efi_menu->active < efi_menu->count - 1) > > + if (efi_menu->active < efi_menu->count - 1) { > > ++efi_menu->active; > > + if (efi_menu->end < efi_menu->active) { > > + efi_menu->start++; > > + efi_menu->end++; > > + } > > + } > > /* no menu key selected, regenerate menu */ > > return NULL; > > case KEY_SELECT: > > @@ -399,6 +412,8 @@ efi_status_t eficonfig_process_common(struct efimenu > > *efi_menu, > > > > efi_menu->delay = -1; > > efi_menu->active = 0; > > + efi_menu->start = 0; > > + efi_menu->end = avail_row - 1; > > > > if (menu_header) { > > efi_menu->menu_header = strdup(menu_header); > > @@ -1865,7 +1880,11 @@ static void > > eficonfig_print_change_boot_order_entry(void *data) > > struct eficonfig_entry *entry = data; > > int reverse = (entry->efi_menu->active == entry->num); > > > > - printf(ANSI_CURSOR_POSITION, entry->num + 4, 7); > > + if (entry->efi_menu->start > entry->num || entry->efi_menu->end < > > entry->num) > > + return; > > + > > + printf(ANSI_CURSOR_POSITION ANSI_CLEAR_LINE, > > + (entry->num - entry->efi_menu->start) + > > EFICONFIG_MENU_HEADER_ROW_NUM + 1, 7); > > > > if (reverse) > > puts(ANSI_COLOR_REVERSE); > > @@ -1916,8 +1935,13 @@ char *eficonfig_choice_change_boot_order(void *data) > > } > > fallthrough; > > case KEY_UP: > > - if (efi_menu->active > 0) > > + if (efi_menu->active > 0) { > > --efi_menu->active; > > + if (efi_menu->start > efi_menu->active) { > > + efi_menu->start--; > > + efi_menu->end--; > > + } > > + } > > return NULL; > > case KEY_MINUS: > > if (efi_menu->active < efi_menu->count - 3) { > > @@ -1933,11 +1957,20 @@ char *eficonfig_choice_change_boot_order(void *data) > > list_add(&entry->list, &tmp->list); > > > > ++efi_menu->active; > > + if (efi_menu->end < efi_menu->active) { > > + efi_menu->start++; > > + efi_menu->end++; > > + } > > } > > return NULL; > > case KEY_DOWN: > > - if (efi_menu->active < efi_menu->count - 1) > > + if (efi_menu->active < efi_menu->count - 1) { > > ++efi_menu->active; > > + if (efi_menu->end < efi_menu->active) { > > + efi_menu->start++; > > + efi_menu->end++; > > + } > > + } > > return NULL; > > case KEY_SELECT: > > /* "Save" */ > > @@ -2585,6 +2618,7 @@ static efi_status_t eficonfig_init(void) > > efi_status_t ret = EFI_SUCCESS; > > static bool init; > > struct efi_handler *handler; > > + unsigned long columns, rows; > > > > if (!init) { > > ret = efi_search_protocol(efi_root, > > &efi_guid_text_input_protocol, &handler); > > @@ -2595,6 +2629,23 @@ static efi_status_t eficonfig_init(void) > > EFI_OPEN_PROTOCOL_GET_PROTOCOL); > > if (ret != EFI_SUCCESS) > > return ret; > > + ret = efi_search_protocol(efi_root, > > &efi_guid_text_output_protocol, &handler); > > + if (ret != EFI_SUCCESS) > > + return ret; > > + > > + ret = efi_protocol_open(handler, (void **)&cout, efi_root, > > NULL, > > + EFI_OPEN_PROTOCOL_GET_PROTOCOL); > > Shouldn't we be closing the protocol if eficonfig terminates?
This protocol is opened with the EFI_OPEN_PROTOCOL_GET_PROTOCOL attribute, so we don't need to close the protocol. Thanks, Masahisa Kojima > > > + if (ret != EFI_SUCCESS) > > + return ret; > > + > > + cout->query_mode(cout, cout->mode->mode, &columns, &rows); > > [...] > > Regards > /Ilias