In some cases dynamic text is needed, e.g. for a menu countdown. Add a function which handles this, allowing the caller to take control of the text that is shown on each render.
Signed-off-by: Simon Glass <s...@chromium.org> --- boot/expo.c | 21 +++++++++++++++++++++ include/expo.h | 17 +++++++++++++++++ test/boot/expo.c | 11 +++++++++++ 3 files changed, 49 insertions(+) diff --git a/boot/expo.c b/boot/expo.c index ee635116abc..a0be1404f1c 100644 --- a/boot/expo.c +++ b/boot/expo.c @@ -104,6 +104,27 @@ const char *expo_get_str(struct expo *exp, uint id) 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; diff --git a/include/expo.h b/include/expo.h index 32d69f269a7..7c6ab4bf630 100644 --- a/include/expo.h +++ b/include/expo.h @@ -469,6 +469,23 @@ int expo_str(struct expo *exp, const char *name, uint id, const char *str); */ const char *expo_get_str(struct expo *exp, uint id); +/** + * expo_edit_str() - Make a string writeable + * + * This allows a string to be updated under the control of the caller. The + * buffer must remain valid while the expo is active. + * + * @exp: Expo to use + * @id: String ID to look up + * @orig: If non-NULL, returns the original buffer, which can be used by the + * caller. It is no-longer used by expo so must be uninited by the caller. + * It contains a snapshot of the string contents + * @copyp: Returns a pointer to the new, writeable buffer + * Return: 0 if OK, -ENOENT if the id was not found, -ENOMEM if out of memory + */ +int expo_edit_str(struct expo *exp, uint id, struct abuf *orig, + struct abuf **copyp); + /** * expo_set_display() - set the display to use for a expo * diff --git a/test/boot/expo.c b/test/boot/expo.c index 96c5943f394..a50e9f721de 100644 --- a/test/boot/expo.c +++ b/test/boot/expo.c @@ -707,6 +707,7 @@ static int expo_test_build(struct unit_test_state *uts) struct scene_obj_menu *menu; struct scene_menitem *item; struct scene_obj_txt *txt; + struct abuf orig, *copy; struct scene_obj *obj; struct scene *scn; struct expo *exp; @@ -774,6 +775,16 @@ static int expo_test_build(struct unit_test_state *uts) count = list_count_nodes(&menu->item_head); ut_asserteq(3, count); + /* try editing some text */ + ut_assertok(expo_edit_str(exp, txt->gen.str_id, &orig, ©)); + ut_asserteq_str("2 GHz", orig.data); + ut_asserteq_str("2 GHz", copy->data); + + /* change it and check that things look right */ + abuf_printf(copy, "atlantic %d", 123); + ut_asserteq_str("2 GHz", orig.data); + ut_asserteq_str("atlantic 123", copy->data); + expo_destroy(exp); return 0; -- 2.43.0