From patchwork Tue Jan 24 06:56:15 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Masahisa Kojima X-Patchwork-Id: 646025 Delivered-To: patch@linaro.org Received: by 2002:a17:522:b9de:b0:4b9:b062:db3b with SMTP id fj30csp40463pvb; Mon, 23 Jan 2023 22:54:59 -0800 (PST) X-Google-Smtp-Source: AMrXdXteoaVKK9+wm7elQn/Usr7EHiKa094K4WbBPd7zGqvnVqrwTzy1O52omKvmfG6niEj0joc9 X-Received: by 2002:a05:6830:18c7:b0:686:4a76:31e with SMTP id v7-20020a05683018c700b006864a76031emr13079415ote.38.1674543299317; Mon, 23 Jan 2023 22:54:59 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1674543299; cv=none; d=google.com; s=arc-20160816; b=O19PXGwOl3gH7HghB+KPsEaZ0rwsqysH6d/5vZqArPPUfBkb1EiUZAUtWowE/ARefL dsnC1mb+IICyuqyvCwuzfrKhMMFI3vUD1H9wPAHG+uKEJCzH+UdmSOMJIH2XgcnzL78O 8x68wt2GHgHqzpD25iQxBy60QjpuIUhZ85Ds6gxx8CDT7BaBK1RrnFmJs6SbDFfFdt9i IfodygCJn6sqpcyi896SkgURe0BQnj5v311YLG3+QbCAM/X9yAndlNnupIugoc7ZO/v5 iIxk6xQyorRIcgHrY+y0gNsBy6aoJkdQM4o/ov+S+CHZYXFPBjcxx3u+F+cvDygVldYP kqnQ== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=sender:errors-to:list-subscribe:list-help:list-post:list-archive :list-unsubscribe:list-id:precedence:references:in-reply-to :message-id:date:subject:cc:to:from:dkim-signature; bh=6DpE3nyrVWFrEbdglRUkZC3O4IVO3YYrNnumV9OtSIc=; b=jp6+4Rl8vYKZBxF2JLX+m7bLpJWThM+P3NmsFmb1fBFtN0oXLPpLMaWOm57DAPxKIu gHLgcFRLUfmMH5a0pLpk/DywGcEo0kE4dLwRgVqKXuxuSwcbx02HGfiE70ZBc07SVF/N pgxF6p3daWIPIfJOU2g5bKnCX8w5+UEd6jvXJuMKTLhnHlJFl0QKbZSHap08CvmD9Z6a KD/BshXFKS+0auXsUIweA3vVfxwP4WdjN08UtKG7h12uBMpkIrxn4+OGHPnfODCY4/Fx pGIwCUMRMg7A5mfKgF+sdQ+hYJ6CKmqMKfEujBpzssCqApW8zUrFtvSbzQTO3BVx5riK GBlA== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@linaro.org header.s=google header.b="W9eSj/tO"; spf=pass (google.com: domain of u-boot-bounces@lists.denx.de designates 2a01:238:438b:c500:173d:9f52:ddab:ee01 as permitted sender) smtp.mailfrom=u-boot-bounces@lists.denx.de; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=linaro.org Return-Path: Received: from phobos.denx.de (phobos.denx.de. [2a01:238:438b:c500:173d:9f52:ddab:ee01]) by mx.google.com with ESMTPS id k8-20020a056830150800b00670813a7928si1430053otp.56.2023.01.23.22.54.58 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 23 Jan 2023 22:54:59 -0800 (PST) Received-SPF: pass (google.com: domain of u-boot-bounces@lists.denx.de designates 2a01:238:438b:c500:173d:9f52:ddab:ee01 as permitted sender) client-ip=2a01:238:438b:c500:173d:9f52:ddab:ee01; Authentication-Results: mx.google.com; dkim=pass header.i=@linaro.org header.s=google header.b="W9eSj/tO"; spf=pass (google.com: domain of u-boot-bounces@lists.denx.de designates 2a01:238:438b:c500:173d:9f52:ddab:ee01 as permitted sender) smtp.mailfrom=u-boot-bounces@lists.denx.de; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=linaro.org Received: from h2850616.stratoserver.net (localhost [IPv6:::1]) by phobos.denx.de (Postfix) with ESMTP id E2702855EB; Tue, 24 Jan 2023 07:54:32 +0100 (CET) Authentication-Results: phobos.denx.de; dmarc=pass (p=none dis=none) header.from=linaro.org Authentication-Results: phobos.denx.de; spf=pass smtp.mailfrom=u-boot-bounces@lists.denx.de Authentication-Results: phobos.denx.de; dkim=pass (2048-bit key; unprotected) header.d=linaro.org header.i=@linaro.org header.b="W9eSj/tO"; dkim-atps=neutral Received: by phobos.denx.de (Postfix, from userid 109) id B0F6E8539D; Tue, 24 Jan 2023 07:54:25 +0100 (CET) X-Spam-Checker-Version: SpamAssassin 3.4.2 (2018-09-13) on phobos.denx.de X-Spam-Level: X-Spam-Status: No, score=-2.1 required=5.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID,DKIM_VALID_AU,DKIM_VALID_EF,SPF_HELO_NONE,SPF_PASS autolearn=ham autolearn_force=no version=3.4.2 Received: from mail-pj1-x102e.google.com (mail-pj1-x102e.google.com [IPv6:2607:f8b0:4864:20::102e]) (using TLSv1.3 with cipher TLS_AES_128_GCM_SHA256 (128/128 bits)) (No client certificate requested) by phobos.denx.de (Postfix) with ESMTPS id 264F5855EB for ; Tue, 24 Jan 2023 07:53:49 +0100 (CET) Authentication-Results: phobos.denx.de; dmarc=pass (p=none dis=none) header.from=linaro.org Authentication-Results: phobos.denx.de; spf=pass smtp.mailfrom=masahisa.kojima@linaro.org Received: by mail-pj1-x102e.google.com with SMTP id m11so2070155pji.0 for ; Mon, 23 Jan 2023 22:53:49 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linaro.org; s=google; h=references:in-reply-to:message-id:date:subject:cc:to:from:from:to :cc:subject:date:message-id:reply-to; bh=6DpE3nyrVWFrEbdglRUkZC3O4IVO3YYrNnumV9OtSIc=; b=W9eSj/tO2/+E1qPqVhPT5xvwed5LLUAQ776HmROMX0Ydzg1zKZaDgrq90VcLnTPtnv woe2dqPKyMJjP524+xAm2FNv7tufvgfuQKVWMHbowAcuxx8EATXEVyBgsKNF3ntqTFrn utE8H9cmXN5nuIJxVBuvypRsFBHoP2a5MSyVAEhTHL+bcFMTmdaTrWCw88vikdDqBE6C 3/Uo+FfaP3y0BL5ryef+C3WbCQcYgkztCa6hppJXjqKdRNdmM+ZJCRmG3mw2gDqbgg4N Ja6de7bw7eIGdaE82HmrbSu+jMcQ81++1smM1MtZ9DorEATEtCvfliX81dr0kv1HhM+x X0Fg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=references:in-reply-to:message-id:date:subject:cc:to:from :x-gm-message-state:from:to:cc:subject:date:message-id:reply-to; bh=6DpE3nyrVWFrEbdglRUkZC3O4IVO3YYrNnumV9OtSIc=; b=Kg53t2GDzG5DMoCt9YYEP1t4WgdCYdYZKjsEuUCrUz7XWvbOZQAeNhjWKaqTHVvnfn dq/uMeullUQeZLAAhN98HqTcfutk+oLkLHrA6rt4T94JPr5ztJbZt8eQTHQ7WnYTYoe0 4gT+FEDBz2gD69XTM4tTbFyZ5/20hHZ/b2a86JxE4B35+FVQsMcIgRjps1llqYz7lWIT 6cTkGC+T/TitEqQlml+dDN94kl542JDh5rBwfV5aEZePkTlIVTZy670Lf73cyUjmywXl BSkfgDQbWUIGn58lpTuD5bmabnADxhHLxy9UQi3+/GWuckJwne/Ub4JPDVIz+/OUzNwz knPw== X-Gm-Message-State: AFqh2kpYJn9VLu4SxR1MAB2qiN9SEZhXfXbCbCKq7IrCAcidsykTxyGz m2Y85lXo3BpHIA/EkB3qLQtpFNzcuaYDR7UP X-Received: by 2002:a17:90a:2ecc:b0:226:7b3e:dea5 with SMTP id h12-20020a17090a2ecc00b002267b3edea5mr52391901pjs.36.1674543227096; Mon, 23 Jan 2023 22:53:47 -0800 (PST) Received: from localhost.localdomain ([240d:1a:cf7:5800:82fa:5bff:fe4b:26b1]) by smtp.gmail.com with ESMTPSA id q102-20020a17090a1b6f00b002293b1aa2b6sm1254873pjq.30.2023.01.23.22.53.45 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 23 Jan 2023 22:53:46 -0800 (PST) From: Masahisa Kojima To: u-boot@lists.denx.de Cc: Heinrich Schuchardt , Ilias Apalodimas , Masahisa Kojima Subject: [PATCH v5 3/4] eficonfig: add vertical scroll support Date: Tue, 24 Jan 2023 15:56:15 +0900 Message-Id: <20230124065616.25559-4-masahisa.kojima@linaro.org> X-Mailer: git-send-email 2.17.1 In-Reply-To: <20230124065616.25559-1-masahisa.kojima@linaro.org> References: <20230124065616.25559-1-masahisa.kojima@linaro.org> X-BeenThere: u-boot@lists.denx.de X-Mailman-Version: 2.1.39 Precedence: list List-Id: U-Boot discussion List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: u-boot-bounces@lists.denx.de Sender: "U-Boot" X-Virus-Scanned: clamav-milter 0.103.6 at phobos.denx.de X-Virus-Status: Clean 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". This commit also fixes the issue that "Save" and "Quit" entries can be moved by BKEY_PLUS in change boot order menu. Signed-off-by: Masahisa Kojima Reviewed-by: Ilias Apalodimas --- Changes in v5: - create common function to update efi_menu active, start and end - fix the issue that "Save" and "Quit" can be moved by BKEY_PLUS press Changes in v3: - modify "reverse" local variable type to bool Changes in v2: - add comment when the user key press is not valid - add const qualifier to eficonfig_change_boot_order_desc cmd/eficonfig.c | 92 ++++++++++++++++++++++++++++++++++++-------- include/efi_config.h | 4 ++ include/efi_loader.h | 1 + 3 files changed, 80 insertions(+), 17 deletions(-) diff --git a/cmd/eficonfig.c b/cmd/eficonfig.c index 01bd1b05bc..47c04cf536 100644 --- a/cmd/eficonfig.c +++ b/cmd/eficonfig.c @@ -30,8 +30,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 @@ -122,6 +127,30 @@ struct eficonfig_save_boot_order_data { bool selected; }; +/** + * struct eficonfig_menu_adjust - update start and end entry index + * + * @efi_menu: pointer to efimenu structure + * @add: flag to add or substract the index + */ +static void eficonfig_menu_adjust(struct efimenu *efi_menu, bool add) +{ + if (add) + ++efi_menu->active; + else + --efi_menu->active; + + if (add && efi_menu->end < efi_menu->active) { + efi_menu->start++; + efi_menu->end++; + } else if (!add && efi_menu->start > efi_menu->active) { + efi_menu->start--; + efi_menu->end--; + } +} +#define eficonfig_menu_up(_a) eficonfig_menu_adjust(_a, false) +#define eficonfig_menu_down(_a) eficonfig_menu_adjust(_a, true) + /** * eficonfig_print_msg() - print message * @@ -157,18 +186,16 @@ void eficonfig_print_entry(void *data) struct eficonfig_entry *entry = data; bool 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); @@ -191,8 +218,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); } /** @@ -217,12 +244,14 @@ char *eficonfig_choice_entry(void *data) switch (key) { case BKEY_UP: if (efi_menu->active > 0) - --efi_menu->active; + eficonfig_menu_up(efi_menu); + /* no menu key selected, regenerate menu */ return NULL; case BKEY_DOWN: if (efi_menu->active < efi_menu->count - 1) - ++efi_menu->active; + eficonfig_menu_down(efi_menu); + /* no menu key selected, regenerate menu */ return NULL; case BKEY_SELECT: @@ -402,6 +431,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); @@ -1868,7 +1899,11 @@ static void eficonfig_print_change_boot_order_entry(void *data) struct eficonfig_entry *entry = data; bool 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); @@ -1906,7 +1941,8 @@ char *eficonfig_choice_change_boot_order(void *data) switch (key) { case BKEY_PLUS: - if (efi_menu->active > 0) { + if (efi_menu->active > 0 && + efi_menu->active < efi_menu->count - 2) { list_for_each_safe(pos, n, &efi_menu->list) { entry = list_entry(pos, struct eficonfig_entry, list); if (entry->num == efi_menu->active) @@ -1917,11 +1953,14 @@ char *eficonfig_choice_change_boot_order(void *data) tmp->num++; list_del(&tmp->list); list_add(&tmp->list, &entry->list); + + eficonfig_menu_up(efi_menu); } - fallthrough; + return NULL; case BKEY_UP: if (efi_menu->active > 0) - --efi_menu->active; + eficonfig_menu_up(efi_menu); + return NULL; case BKEY_MINUS: if (efi_menu->active < efi_menu->count - 3) { @@ -1936,12 +1975,13 @@ char *eficonfig_choice_change_boot_order(void *data) list_del(&entry->list); list_add(&entry->list, &tmp->list); - ++efi_menu->active; + eficonfig_menu_down(efi_menu); } return NULL; case BKEY_DOWN: if (efi_menu->active < efi_menu->count - 1) - ++efi_menu->active; + eficonfig_menu_down(efi_menu); + return NULL; case BKEY_SELECT: /* "Save" */ @@ -2590,6 +2630,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); @@ -2600,6 +2641,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); + if (ret != EFI_SUCCESS) + return ret; + + cout->query_mode(cout, cout->mode->mode, &columns, &rows); + avail_row = rows - (EFICONFIG_MENU_HEADER_ROW_NUM + + EFICONFIG_MENU_DESC_ROW_NUM); + if (avail_row <= 0) { + eficonfig_print_msg("Console size is too small!"); + return EFI_INVALID_PARAMETER; + } + /* TODO: Should we check the minimum column size? */ } init = true; diff --git a/include/efi_config.h b/include/efi_config.h index cec5715f84..6a104e4b1d 100644 --- a/include/efi_config.h +++ b/include/efi_config.h @@ -49,6 +49,8 @@ struct eficonfig_entry { * @menu_header: menu header string * @menu_desc: menu description string * @list: menu entry list structure + * @start: top menu index to draw + * @end: bottom menu index to draw */ struct efimenu { int delay; @@ -57,6 +59,8 @@ struct efimenu { char *menu_header; const char *menu_desc; struct list_head list; + int start; + int end; }; /** diff --git a/include/efi_loader.h b/include/efi_loader.h index f9e427f090..4560b0d04c 100644 --- a/include/efi_loader.h +++ b/include/efi_loader.h @@ -328,6 +328,7 @@ extern const efi_guid_t efi_esrt_guid; extern const efi_guid_t smbios_guid; /*GUID of console */ extern const efi_guid_t efi_guid_text_input_protocol; +extern const efi_guid_t efi_guid_text_output_protocol; extern char __efi_runtime_start[], __efi_runtime_stop[]; extern char __efi_runtime_rel_start[], __efi_runtime_rel_stop[];