summaryrefslogtreecommitdiff
path: root/boot/expo.c
diff options
context:
space:
mode:
authorTom Rini <trini@konsulko.com>2023-07-14 13:26:42 -0400
committerTom Rini <trini@konsulko.com>2023-07-14 13:26:42 -0400
commitb3bbad816e97538c8c3b8acad7c7e134261cf3a3 (patch)
tree0cfdcc657a9e0b3a5cf91e5fbb3ef2415aa2b12f /boot/expo.c
parentcef36755094f0c5463ff34ac89de8d88ef68982b (diff)
parent04f3dcd503a537fab50329686874559dae8a1a22 (diff)
Merge branch '2023-07-14-expo-initial-config-editor'
To quote the author: This series provides a means to edit board configuration in U-Boot in a graphical manner. It supports multiple menu items and allows moving between them and selecting items. The configuration is defined in a data format so that code is not needed in most cases. This allows the board configuration to be provided in the devicetree. This is still at an early stage, since it only supports menus. Numeric values are not supported. Most importantly it does not yet support loading or saving the configuration selected by the user. To try it out you can use something like: ./tools/expo.py -e test/boot/files/expo_layout.dts \ -l test/boot/files/expo_layout.dts -o cedit.dtb ./u-boot -Tl -c "cedit load hostfs - cedit.dtb; cedit run" Use the arrow keys to move between menus, enter to open a menu, escape to exit. Various minor fixes and improvements are provided in this series: - Update STB TrueType library to latest - Support clearing part of the video display - Support multiple livetrees loaded at runtime - Support loading and allocating a file - Support proper measuring of text in expo - Support simple themes for expo
Diffstat (limited to 'boot/expo.c')
-rw-r--r--boot/expo.c102
1 files changed, 100 insertions, 2 deletions
diff --git a/boot/expo.c b/boot/expo.c
index 05950a17603..db837f7b492 100644
--- a/boot/expo.c
+++ b/boot/expo.c
@@ -6,6 +6,8 @@
* Written by Simon Glass <sjg@chromium.org>
*/
+#define LOG_CATEGORY LOGC_EXPO
+
#include <common.h>
#include <dm.h>
#include <expo.h>
@@ -54,6 +56,22 @@ void expo_destroy(struct expo *exp)
free(exp);
}
+uint resolve_id(struct expo *exp, uint id)
+{
+ log_debug("resolve id %d\n", id);
+ if (!id)
+ id = exp->next_id++;
+ else if (id >= exp->next_id)
+ exp->next_id = id + 1;
+
+ return id;
+}
+
+void expo_set_dynamic_start(struct expo *exp, uint dyn_start)
+{
+ exp->next_id = dyn_start;
+}
+
int expo_str(struct expo *exp, const char *name, uint id, const char *str)
{
struct expo_string *estr;
@@ -83,12 +101,45 @@ const char *expo_get_str(struct expo *exp, uint id)
int expo_set_display(struct expo *exp, struct udevice *dev)
{
+ struct udevice *cons;
+ int ret;
+
+ ret = device_find_first_child_by_uclass(dev, UCLASS_VIDEO_CONSOLE,
+ &cons);
+ if (ret)
+ return log_msg_ret("con", ret);
+
exp->display = dev;
+ exp->cons = cons;
+
+ return 0;
+}
+
+int expo_calc_dims(struct expo *exp)
+{
+ struct scene *scn;
+ int ret;
+
+ if (!exp->cons)
+ return log_msg_ret("dim", -ENOTSUPP);
+
+ list_for_each_entry(scn, &exp->scene_head, sibling) {
+ /*
+ * Do the menus last so that all the menus' text objects
+ * are dimensioned
+ */
+ ret = scene_calc_dims(scn, false);
+ if (ret)
+ return log_msg_ret("scn", ret);
+ ret = scene_calc_dims(scn, true);
+ if (ret)
+ return log_msg_ret("scn", ret);
+ }
return 0;
}
-void exp_set_text_mode(struct expo *exp, bool text_mode)
+void expo_set_text_mode(struct expo *exp, bool text_mode)
{
exp->text_mode = text_mode;
}
@@ -107,13 +158,33 @@ struct scene *expo_lookup_scene_id(struct expo *exp, uint scene_id)
int expo_set_scene_id(struct expo *exp, uint scene_id)
{
- if (!expo_lookup_scene_id(exp, scene_id))
+ struct scene *scn;
+ int ret;
+
+ scn = expo_lookup_scene_id(exp, scene_id);
+ if (!scn)
return log_msg_ret("id", -ENOENT);
+ ret = scene_arrange(scn);
+ if (ret)
+ return log_msg_ret("arr", ret);
+
exp->scene_id = scene_id;
return 0;
}
+int expo_first_scene_id(struct expo *exp)
+{
+ struct scene *scn;
+
+ if (list_empty(&exp->scene_head))
+ return -ENOENT;
+
+ scn = list_first_entry(&exp->scene_head, struct scene, sibling);
+
+ return scn->id;
+}
+
int expo_render(struct expo *exp)
{
struct udevice *dev = exp->display;
@@ -156,6 +227,11 @@ int expo_send_key(struct expo *exp, int key)
ret = scene_send_key(scn, key, &exp->action);
if (ret)
return log_msg_ret("key", ret);
+
+ /* arrange it to get any changes */
+ ret = scene_arrange(scn);
+ if (ret)
+ return log_msg_ret("arr", ret);
}
return scn ? 0 : -ECHILD;
@@ -168,3 +244,25 @@ int expo_action_get(struct expo *exp, struct expo_action *act)
return act->type == EXPOACT_NONE ? -EAGAIN : 0;
}
+
+int expo_apply_theme(struct expo *exp, ofnode node)
+{
+ struct scene *scn;
+ struct expo_theme *theme = &exp->theme;
+ int ret;
+
+ log_debug("Applying theme %s\n", ofnode_get_name(node));
+
+ memset(theme, '\0', sizeof(struct expo_theme));
+ ofnode_read_u32(node, "font-size", &theme->font_size);
+ ofnode_read_u32(node, "menu-inset", &theme->menu_inset);
+ ofnode_read_u32(node, "menuitem-gap-y", &theme->menuitem_gap_y);
+
+ list_for_each_entry(scn, &exp->scene_head, sibling) {
+ ret = scene_apply_theme(scn, theme);
+ if (ret)
+ return log_msg_ret("app", ret);
+ }
+
+ return 0;
+}