bootstd: Support setting a theme for the menu
authorSimon Glass <sjg@chromium.org>
Fri, 6 Jan 2023 14:52:42 +0000 (08:52 -0600)
committerTom Rini <trini@konsulko.com>
Mon, 16 Jan 2023 23:26:51 +0000 (18:26 -0500)
Allow a theme to be set. For now this is very simple, just a default font
size to use for all elements.

Signed-off-by: Simon Glass <sjg@chromium.org>
boot/bootflow_menu.c
boot/bootstd-uclass.c
include/bootflow.h
include/bootstd.h
test/boot/bootflow.c

index 1105783afebe5f3506f180a6b5ef56fa3f9c048e..7f06dac0af774bb7ba64218eb031272cf2f278a5 100644 (file)
@@ -129,6 +129,43 @@ int bootflow_menu_new(struct expo **expp)
        return 0;
 }
 
+int bootflow_menu_apply_theme(struct expo *exp, ofnode node)
+{
+       struct menu_priv *priv = exp->priv;
+       struct scene *scn;
+       u32 font_size;
+       int ret;
+
+       log_debug("Applying theme %s\n", ofnode_get_name(node));
+       scn = expo_lookup_scene_id(exp, MAIN);
+       if (!scn)
+               return log_msg_ret("scn", -ENOENT);
+
+       /* Avoid error-checking optional items */
+       if (!ofnode_read_u32(node, "font-size", &font_size)) {
+               int i;
+
+               log_debug("font size %d\n", font_size);
+               scene_txt_set_font(scn, OBJ_PROMPT, NULL, font_size);
+               scene_txt_set_font(scn, OBJ_POINTER, NULL, font_size);
+               for (i = 0; i < priv->num_bootflows; i++) {
+                       ret = scene_txt_set_font(scn, ITEM_DESC + i, NULL,
+                                                font_size);
+                       if (ret)
+                               return log_msg_ret("des", ret);
+                       scene_txt_set_font(scn, ITEM_KEY + i, NULL, font_size);
+                       scene_txt_set_font(scn, ITEM_LABEL + i, NULL,
+                                          font_size);
+               }
+       }
+
+       ret = scene_arrange(scn);
+       if (ret)
+               return log_msg_ret("arr", ret);
+
+       return 0;
+}
+
 int bootflow_menu_run(struct bootstd_priv *std, bool text_mode,
                      struct bootflow **bflowp)
 {
@@ -149,6 +186,12 @@ int bootflow_menu_run(struct bootstd_priv *std, bool text_mode,
        if (ret)
                return log_msg_ret("exp", ret);
 
+       if (ofnode_valid(std->theme)) {
+               ret = bootflow_menu_apply_theme(exp, std->theme);
+               if (ret)
+                       return log_msg_ret("thm", ret);
+       }
+
        /* For now we only support a video console */
        ret = uclass_first_device_err(UCLASS_VIDEO, &dev);
        if (ret)
index 565c22a36e78a5cc986df44efc0de297af6eb412..7887acdc11b2eb82edf47b9db94af65440739384 100644 (file)
@@ -33,6 +33,8 @@ static int bootstd_of_to_plat(struct udevice *dev)
                                           &priv->prefixes);
                dev_read_string_list(dev, "bootdev-order",
                                     &priv->bootdev_order);
+
+               priv->theme = ofnode_find_subnode(dev_ofnode(dev), "theme");
        }
 
        return 0;
index e7a09568f1bf4d494eb5ad6571700a90aafb8d2b..c201246c6ded2077b634cd3a0d404296c7b5f083 100644 (file)
@@ -7,6 +7,7 @@
 #ifndef __bootflow_h
 #define __bootflow_h
 
+#include <dm/ofnode_decl.h>
 #include <linux/list.h>
 
 struct bootstd_priv;
@@ -347,6 +348,15 @@ int bootflow_iter_uses_system(const struct bootflow_iter *iter);
  */
 int bootflow_menu_new(struct expo **expp);
 
