]> git.ipfire.org Git - thirdparty/u-boot.git/commitdiff
expo: Add a function to poll for input
authorSimon Glass <sjg@chromium.org>
Fri, 2 May 2025 14:46:16 +0000 (08:46 -0600)
committerSimon Glass <sjg@chromium.org>
Fri, 30 May 2025 08:49:31 +0000 (09:49 +0100)
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@chromium.org>
boot/bootflow_menu.c
boot/cedit.c
boot/expo.c
cmd/bootflow.c
include/bootflow.h
include/expo.h

index 43125e15832e6bb91c833bcad262acf978c06969..268c93ae8e346bb9f84347de8a63f326b88698f5 100644 (file)
@@ -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) {
+                       return log_msg_ret("bmr", ret);
                }
        } while (!done);
 
-       if (ret)
-               return log_msg_ret("end", ret);
-
        if (sel_id) {
                struct bootflow *bflow;
                int i;
index ed499f11140c351e076fcfdea3f7f3997bc89479..b7b9cc510e05fa091a07c1296578828440cd4143 100644 (file)
@@ -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) {
+                       return log_msg_ret("cep", ret);
                }
        } while (!done);
 
index 9c042f16fe7799a8237513e83104455ecbef6b6c..301bbfa5f9afabdd7cf28095cce0466f9ce48494 100644 (file)
 
 #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,43 @@ 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, ret;
+
+       ret = expo_render(exp);
+       if (ret)
+               return log_msg_ret("ere", ret);
+
+       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;
+
+       ret = expo_send_key(exp, key);
+       if (ret)
+               return log_msg_ret("epk", ret);
+       ret = expo_action_get(exp, act);
+       if (ret)
+               return log_msg_ret("eag", ret);
+
+       return 0;
+}
index d4f7d336150099800068851877415a71b4e0284b..f2662239714e05a20a4b0e7b449690d987b0e450 100644 (file)
@@ -110,7 +110,7 @@ __maybe_unused static int bootflow_handle_menu(struct bootstd_priv *std,
 
        ret = bootflow_menu_run(std, text_mode, &bflow);
        if (ret) {
-               if (ret == -EAGAIN) {
+               if (ret == -EPIPE) {
                        printf("Nothing chosen\n");
                        std->cur_bootflow = NULL;
                } else {
index d408b8c85bd143468013699baa84672700b4eb4c..fe090d39ffb8433e118c393a078d3765636259e7 100644 (file)
@@ -508,7 +508,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,
index b3b9c0b8872309366a42e849ecc1b6df7fd0f2d4..63452bbdd6a5662607af8c78f107b3fba79afb28 100644 (file)
@@ -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 */