public inbox for u-boot@lists.denx.de
 help / color / mirror / Atom feed
From: "Pali Rohár" <pali@kernel.org>
To: Tom Rini <trini@konsulko.com>, Stefan Roese <sr@denx.de>
Cc: u-boot@lists.denx.de
Subject: [PATCH u-boot 3/3] Revert "menu: Make use of CLI character processing"
Date: Sun, 11 Jun 2023 14:53:24 +0200	[thread overview]
Message-ID: <20230611125324.15860-4-pali@kernel.org> (raw)
In-Reply-To: <20230611125324.15860-1-pali@kernel.org>

This reverts commit 32bab0eae51b55898d1e2804e6614d9143840581.

Signed-off-by: Pali Rohár <pali@kernel.org>
---
 cmd/bootmenu.c     |  9 ++---
 cmd/eficonfig.c    | 12 ++----
 common/cli_getch.c | 12 ++----
 common/menu.c      | 92 +++++++++++++++++++++++++++++++++-------------
 include/cli.h      |  4 +-
 include/menu.h     |  7 +---
 6 files changed, 80 insertions(+), 56 deletions(-)

diff --git a/cmd/bootmenu.c b/cmd/bootmenu.c
index 6baeedc69f91..c02dc6269283 100644
--- a/cmd/bootmenu.c
+++ b/cmd/bootmenu.c
@@ -4,7 +4,6 @@
  */
 
 #include <charset.h>
-#include <cli.h>
 #include <common.h>
 #include <command.h>
 #include <ansi.h>
