diff options
| author | Simon Glass <[email protected]> | 2023-06-01 10:23:02 -0600 |
|---|---|---|
| committer | Tom Rini <[email protected]> | 2023-07-14 12:54:51 -0400 |
| commit | a0874dc4ac7153f49f72c3fb818422d940ecbfea (patch) | |
| tree | 301951243204c9654b3c85dc4b85db985d1e2e28 /boot | |
| parent | 82cafee133ee5c087449761988c096fc26a17cf6 (diff) | |
expo: Add a configuration editor
Add a new 'cedit' command which allows editing configuration using an
expo. The configuration items appear as menus on the display.
This is extremely basic, only supporting menus and not providing any way
to load or save the configuration.
Signed-off-by: Simon Glass <[email protected]>
Diffstat (limited to 'boot')
| -rw-r--r-- | boot/Kconfig | 14 | ||||
| -rw-r--r-- | boot/Makefile | 1 | ||||
| -rw-r--r-- | boot/cedit.c | 163 | ||||
| -rw-r--r-- | boot/expo_build.c | 3 | ||||
| -rw-r--r-- | boot/scene.c | 12 | ||||
| -rw-r--r-- | boot/scene_internal.h | 8 |
6 files changed, 200 insertions, 1 deletions
diff --git a/boot/Kconfig b/boot/Kconfig index a643a3d1286..c8b8f36d835 100644 --- a/boot/Kconfig +++ b/boot/Kconfig @@ -1630,4 +1630,18 @@ config SAVE_PREV_BL_INITRAMFS_START_ADDR If no initramfs was provided by previous bootloader, no env variables will be created. +menu "Configuration editor" + +config CEDIT + bool "Configuration editor" + depends on BOOTSTD + help + Provides a way to deal with board configuration and present it to + the user for adjustment. + + This is intended to provide both graphical and text-based user + interfaces, but only graphical is support at present. + +endmenu # Configuration editor + endmenu # Booting diff --git a/boot/Makefile b/boot/Makefile index 28c4e55ca65..f828f870a37 100644 --- a/boot/Makefile +++ b/boot/Makefile @@ -33,6 +33,7 @@ ifdef CONFIG_$(SPL_TPL_)BOOTSTD_FULL obj-$(CONFIG_CMD_BOOTEFI_BOOTMGR) += bootmeth_efi_mgr.o obj-$(CONFIG_$(SPL_TPL_)EXPO) += bootflow_menu.o obj-$(CONFIG_$(SPL_TPL_)BOOTSTD) += bootflow_menu.o +obj-$(CONFIG_$(SPL_TPL_)CEDIT) += cedit.o endif obj-$(CONFIG_$(SPL_TPL_)OF_LIBFDT) += image-fdt.o diff --git a/boot/cedit.c b/boot/cedit.c new file mode 100644 index 00000000000..ee24658917b --- /dev/null +++ b/boot/cedit.c @@ -0,0 +1,163 @@ +// SPDX-License-Identifier: GPL-2.0+ +/* + * Implementation of configuration editor + * + * Copyright 2023 Google LLC + * Written by Simon Glass <[email protected]> + */ + +#include <common.h> +#include <cli.h> +#include <dm.h> +#include <expo.h> +#include <menu.h> +#include <video.h> +#include <linux/delay.h> +#include "scene_internal.h" + +int cedit_arange(struct expo *exp, struct video_priv *vpriv, uint scene_id) +{ + struct scene_obj_txt *txt; + struct scene_obj *obj; + struct scene *scn; + int y; + + scn = expo_lookup_scene_id(exp, scene_id); + if (!scn) + return log_msg_ret("scn", -ENOENT); + + txt = scene_obj_find_by_name(scn, "prompt"); + if (txt) + scene_obj_set_pos(scn, txt->obj.id, 0, vpriv->ysize - 50); + + txt = scene_obj_find_by_name(scn, "title"); + if (txt) + scene_obj_set_pos(scn, txt->obj.id, 200, 10); + + y = 100; + list_for_each_entry(obj, &scn->obj_head, sibling) { + if (obj->type == SCENEOBJT_MENU) { + scene_obj_set_pos(scn, obj->id, 50, y); + scene_menu_arrange(scn, (struct scene_obj_menu *)obj); + y += 50; + } + } + + return 0; +} + +int cedit_run(struct expo *exp) +{ + struct cli_ch_state s_cch, *cch = &s_cch; + struct video_priv *vid_priv; + uint scene_id; + struct udevice *dev; + struct scene *scn; + bool done; + int ret; + + cli_ch_init(cch); + + /* For now we only support a video console */ + ret = uclass_first_device_err(UCLASS_VIDEO, &dev); + if (ret) + return log_msg_ret("vid", ret); + ret = expo_set_display(exp, dev); + if (ret) + return log_msg_ret("dis", ret); + + ret = expo_first_scene_id(exp); + if (ret < 0) + return log_msg_ret("scn", ret); + scene_id = ret; + + ret = expo_set_scene_id(exp, scene_id); + if (ret) + return log_msg_ret("sid", ret); + + exp->popup = true; + + /* This is not supported for now */ + if (0) + expo_set_text_mode(exp, true); + + vid_priv = dev_get_uclass_priv(dev); + + scn = expo_lookup_scene_id(exp, scene_id); + scene_highlight_first(scn); + + cedit_arange(exp, vid_priv, scene_id); + + ret = expo_calc_dims(exp); + if (ret) + return log_msg_ret("dim", ret); + + done = false; + do { + struct expo_action act; + int ichar, key; + + ret = expo_render(exp); + if (ret) + break; + + ichar = cli_ch_process(cch, 0); + if (!ichar) { + while (!ichar && !tstc()) { + schedule(); + mdelay(2); + ichar = cli_ch_process(cch, -ETIMEDOUT); + } + if (!ichar) { + ichar = getchar(); + ichar = cli_ch_process(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); + if (!ret) { + switch (act.type) { + case EXPOACT_POINT_OBJ: + scene_set_highlight_id(scn, act.select.id); + cedit_arange(exp, vid_priv, scene_id); + break; + case EXPOACT_OPEN: + scene_set_open(scn, act.select.id, true); + cedit_arange(exp, vid_priv, scene_id); + break; + case EXPOACT_CLOSE: + scene_set_open(scn, act.select.id, false); + cedit_arange(exp, vid_priv, scene_id); + break; + case EXPOACT_SELECT: + scene_set_open(scn, scn->highlight_id, false); + cedit_arange(exp, vid_priv, scene_id); + break; + case EXPOACT_QUIT: + log_debug("quitting\n"); + done = true; + break; + default: + break; + } + } + } while (!done); + + if (ret) + return log_msg_ret("end", ret); + + return 0; +} diff --git a/boot/expo_build.c b/boot/expo_build.c index 7e61ab06a8d..22f62eb54bc 100644 --- a/boot/expo_build.c +++ b/boot/expo_build.c @@ -376,7 +376,8 @@ int expo_build(ofnode root, struct expo **expp) ret = read_strings(&info, root); if (ret) return log_msg_ret("str", ret); - list_strings(&info); + if (_DEBUG) + list_strings(&info); ret = expo_new("name", NULL, &exp); if (ret) diff --git a/boot/scene.c b/boot/scene.c index 6fbc1fc578c..e52333371f9 100644 --- a/boot/scene.c +++ b/boot/scene.c @@ -92,6 +92,18 @@ void *scene_obj_find(struct scene *scn, uint id, enum scene_obj_t type) return NULL; } +void *scene_obj_find_by_name(struct scene *scn, const char *name) +{ + struct scene_obj *obj; + + list_for_each_entry(obj, &scn->obj_head, sibling) { + if (!strcmp(name, obj->name)) + return obj; + } + + return NULL; +} + int scene_obj_add(struct scene *scn, const char *name, uint id, enum scene_obj_t type, uint size, struct scene_obj **objp) { diff --git a/boot/scene_internal.h b/boot/scene_internal.h index dc98ecd0214..fb1ea5533b9 100644 --- a/boot/scene_internal.h +++ b/boot/scene_internal.h @@ -41,6 +41,14 @@ uint resolve_id(struct expo *exp, uint id); void *scene_obj_find(struct scene *scn, uint id, enum scene_obj_t type); /** + * scene_obj_find_by_name() - Find an object in a scene by name + * + * @scn: Scene to search + * @name: Name to search for + */ +void *scene_obj_find_by_name(struct scene *scn, const char *name); + +/** * scene_obj_add() - Add a new object to a scene * * @scn: Scene to update |
