All of lore.kernel.org
 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 an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.