[PATCH] ui/ncurses: Display warning in nc-lang on VGA

Samuel Mendoza-Jonas sam at mendozajonas.com
Wed Mar 30 16:36:19 AEDT 2016


A basic VGA console has a 512 character font limit, however several
languages have more characters than this and will fail to display
properly. Detect in nc-lang if the current petitboot-nc instance is
running on a VGA console and display a warning in place of the language
name. Also display a warning if the currently set language is likely to
encounter issues on VGA.

Signed-off-by: Samuel Mendoza-Jonas <sam at mendozajonas.com>
---
I'd be much happier with a way to detect if text in the current locale will
display correctly in the current (VGA console) font rather than having a
static list of certain languages, but I haven't come across a solution so far.
Suggestions welcome!

 ui/ncurses/nc-lang.c | 58 +++++++++++++++++++++++++++++++++++++++++++++++++---
 1 file changed, 55 insertions(+), 3 deletions(-)

diff --git a/ui/ncurses/nc-lang.c b/ui/ncurses/nc-lang.c
index a7c9ccc..d7f37a3 100644
--- a/ui/ncurses/nc-lang.c
+++ b/ui/ncurses/nc-lang.c
@@ -33,7 +33,7 @@
 #include "nc-lang.h"
 #include "nc-widgets.h"
 
-#define N_FIELDS	5
+#define N_FIELDS	6
 
 static struct lang {
 	const char	*name;
@@ -70,12 +70,44 @@ struct lang_screen {
 		struct nc_widget_select		*lang_f;
 		struct nc_widget_label		*lang_l;
 
+		struct nc_widget_label		*lang_warning;
 		struct nc_widget_label		*safe_mode;
 		struct nc_widget_button		*ok_b;
 		struct nc_widget_button		*cancel_b;
 	} widgets;
 };
 
+/* Some languages can't be displayed on a raw VGA console due
+ * to limits on the size of the character set - make a note of these
+ * instead of displaying squares */
+static bool lang_displayable(const char *lang)
+{
+	const char *exceptions[] = {
+		"ja_JP.utf8",
+		"ko_KR.utf8",
+		"ru_RU.utf8",
+		"zh_CN.utf8",
+		"zh_TW.utf8",
+	};
+	const char *tty;
+	unsigned int i;
+
+	/* Default language always displays */
+	if (!lang)
+		return true;
+
+	tty = ttyname(STDIN_FILENO);
+
+	if (tty && strncmp(tty, "/dev/tty", strlen("/dev/tty")) != 0)
+		return true;
+
+	for (i = 0; i < ARRAY_SIZE(exceptions); i++)
+		if (strncmp(lang, exceptions[i], strlen(exceptions[i])) == 0)
+			return false;
+
+	return true;
+}
+
 static struct lang_screen *lang_screen_from_scr(struct nc_scr *scr)
 {
 	struct lang_screen *lang_screen;
@@ -227,6 +259,12 @@ static void lang_screen_layout_widgets(struct lang_screen *screen)
 		y += 1;
 	}
 
+	if (screen->widgets.lang_warning != NULL) {
+		widget_move(widget_label_base(screen->widgets.lang_warning),
+			y, 0);
+		y += 1;
+	}
+
 	widget_move(widget_button_base(screen->widgets.ok_b),
 			y, screen->field_x);
 	widget_move(widget_button_base(screen->widgets.cancel_b),
@@ -271,8 +309,14 @@ static void lang_screen_setup_widgets(struct lang_screen *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);
+			if (lang_displayable(lang->name)) {
+				label = talloc_array(screen, char, len + 1);
+				wcstombs(label, lang->label, len + 1);
+			} else {
+				label = talloc_asprintf(screen,
+					"%s not displayable on VGA console\n",
+					lang->name);
+			}
 		}
 
 		selected = config->lang && !strcmp(lang->name, config->lang);
@@ -292,6 +336,14 @@ static void lang_screen_setup_widgets(struct lang_screen *screen,
 	if (config->safe_mode)
 		screen->widgets.safe_mode = widget_new_label(set, 0, 0,
 			 _("Selecting 'OK' will exit safe mode"));
+	if (!lang_displayable(config->lang)) {
+		char *label =  talloc_asprintf(screen,
+				"Warning: the current language '%s' may not "
+				"display correctly on VGA", config->lang);
+		screen->widgets.lang_warning = widget_new_label(set, 0, 0,
+								label);
+	} else
+		screen->widgets.lang_warning = NULL;
 
 	screen->widgets.ok_b = widget_new_button(set, 0, 0, 10, _("OK"),
 			ok_click, screen);
-- 
2.7.4



More information about the Petitboot mailing list