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 <s...@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