2 * Copyright (C) 2013 IBM Corporation
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License as published by
6 * the Free Software Foundation; version 2 of the License.
8 * This program is distributed in the hope that it will be useful,
9 * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 * GNU General Public License for more details.
13 * You should have received a copy of the GNU General Public License
14 * along with this program; if not, write to the Free Software
15 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
18 #if defined(HAVE_CONFIG_H)
25 #include <talloc/talloc.h>
26 #include <types/types.h>
28 #include <i18n/i18n.h>
29 #include <pb-config/pb-config.h>
33 #include "nc-widgets.h"
41 { "en_US.utf8", L"English"},
47 struct nc_widgetset *widgetset;
51 void (*on_exit)(struct cui *);
59 struct nc_widget_select *lang_f;
60 struct nc_widget_label *lang_l;
62 struct nc_widget_label *safe_mode;
63 struct nc_widget_button *ok_b;
64 struct nc_widget_button *cancel_b;
68 static struct lang_screen *lang_screen_from_scr(struct nc_scr *scr)
70 struct lang_screen *lang_screen;
72 assert(scr->sig == pb_lang_screen_sig);
73 lang_screen = (struct lang_screen *)
74 ((char *)scr - (size_t)&((struct lang_screen *)0)->scr);
75 assert(lang_screen->scr.sig == pb_lang_screen_sig);
79 static void pad_refresh(struct lang_screen *screen)
83 getmaxyx(screen->scr.sub_ncw, rows, cols);
84 getbegyx(screen->scr.sub_ncw, y, x);
86 prefresh(screen->pad, screen->scroll_y, 0, y, x, rows, cols);
89 static void lang_screen_process_key(struct nc_scr *scr, int key)
91 struct lang_screen *screen = lang_screen_from_scr(scr);
94 handled = widgetset_process_key(screen->widgetset, key);
106 screen->on_exit(screen->cui);
108 } else if (handled) {
113 static void lang_screen_resize(struct nc_scr *scr)
115 struct lang_screen *screen = lang_screen_from_scr(scr);
119 static int lang_screen_post(struct nc_scr *scr)
121 struct lang_screen *screen = lang_screen_from_scr(scr);
122 widgetset_post(screen->widgetset);
123 nc_scr_frame_draw(scr);
124 redrawwin(scr->main_ncw);
125 wrefresh(screen->scr.main_ncw);
130 static int lang_screen_unpost(struct nc_scr *scr)
132 struct lang_screen *screen = lang_screen_from_scr(scr);
133 widgetset_unpost(screen->widgetset);
137 struct nc_scr *lang_screen_scr(struct lang_screen *screen)
142 static int lang_process_form(struct lang_screen *screen)
144 struct config *config;
148 config = config_copy(screen, screen->cui->config);
150 idx = widget_select_get_value(screen->widgets.lang_f);
152 /* Option -1 ("Unknown") can only be populated from the current
153 * language, so there's no change here */
157 lang = &languages[idx];
159 if (config->lang && !strcmp(lang->name, config->lang))
162 config->lang = talloc_strdup(screen, lang->name);
164 config->safe_mode = false;
165 rc = cui_send_config(screen->cui, config);
169 pb_log("cui_send_config failed!\n");
171 pb_debug("config sent!\n");
176 static void ok_click(void *arg)
178 struct lang_screen *screen = arg;
179 if (lang_process_form(screen))
180 /* errors are written to the status line, so we'll need
182 wrefresh(screen->scr.main_ncw);
187 static void cancel_click(void *arg)
189 struct lang_screen *screen = arg;
193 static int layout_pair(struct lang_screen *screen, int y,
194 struct nc_widget_label *label,
195 struct nc_widget *field)
197 struct nc_widget *label_w = widget_label_base(label);
198 widget_move(label_w, y, screen->label_x);
199 widget_move(field, y, screen->field_x);
200 return max(widget_height(label_w), widget_height(field));
203 static void lang_screen_layout_widgets(struct lang_screen *screen)
209 y += layout_pair(screen, y, screen->widgets.lang_l,
210 widget_select_base(screen->widgets.lang_f));
214 if (screen->cui->config->safe_mode) {
215 widget_move(widget_label_base(screen->widgets.safe_mode),
220 widget_move(widget_button_base(screen->widgets.ok_b),
222 widget_move(widget_button_base(screen->widgets.cancel_b),
223 y, screen->field_x + 10);
226 static void lang_screen_setup_empty(struct lang_screen *screen)
228 widget_new_label(screen->widgetset, 2, screen->field_x,
229 _("Waiting for configuration data..."));
230 screen->widgets.cancel_b = widget_new_button(screen->widgetset,
231 4, screen->field_x, 6, _("Cancel"),
232 cancel_click, screen);
236 static void lang_screen_setup_widgets(struct lang_screen *screen,
237 const struct config *config)
239 struct nc_widgetset *set = screen->widgetset;
243 build_assert(sizeof(screen->widgets) / sizeof(struct widget *)
246 screen->widgets.lang_l = widget_new_label(set, 0, 0, _("Language"));
247 screen->widgets.lang_f = widget_new_select(set, 0, 0, 50);
251 for (i = 0; i < ARRAY_SIZE(languages); i++) {
252 struct lang *lang = &languages[i];
257 len = wcstombs(NULL, lang->label, 0);
259 label = talloc_array(screen, char, len + 1);
260 wcstombs(label, lang->label, len + 1);
262 selected = config->lang && !strcmp(lang->name, config->lang);
265 widget_select_add_option(screen->widgets.lang_f, i,
269 if (!found && config->lang) {
270 char *label = talloc_asprintf(screen,
271 _("Unknown language '%s'"), config->lang);
272 widget_select_add_option(screen->widgets.lang_f, -1,
276 if (config->safe_mode)
277 screen->widgets.safe_mode = widget_new_label(set, 0, 0,
278 _("Selecting 'OK' will exit safe mode"));
280 screen->widgets.ok_b = widget_new_button(set, 0, 0, 6, _("OK"),
282 screen->widgets.cancel_b = widget_new_button(set, 0, 0, 6, _("Cancel"),
283 cancel_click, screen);
286 static void lang_screen_widget_focus(struct nc_widget *widget, void *arg)
288 struct lang_screen *screen = arg;
291 w_y = widget_y(widget) + widget_focus_y(widget);
292 s_max = getmaxy(screen->scr.sub_ncw) - 1;
294 if (w_y < screen->scroll_y)
295 screen->scroll_y = w_y;
297 else if (w_y + screen->scroll_y + 1 > s_max)
298 screen->scroll_y = 1 + w_y - s_max;
306 static void lang_screen_draw(struct lang_screen *screen,
307 const struct config *config)
312 height = ARRAY_SIZE(languages) + 4;
313 if (!screen->pad || getmaxy(screen->pad) < height) {
316 screen->pad = newpad(height, COLS);
319 if (screen->widgetset) {
320 widgetset_unpost(screen->widgetset);
321 talloc_free(screen->widgetset);
325 screen->widgetset = widgetset_create(screen, screen->scr.main_ncw,
327 widgetset_set_widget_focus(screen->widgetset,
328 lang_screen_widget_focus, screen);
331 lang_screen_setup_empty(screen);
333 lang_screen_setup_widgets(screen, config);
334 lang_screen_layout_widgets(screen);
338 widgetset_post(screen->widgetset);
341 void lang_screen_update(struct lang_screen *screen,
342 const struct config *config)
344 lang_screen_draw(screen, config);
348 static int lang_screen_destroy(void *arg)
350 struct lang_screen *screen = arg;
356 struct lang_screen *lang_screen_init(struct cui *cui,
357 const struct config *config,
358 void (*on_exit)(struct cui *))
360 struct lang_screen *screen;
362 screen = talloc_zero(cui, struct lang_screen);
363 talloc_set_destructor(screen, lang_screen_destroy);
364 nc_scr_init(&screen->scr, pb_lang_screen_sig, 0,
365 cui, lang_screen_process_key,
366 lang_screen_post, lang_screen_unpost,
370 screen->on_exit = on_exit;
372 screen->field_x = 17;
374 screen->scr.frame.ltitle = talloc_strdup(screen,
375 _("Petitboot Language Selection"));
376 screen->scr.frame.rtitle = NULL;
377 screen->scr.frame.help = talloc_strdup(screen,
378 _("tab=next, shift+tab=previous, x=exit, h=help"));
379 nc_scr_frame_draw(&screen->scr);
381 scrollok(screen->scr.sub_ncw, true);
383 lang_screen_draw(screen, config);