From: Jeremy Kerr Date: Thu, 10 Oct 2013 07:35:35 +0000 (+0800) Subject: ui/ncurses: Defer item creation until boot editor is done X-Git-Tag: v1.0.0~388 X-Git-Url: http://git.ozlabs.org/?p=petitboot;a=commitdiff_plain;h=6d1eff1e8e1db12e7aa179e8dc9c65050c045536 ui/ncurses: Defer item creation until boot editor is done Currently, when creating new menu entries, we create an empty item, add it to the menu, then run the boot editor. This means that cancelling the edit will leave an empty item in the menu. This change defers the creation until the boot editor is done. To do this, we modify the on_open callback to take a menu rather than an item, and pass NULL boot data to the editor. Signed-off-by: Jeremy Kerr --- diff --git a/ui/ncurses/generic-main.c b/ui/ncurses/generic-main.c index c40ebab..d9fd7d2 100644 --- a/ui/ncurses/generic-main.c +++ b/ui/ncurses/generic-main.c @@ -143,7 +143,7 @@ static struct pmenu *pb_mm_init(struct pb_cui *pb_cui) return NULL; } - m->on_open = cui_on_open; + m->on_new = cui_item_new; m->scr.frame.ltitle = talloc_asprintf(m, "Petitboot (" PACKAGE_VERSION ")"); diff --git a/ui/ncurses/nc-boot-editor.c b/ui/ncurses/nc-boot-editor.c index 100830c..8fe3365 100644 --- a/ui/ncurses/nc-boot-editor.c +++ b/ui/ncurses/nc-boot-editor.c @@ -213,16 +213,14 @@ static void boot_editor_process_key(struct nc_scr *scr, int key) /* hot keys */ case 27: /* ESC */ - boot_editor->on_exit(boot_editor, - boot_editor_cancel, NULL); + boot_editor->on_exit(boot_editor, boot_editor_cancel, NULL); nc_flush_keys(); return; case '\n': case '\r': form_driver(boot_editor->ncf, REQ_VALIDATION); bd = boot_editor_prepare_data(boot_editor); - boot_editor->on_exit(boot_editor, - boot_editor_update, bd); + boot_editor->on_exit(boot_editor, boot_editor_update, bd); nc_flush_keys(); return; @@ -310,30 +308,27 @@ static FIELD *boot_editor_setup_label(unsigned int y, unsigned int x, char *str) return f; } -struct boot_editor *boot_editor_init(void *ui_ctx, +struct boot_editor *boot_editor_init(struct pmenu *menu, const struct pb_boot_data *bd, void (*on_exit)(struct boot_editor *, enum boot_editor_result, struct pb_boot_data *)) { + char *image, *initrd, *dtb, *args; struct boot_editor *boot_editor; - pb_log("%s: image: '%s'\n", __func__, bd->image); - pb_log("%s: initrd: '%s'\n", __func__, bd->initrd); - pb_log("%s: dtb: '%s'\n", __func__, bd->dtb); - pb_log("%s: args: '%s'\n", __func__, bd->args); - assert(on_exit); - boot_editor = talloc_zero(ui_ctx, struct boot_editor); + boot_editor = talloc_zero(menu, struct boot_editor); if (!boot_editor) return NULL; talloc_set_destructor(boot_editor, boot_editor_destructor); + boot_editor->original_pmenu = menu; nc_scr_init(&boot_editor->scr, pb_boot_editor_sig, 0, - ui_ctx, boot_editor_process_key, + menu, boot_editor_process_key, boot_editor_post, boot_editor_unpost, boot_editor_resize); boot_editor->scr.frame.ltitle = talloc_strdup(boot_editor, @@ -346,10 +341,19 @@ struct boot_editor *boot_editor_init(void *ui_ctx, boot_editor->fields = talloc_array(boot_editor, FIELD *, 9); - boot_editor->fields[0] = boot_editor_setup_field(0, 9, bd->image); - boot_editor->fields[1] = boot_editor_setup_field(1, 9, bd->initrd); - boot_editor->fields[2] = boot_editor_setup_field(2, 9, bd->dtb); - boot_editor->fields[3] = boot_editor_setup_field(3, 9, bd->args); + if (bd) { + image = bd->image; + initrd = bd->initrd; + dtb = bd->dtb; + args = bd->args; + } else { + image = initrd = dtb = args = ""; + } + + boot_editor->fields[0] = boot_editor_setup_field(0, 9, image); + boot_editor->fields[1] = boot_editor_setup_field(1, 9, initrd); + boot_editor->fields[2] = boot_editor_setup_field(2, 9, dtb); + boot_editor->fields[3] = boot_editor_setup_field(3, 9, args); boot_editor->fields[4] = boot_editor_setup_label(0, 1, "image:"); boot_editor->fields[5] = boot_editor_setup_label(1, 1, "initrd:"); boot_editor->fields[6] = boot_editor_setup_label(2, 1, "dtb:"); diff --git a/ui/ncurses/nc-boot-editor.h b/ui/ncurses/nc-boot-editor.h index a509f75..ee6d046 100644 --- a/ui/ncurses/nc-boot-editor.h +++ b/ui/ncurses/nc-boot-editor.h @@ -60,16 +60,18 @@ enum boot_editor_result { */ struct boot_editor { - struct nc_scr scr; - FORM *ncf; - FIELD **fields; + struct nc_scr scr; + FORM *ncf; + FIELD **fields; + void *data; + struct pmenu *original_pmenu; + void (*on_exit)(struct boot_editor *boot_editor, + enum boot_editor_result result, + struct pb_boot_data *bd); enum boot_editor_attr_cursor attr_cursor; - void (*on_exit)(struct boot_editor *boot_editor, - enum boot_editor_result result, - struct pb_boot_data *bd); }; -struct boot_editor *boot_editor_init(void *ui_ctx, +struct boot_editor *boot_editor_init(struct pmenu *menu, const struct pb_boot_data *bd, void (*on_exit)(struct boot_editor *, enum boot_editor_result, diff --git a/ui/ncurses/nc-cui.c b/ui/ncurses/nc-cui.c index 35c9deb..8555848 100644 --- a/ui/ncurses/nc-cui.c +++ b/ui/ncurses/nc-cui.c @@ -139,48 +139,76 @@ static int cui_boot(struct pmenu_item *item) * cui_boot_editor_on_exit - The boot_editor on_exit callback. */ -static void cui_boot_editor_on_exit(struct boot_editor *boot_editor, enum boot_editor_result boot_editor_result, - struct pb_boot_data *bd) +static void cui_boot_editor_on_exit(struct boot_editor *boot_editor, + enum boot_editor_result boot_editor_result, + struct pb_boot_data *bd) { - struct cui *cui = cui_from_arg(boot_editor->scr.ui_ctx); + struct cui *cui = cui_from_pmenu(boot_editor->original_pmenu); + struct pmenu_item *item = boot_editor->data; + struct cui_opt_data *cod; - if (boot_editor_result == boot_editor_update) { - struct pmenu_item *i = pmenu_find_selected(cui->main); - struct cui_opt_data *cod = cod_from_item(i); + if (boot_editor_result != boot_editor_update) { + cui_set_current(cui, &cui->main->scr); + talloc_free(boot_editor); + return; + } - assert(bd); + assert(bd); - talloc_steal(i, bd); - talloc_free(cod->bd); - cod->bd = bd; + /* Is this was a new item, we'll need to update the menu */ + if (!item) { + struct pmenu *menu = boot_editor->original_pmenu; + int insert_pt; - pmenu_item_replace(i, cod->name); + /* Detach the items array. */ + set_menu_items(menu->ncm, NULL); - /* FIXME: need to make item visible somehow */ - set_current_item(cui->main->ncm, i->nci); + /* Insert new item at insert_pt. */ + insert_pt = pmenu_grow(menu, 1); + item = pmenu_item_alloc(menu); + item->on_edit = cui_item_edit; + item->on_execute = cui_boot; + item->data = cod = talloc_zero(item, struct cui_opt_data); - pb_log("%s: updating opt '%s'\n", __func__, cod->name); - pb_log(" image '%s'\n", cod->bd->image); - pb_log(" initrd '%s'\n", cod->bd->initrd); - pb_log(" dtb '%s'\n", cod->bd->dtb); - pb_log(" args '%s'\n", cod->bd->args); + cod->name = talloc_asprintf(cod, "User item %u:", insert_pt); + pmenu_item_setup(menu, item, insert_pt, + talloc_strdup(item, cod->name)); + + /* Re-attach the items array. */ + set_menu_items(menu->ncm, menu->items); + menu->scr.post(&menu->scr); + } else { + cod = item->data; } - cui_set_current(cui, &cui->main->scr); + cod->bd = talloc_steal(cod, bd); + /* FIXME: need to make item visible somehow */ + set_current_item(item->pmenu->ncm, item->nci); + cui_set_current(cui, &cui->main->scr); talloc_free(boot_editor); } -int cui_boot_editor_run(struct pmenu_item *item) +void cui_item_edit(struct pmenu_item *item) { struct cui *cui = cui_from_item(item); struct cui_opt_data *cod = cod_from_item(item); struct boot_editor *boot_editor; - boot_editor = boot_editor_init(cui, cod->bd, cui_boot_editor_on_exit); + boot_editor = boot_editor_init(item->pmenu, cod->bd, + cui_boot_editor_on_exit); + boot_editor->data = item; cui_set_current(cui, &boot_editor->scr); +} - return 0; +void cui_item_new(struct pmenu *menu) +{ + struct cui *cui = cui_from_pmenu(menu); + struct boot_editor *boot_editor; + + boot_editor = boot_editor_init(menu, NULL, + cui_boot_editor_on_exit); + cui_set_current(cui, &boot_editor->scr); } /** @@ -290,46 +318,6 @@ static void cui_handle_resize(struct cui *cui) wrefresh(cui->current->main_ncw); } -/** - * cui_on_open - Open new item callback. - */ - -void cui_on_open(struct pmenu *menu) -{ - unsigned int insert_pt; - struct pmenu_item *i; - struct cui_opt_data *cod; - - menu->scr.unpost(&menu->scr); - - /* This disconnects items array from menu. */ - - set_menu_items(menu->ncm, NULL); - - /* Insert new items at insert_pt. */ - - insert_pt = pmenu_grow(menu, 1); - i = pmenu_item_alloc(menu); - - i->on_edit = cui_boot_editor_run; - i->on_execute = cui_boot; - i->data = cod = talloc_zero(i, struct cui_opt_data); - - cod->name = talloc_asprintf(i, "User item %u:", insert_pt); - cod->bd = talloc_zero(i, struct pb_boot_data); - - pmenu_item_setup(menu, i, insert_pt, talloc_strdup(i, cod->name)); - - /* Re-attach the items array. */ - - set_menu_items(menu->ncm, menu->items); - - menu->scr.post(&menu->scr); - set_current_item(menu->ncm, i->nci); - - i->on_edit(i); -} - /** * cui_device_add - Client device_add callback. * @@ -368,7 +356,7 @@ static int cui_boot_option_add(struct device *dev, struct boot_option *opt, opt->ui_info = i = pmenu_item_alloc(cui->main); - i->on_edit = cui_boot_editor_run; + i->on_edit = cui_item_edit; i->on_execute = cui_boot; i->data = cod = talloc(i, struct cui_opt_data); diff --git a/ui/ncurses/nc-cui.h b/ui/ncurses/nc-cui.h index 5298cad..730e721 100644 --- a/ui/ncurses/nc-cui.h +++ b/ui/ncurses/nc-cui.h @@ -67,7 +67,8 @@ struct cui *cui_init(void* platform_info, int start_deamon); struct nc_scr *cui_set_current(struct cui *cui, struct nc_scr *scr); int cui_run(struct cui *cui, struct pmenu *main, unsigned int default_item); -int cui_boot_editor_run(struct pmenu_item *item); +void cui_item_edit(struct pmenu_item *item); +void cui_item_new(struct pmenu *menu); /* convenience routines */ diff --git a/ui/ncurses/nc-menu.c b/ui/ncurses/nc-menu.c index 073860b..b45719d 100644 --- a/ui/ncurses/nc-menu.c +++ b/ui/ncurses/nc-menu.c @@ -233,8 +233,8 @@ static void pmenu_process_key(struct nc_scr *scr, int key) item->on_edit(item); break; case 'n': - if (menu->on_open) - menu->on_open(menu); + if (menu->on_new) + menu->on_new(menu); break; case '\n': case '\r': diff --git a/ui/ncurses/nc-menu.h b/ui/ncurses/nc-menu.h index f010835..3b7bc88 100644 --- a/ui/ncurses/nc-menu.h +++ b/ui/ncurses/nc-menu.h @@ -47,7 +47,7 @@ struct pmenu_item { ITEM *nci; struct pmenu *pmenu; void *data; - int (*on_edit)(struct pmenu_item *item); + void (*on_edit)(struct pmenu_item *item); int (*on_execute)(struct pmenu_item *item); }; @@ -85,7 +85,7 @@ struct pmenu { unsigned int insert_pt; int (*hot_key)(struct pmenu *menu, struct pmenu_item *item, int c); void (*on_exit)(struct pmenu *menu); - void (*on_open)(struct pmenu *menu); + void (*on_new)(struct pmenu *menu); }; struct pmenu *pmenu_init(void *ui_ctx, unsigned int item_count, diff --git a/ui/ncurses/ps3-main.c b/ui/ncurses/ps3-main.c index 5be8c32..9efba3b 100644 --- a/ui/ncurses/ps3-main.c +++ b/ui/ncurses/ps3-main.c @@ -412,7 +412,7 @@ static struct pmenu *ps3_mm_init(struct ps3_cui *ps3_cui) } m->hot_key = ps3_hot_key; - m->on_open = cui_on_open; + m->on_new = cui_item_new; #if defined(DEBUG) m->scr.frame.title = talloc_strdup(m,