expo: Add a function to poll for input
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>
This commit is contained in:
@@ -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;
|
||||
|
||||
35
boot/cedit.c
35
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) {
|
||||
return log_msg_ret("cep", ret);
|
||||
}
|
||||
} while (!done);
|
||||
|
||||
|
||||
44
boot/expo.c
44
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,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;
|
||||
}
|
||||
|
||||
@@ -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 {
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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 */
|
||||
|
||||
Reference in New Issue
Block a user