summaryrefslogtreecommitdiff
path: root/boot/expo.c
diff options
context:
space:
mode:
Diffstat (limited to 'boot/expo.c')
-rw-r--r--boot/expo.c72
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;
+}