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_button *ok_b;
63 struct nc_widget_button *cancel_b;
67 static struct lang_screen *lang_screen_from_scr(struct nc_scr *scr)
69 struct lang_screen *lang_screen;
71 assert(scr->sig == pb_lang_screen_sig);
72 lang_screen = (struct lang_screen *)
73 ((char *)scr - (size_t)&((struct lang_screen *)0)->scr);
74 assert(lang_screen->scr.sig == pb_lang_screen_sig);
78 static void pad_refresh(struct lang_screen *screen)
82 getmaxyx(screen->scr.sub_ncw, rows, cols);
83 getbegyx(screen->scr.sub_ncw, y, x);
85 prefresh(screen->pad, screen->scroll_y, 0, y, x, rows, cols);
88 static void lang_screen_process_key(struct nc_scr *scr, int key)
90 struct lang_screen *screen = lang_screen_from_scr(scr);
93 handled = widgetset_process_key(screen->widgetset, key);
105 screen->on_exit(screen->cui);
107 } else if (handled) {
112 static void lang_screen_resize(struct nc_scr *scr)
114 struct lang_screen *screen = lang_screen_from_scr(scr);
118 static int lang_screen_post(struct nc_scr *scr)
120 struct lang_screen *screen = lang_screen_from_scr(scr);
121 widgetset_post(screen->widgetset);
122 nc_scr_frame_draw(scr);
123 redrawwin(scr->main_ncw);
124 wrefresh(screen->scr.main_ncw);
129 static int lang_screen_unpost(struct nc_scr *scr)
131 struct lang_screen *screen = lang_screen_from_scr(scr);
132 widgetset_unpost(screen->widgetset);
136 struct nc_scr *lang_screen_scr(struct lang_screen *screen)
141 static int lang_process_form(struct lang_screen *screen)
143 struct config *config;
147 config = config_copy(screen, screen->cui->config);
149 idx = widget_select_get_value(screen->widgets.lang_f);
151 /* Option -1 ("Unknown") can only be populated from the current
152 * language, so there's no change here */
156 lang = &languages[idx];
158 if (config->lang && !strcmp(lang->name, config->lang))
161 config->lang = talloc_strdup(screen, lang->name);
163 rc = cui_send_config(screen->cui, config);
167 pb_log("cui_send_config failed!\n");
169 pb_debug("config sent!\n");
174 static void ok_click(void *arg)
176 struct lang_screen *screen = arg;
177 if (lang_process_form(screen))
178 /* errors are written to the status line, so we'll need
180 wrefresh(screen->scr.main_ncw);
185 static void cancel_click(void *arg)
187 struct lang_screen *screen = arg;
191 static int layout_pair(struct lang_screen *screen, int y,
192 struct nc_widget_label *label,
193 struct nc_widget *field)
195 struct nc_widget *label_w = widget_label_base(label);
196 widget_move(label_w, y, screen->label_x);
197 widget_move(field, y, screen->field_x);
198 return max(widget_height(label_w), widget_height(field));
201 static void lang_screen_layout_widgets(struct lang_screen *screen)
207 y += layout_pair(screen, y, screen->widgets.lang_l,
208 widget_select_base(screen->widgets.lang_f));
212 widget_move(widget_button_base(screen->widgets.ok_b),
214 widget_move(widget_button_base(screen->widgets.cancel_b),
215 y, screen->field_x + 10);
218 static void lang_screen_setup_empty(struct lang_screen *screen)
220 widget_new_label(screen->widgetset, 2, screen->field_x,
221 _("Waiting for configuration data..."));
222 screen->widgets.cancel_b = widget_new_button(screen->widgetset,
223 4, screen->field_x, 6, _("Cancel"),
224 cancel_click, screen);
228 static void lang_screen_setup_widgets(struct lang_screen *screen,
229 const struct config *config)
231 struct nc_widgetset *set = screen->widgetset;
235 build_assert(sizeof(screen->widgets) / sizeof(struct widget *)
238 screen->widgets.lang_l = widget_new_label(set, 0, 0, _("Language"));
239 screen->widgets.lang_f = widget_new_select(set, 0, 0, 50);
243 for (i = 0; i < ARRAY_SIZE(languages); i++) {
244 struct lang *lang = &languages[i];
249 len = wcstombs(NULL, lang->label, 0);
251 label = talloc_array(screen, char, len + 1);
252 wcstombs(label, lang->label, len + 1);
254 selected = config->lang && !strcmp(lang->name, config->lang);
257 widget_select_add_option(screen->widgets.lang_f, i,
261 if (!found && config->lang) {
262 char *label = talloc_asprintf(screen,
263 _("Unknown language '%s'"), config->lang);
264 widget_select_add_option(screen->widgets.lang_f, -1,
268 screen->widgets.ok_b = widget_new_button(set, 0, 0, 6, _("OK"),
270 screen->widgets.cancel_b = widget_new_button(set, 0, 0, 6, _("Cancel"),
271 cancel_click, screen);
274 static void lang_screen_widget_focus(struct nc_widget *widget, void *arg)
276 struct lang_screen *screen = arg;
279 w_y = widget_y(widget) + widget_focus_y(widget);
280 s_max = getmaxy(screen->scr.sub_ncw) - 1;
282 if (w_y < screen->scroll_y)
283 screen->scroll_y = w_y;
285 else if (w_y + screen->scroll_y + 1 > s_max)
286 screen->scroll_y = 1 + w_y - s_max;
294 static void lang_screen_draw(struct lang_screen *screen,
295 const struct config *config)
300 height = ARRAY_SIZE(languages) + 4;
301 if (!screen->pad || getmaxy(screen->pad) < height) {
304 screen->pad = newpad(height, COLS);
307 if (screen->widgetset) {
308 widgetset_unpost(screen->widgetset);
309 talloc_free(screen->widgetset);
313 screen->widgetset = widgetset_create(screen, screen->scr.main_ncw,
315 widgetset_set_widget_focus(screen->widgetset,
316 lang_screen_widget_focus, screen);
319 lang_screen_setup_empty(screen);
321 lang_screen_setup_widgets(screen, config);
322 lang_screen_layout_widgets(screen);
326 widgetset_post(screen->widgetset);
329 void lang_screen_update(struct lang_screen *screen,
330 const struct config *config)
332 lang_screen_draw(screen, config);
336 static int lang_screen_destroy(void *arg)
338 struct lang_screen *screen = arg;
344 struct lang_screen *lang_screen_init(struct cui *cui,
345 const struct config *config,
346 void (*on_exit)(struct cui *))
348 struct lang_screen *screen;
350 screen = talloc_zero(cui, struct lang_screen);
351 talloc_set_destructor(screen, lang_screen_destroy);
352 nc_scr_init(&screen->scr, pb_lang_screen_sig, 0,
353 cui, lang_screen_process_key,
354 lang_screen_post, lang_screen_unpost,
358 screen->on_exit = on_exit;
360 screen->field_x = 17;
362 screen->scr.frame.ltitle = talloc_strdup(screen,
363 _("Petitboot Language Selection"));
364 screen->scr.frame.rtitle = NULL;
365 screen->scr.frame.help = talloc_strdup(screen,
366 _("tab=next, shift+tab=previous, x=exit, h=help"));
367 nc_scr_frame_draw(&screen->scr);
369 scrollok(screen->scr.sub_ncw, true);
371 lang_screen_draw(screen, config);