From bf2abf90501858a97bf1e05024d963800312a5c4 Mon Sep 17 00:00:00 2001 From: Aleksey Kuleshov Date: Thu, 18 Aug 2016 17:05:03 +0300 Subject: rework menu so that it can support multiline titles Signed-off-by: Aleksey Kuleshov Signed-off-by: Sascha Hauer --- common/boot.c | 8 ++++-- common/menu.c | 81 ++++++++++++++++++++++++++++++++++++++++++++++++------- common/menutree.c | 9 +++++-- 3 files changed, 84 insertions(+), 14 deletions(-) (limited to 'common') diff --git a/common/boot.c b/common/boot.c index 0e9f27f9bc..bc90502284 100644 --- a/common/boot.c +++ b/common/boot.c @@ -43,7 +43,7 @@ struct bootentries *bootentries_alloc(void) if (IS_ENABLED(CONFIG_MENU)) { bootentries->menu = menu_alloc(); - bootentries->menu->display = basprintf("boot"); + menu_add_title(bootentries->menu, basprintf("boot")); } return bootentries; @@ -61,8 +61,12 @@ void bootentries_free(struct bootentries *bootentries) be->release(be); } - if (bootentries->menu) + if (bootentries->menu) { + int i; + for (i = 0; i < bootentries->menu->display_lines; i++) + free(bootentries->menu->display[i]); free(bootentries->menu->display); + } free(bootentries->menu); free(bootentries); } diff --git a/common/menu.c b/common/menu.c index 9819569f6f..64df458e68 100644 --- a/common/menu.c +++ b/common/menu.c @@ -43,10 +43,13 @@ EXPORT_SYMBOL(menu_get_menus); void menu_free(struct menu *m) { struct menu_entry *me, *tmp; + int i; if (!m) return; free(m->name); + for (i = 0; i < m->display_lines; i++) + free(m->display[i]); free(m->display); free(m->auto_display); @@ -164,7 +167,7 @@ static void __print_entry(const char *str) static void print_menu_entry(struct menu *m, struct menu_entry *me, int selected) { - gotoXY(3, me->num + 1); + gotoXY(3, me->num + m->display_lines); if (me->type == MENU_ENTRY_BOX) { if (me->box_state) @@ -232,14 +235,12 @@ EXPORT_SYMBOL(menu_set_auto_select); static void print_menu(struct menu *m) { struct menu_entry *me; + int i; clear(); - gotoXY(2, 1); - if(m->display) { - __print_entry(m->display); - } else { - puts("Menu : "); - puts(m->name); + for (i = 0; i < m->display_lines; i++) { + gotoXY(2, 1 + i); + __print_entry(m->display[i]); } list_for_each_entry(me, &m->entries, list) { @@ -269,7 +270,7 @@ int menu_show(struct menu *m) countdown = m->auto_select; if (m->auto_select >= 0) { - gotoXY(3, m->nb_entries + 2); + gotoXY(3, m->nb_entries + m->display_lines + 1); if (!m->auto_display) { printf("Auto Select in"); } else { @@ -293,10 +294,10 @@ int menu_show(struct menu *m) } } - gotoXY(3, m->nb_entries + 2); + gotoXY(3, m->nb_entries + m->display_lines + 1); printf("%*c", auto_display_len + 4, ' '); - gotoXY(3, m->selected->num + 1); + gotoXY(3, m->selected->num + m->display_lines); do { struct menu_entry *old_selected = m->selected; @@ -517,3 +518,63 @@ err_free: return ERR_PTR(ret); } EXPORT_SYMBOL(menu_add_command_entry); + +/* + * Add title to menu. + * Lines are separated by explicit char '\n' or by string "\n". + * + * @display: NULL or pointer to the string which will be freed in this function. + * If NULL or zero length string is provided, default title will be added. + */ +void menu_add_title(struct menu *m, char *display) +{ + char *tmp, *src, *dst; + int lines = 1; + int i; + + if (!display || !strlen(display)) { + free(display); + display = xasprintf("Menu : %s", m->name ? m->name : ""); + } + + src = dst = tmp = xstrdup(display); + /* Count lines and separate single string into multiple strings */ + while (*src) { + if (*src == '\\') { + if (*(src + 1) == '\\') { + *dst++ = *src++; + *dst++ = *src++; + continue; + } + if (*(src + 1) == 'n') { + *dst = 0; + src += 2; + dst++; + lines++; + continue; + } + } + if (*src == '\n') { + *dst = 0; + src++; + dst++; + lines++; + continue; + } + *dst++ = *src++; + } + *dst = 0; + + m->display = xzalloc(sizeof(*m->display) * lines); + m->display_lines = lines; + + for (src = tmp, i = 0; i < lines; i++) { + m->display[i] = xstrdup(src); + /* Go to the next line */ + src += strlen(src) + 1; + } + + free(tmp); + free(display); +} +EXPORT_SYMBOL(menu_add_title); diff --git a/common/menutree.c b/common/menutree.c index eb14da0d01..400d1a6939 100644 --- a/common/menutree.c +++ b/common/menutree.c @@ -19,6 +19,7 @@ #include #include +#include #include struct menutree { @@ -95,6 +96,7 @@ int menutree(const char *path, int toplevel) glob_t g; int i; char *globpath, *display; + size_t size; menu = menu_alloc(); @@ -106,14 +108,17 @@ int menutree(const char *path, int toplevel) goto out; } - display = read_file_line("%s/title", path); + globpath = basprintf("%s/title", path); + display = read_file(globpath, &size); + free(globpath); if (!display) { eprintf("no title found in %s/title\n", path); ret = -EINVAL; goto out; } - menu->display = shell_expand(display); + strim(display); + menu_add_title(menu, shell_expand(display)); free(display); for (i = 0; i < g.gl_pathc; i++) { -- cgit v1.2.3