X-Git-Url: http://git.ozlabs.org/?p=petitboot;a=blobdiff_plain;f=ui%2Fncurses%2Fnc-config.c;h=64fb4c792139d71dc0891dda330752b2427dc272;hp=3156b9bf1057bc609bdf031908ee401d7d574b18;hb=68a146bb02f81e746d13b362daaf290a51697a5a;hpb=a3e3b66fbcb18174fc54ffd771ef3a38c9f8defd diff --git a/ui/ncurses/nc-config.c b/ui/ncurses/nc-config.c index 3156b9b..64fb4c7 100644 --- a/ui/ncurses/nc-config.c +++ b/ui/ncurses/nc-config.c @@ -33,7 +33,7 @@ #include "nc-config.h" #include "nc-widgets.h" -#define N_FIELDS 29 +#define N_FIELDS 34 extern struct help_text config_help_text; @@ -53,6 +53,7 @@ struct config_screen { bool show_help; bool show_subset; bool need_redraw; + bool need_update; void (*on_exit)(struct cui *); @@ -65,6 +66,7 @@ struct config_screen { enum net_conf_type net_conf_type; bool autoboot_enabled; + bool ipmi_override; struct { struct nc_widget_label *boot_order_l; @@ -77,6 +79,10 @@ struct config_screen { struct nc_widget_label *timeout_l; struct nc_widget_label *timeout_help_l; + struct nc_widget_label *ipmi_type_l; + struct nc_widget_label *ipmi_clear_l; + struct nc_widget_checkbox *ipmi_clear_cb; + struct nc_widget_label *network_l; struct nc_widget_select *network_f; @@ -95,6 +101,9 @@ struct config_screen { struct nc_widget_label *dns_dhcp_help_l; struct nc_widget_label *dns_help_l; + struct nc_widget_label *allow_write_l; + struct nc_widget_select *allow_write_f; + struct nc_widget_label *safe_mode; struct nc_widget_button *ok_b; struct nc_widget_button *help_b; @@ -162,21 +171,6 @@ static void config_screen_resize(struct nc_scr *scr) (void)screen; } -static int config_screen_post(struct nc_scr *scr) -{ - struct config_screen *screen = config_screen_from_scr(scr); - screen->show_subset = false; - widgetset_post(screen->widgetset); - nc_scr_frame_draw(scr); - if (screen->need_redraw) { - redrawwin(scr->main_ncw); - screen->need_redraw = false; - } - wrefresh(screen->scr.main_ncw); - pad_refresh(screen); - return 0; -} - static int config_screen_unpost(struct nc_scr *scr) { struct config_screen *screen = config_screen_from_scr(scr); @@ -198,6 +192,7 @@ static int screen_process_form(struct config_screen *screen) struct config *config; int i, n_boot_opts, rc, idx; unsigned int *order; + bool allow_write; char mac[20]; config = config_copy(screen, screen->cui->config); @@ -245,6 +240,11 @@ static int screen_process_form(struct config_screen *screen) config->autoboot_timeout_sec = x; } + if (screen->ipmi_override) + if (widget_checkbox_get_value(screen->widgets.ipmi_clear_cb)) + config->ipmi_bootdev = IPMI_BOOTDEV_INVALID; + + net_conf_type = widget_select_get_value(screen->widgets.network_f); /* if we don't have any network interfaces, prevent per-interface @@ -321,6 +321,10 @@ static int screen_process_form(struct config_screen *screen) } } + allow_write = widget_select_get_value(screen->widgets.allow_write_f); + if (allow_write != config->allow_writes) + config->allow_writes = allow_write; + config->safe_mode = false; rc = cui_send_config(screen->cui, config); talloc_free(config); @@ -373,11 +377,11 @@ static void config_screen_layout_widgets(struct config_screen *screen) bool show; y = 1; + /* currently, the longest label we have is the DNS-servers + * widget, so layout our screen based on that */ help_x = screen->field_x + 2 + widget_width(widget_textbox_base(screen->widgets.dns_f)); - y += 1; - wl = widget_label_base(screen->widgets.boot_order_l); widget_set_visible(wl, true); widget_move(wl, y, screen->label_x); @@ -400,11 +404,11 @@ static void config_screen_layout_widgets(struct config_screen *screen) y += 1; widget_move(widget_button_base(screen->widgets.boot_add_b), - y, screen->field_x); + y++, screen->field_x); widget_move(widget_button_base(screen->widgets.boot_any_b), - y, screen->field_x + 12); + y++, screen->field_x); widget_move(widget_button_base(screen->widgets.boot_none_b), - y, screen->field_x + 30); + y, screen->field_x); wf = widget_button_base(screen->widgets.boot_add_b); if (widget_subset_n_inactive(screen->widgets.boot_order_f)) @@ -419,6 +423,7 @@ static void config_screen_layout_widgets(struct config_screen *screen) wh = widget_label_base(screen->widgets.timeout_help_l); widget_set_visible(wl, screen->autoboot_enabled); widget_set_visible(wf, screen->autoboot_enabled); + widget_set_visible(wh, screen->autoboot_enabled); if (screen->autoboot_enabled) { widget_set_visible(wh, screen->autoboot_enabled); widget_move(wl, y, screen->label_x); @@ -427,6 +432,23 @@ static void config_screen_layout_widgets(struct config_screen *screen) y += 2; } + if (screen->ipmi_override) { + wl = widget_label_base(screen->widgets.ipmi_type_l); + widget_set_visible(wl, true); + widget_move(wl, y, screen->label_x); + y += 1; + + wl = widget_label_base(screen->widgets.ipmi_clear_l); + wf = widget_checkbox_base(screen->widgets.ipmi_clear_cb); + widget_set_visible(wl, true); + widget_set_visible(wf, true); + widget_move(wl, y, screen->label_x); + widget_move(wf, y, screen->field_x); + y += 1; + } + + y += 1; + y += layout_pair(screen, y, screen->widgets.network_l, widget_select_base(screen->widgets.network_f)); @@ -512,12 +534,18 @@ static void config_screen_layout_widgets(struct config_screen *screen) y += 1; } + layout_pair(screen, y, screen->widgets.allow_write_l, + widget_select_base(screen->widgets.allow_write_f)); + y += widget_height(widget_select_base(screen->widgets.allow_write_f)); + + y += 1; + widget_move(widget_button_base(screen->widgets.ok_b), y, screen->field_x); widget_move(widget_button_base(screen->widgets.help_b), - y, screen->field_x + 10); + y, screen->field_x + 14); widget_move(widget_button_base(screen->widgets.cancel_b), - y, screen->field_x + 24); + y, screen->field_x + 28); } static void config_screen_network_change(void *arg, int value) @@ -543,7 +571,7 @@ static void config_screen_add_device(void *arg) struct config_screen *screen = arg; screen->show_subset = true; - cui_show_subset(screen->cui, _("Select an option"), + cui_show_subset(screen->cui, _("Select a boot device to add"), screen->widgets.boot_order_f); } @@ -668,6 +696,7 @@ static void config_screen_setup_widgets(struct config_screen *screen, char *str, *ip, *mask, *gw; enum net_conf_type type; unsigned int i; + int add_len, clear_len, any_len, min_len = 20; build_assert(sizeof(screen->widgets) / sizeof(struct widget *) == N_FIELDS); @@ -675,20 +704,24 @@ static void config_screen_setup_widgets(struct config_screen *screen, type = screen->net_conf_type; ifcfg = first_active_interface(config); - screen->widgets.boot_add_b = widget_new_button(set, 0, 0, 10, - _("Add Device"), config_screen_add_device, - screen); + add_len = max(min_len, strncols(_("Add Device"))); + clear_len = max(min_len, strncols(_("Clear"))); + any_len = max(min_len, strncols(_("Clear & Boot Any"))); - screen->widgets.boot_none_b = widget_new_button(set, 0, 0, 10, + screen->widgets.boot_add_b = widget_new_button(set, 0, 0, add_len, + _("Add Device"), + config_screen_add_device, screen); + + screen->widgets.boot_none_b = widget_new_button(set, 0, 0, clear_len, _("Clear"), config_screen_autoboot_none, screen); - screen->widgets.boot_any_b = widget_new_button(set, 0, 0, 16, - _("Clear & Boot Any"), config_screen_autoboot_any, - screen); + screen->widgets.boot_any_b = widget_new_button(set, 0, 0, any_len, + _("Clear & Boot Any"), + config_screen_autoboot_any, screen); screen->widgets.boot_order_l = widget_new_label(set, 0, 0, - _("Boot order:")); + _("Boot Order:")); screen->widgets.boot_order_f = widget_new_subset(set, 0, 0, COLS - screen->field_x, config_screen_update_subset); @@ -720,7 +753,7 @@ static void config_screen_setup_widgets(struct config_screen *screen, widget_subset_add_option(screen->widgets.boot_order_f, label); } - for (i = DEVICE_TYPE_NETWORK; i < DEVICE_TYPE_NETWORK + 4; i++) { + for (i = DEVICE_TYPE_NETWORK; i < DEVICE_TYPE_UNKNOWN; i++) { char *label; if (i == DEVICE_TYPE_ANY) @@ -762,8 +795,24 @@ static void config_screen_setup_widgets(struct config_screen *screen, widget_textbox_set_fixed_size(screen->widgets.timeout_f); widget_textbox_set_validator_integer(screen->widgets.timeout_f, 0, 999); + if (config->ipmi_bootdev) { + char *label = talloc_asprintf(screen, + _("%s IPMI boot option: %s"), + config->ipmi_bootdev_persistent ? + "Persistent" : "Temporary", + ipmi_bootdev_display_name(config->ipmi_bootdev)); + screen->widgets.ipmi_type_l = widget_new_label(set, 0, 0, + label); + screen->widgets.ipmi_clear_l = widget_new_label(set, 0, 0, + _("Clear option:")); + screen->widgets.ipmi_clear_cb = widget_new_checkbox(set, 0, 0, + false); + screen->ipmi_override = true; + } + screen->widgets.network_l = widget_new_label(set, 0, 0, _("Network:")); - screen->widgets.network_f = widget_new_select(set, 0, 0, 50); + screen->widgets.network_f = widget_new_select(set, 0, 0, + COLS - screen->field_x - 1); widget_select_add_option(screen->widgets.network_f, NET_CONF_TYPE_DHCP_ALL, @@ -857,7 +906,20 @@ static void config_screen_setup_widgets(struct config_screen *screen, screen->widgets.safe_mode = widget_new_label(set, 0, 0, _("Selecting 'OK' will exit safe mode")); - screen->widgets.ok_b = widget_new_button(set, 0, 0, 6, _("OK"), + screen->widgets.allow_write_l = widget_new_label(set, 0, 0, + _("Disk R/W:")); + screen->widgets.allow_write_f = widget_new_select(set, 0, 0, + COLS - screen->field_x - 1); + + widget_select_add_option(screen->widgets.allow_write_f, 0, + _("Prevent all writes to disk"), + !config->allow_writes); + + widget_select_add_option(screen->widgets.allow_write_f, 1, + _("Allow bootloader scripts to modify disks"), + config->allow_writes); + + screen->widgets.ok_b = widget_new_button(set, 0, 0, 10, _("OK"), ok_click, screen); screen->widgets.help_b = widget_new_button(set, 0, 0, 10, _("Help"), help_click, screen); @@ -868,18 +930,22 @@ static void config_screen_setup_widgets(struct config_screen *screen, static void config_screen_widget_focus(struct nc_widget *widget, void *arg) { struct config_screen *screen = arg; - int w_y, s_max; + int w_y, w_height, w_focus, s_max, adjust; - w_y = widget_y(widget) + widget_focus_y(widget); + w_height = widget_height(widget); + w_focus = widget_focus_y(widget); + w_y = widget_y(widget) + w_focus; s_max = getmaxy(screen->scr.sub_ncw) - 1; if (w_y < screen->scroll_y) screen->scroll_y = w_y; - else if (w_y + screen->scroll_y + 1 > s_max) - screen->scroll_y = 1 + w_y - s_max; - - else + else if (w_y + screen->scroll_y + 1 > s_max) { + /* Fit as much of the widget into the screen as possible */ + adjust = min(s_max - 1, w_height - w_focus); + if (w_y + adjust >= screen->scroll_y + s_max) + screen->scroll_y = max(0, 1 + w_y + adjust - s_max); + } else return; pad_refresh(screen); @@ -940,10 +1006,38 @@ void config_screen_update(struct config_screen *screen, const struct config *config, const struct system_info *sysinfo) { + if (screen->cui->current != config_screen_scr(screen)) { + screen->need_update = true; + return; + } + config_screen_draw(screen, config, sysinfo); pad_refresh(screen); } +static int config_screen_post(struct nc_scr *scr) +{ + struct config_screen *screen = config_screen_from_scr(scr); + screen->show_subset = false; + + if (screen->need_update) { + config_screen_draw(screen, screen->cui->config, + screen->cui->sysinfo); + screen->need_update = false; + } else { + widgetset_post(screen->widgetset); + } + + nc_scr_frame_draw(scr); + if (screen->need_redraw) { + redrawwin(scr->main_ncw); + screen->need_redraw = false; + } + wrefresh(screen->scr.main_ncw); + pad_refresh(screen); + return 0; +} + static int config_screen_destroy(void *arg) { struct config_screen *screen = arg; @@ -969,9 +1063,11 @@ struct config_screen *config_screen_init(struct cui *cui, screen->cui = cui; screen->on_exit = on_exit; screen->need_redraw = false; + screen->need_update = false; screen->label_x = 2; screen->field_x = 17; + screen->ipmi_override = false; screen->show_subset = false; screen->scr.frame.ltitle = talloc_strdup(screen,