From patchwork Thu Jun 1 15:25:41 2017 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Thomas Huth X-Patchwork-Id: 769800 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Received: from lists.ozlabs.org (lists.ozlabs.org [IPv6:2401:3900:2:1::3]) (using TLSv1.2 with cipher ADH-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 3wdrlY2xWFz9s8J for ; Fri, 2 Jun 2017 01:26:01 +1000 (AEST) Received: from lists.ozlabs.org (lists.ozlabs.org [IPv6:2401:3900:2:1::3]) by lists.ozlabs.org (Postfix) with ESMTP id 3wdrlY1m00zDqG5 for ; Fri, 2 Jun 2017 01:26:01 +1000 (AEST) X-Original-To: slof@lists.ozlabs.org Delivered-To: slof@lists.ozlabs.org Received: from mx1.redhat.com (mx1.redhat.com [209.132.183.28]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by lists.ozlabs.org (Postfix) with ESMTPS id 3wdrlJ2r8tzDq5x for ; Fri, 2 Jun 2017 01:25:48 +1000 (AEST) Received: from smtp.corp.redhat.com (int-mx04.intmail.prod.int.phx2.redhat.com [10.5.11.14]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mx1.redhat.com (Postfix) with ESMTPS id 8594619C622; Thu, 1 Jun 2017 15:25:46 +0000 (UTC) DMARC-Filter: OpenDMARC Filter v1.3.2 mx1.redhat.com 8594619C622 Authentication-Results: ext-mx09.extmail.prod.ext.phx2.redhat.com; dmarc=none (p=none dis=none) header.from=redhat.com Authentication-Results: ext-mx09.extmail.prod.ext.phx2.redhat.com; spf=pass smtp.mailfrom=thuth@redhat.com DKIM-Filter: OpenDKIM Filter v2.11.0 mx1.redhat.com 8594619C622 Received: from thh440s.str.redhat.com (dhcp-192-189.str.redhat.com [10.33.192.189]) by smtp.corp.redhat.com (Postfix) with ESMTP id 0F74117B79; Thu, 1 Jun 2017 15:25:45 +0000 (UTC) From: Thomas Huth To: slof@lists.ozlabs.org Date: Thu, 1 Jun 2017 17:25:41 +0200 Message-Id: <1496330742-18181-4-git-send-email-thuth@redhat.com> In-Reply-To: <1496330742-18181-1-git-send-email-thuth@redhat.com> References: <1496330742-18181-1-git-send-email-thuth@redhat.com> X-Scanned-By: MIMEDefang 2.79 on 10.5.11.14 X-Greylist: Sender IP whitelisted, not delayed by milter-greylist-4.5.16 (mx1.redhat.com [10.5.110.38]); Thu, 01 Jun 2017 15:25:46 +0000 (UTC) Subject: [SLOF] [PATCH 3/4] bootmenu: Implement keyboard handling and boot menu selection X-BeenThere: slof@lists.ozlabs.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: "Patches for https://github.com/aik/SLOF" List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , MIME-Version: 1.0 Errors-To: slof-bounces+incoming=patchwork.ozlabs.org@lists.ozlabs.org Sender: "SLOF" Wait for a key and return the selected boot device on the Forth stack. Signed-off-by: Thomas Huth --- lib/libbootmenu/bootmenu.c | 74 +++++++++++++++++++++++++++++++++++++++++++ lib/libbootmenu/bootmenu.code | 2 +- 2 files changed, 75 insertions(+), 1 deletion(-) diff --git a/lib/libbootmenu/bootmenu.c b/lib/libbootmenu/bootmenu.c index 649e518..979cdc4 100644 --- a/lib/libbootmenu/bootmenu.c +++ b/lib/libbootmenu/bootmenu.c @@ -12,10 +12,12 @@ * Thomas Huth, Red Hat Inc. - initial implementation *****************************************************************************/ +#include #include #include #include #include +#include #include "bootmenu.h" #define MAX_DEVS 36 /* Enough for 10 digits + 26 letters */ @@ -93,15 +95,87 @@ static void bootmenu_show_devs(void) } } +static bool has_key(void) +{ + forth_eval("key?"); + return forth_pop(); +} + +static char get_key(void) +{ + forth_eval("key"); + return forth_pop(); +} + +/* Flush pending key presses */ +static void flush_keys(void) +{ + uint32_t start; + + start = SLOF_GetTimer(); + while (SLOF_GetTimer() - start < 10) { + if (has_key()) { + get_key(); + start = SLOF_GetTimer(); + } + } +} + +static int bootmenu_get_selection(void) +{ + char key = 0; + int sel; + + do { + sel = -1; + if (!has_key()) + continue; + key = get_key(); + switch (key) { + case '0': + return -1; + case '1' ... '9': + sel = key - '1'; + break; + case 'a' ... 'z': + sel = key - 'a' + 9; + break; + case 'A' ... 'Z': + sel = key - 'A' + 9; + break; + default: + /* Might be another escape code (F12) ... skip it */ + flush_keys(); + break; + } + } while (sel < 0 || sel >= nr_devs); + + return sel; +} + void bootmenu(void) { + int sel; + bootmenu_populate_devs(); if (!nr_devs) { puts("No available boot devices!"); return; } + puts("\nSelect boot device (or press '0' to abort):"); bootmenu_show_devs(); + if (has_key()) /* In case the user hammered on F12 */ + flush_keys(); + + sel = bootmenu_get_selection(); + if (sel < 0) { + forth_push(0); + } else { + forth_push((unsigned long)bootdevs[sel].alias); + forth_push(strlen(bootdevs[sel].alias)); + } + bootmenu_free_devs(); } diff --git a/lib/libbootmenu/bootmenu.code b/lib/libbootmenu/bootmenu.code index f51784d..2a55c09 100644 --- a/lib/libbootmenu/bootmenu.code +++ b/lib/libbootmenu/bootmenu.code @@ -14,7 +14,7 @@ #include "bootmenu.h" -// ( -- ) +// ( -- [str] len|0 ) PRIM(boot_X2d_menu) bootmenu(); MIRP