[PATCH 00/16] boot: Separate out the boot-menu style
This series refactors the boot menu so that it is possible to create the items and then (later) change the style/position to the simple style. This allows swapping back and forth between a different style and the simple style. It also adjusts how the mouse is set up, so that the initial mouse position is only set up once the video device is known. This allows the position to be centred on the display, a better starting point than the top left. Simon Glass (16): scripts: build-efi: Use the USB mouse video: Report failure to write a frame to a file expo: Check the mouse once the video device is known expo: Avoid setting SCENEOF_SIZE_VALID with calculated size expo: Avoid setting SCENEOF_SIZE_VALID with menu items expo: Allow applying the theme to just the display expo: Clarify that text objects are not string IDs mouse: Place mouse in the middle of the display boot: Split out setting menu properties from menu creation boot: Move prompt strings into bootflow_menu_set_props() boot: Hide unwanted objects and show the menu pointer boot: Add the distro version and box into the menu boot: Move text for desc and label items to after setup boot: Explicitly request that the menu position its objects boot: Explicitly set up the theme with the boot menu boot: Set the item properties with the boot menu boot/bootflow_menu.c | 204 ++++++++++++++++++++++++++--------- boot/expo.c | 32 +++--- boot/scene.c | 19 ++-- boot/scene_menu.c | 13 +-- drivers/input/mouse-uclass.c | 2 + include/bootflow.h | 14 +++ include/expo.h | 23 +++- include/mouse.h | 2 + scripts/build-efi | 2 +- test/dm/video.c | 7 +- 10 files changed, 235 insertions(+), 83 deletions(-) -- 2.43.0 base-commit: 4855727dbde154a25671f61bfec9db4caf0604db branch: proh
The USB mouse seems to have an absolute-pointer driver which can be enabled in OVMF. Switch to this for x86. Signed-off-by: Simon Glass <sjg@chromium.org> --- scripts/build-efi | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/scripts/build-efi b/scripts/build-efi index 21c2b656530..032b9f7b1ab 100755 --- a/scripts/build-efi +++ b/scripts/build-efi @@ -114,7 +114,7 @@ class BuildEfi: extra += ['-display', 'default,show-cursor=on'] else: # x86 extra += ['-device', 'qemu-xhci', '-device', 'usb-kbd', - '-device', 'usb-tablet'] + '-device', 'usb-mouse'] extra += ['-serial', 'mon:stdio'] serial_msg = '' if self.args.kvm: -- 2.43.0
Rather than just printing a message (which is suppressed unless -v is used) fail the test if it is not possible to write to the provided directory. Signed-off-by: Simon Glass <sjg@chromium.org> --- test/dm/video.c | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/test/dm/video.c b/test/dm/video.c index e51ff7789c7..616aee3f84d 100644 --- a/test/dm/video.c +++ b/test/dm/video.c @@ -169,9 +169,10 @@ int video_compress_fb(struct unit_test_state *uts, struct udevice *dev, snprintf(filename, sizeof(filename), "%s/frame%d.bmp", state->video_frames_dir, state->video_frame_count++); ret = video_write_bmp(uts, dev, filename); - if (ret) - printf("Failed to write frame to %s: %d\n", filename, - ret); + if (ret) { + ut_reportf("Failed to write frame to %s: %d", + filename, ret); + } } /* provide a useful delay if -V flag is used or LOG_DEBUG is set */ -- 2.43.0
For expos which are designed to use the mouse, the mouse is normally enabled when the expo is created. Setting the display comes later, so move the display-related mouse to expo_set_display() Also get the current mouse position if available. Signed-off-by: Simon Glass <sjg@chromium.org> --- boot/expo.c | 16 +++++++++++----- 1 file changed, 11 insertions(+), 5 deletions(-) diff --git a/boot/expo.c b/boot/expo.c index 1fb6d6e9417..432e81d3552 100644 --- a/boot/expo.c +++ b/boot/expo.c @@ -151,6 +151,17 @@ int expo_set_display(struct expo *exp, struct udevice *dev) exp->display = dev; exp->cons = cons; + if (IS_ENABLED(CONFIG_MOUSE) && exp->mouse_enabled) { + /* + * Tell the mouse driver about the video device for coordinate + * scaling + */ + ret = mouse_set_video(exp->mouse, exp->display); + if (ret) + return log_msg_ret("msv", ret); + mouse_get_pos(exp->mouse, &exp->mouse_pos); + } + return 0; } @@ -189,11 +200,6 @@ int expo_set_mouse_enable(struct expo *exp, bool enable) if (ret) return log_msg_ret("sme", ret); - /* Tell the mouse driver about the video device for coordinate scaling */ - ret = mouse_set_video(exp->mouse, exp->display); - if (ret) - return log_msg_ret("msv", ret); - /* Get mouse pointer image and dimensions */ exp->mouse_ptr = video_image_getptr(riscos_arrow); if (exp->mouse_ptr) { -- 2.43.0
When the size of an object is calculated from its contents, we should not set the SCENEOF_SIZE_VALID flag. This flag prevents the object from resizing if the font is changed, for example. The flag is intended to mean that the size was explicitly set by the controller, so we should generally not set it in the expo implementation. It is also inefficient to search for the object ID when we already have the object. Update scene_set_default_bbox() to just set the size and request that it be synced. Signed-off-by: Simon Glass <sjg@chromium.org> --- boot/scene.c | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/boot/scene.c b/boot/scene.c index dd13b74b4d7..04a5e8a03e2 100644 --- a/boot/scene.c +++ b/boot/scene.c @@ -803,10 +803,12 @@ static int scene_set_default_bbox(struct scene *scn) switch (obj->type) { case SCENEOBJT_IMAGE: case SCENEOBJT_TEXT: - if (!(obj->flags & SCENEOF_SIZE_VALID)) { - scene_obj_set_size(scn, obj->id, obj->dims.x, - obj->dims.y); - } + if (obj->flags & SCENEOF_SIZE_VALID) + break; + obj->req_bbox.x1 = obj->req_bbox.x0 + obj->dims.x; + obj->req_bbox.y1 = obj->req_bbox.y0 + obj->dims.y; + obj->flags |= SCENEOF_SYNC_SIZE; + break; default: break; } -- 2.43.0
The font size of menu items might change, thus requiring the size to be updated. So it is not correct to mark the items as fixed size. Drop this code. Signed-off-by: Simon Glass <sjg@chromium.org> --- boot/scene.c | 9 +++++++-- boot/scene_menu.c | 13 +++++++------ include/expo.h | 14 ++++++++++++++ 3 files changed, 28 insertions(+), 8 deletions(-) diff --git a/boot/scene.c b/boot/scene.c index 04a5e8a03e2..c2d106738f5 100644 --- a/boot/scene.c +++ b/boot/scene.c @@ -316,7 +316,7 @@ int scene_obj_set_size(struct scene *scn, uint id, int w, int h) return 0; } -int scene_obj_set_width(struct scene *scn, uint id, int w) +int scene_obj_set_width_flags(struct scene *scn, uint id, int w, uint flags) { struct scene_obj *obj; @@ -324,11 +324,16 @@ int scene_obj_set_width(struct scene *scn, uint id, int w) if (!obj) return log_msg_ret("find", -ENOENT); obj->req_bbox.x1 = obj->req_bbox.x0 + w; - obj->flags |= SCENEOF_SYNC_WIDTH; + obj->flags |= flags; return 0; } +int scene_obj_set_width(struct scene *scn, uint id, int w) +{ + return scene_obj_set_width_flags(scn, id, w, SCENEOF_SYNC_WIDTH); +} + int scene_obj_set_bbox(struct scene *scn, uint id, int x0, int y0, int x1, int y1) { diff --git a/boot/scene_menu.c b/boot/scene_menu.c index f52d561094b..6aa217ecfab 100644 --- a/boot/scene_menu.c +++ b/boot/scene_menu.c @@ -359,13 +359,14 @@ int scene_menu_arrange(struct scene *scn, struct expo_arrange_info *arr, y += height + theme->menuitem_gap_y; } + /* line up the right size of each set of items */ list_for_each_entry(item, &menu->item_head, sibling) { - scene_obj_set_width(menu->obj.scene, item->label_id, - dims[SCENEBB_label].x); - scene_obj_set_width(menu->obj.scene, item->key_id, - dims[SCENEBB_key].x); - scene_obj_set_width(menu->obj.scene, item->desc_id, - dims[SCENEBB_desc].x); + scene_obj_set_width_flags(menu->obj.scene, item->label_id, + dims[SCENEBB_label].x, 0); + scene_obj_set_width_flags(menu->obj.scene, item->key_id, + dims[SCENEBB_key].x, 0); + scene_obj_set_width_flags(menu->obj.scene, item->desc_id, + dims[SCENEBB_desc].x, 0); } if (sel_id) diff --git a/include/expo.h b/include/expo.h index aa8e41af176..7307c3aef98 100644 --- a/include/expo.h +++ b/include/expo.h @@ -943,6 +943,20 @@ int scene_obj_set_pos(struct scene *scn, uint id, int x, int y); */ int scene_obj_set_size(struct scene *scn, uint id, int w, int h); +/** + * scene_obj_set_width_flags() - Set the width of an object, with flags + * + * The given width is marked as 'requested' and will be applied when the scene + * is next arranged. The object flags are ORed with @flags + * + * @scn: Scene to update + * @id: ID of object to update + * @w: width in pixels + * @flags: Flags to OR with the current flags + * Returns: 0 if OK, -ENOENT if @id is invalid + */ +int scene_obj_set_width_flags(struct scene *scn, uint id, int w, uint flags); + /** * scene_obj_set_width() - Set the width of an object * -- 2.43.0
In some cases it is useful to apply the display-related theme elements without touching the objects. Add an argument to expo_apply_theme() to support this. Signed-off-by: Simon Glass <sjg@chromium.org> --- boot/expo.c | 16 +++++++++------- include/expo.h | 3 ++- 2 files changed, 11 insertions(+), 8 deletions(-) diff --git a/boot/expo.c b/boot/expo.c index 432e81d3552..30f3cbeb9ef 100644 --- a/boot/expo.c +++ b/boot/expo.c @@ -432,7 +432,7 @@ 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) +int expo_apply_theme(struct expo *exp, bool do_objs) { struct expo_theme *theme = &exp->theme; struct scene *scn; @@ -440,12 +440,14 @@ int expo_apply_theme(struct expo *exp) if (exp->display) video_set_white_on_black(exp->display, theme->white_on_black); - list_for_each_entry(scn, &exp->scene_head, sibling) { - int ret; + if (do_objs) { + list_for_each_entry(scn, &exp->scene_head, sibling) { + int ret; - ret = scene_apply_theme(scn, theme); - if (ret) - return log_msg_ret("asn", ret); + ret = scene_apply_theme(scn, theme); + if (ret) + return log_msg_ret("asn", ret); + } } return 0; @@ -468,7 +470,7 @@ int expo_setup_theme(struct expo *exp, ofnode node) &theme->textline_label_margin_x); theme->white_on_black = ofnode_read_bool(node, "white-on-black"); - ret = expo_apply_theme(exp); + ret = expo_apply_theme(exp, true); if (ret) return log_msg_ret("asn", ret); diff --git a/include/expo.h b/include/expo.h index 7307c3aef98..454889d5db9 100644 --- a/include/expo.h +++ b/include/expo.h @@ -1163,9 +1163,10 @@ int expo_setup_theme(struct expo *exp, ofnode node); * The theme to be applied must be set up exp->theme * * @exp: Expo to update + * @do_objs: Apply theme to objects as well (normally this should be true) * Returns: 0 if OK, -ve on error */ -int expo_apply_theme(struct expo *exp); +int expo_apply_theme(struct expo *exp, bool do_objs); /** * expo_build() - Build an expo from an FDT description -- 2.43.0
Add a reminder in the struct comments that a text ID is not a string ID. Signed-off-by: Simon Glass <sjg@chromium.org> --- include/expo.h | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/include/expo.h b/include/expo.h index 454889d5db9..2f32ff0aa72 100644 --- a/include/expo.h +++ b/include/expo.h @@ -444,7 +444,7 @@ struct scene_obj_txt { * - a preview object which shows an image related to the current item * * @obj: Basic object information - * @title_id: ID of the title text, or 0 if none + * @title_id: ID of the title text object (not string ID), or 0 if none * @cur_item_id: ID of the current menu item, or 0 if none * @pointer_id: ID of the object pointing to the current selection * @pointer_xofs: x position of pointer relative to the left side of the menu @@ -504,8 +504,8 @@ struct scene_menitem { * A textline has a prompt and a line of editable text * * @obj: Basic object information - * @label_id: ID of the label text, or 0 if none - * @edit_id: ID of the editable text + * @label_id: ID of the label text object (not string ID), or 0 if none + * @edit_id: ID of the editable text object (not string ID) * @max_chars: Maximum number of characters allowed * @buf: Text buffer containing current text * @pos: Cursor position -- 2.43.0
When starting the expo, put the mouse in the middle of the display so it is more visible to the user. Signed-off-by: Simon Glass <sjg@chromium.org> --- drivers/input/mouse-uclass.c | 2 ++ include/mouse.h | 2 ++ 2 files changed, 4 insertions(+) diff --git a/drivers/input/mouse-uclass.c b/drivers/input/mouse-uclass.c index 16a391532ae..dea8babf5fe 100644 --- a/drivers/input/mouse-uclass.c +++ b/drivers/input/mouse-uclass.c @@ -97,6 +97,8 @@ int mouse_set_video(struct udevice *dev, struct udevice *video_dev) if (video_dev) { uc_priv->video_width = video_get_xsize(video_dev); uc_priv->video_height = video_get_ysize(video_dev); + uc_priv->last_pos.x = uc_priv->video_width / 2; + uc_priv->last_pos.y = uc_priv->video_height / 2; } else { uc_priv->video_width = 0; uc_priv->video_height = 0; diff --git a/include/mouse.h b/include/mouse.h index 1a3a93801e2..92609cfd0e0 100644 --- a/include/mouse.h +++ b/include/mouse.h @@ -168,6 +168,8 @@ int mouse_set_ptr_visible(struct udevice *dev, bool visible); * Sets up the video device in the mouse uclass private data so mouse drivers * can scale coordinates to match the display resolution. * + * This also places the mouse in the middle of the display + * * @dev: Mouse device * @video_dev: Video device * Returns: 0 if OK, -ve on error -- 2.43.0
The existing menu is functional but basic. It would be useful to be able to create the objects but apply a different layout or style for them. The bootflow_menu_new() function is quite long in any case. Split out the parts which adjust the position, alignment, etc. of the objects into a separate function. We can (later) call this from elsewhere to apply the basic styling. Signed-off-by: Simon Glass <sjg@chromium.org> --- boot/bootflow_menu.c | 75 +++++++++++++++++++++++++++----------------- include/bootflow.h | 12 +++++++ 2 files changed, 58 insertions(+), 29 deletions(-) diff --git a/boot/bootflow_menu.c b/boot/bootflow_menu.c index 1f24215f392..b66ab2d3b73 100644 --- a/boot/bootflow_menu.c +++ b/boot/bootflow_menu.c @@ -32,13 +32,54 @@ struct menu_priv { struct udevice *last_bootdev; }; +int bootflow_menu_set_props(struct expo *exp, struct scene *scn, bool has_logo) +{ + int ret = 0; + bool use_font; + + ret |= scene_obj_set_bbox(scn, OBJ_BOX, 30, 90, 1366 - 30, 720); + ret |= scene_obj_set_pos(scn, OBJ_MENU, MARGIN_LEFT, 100); + ret |= scene_obj_set_bbox(scn, OBJ_MENU_TITLE, 0, 32, + 1366, 60); + ret |= scene_obj_set_halign(scn, OBJ_MENU_TITLE, SCENEOA_CENTRE); + + if (has_logo) + ret |= scene_obj_set_pos(scn, OBJ_U_BOOT_LOGO, 1165, 100); + + ret |= scene_obj_set_bbox(scn, OBJ_PROMPT1A, 0, 590, + 1366, 590 + 40); + ret |= scene_obj_set_bbox(scn, OBJ_PROMPT1B, 0, 620, + 1366, 620 + 40); + ret |= scene_obj_set_bbox(scn, OBJ_PROMPT2, 100, 650, + 1366 - 100, 700); + ret |= scene_obj_set_bbox(scn, OBJ_AUTOBOOT, 0, 720, + 1366, 750); + ret |= scene_obj_set_halign(scn, OBJ_PROMPT1A, SCENEOA_CENTRE); + ret |= scene_obj_set_halign(scn, OBJ_PROMPT1B, SCENEOA_CENTRE); + ret |= scene_obj_set_halign(scn, OBJ_PROMPT2, SCENEOA_CENTRE); + ret |= scene_obj_set_valign(scn, OBJ_PROMPT2, SCENEOA_CENTRE); + ret |= scene_obj_set_halign(scn, OBJ_AUTOBOOT, SCENEOA_CENTRE); + ret |= scene_menu_set_pointer(scn, OBJ_MENU, OBJ_POINTER); + + if (ret) + return log_msg_ret("msp", ret); + + use_font = IS_ENABLED(CONFIG_CONSOLE_TRUETYPE); + scene_obj_set_hide(scn, OBJ_PROMPT1A, use_font); + scene_obj_set_hide(scn, OBJ_PROMPT1B, !use_font); + scene_obj_set_hide(scn, OBJ_AUTOBOOT, use_font); + + exp->show_highlight = true; + + return 0; +} + int bootflow_menu_new(struct expo **expp) { struct scene_obj_menu *menu; struct menu_priv *priv; struct scene *scn; struct expo *exp; - bool use_font; void *logo; int ret; @@ -60,21 +101,14 @@ int bootflow_menu_new(struct expo **expp) ret = scene_box(scn, "box", OBJ_BOX, 2, false, NULL); if (ret < 0) return log_msg_ret("bmb", ret); - ret |= scene_obj_set_bbox(scn, OBJ_BOX, 30, 90, 1366 - 30, 720); ret = scene_menu(scn, "main", OBJ_MENU, &menu); - ret |= scene_obj_set_pos(scn, OBJ_MENU, MARGIN_LEFT, 100); ret |= scene_txt_str(scn, "title", OBJ_MENU_TITLE, STR_MENU_TITLE, "U-Boot - Boot Menu", NULL); - ret |= scene_obj_set_bbox(scn, OBJ_MENU_TITLE, 0, 32, - 1366, 60); - ret |= scene_obj_set_halign(scn, OBJ_MENU_TITLE, SCENEOA_CENTRE); logo = video_get_u_boot_logo(NULL); - if (logo) { + if (logo) ret |= scene_img(scn, "ulogo", OBJ_U_BOOT_LOGO, logo, NULL); - ret |= scene_obj_set_pos(scn, OBJ_U_BOOT_LOGO, 1165, 100); - } ret |= scene_txt_str(scn, "prompt1a", OBJ_PROMPT1A, STR_PROMPT1A, "Use the \x18 and \x19 keys to select which entry is highlighted.", @@ -89,32 +123,15 @@ int bootflow_menu_new(struct expo **expp) ret |= scene_txt_str(scn, "autoboot", OBJ_AUTOBOOT, STR_AUTOBOOT, "The highlighted entry will be executed automatically in %ds.", NULL); - ret |= scene_obj_set_bbox(scn, OBJ_PROMPT1A, 0, 590, - 1366, 590 + 40); - ret |= scene_obj_set_bbox(scn, OBJ_PROMPT1B, 0, 620, - 1366, 620 + 40); - ret |= scene_obj_set_bbox(scn, OBJ_PROMPT2, 100, 650, - 1366 - 100, 700); - ret |= scene_obj_set_bbox(scn, OBJ_AUTOBOOT, 0, 720, - 1366, 750); - ret |= scene_obj_set_halign(scn, OBJ_PROMPT1A, SCENEOA_CENTRE); - ret |= scene_obj_set_halign(scn, OBJ_PROMPT1B, SCENEOA_CENTRE); - ret |= scene_obj_set_halign(scn, OBJ_PROMPT2, SCENEOA_CENTRE); - ret |= scene_obj_set_valign(scn, OBJ_PROMPT2, SCENEOA_CENTRE); - ret |= scene_obj_set_halign(scn, OBJ_AUTOBOOT, SCENEOA_CENTRE); - - use_font = IS_ENABLED(CONFIG_CONSOLE_TRUETYPE); - scene_obj_set_hide(scn, OBJ_PROMPT1A, use_font); - scene_obj_set_hide(scn, OBJ_PROMPT1B, !use_font); - scene_obj_set_hide(scn, OBJ_AUTOBOOT, use_font); ret |= scene_txt_str(scn, "cur_item", OBJ_POINTER, STR_POINTER, ">", NULL); - ret |= scene_menu_set_pointer(scn, OBJ_MENU, OBJ_POINTER); if (ret < 0) return log_msg_ret("new", -EINVAL); - exp->show_highlight = true; + ret = bootflow_menu_set_props(exp, scn, logo); + if (ret < 0) + return log_msg_ret("nep", -EINVAL); *expp = exp; diff --git a/include/bootflow.h b/include/bootflow.h index 17ecc80c2eb..9ee11b33dbf 100644 --- a/include/bootflow.h +++ b/include/bootflow.h @@ -560,6 +560,18 @@ int bootflow_menu_add(struct expo *exp, struct bootflow *bflow, int seq, */ int bootflow_menu_apply_theme(struct expo *exp, ofnode node); +/** + * bootflow_menu_set_props() - Apply properties for the menu + * + * This sets up the positions of the objects in the basic menu. It also + * enables show_highlight + * + * @exp: Expo to update + * @scn: Scene to update + * @has_logo: true if a logo should be visible + */ +int bootflow_menu_set_props(struct expo *exp, struct scene *scn, bool has_logo); + #define BOOTFLOWCL_EMPTY ((void *)1) /** -- 2.43.0
These strings are part of the basic menu and may be different for other menus. Rather than setting them up on creation, add them as part of setting the properties of the objects. Provide a way to set the title as well. Signed-off-by: Simon Glass <sjg@chromium.org> --- boot/bootflow_menu.c | 40 ++++++++++++++++++++++++++++++---------- include/bootflow.h | 4 +++- 2 files changed, 33 insertions(+), 11 deletions(-) diff --git a/boot/bootflow_menu.c b/boot/bootflow_menu.c index b66ab2d3b73..3df15959c0e 100644 --- a/boot/bootflow_menu.c +++ b/boot/bootflow_menu.c @@ -32,8 +32,10 @@ struct menu_priv { struct udevice *last_bootdev; }; -int bootflow_menu_set_props(struct expo *exp, struct scene *scn, bool has_logo) +int bootflow_menu_set_props(struct expo *exp, struct scene *scn, bool has_logo, + const char *title) { + struct abuf *buf; int ret = 0; bool use_font; @@ -69,6 +71,28 @@ int bootflow_menu_set_props(struct expo *exp, struct scene *scn, bool has_logo) scene_obj_set_hide(scn, OBJ_PROMPT1B, !use_font); scene_obj_set_hide(scn, OBJ_AUTOBOOT, use_font); + /* Set the title and prompt texts */ + ret = expo_edit_str(exp, STR_MENU_TITLE, NULL, &buf); + if (ret) + return log_msg_ret("mss", ret); + abuf_printf(buf, "%s", title); + + ret = expo_edit_str(exp, STR_PROMPT1A, NULL, &buf); + if (!ret) + abuf_printf(buf, "Use the \x18 and \x19 keys to select which " + "entry is highlighted."); + + ret = expo_edit_str(exp, STR_PROMPT1B, NULL, &buf); + if (!ret) + abuf_printf(buf, "Use the UP and DOWN keys to select which " + "entry is highlighted."); + + ret = expo_edit_str(exp, STR_PROMPT2, NULL, &buf); + if (!ret) + abuf_printf(buf, "Press enter to boot the selected OS, 'e' to " + "edit the commands before booting or 'c' for a " + "command-line. ESC to return to previous menu"); + exp->show_highlight = true; return 0; @@ -104,22 +128,18 @@ int bootflow_menu_new(struct expo **expp) ret = scene_menu(scn, "main", OBJ_MENU, &menu); ret |= scene_txt_str(scn, "title", OBJ_MENU_TITLE, STR_MENU_TITLE, - "U-Boot - Boot Menu", NULL); + "", NULL); logo = video_get_u_boot_logo(NULL); if (logo) ret |= scene_img(scn, "ulogo", OBJ_U_BOOT_LOGO, logo, NULL); ret |= scene_txt_str(scn, "prompt1a", OBJ_PROMPT1A, STR_PROMPT1A, - "Use the \x18 and \x19 keys to select which entry is highlighted.", - NULL); + "", NULL); ret |= scene_txt_str(scn, "prompt1b", OBJ_PROMPT1B, STR_PROMPT1B, - "Use the UP and DOWN keys to select which entry is highlighted.", - NULL); + "", NULL); ret |= scene_txt_str(scn, "prompt2", OBJ_PROMPT2, STR_PROMPT2, - "Press enter to boot the selected OS, 'e' to edit the commands " - "before booting or 'c' for a command-line. ESC to return to " - "previous menu", NULL); + "", NULL); ret |= scene_txt_str(scn, "autoboot", OBJ_AUTOBOOT, STR_AUTOBOOT, "The highlighted entry will be executed automatically in %ds.", NULL); @@ -129,7 +149,7 @@ int bootflow_menu_new(struct expo **expp) if (ret < 0) return log_msg_ret("new", -EINVAL); - ret = bootflow_menu_set_props(exp, scn, logo); + ret = bootflow_menu_set_props(exp, scn, logo, "U-Boot - Boot Menu"); if (ret < 0) return log_msg_ret("nep", -EINVAL); diff --git a/include/bootflow.h b/include/bootflow.h index 9ee11b33dbf..3a5c7bce847 100644 --- a/include/bootflow.h +++ b/include/bootflow.h @@ -569,8 +569,10 @@ int bootflow_menu_apply_theme(struct expo *exp, ofnode node); * @exp: Expo to update * @scn: Scene to update * @has_logo: true if a logo should be visible + * @title: Title to use for the boot menu */ -int bootflow_menu_set_props(struct expo *exp, struct scene *scn, bool has_logo); +int bootflow_menu_set_props(struct expo *exp, struct scene *scn, bool has_logo, + const char *title); #define BOOTFLOWCL_EMPTY ((void *)1) -- 2.43.0
The basic menu uses a pointer to show the current menu item. Show this and hide some other objects which are not wanted. Mark the box as unfilled, since this is how it is used with the basic menu. Explicitly disable the mouse pointer. Signed-off-by: Simon Glass <sjg@chromium.org> --- boot/bootflow_menu.c | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/boot/bootflow_menu.c b/boot/bootflow_menu.c index 3df15959c0e..686769e57b5 100644 --- a/boot/bootflow_menu.c +++ b/boot/bootflow_menu.c @@ -40,6 +40,7 @@ int bootflow_menu_set_props(struct expo *exp, struct scene *scn, bool has_logo, bool use_font; ret |= scene_obj_set_bbox(scn, OBJ_BOX, 30, 90, 1366 - 30, 720); + scene_box_set_fill(scn, OBJ_BOX, false); ret |= scene_obj_set_pos(scn, OBJ_MENU, MARGIN_LEFT, 100); ret |= scene_obj_set_bbox(scn, OBJ_MENU_TITLE, 0, 32, 1366, 60); @@ -93,6 +94,17 @@ int bootflow_menu_set_props(struct expo *exp, struct scene *scn, bool has_logo, "edit the commands before booting or 'c' for a " "command-line. ESC to return to previous menu"); + /* hide a few things we don't use */ + scene_obj_set_hide(scn, OBJ_OTHER_LOGO, true); + scene_obj_set_hide(scn, OBJ_SETTINGS, true); + scene_obj_set_hide(scn, OBJ_HELP, true); + + /* select the menu and hide the pointer */ + scene_set_highlight_id(scn, OBJ_MENU); + scene_obj_set_hide(scn, OBJ_POINTER, false); + + expo_set_mouse_enable(exp, false); + exp->show_highlight = true; return 0; -- 2.43.0
These can be used if desired, so add them to the menu. Since they are not part of the simple menu, hide them in that case, via a new function which sets up the properties of items. Signed-off-by: Simon Glass <sjg@chromium.org> --- boot/bootflow_menu.c | 26 +++++++++++++++++++++++++- 1 file changed, 25 insertions(+), 1 deletion(-) diff --git a/boot/bootflow_menu.c b/boot/bootflow_menu.c index 686769e57b5..057ebee01a1 100644 --- a/boot/bootflow_menu.c +++ b/boot/bootflow_menu.c @@ -32,6 +32,22 @@ struct menu_priv { struct udevice *last_bootdev; }; +static int bootflow_menu_set_item_props(struct scene *scn, + int i, const struct bootflow *bflow) +{ + int ret; + + scene_obj_set_hide(scn, ITEM_PREVIEW + i, true); + ret = scene_obj_set_hide(scn, ITEM_BOX + i, true); + ret |= scene_obj_set_hide(scn, ITEM_VERSION_NAME + i, true); + scene_obj_set_hide(scn, ITEM_VERIFIED + i, true); + ret |= scene_obj_set_hide(scn, ITEM_KEY + i, false); + if (ret) + return log_msg_ret("msp", ret); + + return 0; +} + int bootflow_menu_set_props(struct expo *exp, struct scene *scn, bool has_logo, const char *title) { @@ -216,6 +232,10 @@ int bootflow_menu_add(struct expo *exp, struct bootflow *bflow, int seq, bflow->name, NULL); ret |= scene_txt_str(scn, "key", ITEM_KEY + seq, STR_KEY + seq, key, NULL); + ret |= scene_box(scn, "item-box", ITEM_BOX + seq, 1, false, NULL); + ret |= scene_txt_str(scn, "version", ITEM_VERSION_NAME + seq, + STR_VERSION_NAME + seq, "", NULL); + preview_id = 0; if (bflow->logo) { preview_id = ITEM_PREVIEW + seq; @@ -227,9 +247,13 @@ int bootflow_menu_add(struct expo *exp, struct bootflow *bflow, int seq, ITEM_DESC + seq, preview_id, add_gap ? SCENEMIF_GAP_BEFORE : 0, NULL); - if (ret < 0) return log_msg_ret("itm", -EINVAL); + + ret = bootflow_menu_set_item_props(scn, seq, bflow); + if (ret) + return log_msg_ret("itp", -EINVAL); + priv->num_bootflows++; *scnp = scn; -- 2.43.0
Use the bootflow_menu_set_item_props() to set the text in these items, since it can be presented differently depending on the layout. Signed-off-by: Simon Glass <sjg@chromium.org> --- boot/bootflow_menu.c | 27 ++++++++++++++------------- 1 file changed, 14 insertions(+), 13 deletions(-) diff --git a/boot/bootflow_menu.c b/boot/bootflow_menu.c index 057ebee01a1..5f559e2220c 100644 --- a/boot/bootflow_menu.c +++ b/boot/bootflow_menu.c @@ -35,6 +35,8 @@ struct menu_priv { static int bootflow_menu_set_item_props(struct scene *scn, int i, const struct bootflow *bflow) { + struct expo *exp = scn->expo; + struct abuf *buf; int ret; scene_obj_set_hide(scn, ITEM_PREVIEW + i, true); @@ -45,6 +47,15 @@ static int bootflow_menu_set_item_props(struct scene *scn, if (ret) return log_msg_ret("msp", ret); + ret = expo_edit_str(exp, STR_DESC + i, NULL, &buf); + if (ret) + return log_msg_ret("msr", ret); + abuf_printf(buf, "%s", bflow->os_name ? bflow->os_name : bflow->name); + + ret = expo_edit_str(exp, STR_LABEL + i, NULL, &buf); + if (!ret) + abuf_printf(buf, "%s", bootflow_guess_label(bflow)); + return 0; } @@ -190,9 +201,8 @@ int bootflow_menu_add(struct expo *exp, struct bootflow *bflow, int seq, struct scene **scnp) { struct menu_priv *priv = exp->priv; - char str[2], *label, *key; + char str[2], *key; struct scene *scn; - const char *name; uint preview_id; uint scene_id; bool add_gap; @@ -210,14 +220,6 @@ int bootflow_menu_add(struct expo *exp, struct bootflow *bflow, int seq, if (!key) return log_msg_ret("key", -ENOMEM); - name = bootflow_guess_label(bflow); - label = strdup(name); - - if (!label) { - free(key); - return log_msg_ret("nam", -ENOMEM); - } - add_gap = priv->last_bootdev != bflow->dev; /* disable this gap for now, since it looks a little ugly */ @@ -226,10 +228,9 @@ int bootflow_menu_add(struct expo *exp, struct bootflow *bflow, int seq, ret = expo_str(exp, "prompt", STR_POINTER, ">"); ret |= scene_txt_str(scn, "label", ITEM_LABEL + seq, - STR_LABEL + seq, label, NULL); + STR_LABEL + seq, "", NULL); ret |= scene_txt_str(scn, "desc", ITEM_DESC + seq, STR_DESC + seq, - bflow->os_name ? bflow->os_name : - bflow->name, NULL); + "", NULL); ret |= scene_txt_str(scn, "key", ITEM_KEY + seq, STR_KEY + seq, key, NULL); ret |= scene_box(scn, "item-box", ITEM_BOX + seq, 1, false, NULL); -- 2.43.0
Manual mode is not enabled by default, but we should explicitly clear it with the basic menu, since a different style may have set the flag. Set manual mode to false in bootflow_menu_set_props() Signed-off-by: Simon Glass <sjg@chromium.org> --- boot/bootflow_menu.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/boot/bootflow_menu.c b/boot/bootflow_menu.c index 5f559e2220c..2f60ccd59ce 100644 --- a/boot/bootflow_menu.c +++ b/boot/bootflow_menu.c @@ -130,6 +130,9 @@ int bootflow_menu_set_props(struct expo *exp, struct scene *scn, bool has_logo, scene_set_highlight_id(scn, OBJ_MENU); scene_obj_set_hide(scn, OBJ_POINTER, false); + /* tell the menu to lay out its objects */ + scene_obj_set_manual(scn, OBJ_MENU, false); + expo_set_mouse_enable(exp, false); exp->show_highlight = true; -- 2.43.0
Set up the theme colour and apply it in bootflow_menu_set_props() so that the simple menu always looks the same when selected. Signed-off-by: Simon Glass <sjg@chromium.org> --- boot/bootflow_menu.c | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/boot/bootflow_menu.c b/boot/bootflow_menu.c index 2f60ccd59ce..d731a8a8c8c 100644 --- a/boot/bootflow_menu.c +++ b/boot/bootflow_menu.c @@ -62,6 +62,7 @@ static int bootflow_menu_set_item_props(struct scene *scn, int bootflow_menu_set_props(struct expo *exp, struct scene *scn, bool has_logo, const char *title) { + struct expo_theme *theme = &exp->theme; struct abuf *buf; int ret = 0; bool use_font; @@ -133,6 +134,13 @@ int bootflow_menu_set_props(struct expo *exp, struct scene *scn, bool has_logo, /* tell the menu to lay out its objects */ scene_obj_set_manual(scn, OBJ_MENU, false); + scene_obj_set_hide(scn, OBJ_POINTER, false); + + theme->white_on_black = true; + ret = expo_apply_theme(exp, true); + if (ret) + return log_msg_ret("mat", ret); + expo_set_mouse_enable(exp, false); exp->show_highlight = true; -- 2.43.0
Initially there may be no items. But when switching to the basic menu there may well be items already present. Set up their properties so that they follow the basic-menu theme. Signed-off-by: Simon Glass <sjg@chromium.org> --- boot/bootflow_menu.c | 19 ++++++++++++++++++- 1 file changed, 18 insertions(+), 1 deletion(-) diff --git a/boot/bootflow_menu.c b/boot/bootflow_menu.c index d731a8a8c8c..161c5a42401 100644 --- a/boot/bootflow_menu.c +++ b/boot/bootflow_menu.c @@ -63,8 +63,10 @@ int bootflow_menu_set_props(struct expo *exp, struct scene *scn, bool has_logo, const char *title) { struct expo_theme *theme = &exp->theme; + struct menu_priv *priv = exp->priv; + struct bootstd_priv *std; struct abuf *buf; - int ret = 0; + int i, ret = 0; bool use_font; ret |= scene_obj_set_bbox(scn, OBJ_BOX, 30, 90, 1366 - 30, 720); @@ -145,6 +147,21 @@ int bootflow_menu_set_props(struct expo *exp, struct scene *scn, bool has_logo, exp->show_highlight = true; + ret = bootstd_get_priv(&std); + if (ret) + return ret; + + for (i = 0; i < priv->num_bootflows; i++) { + const struct bootflow *bflow; + + bflow = alist_get(&std->bootflows, i, struct bootflow); + if (!bflow) + return log_msg_ret("bmb", -ENOENT); + ret = bootflow_menu_set_item_props(scn, i, bflow); + if (ret) + return log_msg_ret("mst", ret); + } + return 0; } -- 2.43.0
participants (1)
-
Simon Glass