From: Jeremy Kerr Date: Mon, 21 Oct 2013 10:59:12 +0000 (+0800) Subject: ui/ncurses: Add basic config editor X-Git-Tag: v1.0.0~342 X-Git-Url: http://git.ozlabs.org/?p=petitboot;a=commitdiff_plain;h=2a6f3ebc8263e94441c2c865a6b28dae40e35990;ds=sidebyside ui/ncurses: Add basic config editor This change adds a simple configuration editor to the ncurses UI. Signed-off-by: Jeremy Kerr --- diff --git a/ui/ncurses/Makefile.am b/ui/ncurses/Makefile.am index a341780..61ed67e 100644 --- a/ui/ncurses/Makefile.am +++ b/ui/ncurses/Makefile.am @@ -29,6 +29,8 @@ common_libs = \ noinst_LTLIBRARIES = libpbnc.la libpbnc_la_SOURCES = \ + nc-config.c \ + nc-config.h \ nc-cui.c \ nc-cui.h \ nc-boot-editor.c \ diff --git a/ui/ncurses/generic-main.c b/ui/ncurses/generic-main.c index 9d8ebb9..feff506 100644 --- a/ui/ncurses/generic-main.c +++ b/ui/ncurses/generic-main.c @@ -132,6 +132,12 @@ static int pmenu_sysinfo(struct pmenu_item *item) return 0; } +static int pmenu_config(struct pmenu_item *item) +{ + cui_show_config(cui_from_item(item)); + return 0; +} + /** * pb_mm_init - Setup the main menu instance. */ @@ -142,7 +148,7 @@ static struct pmenu *pb_mm_init(struct pb_cui *pb_cui) struct pmenu *m; struct pmenu_item *i; - m = pmenu_init(pb_cui->cui, 3, cui_on_exit); + m = pmenu_init(pb_cui->cui, 4, cui_on_exit); if (!m) { pb_log("%s: failed\n", __func__); @@ -162,7 +168,9 @@ static struct pmenu *pb_mm_init(struct pb_cui *pb_cui) item_opts_off(i->nci, O_SELECTABLE); i = pmenu_item_init(m, 1, "System information"); i->on_execute = pmenu_sysinfo; - i = pmenu_item_init(m, 2, "Exit to shell"); + i = pmenu_item_init(m, 2, "System configuration"); + i->on_execute = pmenu_config; + i = pmenu_item_init(m, 3, "Exit to shell"); i->on_execute = pmenu_exit_cb; result = pmenu_setup(m); diff --git a/ui/ncurses/nc-config.c b/ui/ncurses/nc-config.c new file mode 100644 index 0000000..b7985aa --- /dev/null +++ b/ui/ncurses/nc-config.c @@ -0,0 +1,213 @@ +/* + * Copyright (C) 2013 IBM Corporation + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; version 2 of the License. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#define _GNU_SOURCE + + +#include + +#include +#include +#include + +#include "config.h" +#include "nc-cui.h" +#include "nc-config.h" +#include "nc-widgets.h" + +#define N_FIELDS 9 + +struct config_screen { + struct nc_scr scr; + struct cui *cui; + struct nc_widgetset *widgetset; + bool exit; + void (*on_exit)(struct cui *); + + int label_x; + int field_x; + + struct { + struct nc_widget_checkbox *autoboot_f; + struct nc_widget_label *autoboot_l; + struct nc_widget_textbox *timeout_f; + struct nc_widget_label *timeout_l; + + struct nc_widget_label *network_l; + struct nc_widget_label *iface_l; + struct nc_widget_select *iface_f; + + struct nc_widget_button *ok_b; + struct nc_widget_button *cancel_b; + } widgets; +}; + +static struct config_screen *config_screen_from_scr(struct nc_scr *scr) +{ + struct config_screen *config_screen; + + assert(scr->sig == pb_config_screen_sig); + config_screen = (struct config_screen *) + ((char *)scr - (size_t)&((struct config_screen *)0)->scr); + assert(config_screen->scr.sig == pb_config_screen_sig); + return config_screen; +} + +static void config_screen_process_key(struct nc_scr *scr, int key) +{ + struct config_screen *screen = config_screen_from_scr(scr); + bool handled; + + handled = widgetset_process_key(screen->widgetset, key); + if (screen->exit) + screen->on_exit(screen->cui); + else if (handled) + wrefresh(screen->scr.main_ncw); +} + +static void config_screen_resize(struct nc_scr *scr) +{ + struct config_screen *screen = config_screen_from_scr(scr); + (void)screen; +} + +static int config_screen_post(struct nc_scr *scr) +{ + struct config_screen *screen = config_screen_from_scr(scr); + widgetset_post(screen->widgetset); + nc_scr_frame_draw(scr); + wrefresh(scr->main_ncw); + return 0; +} + +static int config_screen_unpost(struct nc_scr *scr) +{ + struct config_screen *screen = config_screen_from_scr(scr); + widgetset_unpost(screen->widgetset); + return 0; +} + +struct nc_scr *config_screen_scr(struct config_screen *screen) +{ + return &screen->scr; +} + +static void ok_click(void *arg) +{ + struct config_screen *screen = arg; + /* todo: save config */ + screen->on_exit(screen->cui); +} + +static void cancel_click(void *arg) +{ + struct config_screen *screen = arg; + screen->exit = true; +} + +static int layout_pair(struct config_screen *screen, int y, + struct nc_widget_label *label, + struct nc_widget *field) +{ + struct nc_widget *label_w = widget_label_base(label); + widget_move(label_w, y, screen->label_x); + widget_move(field, y, screen->field_x); + return max(widget_height(label_w), widget_height(field)); +} + +static void config_screen_layout_widgets(struct config_screen *screen) +{ + int y; + + y = 1; + + y += layout_pair(screen, y, screen->widgets.autoboot_l, + widget_checkbox_base(screen->widgets.autoboot_f)); + + y += layout_pair(screen, y, screen->widgets.timeout_l, + widget_textbox_base(screen->widgets.timeout_f)); + + y++; + + widget_move(widget_button_base(screen->widgets.ok_b), + y, screen->field_x); + widget_move(widget_button_base(screen->widgets.cancel_b), + y, screen->field_x + 10); +} + +static void config_screen_setup_widgets(struct config_screen *screen, + const struct config *config, + const struct system_info *sysinfo) +{ + struct nc_widgetset *set = screen->widgetset; + char *str; + + (void)sysinfo; + + build_assert(sizeof(screen->widgets) / sizeof(struct widget *) + == N_FIELDS); + + screen->widgets.autoboot_l = widget_new_label(set, 0, 0, "Autoboot:"); + screen->widgets.autoboot_f = widget_new_checkbox(set, 0, 0, + config->autoboot_enabled); + + str = talloc_asprintf(screen, "%d", config->autoboot_timeout_sec); + screen->widgets.timeout_l = widget_new_label(set, 0, 0, "Timeout:"); + screen->widgets.timeout_f = widget_new_textbox(set, 0, 0, 5, str); + + screen->widgets.ok_b = widget_new_button(set, 0, 0, 6, "OK", + ok_click, screen); + screen->widgets.cancel_b = widget_new_button(set, 0, 0, 6, "Cancel", + cancel_click, screen); + +} + +struct config_screen *config_screen_init(struct cui *cui, + const struct config *config, + const struct system_info *sysinfo, + void (*on_exit)(struct cui *)) +{ + struct config_screen *screen; + + screen = talloc_zero(cui, struct config_screen); + nc_scr_init(&screen->scr, pb_config_screen_sig, 0, + cui, config_screen_process_key, + config_screen_post, config_screen_unpost, + config_screen_resize); + + screen->cui = cui; + screen->on_exit = on_exit; + screen->label_x = 2; + screen->field_x = 16; + + screen->scr.frame.ltitle = talloc_strdup(screen, + "Petitboot System Configuration"); + screen->scr.frame.rtitle = NULL; + screen->scr.frame.help = talloc_strdup(screen, + "tab=next, shift+tab=previous"); + nc_scr_frame_draw(&screen->scr); + + screen->widgetset = widgetset_create(screen, screen->scr.main_ncw, + screen->scr.sub_ncw); + config_screen_setup_widgets(screen, config, sysinfo); + config_screen_layout_widgets(screen); + + wrefresh(screen->scr.main_ncw); + scrollok(screen->scr.sub_ncw, true); + + return screen; +} diff --git a/ui/ncurses/nc-config.h b/ui/ncurses/nc-config.h new file mode 100644 index 0000000..71e0ea4 --- /dev/null +++ b/ui/ncurses/nc-config.h @@ -0,0 +1,35 @@ +/* + * Copyright (C) 2013 IBM Corporation + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; version 2 of the License. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#ifndef _NC_CONFIG_H +#define _NC_CONFIG_H + +#include "types/types.h" +#include "nc-cui.h" + +struct config_screen; + +struct config_screen *config_screen_init(struct cui *cui, + const struct config *config, + const struct system_info *sysinfo, + void (*on_exit)(struct cui *)); + +struct nc_scr *config_screen_scr(struct config_screen *screen); +void config_screen_update(struct config_screen *screen, + const struct config *config); + +#endif /* defined _NC_CONFIG_H */ diff --git a/ui/ncurses/nc-cui.c b/ui/ncurses/nc-cui.c index 6aa2a28..d74c1a4 100644 --- a/ui/ncurses/nc-cui.c +++ b/ui/ncurses/nc-cui.c @@ -34,6 +34,7 @@ #include "process/process.h" #include "ui/common/discover-client.h" #include "nc-cui.h" +#include "nc-config.h" #include "nc-sysinfo.h" static struct cui_opt_data *cod_from_item(struct pmenu_item *item) @@ -251,6 +252,20 @@ void cui_show_sysinfo(struct cui *cui) cui_set_current(cui, sysinfo_screen_scr(cui->sysinfo_screen)); } +static void cui_config_exit(struct cui *cui) +{ + cui_set_current(cui, &cui->main->scr); + talloc_free(cui->config_screen); + cui->config_screen = NULL; +} + +void cui_show_config(struct cui *cui) +{ + cui->config_screen = config_screen_init(cui, cui->config, + cui->sysinfo, cui_config_exit); + cui_set_current(cui, config_screen_scr(cui->config_screen)); +} + /** * cui_set_current - Set the currently active screen and redraw it. */ diff --git a/ui/ncurses/nc-cui.h b/ui/ncurses/nc-cui.h index 0e3708d..752f2db 100644 --- a/ui/ncurses/nc-cui.h +++ b/ui/ncurses/nc-cui.h @@ -58,6 +58,7 @@ struct cui { struct system_info *sysinfo; struct sysinfo_screen *sysinfo_screen; struct config *config; + struct config_screen *config_screen; struct pjs *pjs; void *platform_info; unsigned int default_item; @@ -72,6 +73,7 @@ int cui_run(struct cui *cui, struct pmenu *main, unsigned int default_item); void cui_item_edit(struct pmenu_item *item); void cui_item_new(struct pmenu *menu); void cui_show_sysinfo(struct cui *cui); +void cui_show_config(struct cui *cui); /* convenience routines */ diff --git a/ui/ncurses/nc-menu.c b/ui/ncurses/nc-menu.c index dc46807..5dc6469 100644 --- a/ui/ncurses/nc-menu.c +++ b/ui/ncurses/nc-menu.c @@ -245,6 +245,10 @@ static void pmenu_process_key(struct nc_scr *scr, int key) break; case 'i': cui_show_sysinfo(cui_from_arg(scr->ui_ctx)); + break; + case 'c': + cui_show_config(cui_from_arg(scr->ui_ctx)); + break; default: menu_driver(menu->ncm, key); break; diff --git a/ui/ncurses/nc-scr.h b/ui/ncurses/nc-scr.h index e3ed20a..060ee40 100644 --- a/ui/ncurses/nc-scr.h +++ b/ui/ncurses/nc-scr.h @@ -45,7 +45,8 @@ enum pb_nc_sig { pb_item_sig = 333, pb_boot_editor_sig = 444, pb_sysinfo_screen_sig = 555, - pb_removed_sig = -666, + pb_config_screen_sig = 666, + pb_removed_sig = -777, }; static inline void nc_flush_keys(void)