Rather than returning a bootflow, return the index of the bootflow. This
will allow callers to do their own translation to bootflows or some
other data structure.

Also return a special code when the user tries to move the pointer, so
that the caller can cancel the boot-menu timeout, if this is in use.

Signed-off-by: Simon Glass <s...@chromium.org>
---

 boot/bootflow_menu.c | 32 +++++++++++++-------------------
 cmd/bootflow.c       | 12 +++++++-----
 include/bootflow.h   |  8 ++++----
 3 files changed, 24 insertions(+), 28 deletions(-)

diff --git a/boot/bootflow_menu.c b/boot/bootflow_menu.c
index a44c340167c..7e131de3f6d 100644
--- a/boot/bootflow_menu.c
+++ b/boot/bootflow_menu.c
@@ -290,32 +290,26 @@ int bootflow_menu_start(struct bootstd_priv *std, bool 
text_mode,
        return 0;
 }
 
-int bootflow_menu_poll(struct expo *exp, struct bootflow **bflowp)
+int bootflow_menu_poll(struct expo *exp, int *seqp)
 {
        struct bootflow *sel_bflow;
        struct expo_action act;
-       int ret;
+       struct scene *scn;
+       int item;
 
        sel_bflow = NULL;
-       *bflowp = NULL;
+
+       scn = expo_lookup_scene_id(exp, exp->scene_id);
+
+       item = scene_menu_get_cur_item(scn, OBJ_MENU);
+       *seqp = item > 0 ? item - ITEM : -1;
 
        LOGR("bmp", expo_poll(exp, &act));
 
        switch (act.type) {
-       case EXPOACT_SELECT: {
-               struct bootflow *bflow;
-               int i;
-
-               for (ret = bootflow_first_glob(&bflow), i = 0; !ret && i < 36;
-                    ret = bootflow_next_glob(&bflow), i++) {
-                       if (i == act.select.id - ITEM) {
-                               *bflowp = bflow;
-                               // printf("found %p\n", bflow);
-                               return 0;
-                       }
-               }
+       case EXPOACT_SELECT:
+               *seqp = act.select.id - ITEM;
                break;
-       }
        case EXPOACT_POINT_ITEM: {
                struct scene *scn = expo_lookup_scene_id(exp, MAIN);
 
@@ -323,13 +317,13 @@ int bootflow_menu_poll(struct expo *exp, struct bootflow 
**bflowp)
                        return log_msg_ret("bms", -ENOENT);
                LOGR("bmp", scene_menu_select_item(scn, OBJ_MENU,
                                                   act.select.id));
-               break;
+               return -ERESTART;
        }
        case EXPOACT_QUIT:
                return -EPIPE;
        default:
-               break;
+               return -EAGAIN;
        }
 
-       return -EAGAIN;
+       return 0;
 }
diff --git a/cmd/bootflow.c b/cmd/bootflow.c
index b8f61f966fb..3c367a10c8a 100644
--- a/cmd/bootflow.c
+++ b/cmd/bootflow.c
@@ -109,15 +109,16 @@ __maybe_unused static int bootflow_handle_menu(struct 
bootstd_priv *std,
 {
        struct expo *exp;
        struct bootflow *bflow;
-       int ret;
+       int ret, seq;
 
        LOGR("bhs", bootflow_menu_start(std, text_mode, &exp));
 
+       ret = -ERESTART;
        do {
-               LOGR("bhr", expo_render(exp));
-               ret = bootflow_menu_poll(exp, &bflow);
-       } while (ret == -EAGAIN);
-       // printf("ret %d bflow %p\n", ret, bflow);
+               if (ret == -ERESTART)
+                       LOGR("bhr", expo_render(exp));
+               ret = bootflow_menu_poll(exp, &seq);
+       } while (ret == -EAGAIN || ret == -ERESTART);
 
        if (ret == -EPIPE) {
                printf("Nothing chosen\n");
@@ -125,6 +126,7 @@ __maybe_unused static int bootflow_handle_menu(struct 
bootstd_priv *std,
        } else if (ret) {
                printf("Menu failed (err=%d)\n", ret);
        } else {
+               bflow = alist_getw(&std->bootflows, seq, struct bootflow);
                printf("Selected: %s\n", bflow->os_name ? bflow->os_name :
                       bflow->name);
                std->cur_bootflow = bflow;
diff --git a/include/bootflow.h b/include/bootflow.h
index aa46cec4979..8362cbe2e69 100644
--- a/include/bootflow.h
+++ b/include/bootflow.h
@@ -671,10 +671,10 @@ int bootflow_menu_start(struct bootstd_priv *std, bool 
text_mode,
  * bootflow_menu_poll() - Poll a menu for user action
  *
  * @exp: Expo to poll
- * @bflowp: Returns chosen bootflow (set to NULL if nothing is chosen)
- * Return 0 if a bootflow was chosen, -EAGAIN if nothing is chosen yet, -EPIPE
- *     if the user quit
+ * @seqp: Returns the bootflow chosen or currently pointed to (numbered from 0)
+ * Return: 0 if a bootflow was chosen, -EAGAIN if nothing is chosen yet, -EPIPE
+ *     if the user quit, -ERESTART if the expo needs refreshing
  */
-int bootflow_menu_poll(struct expo *exp, struct bootflow **bflowp);
+int bootflow_menu_poll(struct expo *exp, int *seqp);
 
 #endif
-- 
2.43.0

Reply via email to