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)
26 #include <talloc/talloc.h>
27 #include <types/types.h>
29 #include <i18n/i18n.h>
30 #include <pb-config/pb-config.h>
32 #include "ui/common/discover-client.h"
35 #include "nc-widgets.h"
43 { "de_DE.utf8", L"Deutsch"},
44 { "en_US.utf8", L"English"},
45 { "es_ES.utf8", L"Espa\u00f1ol"},
46 { "fr_FR.utf8", L"Fran\u00e7ais"},
47 { "it_IT.utf8", L"Italiano"},
48 { "ja_JP.utf8", L"\u65e5\u672c\u8a9e"},
49 { "ko_KR.utf8", L"\ud55c\uad6d\uc5b4"},
50 { "pt_BR.utf8", L"Portugu\u00eas/Brasil"},
51 { "ru_RU.utf8", L"\u0420\u0443\u0441\u0441\u043a\u0438\u0439"},
52 { "zh_CN.utf8", L"\u7b80\u4f53\u4e2d\u6587"},
53 { "zh_TW.utf8", L"\u7e41\u9ad4\u4e2d\u6587"},
59 struct nc_widgetset *widgetset;
63 void (*on_exit)(struct cui *);
71 struct nc_widget_select *lang_f;
72 struct nc_widget_label *lang_l;
74 struct nc_widget_label *save_l;
75 struct nc_widget_checkbox *save_cb;
77 struct nc_widget_label *safe_mode;
78 struct nc_widget_button *ok_b;
79 struct nc_widget_button *cancel_b;
83 static struct lang_screen *lang_screen_from_scr(struct nc_scr *scr)
85 struct lang_screen *lang_screen;
87 assert(scr->sig == pb_lang_screen_sig);
88 lang_screen = (struct lang_screen *)
89 ((char *)scr - (size_t)&((struct lang_screen *)0)->scr);
90 assert(lang_screen->scr.sig == pb_lang_screen_sig);
94 static void pad_refresh(struct lang_screen *screen)
98 getmaxyx(screen->scr.sub_ncw, rows, cols);
99 getbegyx(screen->scr.sub_ncw, y, x);
101 prefresh(screen->pad, screen->scroll_y, 0, y, x, rows, cols);
104 static void lang_screen_process_key(struct nc_scr *scr, int key)
106 struct lang_screen *screen = lang_screen_from_scr(scr);
109 handled = widgetset_process_key(screen->widgetset, key);
121 screen->on_exit(screen->cui);
122 } else if (handled && (screen->cui->current == scr)) {
127 static const char *lang_get_lang_name(struct lang_screen *screen)
132 idx = widget_select_get_value(screen->widgets.lang_f);
134 /* Option -1 ("Unknown") can only be populated from the current
135 * language, so there's no change here */
139 lang = &languages[idx];
144 static int lang_process_form(struct lang_screen *screen)
146 struct config *config;
150 config = config_copy(screen, screen->cui->config);
152 lang = lang_get_lang_name(screen);
154 if (!lang || (config->lang && !strcmp(lang, config->lang)))
157 config->lang = talloc_strdup(screen, lang);
159 config->safe_mode = false;
160 rc = cui_send_config(screen->cui, config);
164 pb_log("cui_send_config failed!\n");
166 pb_debug("config sent!\n");
171 static void lang_screen_resize(struct nc_scr *scr)
173 struct lang_screen *screen = lang_screen_from_scr(scr);
177 static int lang_screen_post(struct nc_scr *scr)
179 struct lang_screen *screen = lang_screen_from_scr(scr);
182 screen->on_exit(screen->cui);
184 widgetset_post(screen->widgetset);
185 nc_scr_frame_draw(scr);
186 wrefresh(screen->scr.main_ncw);
191 static int lang_screen_unpost(struct nc_scr *scr)
193 struct lang_screen *screen = lang_screen_from_scr(scr);
194 widgetset_unpost(screen->widgetset);
198 struct nc_scr *lang_screen_scr(struct lang_screen *screen)
203 static void lang_screen_update_cb(struct nc_scr *scr)
205 struct lang_screen *screen = lang_screen_from_scr(scr);
207 if (!lang_process_form(screen))
211 static void ok_click(void *arg)
213 struct lang_screen *screen = arg;
216 if (!widget_checkbox_get_value(screen->widgets.save_cb)) {
217 /* Just update the client display */
218 lang = lang_get_lang_name(screen);
220 cui_update_language(screen->cui, lang);
225 if (discover_client_authenticated(screen->cui->client)) {
226 if (lang_process_form(screen))
227 /* errors are written to the status line, so we'll need
229 wrefresh(screen->scr.main_ncw);
233 cui_show_auth(screen->cui, screen->scr.main_ncw, false,
234 lang_screen_update_cb);
238 static void cancel_click(void *arg)
240 struct lang_screen *screen = arg;
244 static int layout_pair(struct lang_screen *screen, int y,
245 struct nc_widget_label *label,
246 struct nc_widget *field)
248 struct nc_widget *label_w = widget_label_base(label);
249 widget_move(label_w, y, screen->label_x);
250 widget_move(field, y, screen->field_x);
251 return max(widget_height(label_w), widget_height(field));
254 static void lang_screen_layout_widgets(struct lang_screen *screen)
260 y += layout_pair(screen, y, screen->widgets.lang_l,
261 widget_select_base(screen->widgets.lang_f));
265 y += layout_pair(screen, y, screen->widgets.save_l,
266 widget_checkbox_base(screen->widgets.save_cb));
269 if (screen->cui->config->safe_mode) {
270 widget_move(widget_label_base(screen->widgets.safe_mode),
275 widget_move(widget_button_base(screen->widgets.ok_b),
277 widget_move(widget_button_base(screen->widgets.cancel_b),
278 y, screen->field_x + 14);
281 static void lang_screen_setup_empty(struct lang_screen *screen)
283 widget_new_label(screen->widgetset, 2, screen->field_x,
284 _("Waiting for configuration data..."));
285 screen->widgets.cancel_b = widget_new_button(screen->widgetset,
286 4, screen->field_x, 9, _("Cancel"),
287 cancel_click, screen);
291 static void lang_screen_setup_widgets(struct lang_screen *screen,
292 const struct config *config)
294 struct nc_widgetset *set = screen->widgetset;
298 build_assert(sizeof(screen->widgets) / sizeof(struct widget *)
301 screen->widgets.lang_l = widget_new_label(set, 0, 0, _("Language"));
302 screen->widgets.lang_f = widget_new_select(set, 0, 0, 50);
306 for (i = 0; i < ARRAY_SIZE(languages); i++) {
307 struct lang *lang = &languages[i];
312 len = wcstombs(NULL, lang->label, 0);
315 label = talloc_asprintf(screen,
316 "Unable to display text in this locale (%s)\n",
317 setlocale(LC_ALL, NULL));
319 label = talloc_array(screen, char, len + 1);
320 wcstombs(label, lang->label, len + 1);
323 selected = config->lang && !strcmp(lang->name, config->lang);
326 widget_select_add_option(screen->widgets.lang_f, i,
330 if (!found && config->lang) {
331 char *label = talloc_asprintf(screen,
332 _("Unknown language '%s'"), config->lang);
333 widget_select_add_option(screen->widgets.lang_f, -1,
337 screen->widgets.save_l = widget_new_label(set, 0, 0,
339 screen->widgets.save_cb = widget_new_checkbox(set, 0, 0, false);
341 if (config->safe_mode)
342 screen->widgets.safe_mode = widget_new_label(set, 0, 0,
343 _("Selecting 'OK' will exit safe mode"));
345 screen->widgets.ok_b = widget_new_button(set, 0, 0, 10, _("OK"),
347 screen->widgets.cancel_b = widget_new_button(set, 0, 0, 10, _("Cancel"),
348 cancel_click, screen);
351 static void lang_screen_widget_focus(struct nc_widget *widget, void *arg)
353 struct lang_screen *screen = arg;
356 w_y = widget_y(widget) + widget_focus_y(widget);
357 s_max = getmaxy(screen->scr.sub_ncw) - 1;
359 if (w_y < screen->scroll_y)
360 screen->scroll_y = w_y;
362 else if (w_y + screen->scroll_y + 1 > s_max)
363 screen->scroll_y = 1 + w_y - s_max;
371 static void lang_screen_draw(struct lang_screen *screen,
372 const struct config *config)
377 height = ARRAY_SIZE(languages) + N_FIELDS + 4;
378 if (!screen->pad || getmaxy(screen->pad) < height) {
381 screen->pad = newpad(height, COLS);
384 if (screen->widgetset) {
385 widgetset_unpost(screen->widgetset);
386 talloc_free(screen->widgetset);
390 screen->widgetset = widgetset_create(screen, screen->scr.main_ncw,
392 widgetset_set_widget_focus(screen->widgetset,
393 lang_screen_widget_focus, screen);
396 lang_screen_setup_empty(screen);
398 lang_screen_setup_widgets(screen, config);
399 lang_screen_layout_widgets(screen);
403 widgetset_post(screen->widgetset);
406 void lang_screen_update(struct lang_screen *screen,
407 const struct config *config)
409 lang_screen_draw(screen, config);
413 static int lang_screen_destroy(void *arg)
415 struct lang_screen *screen = arg;
421 struct lang_screen *lang_screen_init(struct cui *cui,
422 const struct config *config,
423 void (*on_exit)(struct cui *))
425 struct lang_screen *screen;
427 screen = talloc_zero(cui, struct lang_screen);
428 talloc_set_destructor(screen, lang_screen_destroy);
429 nc_scr_init(&screen->scr, pb_lang_screen_sig, 0,
430 cui, lang_screen_process_key,
431 lang_screen_post, lang_screen_unpost,
435 screen->on_exit = on_exit;
437 screen->field_x = 17;
439 screen->scr.frame.ltitle = talloc_strdup(screen,
440 _("Petitboot Language Selection"));
441 screen->scr.frame.rtitle = NULL;
442 screen->scr.frame.help = talloc_strdup(screen,
443 _("tab=next, shift+tab=previous, x=exit"));
444 nc_scr_frame_draw(&screen->scr);
446 scrollok(screen->scr.sub_ncw, true);
448 lang_screen_draw(screen, config);