]> git.ozlabs.org Git - petitboot/blobdiff - ui/ncurses/nc-lang.c
ui/ncurses: Add nc-auth and authenticate when required.
[petitboot] / ui / ncurses / nc-lang.c
index 35f54e628456ce2a98af61947dc27addf92d5be7..91d86e10866d6ec362883bcade8a2995db6ed5cc 100644 (file)
@@ -21,6 +21,7 @@
 
 #include <stdlib.h>
 #include <string.h>
+#include <locale.h>
 
 #include <talloc/talloc.h>
 #include <types/types.h>
 #include <i18n/i18n.h>
 #include <pb-config/pb-config.h>
 
+#include "ui/common/discover-client.h"
 #include "nc-cui.h"
 #include "nc-lang.h"
 #include "nc-widgets.h"
 
-#define N_FIELDS       4
+#define N_FIELDS       7
 
 static struct lang {
        const char      *name;
        const wchar_t   *label;
 } languages[] = {
+       { "de_DE.utf8", L"Deutsch"},
        { "en_US.utf8", L"English"},
+       { "es_ES.utf8", L"Espa\u00f1ol"},
+       { "fr_FR.utf8", L"Fran\u00e7ais"},
+       { "it_IT.utf8", L"Italiano"},
+       { "ja_JP.utf8", L"\u65e5\u672c\u8a9e"},
+       { "ko_KR.utf8", L"\ud55c\uad6d\uc5b4"},
+       { "pt_BR.utf8", L"Portugu\u00eas/Brasil"},
+       { "ru_RU.utf8", L"\u0420\u0443\u0441\u0441\u043a\u0438\u0439"},
+       { "zh_CN.utf8", L"\u7b80\u4f53\u4e2d\u6587"},
+       { "zh_TW.utf8", L"\u7e41\u9ad4\u4e2d\u6587"},
 };
 
 struct lang_screen {
@@ -59,6 +71,10 @@ struct lang_screen {
                struct nc_widget_select         *lang_f;
                struct nc_widget_label          *lang_l;
 
+               struct nc_widget_label          *save_l;
+               struct nc_widget_checkbox       *save_cb;
+
+               struct nc_widget_label          *safe_mode;
                struct nc_widget_button         *ok_b;
                struct nc_widget_button         *cancel_b;
        } widgets;
@@ -103,12 +119,55 @@ static void lang_screen_process_key(struct nc_scr *scr, int key)
 
        if (screen->exit) {
                screen->on_exit(screen->cui);
-
-       } else if (handled) {
+       } else if (handled && (screen->cui->current == scr)) {
                pad_refresh(screen);
        }
 }
 
+static const char *lang_get_lang_name(struct lang_screen *screen)
+{
+       struct lang *lang;
+       int idx;
+
+       idx = widget_select_get_value(screen->widgets.lang_f);
+
+       /* Option -1 ("Unknown") can only be populated from the current
+        * language, so there's no change here */
+       if (idx == -1)
+               return NULL;
+
+       lang = &languages[idx];
+
+       return lang->name;
+}
+
+static int lang_process_form(struct lang_screen *screen)
+{
+       struct config *config;
+       const char *lang;
+       int rc;
+
+       config = config_copy(screen, screen->cui->config);
+
+       lang = lang_get_lang_name(screen);
+
+       if (!lang || (config->lang && !strcmp(lang, config->lang)))
+               return 0;
+
+       config->lang = talloc_strdup(screen, lang);
+
+       config->safe_mode = false;
+       rc = cui_send_config(screen->cui, config);
+       talloc_free(config);
+
+       if (rc)
+               pb_log("cui_send_config failed!\n");
+       else
+               pb_debug("config sent!\n");
+
+       return 0;
+}
+
 static void lang_screen_resize(struct nc_scr *scr)
 {
        struct lang_screen *screen = lang_screen_from_scr(scr);
@@ -118,9 +177,12 @@ static void lang_screen_resize(struct nc_scr *scr)
 static int lang_screen_post(struct nc_scr *scr)
 {
        struct lang_screen *screen = lang_screen_from_scr(scr);
+
+       if (screen->exit)
+               screen->on_exit(screen->cui);
+
        widgetset_post(screen->widgetset);
        nc_scr_frame_draw(scr);
-       redrawwin(scr->main_ncw);
        wrefresh(screen->scr.main_ncw);
        pad_refresh(screen);
        return 0;
@@ -138,48 +200,39 @@ struct nc_scr *lang_screen_scr(struct lang_screen *screen)
        return &screen->scr;
 }
 
-static int lang_process_form(struct lang_screen *screen)
+static void lang_screen_update_cb(struct nc_scr *scr)
 {
-       struct config *config;
-       struct lang *lang;
-       int idx, rc;
-
-       config = config_copy(screen, screen->cui->config);
-
-       idx = widget_select_get_value(screen->widgets.lang_f);
-
-       /* Option -1 ("Unknown") can only be populated from the current
-        * language, so there's no change here */
-       if (idx == -1)
-               return 0;
-
-       lang = &languages[idx];
-
-       if (config->lang && !strcmp(lang->name, config->lang))
-               return 0;
-
-       config->lang = talloc_strdup(screen, lang->name);
-
-       rc = cui_send_config(screen->cui, config);
-       talloc_free(config);
-
-       if (rc)
-               pb_log("cui_send_config failed!\n");
-       else
-               pb_debug("config sent!\n");
+       struct lang_screen *screen = lang_screen_from_scr(scr);
 
-       return 0;
+       if (!lang_process_form(screen))
+               screen->exit = true;
 }
 
 static void ok_click(void *arg)
 {
        struct lang_screen *screen = arg;
-       if (lang_process_form(screen))
-               /* errors are written to the status line, so we'll need
-                * to refresh */
-               wrefresh(screen->scr.main_ncw);
-       else
+       const char *lang;
+
+       if (!widget_checkbox_get_value(screen->widgets.save_cb)) {
+               /* Just update the client display */
+               lang = lang_get_lang_name(screen);
+               if (lang)
+                       cui_update_language(screen->cui, lang);
                screen->exit = true;
+               return;
+       }
+
+       if (discover_client_authenticated(screen->cui->client)) {
+               if (lang_process_form(screen))
+                       /* errors are written to the status line, so we'll need
+                        * to refresh */
+                       wrefresh(screen->scr.main_ncw);
+               else
+                       screen->exit = true;
+       } else {
+               cui_show_auth(screen->cui, screen->scr.main_ncw, false,
+                               lang_screen_update_cb);
+       }
 }
 
 static void cancel_click(void *arg)
@@ -209,10 +262,20 @@ static void lang_screen_layout_widgets(struct lang_screen *screen)
 
        y += 1;
 
+       y += layout_pair(screen, y, screen->widgets.save_l,
+                       widget_checkbox_base(screen->widgets.save_cb));
+       y += 1;
+
+       if (screen->cui->config->safe_mode) {
+               widget_move(widget_label_base(screen->widgets.safe_mode),
+                       y, screen->field_x);
+               y += 1;
+       }
+
        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);
+                       y, screen->field_x + 14);
 }
 
 static void lang_screen_setup_empty(struct lang_screen *screen)
@@ -220,7 +283,7 @@ static void lang_screen_setup_empty(struct lang_screen *screen)
        widget_new_label(screen->widgetset, 2, screen->field_x,
                        _("Waiting for configuration data..."));
        screen->widgets.cancel_b = widget_new_button(screen->widgetset,
-                       4, screen->field_x, 6, _("Cancel"),
+                       4, screen->field_x, 9, _("Cancel"),
                        cancel_click, screen);
 }
 
@@ -248,8 +311,14 @@ static void lang_screen_setup_widgets(struct lang_screen *screen,
 
                len = wcstombs(NULL, lang->label, 0);
                assert(len >= 0);
-               label = talloc_array(screen, char, len + 1);
-               wcstombs(label, lang->label, len + 1);
+               if (len < 0) {
+                       label = talloc_asprintf(screen,
+                               "Unable to display text in this locale (%s)\n",
+                               setlocale(LC_ALL, NULL));
+               } else {
+                       label = talloc_array(screen, char, len + 1);
+                       wcstombs(label, lang->label, len + 1);
+               }
 
                selected = config->lang && !strcmp(lang->name, config->lang);
                found |= selected;
@@ -265,9 +334,17 @@ static void lang_screen_setup_widgets(struct lang_screen *screen,
                                        label, true);
        }
 
-       screen->widgets.ok_b = widget_new_button(set, 0, 0, 6, _("OK"),
+       screen->widgets.save_l = widget_new_label(set, 0, 0,
+                       _("Save changes?"));
+       screen->widgets.save_cb = widget_new_checkbox(set, 0, 0, false);
+
+       if (config->safe_mode)
+               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, 10, _("OK"),
                        ok_click, screen);
-       screen->widgets.cancel_b = widget_new_button(set, 0, 0, 6, _("Cancel"),
+       screen->widgets.cancel_b = widget_new_button(set, 0, 0, 10, _("Cancel"),
                        cancel_click, screen);
 }
 
@@ -297,7 +374,7 @@ static void lang_screen_draw(struct lang_screen *screen,
        bool repost = false;
        int height;
 
-       height = ARRAY_SIZE(languages) + 4;
+       height = ARRAY_SIZE(languages) + N_FIELDS + 4;
        if (!screen->pad || getmaxy(screen->pad) < height) {
                if (screen->pad)
                        delwin(screen->pad);
@@ -363,7 +440,7 @@ struct lang_screen *lang_screen_init(struct cui *cui,
                        _("Petitboot Language Selection"));
        screen->scr.frame.rtitle = NULL;
        screen->scr.frame.help = talloc_strdup(screen,
-                       _("tab=next, shift+tab=previous, x=exit, h=help"));
+                       _("tab=next, shift+tab=previous, x=exit"));
        nc_scr_frame_draw(&screen->scr);
 
        scrollok(screen->scr.sub_ncw, true);