diff options
Diffstat (limited to 'boot/expo.c')
-rw-r--r-- | boot/expo.c | 72 |
1 files changed, 70 insertions, 2 deletions
diff --git a/boot/expo.c b/boot/expo.c index 8ce645e5a8f..94413acd381 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) @@ -30,6 +34,7 @@ int expo_new(const char *name, void *priv, struct expo **expp) INIT_LIST_HEAD(&exp->scene_head); INIT_LIST_HEAD(&exp->str_head); exp->next_id = EXPOID_BASE_ID; + cli_ch_init(&exp->cch); *expp = exp; @@ -81,7 +86,7 @@ int expo_str(struct expo *exp, const char *name, uint id, const char *str) return log_msg_ret("obj", -ENOMEM); estr->id = resolve_id(exp, id); - estr->str = str; + abuf_init_const(&estr->buf, str, strlen(str) + 1); list_add_tail(&estr->sibling, &exp->str_head); return estr->id; @@ -93,12 +98,33 @@ const char *expo_get_str(struct expo *exp, uint id) list_for_each_entry(estr, &exp->str_head, sibling) { if (estr->id == id) - return estr->str; + return estr->buf.data; } return NULL; } +int expo_edit_str(struct expo *exp, uint id, struct abuf *orig, + struct abuf **copyp) +{ + struct expo_string *estr; + struct abuf old; + + list_for_each_entry(estr, &exp->str_head, sibling) { + if (estr->id == id) { + old = estr->buf; + if (!abuf_copy(&old, &estr->buf)) + return -ENOMEM; + *copyp = &estr->buf; + if (orig) + *orig = old; + return 0; + } + } + + return -ENOENT; +} + int expo_set_display(struct expo *exp, struct udevice *dev) { struct udevice *cons; @@ -251,6 +277,7 @@ int expo_apply_theme(struct expo *exp, ofnode node) { struct scene *scn; struct expo_theme *theme = &exp->theme; + bool white_on_black; int ret; log_debug("Applying theme %s\n", ofnode_get_name(node)); @@ -261,6 +288,9 @@ int expo_apply_theme(struct expo *exp, ofnode node) ofnode_read_u32(node, "menuitem-gap-y", &theme->menuitem_gap_y); ofnode_read_u32(node, "menu-title-margin-x", &theme->menu_title_margin_x); + white_on_black = ofnode_read_bool(node, "white-on-black"); + if (exp->display) + video_set_white_on_black(exp->display, white_on_black); list_for_each_entry(scn, &exp->scene_head, sibling) { ret = scene_apply_theme(scn, theme); @@ -285,3 +315,41 @@ 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; + + ichar = cli_ch_process(&exp->cch, 0); + if (!ichar) { + int i; + + for (i = 0; i < 10 && !ichar && !tstc(); i++) { + schedule(); + mdelay(2); + ichar = cli_ch_process(&exp->cch, -ETIMEDOUT); + } + while (!ichar && tstc()) { + 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; +} |