@@ -85,21 +84,19 @@ static void bootmenu_print_entry(void *data)
 
 static char *bootmenu_choice_entry(void *data)
 {
-	struct cli_ch_state s_cch, *cch = &s_cch;
 	struct bootmenu_data *menu = data;
 	struct bootmenu_entry *iter;
 	enum bootmenu_key key = BKEY_NONE;
+	int esc = 0;
 	int i;
 
-	cli_ch_init(cch);
-
 	while (1) {
 		if (menu->delay >= 0) {
 			/* Autoboot was not stopped */
-			key = bootmenu_autoboot_loop(menu, cch);
+			key = bootmenu_autoboot_loop(menu, &esc);
 		} else {
 			/* Some key was pressed, so autoboot was stopped */
-			key = bootmenu_loop(menu, cch);
+			key = bootmenu_loop(menu, &esc);
 		}
 
 		switch (key) {
diff --git a/cmd/eficonfig.c b/cmd/eficonfig.c
index 720f52b48b8c..5c3ed76e78f5 100644
--- a/cmd/eficonfig.c
+++ b/cmd/eficonfig.c
@@ -6,7 +6,6 @@
  */
 
 #include <ansi.h>
-#include <cli.h>
 #include <common.h>
 #include <charset.h>
 #include <efi_loader.h>
@@ -230,16 +229,14 @@ void eficonfig_display_statusline(struct menu *m)
  */
 char *eficonfig_choice_entry(void *data)
 {
-	struct cli_ch_state s_cch, *cch = &s_cch;
+	int esc = 0;
 	struct list_head *pos, *n;
 	struct eficonfig_entry *entry;
 	enum bootmenu_key key = BKEY_NONE;
 	struct efimenu *efi_menu = data;
 
-	cli_ch_init(cch);
-
 	while (1) {
-		key = bootmenu_loop((struct bootmenu_data *)efi_menu, cch);
+		key = bootmenu_loop((struct bootmenu_data *)efi_menu, &esc);
 
 		switch (key) {
 		case BKEY_UP:
@@ -1929,15 +1926,14 @@ static void eficonfig_print_change_boot_order_entry(void *data)
  */
 char *eficonfig_choice_change_boot_order(void *data)
 {
-	struct cli_ch_state s_cch, *cch = &s_cch;
+	int esc = 0;
 	struct list_head *pos, *n;
 	struct efimenu *efi_menu = data;
 	enum bootmenu_key key = BKEY_NONE;
 	struct eficonfig_entry *entry, *tmp;
 
-	cli_ch_init(cch);
 	while (1) {
-		key = bootmenu_loop(NULL, cch);
+		key = bootmenu_loop(NULL, &esc);
 
 		switch (key) {
 		case BKEY_PLUS:
diff --git a/common/cli_getch.c b/common/cli_getch.c
index 61d4cb261b81..8080ff814eff 100644
--- a/common/cli_getch.c
+++ b/common/cli_getch.c
@@ -140,11 +140,10 @@ int cli_ch_process(struct cli_ch_state *cch, int ichar)
 	 * sequence
 	 */
 	if (!ichar) {
-		if (cch->emitting) {
+		if (cch->emit_upto) {
 			if (cch->emit_upto < cch->esc_len)
 				return cch->esc_save[cch->emit_upto++];
 			cch->emit_upto = 0;
-			cch->emitting = false;
 			cch->esc_len = 0;
 		}
 		return 0;
@@ -176,21 +175,18 @@ int cli_ch_process(struct cli_ch_state *cch, int ichar)
 		case ESC_SAVE:
 			/* save this character and return nothing */
 			cch->esc_save[cch->esc_len++] = ichar;
-			ichar = 0;
-			break;
+			return 0;
 		case ESC_REJECT:
 			/*
 			 * invalid escape sequence, start returning the
 			 * characters in it
 			 */
 			cch->esc_save[cch->esc_len++] = ichar;
-			ichar = cch->esc_save[cch->emit_upto++];
-			cch->emitting = true;
-			return ichar;
+			return cch->esc_save[cch->emit_upto++];
 		case ESC_CONVERTED:
 			/* valid escape sequence, return the resulting char */
 			cch->esc_len = 0;
-			break;
+			return ichar;
 		}
 	}
 
diff --git a/common/menu.c b/common/menu.c
index b6ec2e9c616c..5b614eafa413 100644
--- a/common/menu.c
+++ b/common/menu.c
@@ -15,8 +15,6 @@
 
 #include "menu.h"
 
-#define ansi 0
-
 /*
  * Internally, each item in a menu is represented by a struct menu_item.
  *
@@ -427,19 +425,15 @@ int menu_destroy(struct menu *m)
 	return 1;
 }
 
-enum bootmenu_key bootmenu_autoboot_loop(struct bootmenu_data *menu,
-					 struct cli_ch_state *cch)
+enum bootmenu_key bootmenu_autoboot_loop(struct bootmenu_data *menu, int *esc)
 {
 	enum bootmenu_key key = BKEY_NONE;
 	int i, c;
 
 	while (menu->delay > 0) {
-		if (ansi)
-			printf(ANSI_CURSOR_POSITION, menu->count + 5, 3);
+		printf(ANSI_CURSOR_POSITION, menu->count + 5, 3);
 		printf("Hit any key to stop autoboot: %d ", menu->delay);
 		for (i = 0; i < 100; ++i) {
-			int ichar;
-
 			if (!tstc()) {
 				schedule();
 				mdelay(10);
@@ -449,13 +443,12 @@ enum bootmenu_key bootmenu_autoboot_loop(struct bootmenu_data *menu,
 			menu->delay = -1;
 			c = getchar();
 
-			ichar = cli_ch_process(cch, c);
-
-			switch (ichar) {
-			case '\0':
+			switch (c) {
+			case '\e':
+				*esc = 1;
 				key = BKEY_NONE;
 				break;
-			case '\n':
+			case '\r':
 				key = BKEY_SELECT;
 				break;
 			case 0x3: /* ^C */
@@ -465,6 +458,7 @@ enum bootmenu_key bootmenu_autoboot_loop(struct bootmenu_data *menu,
 				key = BKEY_NONE;
 				break;
 			}
+
 			break;
 		}
 
@@ -474,8 +468,7 @@ enum bootmenu_key bootmenu_autoboot_loop(struct bootmenu_data *menu,
 		--menu->delay;
 	}
 
-	if (ansi)
-		printf(ANSI_CURSOR_POSITION ANSI_CLEAR_LINE, menu->count + 5, 1);
+	printf(ANSI_CURSOR_POSITION ANSI_CLEAR_LINE, menu->count + 5, 1);
 
 	if (menu->delay == 0)
 		key = BKEY_SELECT;
@@ -483,32 +476,79 @@ enum bootmenu_key bootmenu_autoboot_loop(struct bootmenu_data *menu,
 	return key;
 }
 
-enum bootmenu_key bootmenu_loop(struct bootmenu_data *menu,
-				struct cli_ch_state *cch)
+enum bootmenu_key bootmenu_loop(struct bootmenu_data *menu, int *esc)
 {
 	enum bootmenu_key key = BKEY_NONE;
 	int c;
 
-	c = cli_ch_process(cch, 0);
-	if (!c) {
-		while (!c && !tstc()) {
+	if (*esc == 1) {
+		if (tstc()) {
+			c = getchar();
+		} else {
 			schedule();
 			mdelay(10);
-			c = cli_ch_process(cch, -ETIMEDOUT);
+			if (tstc())
+				c = getchar();
+			else
+				c = '\e';
 		}
-		if (!c) {
-			c = getchar();
-			c = cli_ch_process(cch, c);
+	} else {
+		while (!tstc()) {
+			schedule();
+			mdelay(10);
 		}
+		c = getchar();
+	}
+
+	switch (*esc) {
+	case 0:
+		/* First char of ANSI escape sequence '\e' */
+		if (c == '\e') {
+			*esc = 1;
+			key = BKEY_NONE;
+		}
+		break;
+	case 1:
+		/* Second char of ANSI '[' */
+		if (c == '[') {
+			*esc = 2;
+			key = BKEY_NONE;
+		} else {
+		/* Alone ESC key was pressed */
+			key = BKEY_QUIT;
+			*esc = (c == '\e') ? 1 : 0;
+		}
+		break;
+	case 2:
+	case 3:
+		/* Third char of ANSI (number '1') - optional */
+		if (*esc == 2 && c == '1') {
+			*esc = 3;
+			key = BKEY_NONE;
+			break;
+		}
+
+		*esc = 0;
+
+		/* ANSI 'A' - key up was pressed */
+		if (c == 'A')
+			key = BKEY_UP;
+		/* ANSI 'B' - key down was pressed */
+		else if (c == 'B')
+			key = BKEY_DOWN;
+		/* other key was pressed */
+		else
+			key = BKEY_NONE;
+
+		break;
 	}
 
 	switch (c) {
-	case '\n':
+	case '\r':
 		/* enter key was pressed */
 		key = BKEY_SELECT;
 		break;
 	case CTL_CH('c'):
-	case '\e':
 		/* ^C was pressed */
 		key = BKEY_QUIT;
 		break;
diff --git a/include/cli.h b/include/cli.h
index 094a6602d70e..0c7995fb90a4 100644
--- a/include/cli.h
+++ b/include/cli.h
@@ -14,14 +14,12 @@
  *
  * @esc_len: Number of escape characters read so far
  * @esc_save: Escape characters collected so far
- * @emit_upto: Next index to emit from esc_save
- * @emitting: true if emitting from esc_save
+ * @emit_upto: Next character to emit from esc_save (0 if not emitting)
  */
 struct cli_ch_state {
 	int esc_len;
 	char esc_save[8];
 	int emit_upto;
-	bool emitting;
 };
 
 /**
diff --git a/include/menu.h b/include/menu.h
index 5e54f033dfa4..e4fae283f74f 100644
--- a/include/menu.h
+++ b/include/menu.h
@@ -6,7 +6,6 @@
 #ifndef __MENU_H__
 #define __MENU_H__
 
-struct cli_ch_state;
 struct menu;
 
 struct menu *menu_create(char *title, int timeout, int prompt,
@@ -73,8 +72,7 @@ enum bootmenu_key {
  *	Ctrl-C: KEY_QUIT
  *	anything else: KEY_NONE
  */
-enum bootmenu_key bootmenu_autoboot_loop(struct bootmenu_data *menu,
-					 struct cli_ch_state *cch);
+enum bootmenu_key bootmenu_autoboot_loop(struct bootmenu_data *menu, int *esc);
 
 /**
  * bootmenu_loop() - handle waiting for a keypress when autoboot is disabled
@@ -99,7 +97,6 @@ enum bootmenu_key bootmenu_autoboot_loop(struct bootmenu_data *menu,
  *	Minus: BKEY_MINUS
  *	Space: BKEY_SPACE
  */
-enum bootmenu_key bootmenu_loop(struct bootmenu_data *menu,
-				struct cli_ch_state *cch);
+enum bootmenu_key bootmenu_loop(struct bootmenu_data *menu, int *esc);
 
 #endif /* __MENU_H__ */
-- 
2.20.1


  parent reply	other threads:[~2023-06-11 12:54 UTC|newest]

Thread overview: 17+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2023-06-11 12:53 [PATCH u-boot 0/3] Revert broken Bootmenu commits Pali Rohár
2023-06-11 12:53 ` [PATCH u-boot 1/3] Revert "video: Enable VIDEO_ANSI by default only with EFI" Pali Rohár
2023-06-11 12:53 ` [PATCH u-boot 2/3] Revert "menu: Factor out menu-keypress decoding" Pali Rohár
2023-06-11 12:53 ` Pali Rohár [this message]
2023-06-14 19:51 ` [PATCH u-boot 0/3] Revert broken Bootmenu commits Tom Rini
2023-06-20 10:20   ` Simon Glass
2023-06-24  8:50     ` Pali Rohár
2023-06-24 16:58       ` Tom Rini
2023-06-25  7:50         ` Pali Rohár
2023-06-25 14:52           ` Tom Rini
2023-06-25 15:15             ` Pali Rohár
2023-06-26  1:08               ` Tom Rini
2023-07-10 14:10                 ` Pali Rohár
2023-07-10 14:17                   ` Simon Glass
2023-07-10 15:17                   ` Tom Rini
2023-07-10 16:03                     ` Stefan Roese
2023-07-13 15:12                       ` Stefan Roese

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20230611125324.15860-4-pali@kernel.org \
    --to=pali@kernel.org \
    --cc=sr@denx.de \
    --cc=trini@konsulko.com \
    --cc=u-boot@lists.denx.de \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox