From patchwork Wed Dec 21 13:50:38 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Masahisa Kojima X-Patchwork-Id: 635629 Delivered-To: patch@linaro.org Received: by 2002:a17:522:c983:b0:460:3032:e3c4 with SMTP id kr3csp3520103pvb; Wed, 21 Dec 2022 05:51:49 -0800 (PST) X-Google-Smtp-Source: AMrXdXufUIYuBzXomip2att/u064+0INoNKDfsVjwx98pnKp4npG1BXHskm/LQxHBU1mu8Jq+X6+ X-Received: by 2002:a05:6808:90b:b0:35e:a9d4:30d6 with SMTP id w11-20020a056808090b00b0035ea9d430d6mr7006828oih.44.1671630709032; Wed, 21 Dec 2022 05:51:49 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1671630709; cv=none; d=google.com; s=arc-20160816; b=PGOcRnjJzjQIw89fyqVW6KguXsHNzWI7ouHB/BUnDpQ9IJRtmaYtMOQUrYRODLZHNb bOc27nGgF6QFmdufkkdjTyuA0xFEYFwcClu07/GE95RRy2Lw6LeBYp1LKl47hhcfwVzl 0WdLXe/05i6ZTsSVsZ9LZABInQiXsxWYnXb6te/9B0+LV/u1umOvnflYE7RuEnb8MKc1 zR+2/7o99TFWZ9GZVINipwpnYQGwCjDNNe4B4aZagZdjXl1l6O5SRSOVdxnfm8QVGIlK Pb51lajdZVSqJpzNq5XSTzwaySza591hrBzmQIYcGjJoGpJy0Kc/dKx5u/EBEGM6SCfW Udng== 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=9t0XeEqf3kElZBMQa3PEHIDuNsaT6jdsb+D3a+zta9E=; b=VtrK/lNco0LX2z+zmgI98Q+rLYixxo2HdqOtgDUFotKaxoiYmAUrKb/wOhbAdkFBo5 L67uPRyzURclA67AH4sRUl5YNCeXoc/Oowi/fdK2CdP/CXTRCVkomX7lzHPtQWLuekX0 9+XfGpqLENBo+2USX4CgztGiDYmArb9+Dsesc7rnWJVQBQs6UMn1xdmsrIHiOBuPfFnx OIefNFCoekWZSs8FcQ2L9iPF3itHlHmN7wlsYeXkaF/59TU/zm4LBISF6GXo84BU7b2o PY9HOiFvw3W/iLwJ+wiqt2tnH1bZCUUVM7sNV9IiioQwdQC81ruZKcc5YlcoIvh4QHVT ezyw== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@linaro.org header.s=google header.b=BKXlNKRZ; 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 w10-20020a056830410a00b0066ea531a0c2si13954602ott.327.2022.12.21.05.51.48 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Wed, 21 Dec 2022 05:51:49 -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=BKXlNKRZ; 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 87C3E8543D; Wed, 21 Dec 2022 14:51:25 +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="BKXlNKRZ"; dkim-atps=neutral Received: by phobos.denx.de (Postfix, from userid 109) id 94FB4852F8; Wed, 21 Dec 2022 14:51:13 +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-pf1-x42d.google.com (mail-pf1-x42d.google.com [IPv6:2607:f8b0:4864:20::42d]) (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 6EB7F85236 for ; Wed, 21 Dec 2022 14:51:07 +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-pf1-x42d.google.com with SMTP id t18so10698323pfq.13 for ; Wed, 21 Dec 2022 05:51:07 -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=9t0XeEqf3kElZBMQa3PEHIDuNsaT6jdsb+D3a+zta9E=; b=BKXlNKRZkSwfuIFspk6IHpJB3qgszaY36LjovXlsOnN+ZLoW5WNjy17vaKa3/jOIxa mtXId7H6e9YeM8WkTDmygWGfvynAMGJAaZ9uP5FZMcJF8vxuyHkxPBOowH1RG72y9Bk1 ig3FYGQmkWqFtdK+JmExvfBWI7Znh/WPr8bcnO00FhtaTYOMw2yvJUINZUd7oTWQ3bnH xFVugIopL03KOEjYiWwc3U9ZpFvLoF6yflZem++T48aiWjfSN0vFW0NXQPVThXUe+oaa Rtjjy/qMydKLKesS7zkdGQKaH/qlIq4VVOu3kSL1/HCjJvStn0KZ7/1UcV1QWcwXtEdQ X7HQ== 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=9t0XeEqf3kElZBMQa3PEHIDuNsaT6jdsb+D3a+zta9E=; b=2BHeeaPCUFnQkDsgv1pp/+TWqWtGvKwbgE06L9Xjp1Q/zZahRf9ySqvJTF/tNSXhZM w/CMpwUOOMvk9l7PaY1troVk/xXkPKDFuQSzVnEpeQNKodB+8j1wj1Mnaj0Jw7W6Hb2+ qu/gMYahmTBxLSHo4rToO2ZCExObha92N/S3I2Kb4XUnqaQNt0sfpY93R70itc0gsaIw TmL7DR6z/8v99aWLKm4rO8uWqkRK88FG27Anv0vtHcKaOLMO6LufwOKeMfHsvw/llfqj SN5QLbWGPobbx/KxgSnPDjDBTGRtxMQifLbfpDyNjwWBvenu5Wcw3uFxetLD6JDbBYw4 eQjQ== X-Gm-Message-State: AFqh2kpRaqrAn0rsBrcPvUB6k7HZTAHHgxdB4iwqb2JIJxknZkt1eaKB UZtOAFsmc3KYPMg52QzGjed2xwHISc7j4WIv X-Received: by 2002:a05:6a00:300d:b0:577:b52:4ec3 with SMTP id ay13-20020a056a00300d00b005770b524ec3mr16487554pfb.22.1671630665408; Wed, 21 Dec 2022 05:51:05 -0800 (PST) Received: from localhost.localdomain ([240d:1a:cf7:5800:82fa:5bff:fe4b:26b1]) by smtp.gmail.com with ESMTPSA id h10-20020aa796ca000000b00571cdbd0771sm10618227pfq.102.2022.12.21.05.51.03 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Wed, 21 Dec 2022 05:51:04 -0800 (PST) From: Masahisa Kojima To: u-boot@lists.denx.de Cc: Heinrich Schuchardt , Ilias Apalodimas , Masahisa Kojima Subject: [PATCH 3/3] eficonfig: add vertical scroll support Date: Wed, 21 Dec 2022 22:50:38 +0900 Message-Id: <20221221135039.32349-4-masahisa.kojima@linaro.org> X-Mailer: git-send-email 2.17.1 In-Reply-To: <20221221135039.32349-1-masahisa.kojima@linaro.org> References: <20221221135039.32349-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 --- 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 c2c6c01c3b..9b64fc4826 100644 --- a/cmd/eficonfig.c +++ b/cmd/eficonfig.c @@ -29,8 +29,13 @@ static 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" */ @@ -2580,6 +2613,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); @@ -2590,6 +2624,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 9432d13f2e..fa5f2ce090 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; 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[];