+/**
+ * bootflow_menu_apply_theme() - Apply a theme to a bootmenu
+ *
+ * @exp: Expo to update
+ * @node: Node containing the theme information
+ * Returns 0 on success, -ve on error
+ */
+int bootflow_menu_apply_theme(struct expo *exp, ofnode node);
+
 /**
  * bootflow_menu_run() - Create and run a menu of available bootflows
  *
index 01be249d16e9cd69a5a09d6463b8049fa5f3ba34..4fa0d531001a843e1da8b88ca400e98f68df41ee 100644 (file)
@@ -9,6 +9,8 @@
 #ifndef __bootstd_h
 #define __bootstd_h
 
+#include <dm/ofnode_decl.h>
+
 struct udevice;
 
 /**
@@ -27,6 +29,7 @@ struct udevice;
  * @bootmeth_count: Number of bootmeth devices in @bootmeth_order
  * @bootmeth_order: List of bootmeth devices to use, in order, NULL-terminated
  * @vbe_bootmeth: Currently selected VBE bootmeth, NULL if none
+ * @theme: Node containing the theme information
  */
 struct bootstd_priv {
        const char **prefixes;
@@ -37,6 +40,7 @@ struct bootstd_priv {
        int bootmeth_count;
        struct udevice **bootmeth_order;
        struct udevice *vbe_bootmeth;
+       ofnode theme;
 };
 
 /**
index abafa44b2edf35d8b19b8ade1ac41cb09b7334b1..5b76cd3ab14cfd3d86b158c747f60f9f70460e8f 100644 (file)
@@ -13,6 +13,7 @@
 #include <bootstd.h>
 #include <cli.h>
 #include <dm.h>
+#include <expo.h>
 #ifdef CONFIG_SANDBOX
 #include <asm/test.h>
 #endif
@@ -21,6 +22,8 @@
 #include <test/suites.h>
 #include <test/ut.h>
 #include "bootstd_common.h"
+#include "../../boot/bootflow_internal.h"
+#include "../../boot/scene_internal.h"
 
 DECLARE_GLOBAL_DATA_PTR;
 
@@ -469,14 +472,18 @@ static int bootflow_cmd_boot(struct unit_test_state *uts)
 }
 BOOTSTD_TEST(bootflow_cmd_boot, UT_TESTF_DM | UT_TESTF_SCAN_FDT);
 
-/* Check 'bootflow menu' to select a bootflow */
-static int bootflow_cmd_menu(struct unit_test_state *uts)
+/**
+ * prep_mmc4_bootdev() - Set up the mmc4 bootdev so we can access a fake Armbian
+ *
+ * @uts: Unit test state
+ * Returns 0 on success, -ve on failure
+ */
+static int prep_mmc4_bootdev(struct unit_test_state *uts)
 {
        static const char *order[] = {"mmc2", "mmc1", "mmc4", NULL};
        struct udevice *dev, *bootstd;
        struct bootstd_priv *std;
        const char **old_order;
-       char prev[3];
        ofnode node;
 
        /* Enable the mmc4 node since we need a second bootflow */
@@ -500,6 +507,16 @@ static int bootflow_cmd_menu(struct unit_test_state *uts)
        /* Restore the order used by the device tree */
        std->bootdev_order = old_order;
 
+       return 0;
+}
+
+/* Check 'bootflow menu' to select a bootflow */
+static int bootflow_cmd_menu(struct unit_test_state *uts)
+{
+       char prev[3];
+
+       ut_assertok(prep_mmc4_bootdev(uts));
+
        /* Add keypresses to move to and select the second one in the list */
        prev[0] = CTL_CH('n');
        prev[1] = '\r';
@@ -513,3 +530,63 @@ static int bootflow_cmd_menu(struct unit_test_state *uts)
        return 0;
 }
 BOOTSTD_TEST(bootflow_cmd_menu, UT_TESTF_DM | UT_TESTF_SCAN_FDT);
+
+/**
+ * check_font() - Check that the font size for an item matches expectations
+ *
+ * @uts: Unit test state
+ * @scn: Scene containing the text object
+ * @id: ID of the text object
+ * Returns 0 on success, -ve on failure
+ */
+static int check_font(struct unit_test_state *uts, struct scene *scn, uint id,
+                     int font_size)
+{
+       struct scene_obj_txt *txt;
+
+       txt = scene_obj_find(scn, id, SCENEOBJT_TEXT);
+       ut_assertnonnull(txt);
+
+       ut_asserteq(font_size, txt->font_size);
+
+       return 0;
+}
+
+/* Check themes work with a bootflow menu */
+static int bootflow_menu_theme(struct unit_test_state *uts)
+{
+       const int font_size = 30;
+       struct scene *scn;
+       struct expo *exp;
+       ofnode node;
+       int i;
+
+       ut_assertok(prep_mmc4_bootdev(uts));
+
+       ut_assertok(bootflow_menu_new(&exp));
+       node = ofnode_path("/bootstd/theme");
+       ut_assert(ofnode_valid(node));
+       ut_assertok(bootflow_menu_apply_theme(exp, node));
+
+       scn = expo_lookup_scene_id(exp, MAIN);
+       ut_assertnonnull(scn);
+
+       /*
+        * Check that the txt objects have the correct font size from the
+        * device tree node: bootstd/theme
+        *
+        * Check both menu items, since there are two bootflows
+        */
+       ut_assertok(check_font(uts, scn, OBJ_PROMPT, font_size));
+       ut_assertok(check_font(uts, scn, OBJ_POINTER, font_size));
+       for (i = 0; i < 2; i++) {
+               ut_assertok(check_font(uts, scn, ITEM_DESC + i, font_size));
+               ut_assertok(check_font(uts, scn, ITEM_KEY + i, font_size));
+               ut_assertok(check_font(uts, scn, ITEM_LABEL + i, font_size));
+       }
+
+       expo_destroy(exp);
+
+       return 0;
+}
+BOOTSTD_TEST(bootflow_menu_theme, UT_TESTF_DM | UT_TESTF_SCAN_FDT);