From patchwork Thu Jan 5 02:58:54 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Masahisa Kojima X-Patchwork-Id: 639243 Delivered-To: patch@linaro.org Received: by 2002:a17:522:f3c4:b0:4b4:3859:abed with SMTP id in4csp27517pvb; Wed, 4 Jan 2023 18:59:16 -0800 (PST) X-Google-Smtp-Source: AMrXdXt0nPTM5WOgfRfFiftILWid0ItXw63qZkj2b1qewlIrBfbsNAM584ITu6dwCrOF9CIroBti X-Received: by 2002:a9d:578c:0:b0:670:6b4d:78b5 with SMTP id q12-20020a9d578c000000b006706b4d78b5mr26866742oth.16.1672887556639; Wed, 04 Jan 2023 18:59:16 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1672887556; cv=none; d=google.com; s=arc-20160816; b=aMDxRRDBJF2mg6uioTMv9DiOyFWrJQDBUH4s1bwejl3KMxL0m++0wKHPjkQM9JMCzt elE3FjXi/SfAKcJyY9TaoIZyCfe4c4NuRa1uHC06ye8NUIWoI1ZNL6B7iMNzBLOYXDaR KM1wS4ydUWHNREoi1sgq1keyrYB0S8ghODAmvugIWlB5lLrUpkIC8juINyOMD3WsiKS5 p7QxoJSUZylr8BhoXSR7yr379b8f3eV426nx+JR50z3YMXaJDn4+DLCn4Iw7djcNilc/ F563qDBtwNr8a2pjvEwSxB5M56dkVUapUUUJs6gv6dppIzaMqyaWakFnA0m4V3BgeB7c 99WQ== 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=OkQgxo/7EcS17JiG033aLF/gAqWLsnYpODzAnK6PgwQ=; b=kgw+5jDK2DHVQAmm0cWsKTlyDMj0OHsmPfVsPbLIwSHM0sTjwSxZHVr8Jt/n7gulp8 ssQDfwBTN8l2U/HG0kG5sSvAWnyIXBJyeBEW2m9nwi+H/BofZjcDyP3+NMXNApqTNNun qG/MLC3PIDH1ePatmn4oB5YHdHY3Qj/uTx3km3KaVoe45Dd0T9esJaWUhEg/0eK6kNwt +1Kh1ufsdzrU55IEmeIwSWCsgREofigKx83fN+jYjKVB0vC+OQt5BnzMJ0MCt/1tAfCR yHtBGd0qG/JECBwRnunJdq+gYcu/F+TN1hba0tscoU7Z1qxVlAu8aSY+1RGGlY1Lj/rr hvMQ== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@linaro.org header.s=google header.b="hCHo+D/a"; spf=pass (google.com: domain of u-boot-bounces@lists.denx.de designates 85.214.62.61 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. [85.214.62.61]) by mx.google.com with ESMTPS id v22-20020a544496000000b0035ecf6d61e9si27558986oiv.99.2023.01.04.18.59.16 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Wed, 04 Jan 2023 18:59:16 -0800 (PST) Received-SPF: pass (google.com: domain of u-boot-bounces@lists.denx.de designates 85.214.62.61 as permitted sender) client-ip=85.214.62.61; Authentication-Results: mx.google.com; dkim=pass header.i=@linaro.org header.s=google header.b="hCHo+D/a"; spf=pass (google.com: domain of u-boot-bounces@lists.denx.de designates 85.214.62.61 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 3290B8559E; Thu, 5 Jan 2023 03:58: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=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="hCHo+D/a"; dkim-atps=neutral Received: by phobos.denx.de (Postfix, from userid 109) id F299085587; Thu, 5 Jan 2023 03:58:38 +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-x1031.google.com (mail-pj1-x1031.google.com [IPv6:2607:f8b0:4864:20::1031]) (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 BC7B38558E for ; Thu, 5 Jan 2023 03:58:34 +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-x1031.google.com with SMTP id o21so8347486pjw.0 for ; Wed, 04 Jan 2023 18:58:34 -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=OkQgxo/7EcS17JiG033aLF/gAqWLsnYpODzAnK6PgwQ=; b=hCHo+D/ao7RFhEDdJ2NhfhepHUd9SbFWKb3X0o9Vho4Kk+h9cmPGPG3vvJp9IzLesA 5aDgGmmoEEC06p1Bf8NcH3yhpfrzbr/lsXzK9fi7o6cY1p3tvhFpdePAsorCiICvLnhw RhezN9OwBIYjBddu0BSuGmOcqrml9hY4unQRHXEiKBe7dvhpVhXNcg4h9VMU3M083vou Jsy6/hLCTWinw40SvDrW/1yhU07D/66oVSty3LOPZe893jIkQcW7QyhoqW8XUXWX+xBa L7WfpHyeWXr004BTA8w2vThwi3cu8uGGEr3SWRcnYWmjMUdK1EizCfLhvaB4mvFBlUmn s+YA== 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=OkQgxo/7EcS17JiG033aLF/gAqWLsnYpODzAnK6PgwQ=; b=wDQCZe6mPAcJUNjGpKD7E2MwZXR3ZI+8mF2n8/1fHLROe9az6p9aGLkE6R3F6gL5wQ iPWyCAJ53f1hkvo0pLhtBTvanVS+RO9soORwKnyNiMSO9EVoXxu9fcaX4FIRB50ECcQe Mq3Y52YxbVV/EuxbuZHJV/7AkIvh5svMiRi4IRHN+bhMM+aVXe2iMWQnZquHB4vDdqlM ovwYWHXjYkCv+U+Gk3BPMx7wO15VYwCrkt8kVdpRFpQ+vGikkb88yOh+SlXjk/yFB9Y2 2LI4DzxufuIA95MKLFaomY7QC6J1OZF3kt5KEi9Eh0q2csq+OdPklBuUMSSv+ii2kOJS 4hDQ== X-Gm-Message-State: AFqh2kqHprVprd6eRe6cpSDah8kNB5Sr1coBpiQBypkBiqYRMySsxB5y jlEMMMtH1Gt62XZgL9yljBnCeDsLxk2bmLWe X-Received: by 2002:a17:903:2685:b0:192:bd33:7b59 with SMTP id jf5-20020a170903268500b00192bd337b59mr16246853plb.61.1672887514004; Wed, 04 Jan 2023 18:58:34 -0800 (PST) Received: from localhost.localdomain ([240d:1a:cf7:5800:82fa:5bff:fe4b:26b1]) by smtp.gmail.com with ESMTPSA id g18-20020a170902869200b00192b23b8451sm10729546plo.108.2023.01.04.18.58.32 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Wed, 04 Jan 2023 18:58:33 -0800 (PST) From: Masahisa Kojima To: u-boot@lists.denx.de Cc: Heinrich Schuchardt , Ilias Apalodimas , Masahisa Kojima Subject: [PATCH v3 3/3] eficonfig: add vertical scroll support Date: Thu, 5 Jan 2023 11:58:54 +0900 Message-Id: <20230105025855.16936-4-masahisa.kojima@linaro.org> X-Mailer: git-send-email 2.17.1 In-Reply-To: <20230105025855.16936-1-masahisa.kojima@linaro.org> References: <20230105025855.16936-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". Signed-off-by: Masahisa Kojima --- 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 6d5ebc4055..bf765a239b 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; 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); @@ -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; 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); @@ -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); + 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 699176872d..91d8a5ef0c 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[];