expo: Allow strings to be editable

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 <sjg@chromium.org>
This commit is contained in:
Simon Glass 2025-05-02 08:46:40 -06:00
parent 589e4ccacf
commit 87750b0276
3 changed files with 49 additions and 0 deletions

View File

@ -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;

View File

@ -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
*

View File

@ -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, &copy));
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;