[PATCH 14/52] expo: Add a function to poll for input
Simon Glass
sjg at chromium.org
Wed Mar 19 15:54:19 CET 2025
Both bootflow_menu and cedit use similar logic to poll an expo. Move
this into the expo library so the code can be shared.
Update bootflow_menu_run() to return -EPIPE when the user quits without
choosing anything, since -EAGAIN is ambiguous and elsewhere means that
there is no input yet.
Signed-off-by: Simon Glass <sjg at chromium.org>
---
boot/bootflow_menu.c | 41 ++++-------------------------------------
boot/cedit.c | 35 +++--------------------------------
boot/expo.c | 38 ++++++++++++++++++++++++++++++++++++++
include/bootflow.h | 2 +-
include/expo.h | 13 +++++++++++++
5 files changed, 59 insertions(+), 70 deletions(-)
diff --git a/boot/bootflow_menu.c b/boot/bootflow_menu.c
index 43125e15832..e3a27f16daa 100644
--- a/boot/bootflow_menu.c
+++ b/boot/bootflow_menu.c
@@ -216,39 +216,8 @@ int bootflow_menu_run(struct bootstd_priv *std, bool text_mode,
done = false;
do {
struct expo_action act;
- int ichar, key;
- ret = expo_render(exp);
- if (ret)
- break;
-
- ichar = cli_ch_process(&exp->cch, 0);
- if (!ichar) {
- while (!ichar && !tstc()) {
- schedule();
- mdelay(2);
- ichar = cli_ch_process(&exp->cch, -ETIMEDOUT);
- }
- if (!ichar) {
- ichar = getchar();
- ichar = cli_ch_process(&exp->cch, ichar);
- }
- }
-
- key = 0;
- if (ichar) {
- key = bootmenu_conv_key(ichar);
- if (key == BKEY_NONE)
- key = ichar;
- }
- if (!key)
- continue;
-
- ret = expo_send_key(exp, key);
- if (ret)
- break;
-
- ret = expo_action_get(exp, &act);
+ ret = expo_poll(exp, &act);
if (!ret) {
switch (act.type) {
case EXPOACT_SELECT:
@@ -256,17 +225,15 @@ int bootflow_menu_run(struct bootstd_priv *std, bool text_mode,
done = true;
break;
case EXPOACT_QUIT:
- done = true;
- break;
+ return -EPIPE;
default:
break;
}
+ } else if (ret != -EPIPE && ret != -EAGAIN) {
+ LOGR("bmr", ret);
}
} while (!done);
- if (ret)
- return log_msg_ret("end", ret);
-
if (sel_id) {
struct bootflow *bflow;
int i;
diff --git a/boot/cedit.c b/boot/cedit.c
index 50d63c8258d..9baef39a0cd 100644
--- a/boot/cedit.c
+++ b/boot/cedit.c
@@ -166,39 +166,8 @@ int cedit_run(struct expo *exp)
save = false;
do {
struct expo_action act;
- int ichar, key;
- ret = expo_render(exp);
- if (ret)
- break;
-
- ichar = cli_ch_process(&exp->cch, 0);
- if (!ichar) {
- while (!ichar && !tstc()) {
- schedule();
- mdelay(2);
- ichar = cli_ch_process(&exp->cch, -ETIMEDOUT);
- }
- if (!ichar) {
- ichar = getchar();
- ichar = cli_ch_process(&exp->cch, ichar);
- }
- }
-
- key = 0;
- if (ichar) {
- key = bootmenu_conv_key(ichar);
- if (key == BKEY_NONE || key >= BKEY_FIRST_EXTRA)
- key = ichar;
- }
- if (!key)
- continue;
-
- ret = expo_send_key(exp, key);
- if (ret)
- break;
-
- ret = expo_action_get(exp, &act);
+ ret = expo_poll(exp, &act);
if (!ret) {
switch (act.type) {
case EXPOACT_POINT_OBJ:
@@ -233,6 +202,8 @@ int cedit_run(struct expo *exp)
default:
break;
}
+ } else if (ret != -EAGAIN) {
+ LOGR("cep", ret);
}
} while (!done);
diff --git a/boot/expo.c b/boot/expo.c
index 9c042f16fe7..ba052df932c 100644
--- a/boot/expo.c
+++ b/boot/expo.c
@@ -10,8 +10,12 @@
#include <dm.h>
#include <expo.h>
+#include <log.h>
#include <malloc.h>
+#include <menu.h>
#include <video.h>
+#include <watchdog.h>
+#include <linux/delay.h>
#include "scene_internal.h"
int expo_new(const char *name, void *priv, struct expo **expp)
@@ -286,3 +290,37 @@ int expo_iter_scene_objs(struct expo *exp, expo_scene_obj_iterator iter,
return 0;
}
+
+int expo_poll(struct expo *exp, struct expo_action *act)
+{
+ int ichar, key;
+
+ LOGR("ere", expo_render(exp));
+
+ ichar = cli_ch_process(&exp->cch, 0);
+ if (!ichar) {
+ while (!ichar && !tstc()) {
+ schedule();
+ mdelay(2);
+ ichar = cli_ch_process(&exp->cch, -ETIMEDOUT);
+ }
+ if (!ichar) {
+ ichar = getchar();
+ ichar = cli_ch_process(&exp->cch, ichar);
+ }
+ }
+
+ key = 0;
+ if (ichar) {
+ key = bootmenu_conv_key(ichar);
+ if (key == BKEY_NONE || key >= BKEY_FIRST_EXTRA)
+ key = ichar;
+ }
+ if (!key)
+ return -EAGAIN;
+
+ LOGR("epk", expo_send_key(exp, key));
+ LOGR("eag", expo_action_get(exp, act));
+
+ return 0;
+}
diff --git a/include/bootflow.h b/include/bootflow.h
index d988bc9355b..ef1d1a75ded 100644
--- a/include/bootflow.h
+++ b/include/bootflow.h
@@ -509,7 +509,7 @@ int bootflow_menu_apply_theme(struct expo *exp, ofnode node);
* @std: Bootstd information
* @text_mode: Uses a text-based menu suitable for a serial port
* @bflowp: Returns chosen bootflow (set to NULL if nothing is chosen)
- * @return 0 if an option was chosen, -EAGAIN if nothing was chosen, -ve on
+ * @return 0 if an option was chosen, -EPIPE if nothing was chosen, -ve on
* error
*/
int bootflow_menu_run(struct bootstd_priv *std, bool text_mode,
diff --git a/include/expo.h b/include/expo.h
index b3b9c0b8872..63452bbdd6a 100644
--- a/include/expo.h
+++ b/include/expo.h
@@ -772,4 +772,17 @@ int expo_build(ofnode root, struct expo **expp);
*/
int cb_expo_build(struct expo **expp);
+/**
+ * expo_poll() - render an expo and see if the user takes an action
+ *
+ * Thsi calls expo_render() and then checks for a keypress. If there is one, it
+ * is processed and the resulting action returned, if any
+ *
+ * @exp: Expo to poll
+ * @act: Returns action on success
+ * Return: 0 if an action was obtained, -EAGAIN if not, other error if something
+ * went wrong
+ */
+int expo_poll(struct expo *exp, struct expo_action *act);
+
#endif /*__EXPO_H */
--
2.43.0
More information about the U-Boot
mailing list