All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH 0/6] efi_loader: Unicode output in UEFI applications
@ 2021-02-27 13:08 Heinrich Schuchardt
  2021-02-27 13:08 ` [PATCH 1/6] efi_loader: move codepage 437 table Heinrich Schuchardt
                   ` (5 more replies)
  0 siblings, 6 replies; 7+ messages in thread
From: Heinrich Schuchardt @ 2021-02-27 13:08 UTC (permalink / raw)
  To: u-boot

UEFI programs use Unicode for console output, e.g. GRUB uses characters
from the 0x2500 code block to draw a box around the menu.

The video console does not understand the UTF-8 codes and renders each byte
individually.

The series adds the necessary conversions both for the TrueType as well as
for the normal and rotated consoles which only support code page 437.

Signed-off-by: Heinrich Schuchardt <xypron.glpk@gmx.de>

Heinrich Schuchardt (6):
  efi_loader: move codepage 437 table
  efi_loader: carve out utf_to_cp()
  lib/charset: utf8_get() should return error
  lib/charset: UTF-8 stream conversion
  video: use int for character in putc_xy()
  video: support Unicode in video console

 drivers/video/console_normal.c         |   2 +-
 drivers/video/console_rotate.c         |   6 +-
 drivers/video/console_truetype.c       |   2 +-
 drivers/video/vidconsole-uclass.c      |  29 ++++++-
 include/charset.h                      |  34 ++++++++
 include/video_console.h                |   4 +-
 lib/charset.c                          |  96 +++++++++++++++++++--
 lib/efi_loader/efi_unicode_collation.c |  21 +----
 test/unicode_ut.c                      | 114 +++++++++++++++++++++++++
 9 files changed, 271 insertions(+), 37 deletions(-)

--
2.30.0

^ permalink raw reply	[flat|nested] 7+ messages in thread

* [PATCH 1/6] efi_loader: move codepage 437 table
  2021-02-27 13:08 [PATCH 0/6] efi_loader: Unicode output in UEFI applications Heinrich Schuchardt
@ 2021-02-27 13:08 ` Heinrich Schuchardt
  2021-02-27 13:08 ` [PATCH 2/6] efi_loader: carve out utf_to_cp() Heinrich Schuchardt
                   ` (4 subsequent siblings)
  5 siblings, 0 replies; 7+ messages in thread
From: Heinrich Schuchardt @ 2021-02-27 13:08 UTC (permalink / raw)
  To: u-boot

Move the Unicode to codepage 437 table to charset.c

Signed-off-by: Heinrich Schuchardt <xypron.glpk@gmx.de>
---
 include/charset.h                      | 5 +++++
 lib/charset.c                          | 6 ++++++
 lib/efi_loader/efi_unicode_collation.c | 2 +-
 3 files changed, 12 insertions(+), 1 deletion(-)

diff --git a/include/charset.h b/include/charset.h
index cc650a2ce7..64ba91f791 100644
--- a/include/charset.h
+++ b/include/charset.h
@@ -13,6 +13,11 @@

 #define MAX_UTF8_PER_UTF16 3

+/**
+ * codepage_437 - Unicode to codepage 437 translation table
+ */
+extern const u16 codepage_437[128];
+
 /**
  * console_read_unicode() - read Unicode code point from console
  *
diff --git a/lib/charset.c b/lib/charset.c
index 2177014ee1..814847d165 100644
--- a/lib/charset.c
+++ b/lib/charset.c
@@ -8,9 +8,15 @@
 #include <common.h>
 #include <charset.h>
 #include <capitalization.h>
+#include <cp437.h>
 #include <efi_loader.h>
 #include <malloc.h>

+/**
+ * codepage_437 - Unicode to codepage 437 translation table
+ */
+const u16 codepage_437[128] = CP437;
+
 static struct capitalization_table capitalization_table[] =
 #ifdef CONFIG_EFI_UNICODE_CAPITALIZATION
 	UNICODE_CAPITALIZATION_TABLE;
diff --git a/lib/efi_loader/efi_unicode_collation.c b/lib/efi_loader/efi_unicode_collation.c
index f6c875bc33..bf5314c4ff 100644
--- a/lib/efi_loader/efi_unicode_collation.c
+++ b/lib/efi_loader/efi_unicode_collation.c
@@ -23,7 +23,7 @@ static const char illegal[] = "+,<=>:;\"/\\|?*[]\x7f";
 static const u16 codepage[] = CP1250;
 #else
 /* Unicode code points for code page 437 characters 0x80 - 0xff */
-static const u16 codepage[] = CP437;
+static const u16 *codepage = codepage_437;
 #endif

 /* GUID of the EFI_UNICODE_COLLATION_PROTOCOL2 */
--
2.30.0

^ permalink raw reply related	[flat|nested] 7+ messages in thread

* [PATCH 2/6] efi_loader: carve out utf_to_cp()
  2021-02-27 13:08 [PATCH 0/6] efi_loader: Unicode output in UEFI applications Heinrich Schuchardt
  2021-02-27 13:08 ` [PATCH 1/6] efi_loader: move codepage 437 table Heinrich Schuchardt
@ 2021-02-27 13:08 ` Heinrich Schuchardt
  2021-02-27 13:08 ` [PATCH 3/6] lib/charset: utf8_get() should return error Heinrich Schuchardt
                   ` (3 subsequent siblings)
  5 siblings, 0 replies; 7+ messages in thread
From: Heinrich Schuchardt @ 2021-02-27 13:08 UTC (permalink / raw)
  To: u-boot

Carve out a function to translate a Unicode code point to an 8bit codepage.

Provide a unit test for the new function.

Signed-off-by: Heinrich Schuchardt <xypron.glpk@gmx.de>
---
 include/charset.h                      | 11 ++++++++++
 lib/charset.c                          | 28 +++++++++++++++++++++++++
 lib/efi_loader/efi_unicode_collation.c | 19 +++--------------
 test/unicode_ut.c                      | 29 ++++++++++++++++++++++++++
 4 files changed, 71 insertions(+), 16 deletions(-)

diff --git a/include/charset.h b/include/charset.h
index 64ba91f791..52e7d1474e 100644
--- a/include/charset.h
+++ b/include/charset.h
@@ -275,4 +275,15 @@ u16 *u16_strdup(const void *src);
  */
 uint8_t *utf16_to_utf8(uint8_t *dest, const uint16_t *src, size_t size);

+/**
+ * utf_to_cp() - translate Unicode code point to 8bit codepage
+ *
+ * Codepoints that do not exist in the codepage are rendered as question mark.
+ *
+ * @c:		pointer to Unicode code point to be translated
+ * @codepage:	Unicode to codepage translation table
+ * Return:	0 on success, -ENOENT if codepoint cannot be translated
+ */
+int utf_to_cp(s32 *c, const u16 *codepage);
+
 #endif /* __CHARSET_H_ */
diff --git a/lib/charset.c b/lib/charset.c
index 814847d165..1345c8f9f0 100644
--- a/lib/charset.c
+++ b/lib/charset.c
@@ -10,6 +10,7 @@
 #include <capitalization.h>
 #include <cp437.h>
 #include <efi_loader.h>
+#include <errno.h>
 #include <malloc.h>

 /**
@@ -472,3 +473,30 @@ uint8_t *utf16_to_utf8(uint8_t *dest, const uint16_t *src, size_t size)

 	return dest;
 }
+
+/**
+ * utf_to_cp() - translate Unicode code point to 8bit codepage
+ *
+ * Codepoints that do not exist in the codepage are rendered as question mark.
+ *
+ * @c:		pointer to Unicode code point to be translated
+ * @codepage:	Unicode to codepage translation table
+ * Return:	0 on success, -ENOENT if codepoint cannot be translated
+ */
+int utf_to_cp(s32 *c, const u16 *codepage)
+{
+	if (*c >= 0x80) {
+		int j;
+
+		/* Look up codepage translation */
+		for (j = 0; j < 0x80; ++j) {
+			if (*c == codepage[j]) {
+				*c = j + 0x80;
+				return 0;
+			}
+		}
+		*c = '?';
+		return -ENOENT;
+	}
+	return 0;
+}
diff --git a/lib/efi_loader/efi_unicode_collation.c b/lib/efi_loader/efi_unicode_collation.c
index bf5314c4ff..36be798f64 100644
--- a/lib/efi_loader/efi_unicode_collation.c
+++ b/lib/efi_loader/efi_unicode_collation.c
@@ -300,23 +300,10 @@ static bool EFIAPI efi_str_to_fat(struct efi_unicode_collation_protocol *this,
 			break;
 		}
 		c = utf_to_upper(c);
-		if (c >= 0x80) {
-			int j;
-
-			/* Look for codepage translation */
-			for (j = 0; j < 0x80; ++j) {
-				if (c == codepage[j]) {
-					c = j + 0x80;
-					break;
-				}
-			}
-			if (j >= 0x80) {
-				c = '_';
-				ret = true;
-			}
-		} else if (c && (c < 0x20 || strchr(illegal, c))) {
-			c = '_';
+		if (utf_to_cp(&c, codepage) ||
+		    (c && (c < 0x20 || strchr(illegal, c)))) {
 			ret = true;
+			c = '_';
 		}

 		fat[i] = c;
diff --git a/test/unicode_ut.c b/test/unicode_ut.c
index 6130ef0b54..2cc6b5feff 100644
--- a/test/unicode_ut.c
+++ b/test/unicode_ut.c
@@ -595,6 +595,35 @@ static int unicode_test_u16_strsize(struct unit_test_state *uts)
 }
 UNICODE_TEST(unicode_test_u16_strsize);

+static int unicode_test_utf_to_cp(struct unit_test_state *uts)
+{
+	int ret;
+	s32 c;
+
+	c = '\n';
+	ret = utf_to_cp(&c, codepage_437);
+	ut_asserteq(0, ret);
+	ut_asserteq('\n', c);
+
+	c = 'a';
+	ret = utf_to_cp(&c, codepage_437);
+	ut_asserteq(0, ret);
+	ut_asserteq('a', c);
+
+	c = 0x03c4; /* Greek small letter tau */
+	ret = utf_to_cp(&c, codepage_437);
+	ut_asserteq(0, ret);
+	ut_asserteq(0xe7, c);
+
+	c = 0x03a4; /* Greek capital letter tau */
+	ret = utf_to_cp(&c, codepage_437);
+	ut_asserteq(-ENOENT, ret);
+	ut_asserteq('?', c);
+
+	return 0;
+}
+UNICODE_TEST(unicode_test_utf_to_cp);
+
 #ifdef CONFIG_EFI_LOADER
 static int unicode_test_efi_create_indexed_name(struct unit_test_state *uts)
 {
--
2.30.0

^ permalink raw reply related	[flat|nested] 7+ messages in thread

* [PATCH 3/6] lib/charset: utf8_get() should return error
  2021-02-27 13:08 [PATCH 0/6] efi_loader: Unicode output in UEFI applications Heinrich Schuchardt
  2021-02-27 13:08 ` [PATCH 1/6] efi_loader: move codepage 437 table Heinrich Schuchardt
  2021-02-27 13:08 ` [PATCH 2/6] efi_loader: carve out utf_to_cp() Heinrich Schuchardt
@ 2021-02-27 13:08 ` Heinrich Schuchardt
  2021-02-27 13:08 ` [PATCH 4/6] lib/charset: UTF-8 stream conversion Heinrich Schuchardt
                   ` (2 subsequent siblings)
  5 siblings, 0 replies; 7+ messages in thread
From: Heinrich Schuchardt @ 2021-02-27 13:08 UTC (permalink / raw)
  To: u-boot

utf8_get() should return an error if hitting an illegal UTF-8 sequence and
not silently convert the input to a question mark.

Correct utf_8() and the its unit test.

console_read_unicode() now will ignore illegal UTF-8 sequences.

Signed-off-by: Heinrich Schuchardt <xypron.glpk@gmx.de>
---
 lib/charset.c     | 25 ++++++++++++++++---------
 test/unicode_ut.c |  7 +++++++
 2 files changed, 23 insertions(+), 9 deletions(-)

diff --git a/lib/charset.c b/lib/charset.c
index 1345c8f9f0..946d5ee23e 100644
--- a/lib/charset.c
+++ b/lib/charset.c
@@ -32,7 +32,7 @@ static struct capitalization_table capitalization_table[] =
  *
  * @read_u8:	- stream reader
  * @src:	- string buffer passed to stream reader, optional
- * Return:	- Unicode code point
+ * Return:	- Unicode code point, or -1
  */
 static int get_code(u8 (*read_u8)(void *data), void *data)
 {
@@ -78,7 +78,7 @@ static int get_code(u8 (*read_u8)(void *data), void *data)
 	}
 	return ch;
 error:
-	return '?';
+	return -1;
 }

 /**
@@ -120,14 +120,21 @@ static u8 read_console(void *data)

 int console_read_unicode(s32 *code)
 {
-	if (!tstc()) {
-		/* No input available */
-		return 1;
-	}
+	for (;;) {
+		s32 c;

-	/* Read Unicode code */
-	*code = get_code(read_console, NULL);
-	return 0;
+		if (!tstc()) {
+			/* No input available */
+			return 1;
+		}
+
+		/* Read Unicode code */
+		c = get_code(read_console, NULL);
+		if (c > 0) {
+			*code = c;
+			return 0;
+		}
+	}
 }

 s32 utf8_get(const char **src)
diff --git a/test/unicode_ut.c b/test/unicode_ut.c
index 2cc6b5feff..154361aea7 100644
--- a/test/unicode_ut.c
+++ b/test/unicode_ut.c
@@ -52,6 +52,7 @@ static const char d4[] = {0xf0, 0x90, 0x92, 0x8d, 0xf0, 0x90, 0x92, 0x96,
 static const char j1[] = {0x6a, 0x31, 0xa1, 0x6c, 0x00};
 static const char j2[] = {0x6a, 0x32, 0xc3, 0xc3, 0x6c, 0x00};
 static const char j3[] = {0x6a, 0x33, 0xf0, 0x90, 0xf0, 0x00};
+static const char j4[] = {0xa1, 0x00};

 static int unicode_test_u16_strlen(struct unit_test_state *uts)
 {
@@ -165,6 +166,12 @@ static int unicode_test_utf8_get(struct unit_test_state *uts)
 	ut_asserteq(0x0001048d, code);
 	ut_asserteq_ptr(s, d4 + 4);

+	/* Check illegal character */
+	s = j4;
+	code = utf8_get((const char **)&s);
+	ut_asserteq(-1, code);
+	ut_asserteq_ptr(j4 + 1, s);
+
 	return 0;
 }
 UNICODE_TEST(unicode_test_utf8_get);
--
2.30.0

^ permalink raw reply related	[flat|nested] 7+ messages in thread

* [PATCH 4/6] lib/charset: UTF-8 stream conversion
  2021-02-27 13:08 [PATCH 0/6] efi_loader: Unicode output in UEFI applications Heinrich Schuchardt
                   ` (2 preceding siblings ...)
  2021-02-27 13:08 ` [PATCH 3/6] lib/charset: utf8_get() should return error Heinrich Schuchardt
@ 2021-02-27 13:08 ` Heinrich Schuchardt
  2021-02-27 13:08 ` [PATCH 5/6] video: use int for character in putc_xy() Heinrich Schuchardt
  2021-02-27 13:08 ` [PATCH 6/6] video: support Unicode in video console Heinrich Schuchardt
  5 siblings, 0 replies; 7+ messages in thread
From: Heinrich Schuchardt @ 2021-02-27 13:08 UTC (permalink / raw)
  To: u-boot

Provide functions to convert an UTF-8 stream to code page 437 or UTF-32.

Add unit tests.

Signed-off-by: Heinrich Schuchardt <xypron.glpk@gmx.de>
---
 include/charset.h | 18 +++++++++++
 lib/charset.c     | 55 +++++++++++++++++++++++++++------
 test/unicode_ut.c | 78 +++++++++++++++++++++++++++++++++++++++++++++++
 3 files changed, 142 insertions(+), 9 deletions(-)

diff --git a/include/charset.h b/include/charset.h
index 52e7d1474e..a911160f19 100644
--- a/include/charset.h
+++ b/include/charset.h
@@ -286,4 +286,22 @@ uint8_t *utf16_to_utf8(uint8_t *dest, const uint16_t *src, size_t size);
  */
 int utf_to_cp(s32 *c, const u16 *codepage);

+/**
+ * utf8_to_cp437_stream() - convert UTF-8 stream to codepage 437
+ *
+ * @c:		next UTF-8 character to convert
+ * @buffer:	buffer, at least 5 characters
+ * Return:	next codepage 437 character or 0
+ */
+int utf8_to_cp437_stream(u8 c, char *buffer);
+
+/**
+ * utf8_to_utf32_stream() - convert UTF-8 stream to UTF-32
+ *
+ * @c:		next UTF-8 character to convert
+ * @buffer:	buffer, at least 5 characters
+ * Return:	next codepage 437 character or 0
+ */
+int utf8_to_utf32_stream(u8 c, char *buffer);
+
 #endif /* __CHARSET_H_ */
diff --git a/lib/charset.c b/lib/charset.c
index 946d5ee23e..f44c58d9d8 100644
--- a/lib/charset.c
+++ b/lib/charset.c
@@ -481,15 +481,6 @@ uint8_t *utf16_to_utf8(uint8_t *dest, const uint16_t *src, size_t size)
 	return dest;
 }

-/**
- * utf_to_cp() - translate Unicode code point to 8bit codepage
- *
- * Codepoints that do not exist in the codepage are rendered as question mark.
- *
- * @c:		pointer to Unicode code point to be translated
- * @codepage:	Unicode to codepage translation table
- * Return:	0 on success, -ENOENT if codepoint cannot be translated
- */
 int utf_to_cp(s32 *c, const u16 *codepage)
 {
 	if (*c >= 0x80) {
@@ -507,3 +498,49 @@ int utf_to_cp(s32 *c, const u16 *codepage)
 	}
 	return 0;
 }
+
+int utf8_to_cp437_stream(u8 c, char *buffer)
+{
+	char *end;
+	const char *pos;
+	s32 s;
+	int ret;
+
+	for (;;) {
+		pos = buffer;
+		end = buffer + strlen(buffer);
+		*end++ = c;
+		*end = 0;
+		s = utf8_get(&pos);
+		if (s > 0) {
+			*buffer = 0;
+			ret = utf_to_cp(&s, codepage_437);
+			return s;
+			}
+		if (pos == end)
+			return 0;
+		*buffer = 0;
+	}
+}
+
+int utf8_to_utf32_stream(u8 c, char *buffer)
+{
+	char *end;
+	const char *pos;
+	s32 s;
+
+	for (;;) {
+		pos = buffer;
+		end = buffer + strlen(buffer);
+		*end++ = c;
+		*end = 0;
+		s = utf8_get(&pos);
+		if (s > 0) {
+			*buffer = 0;
+			return s;
+		}
+		if (pos == end)
+			return 0;
+		*buffer = 0;
+	}
+}
diff --git a/test/unicode_ut.c b/test/unicode_ut.c
index 154361aea7..6f6aea5f60 100644
--- a/test/unicode_ut.c
+++ b/test/unicode_ut.c
@@ -47,6 +47,9 @@ static const char d3[] = {0xe6, 0xbd, 0x9c, 0xe6, 0xb0, 0xb4, 0xe8, 0x89,
 /* Three letters translating to two utf-16 word each */
 static const char d4[] = {0xf0, 0x90, 0x92, 0x8d, 0xf0, 0x90, 0x92, 0x96,
 			  0xf0, 0x90, 0x92, 0x87, 0x00};
+/* Letter not in code page 437 */
+static const char d5[] = {0xCE, 0x92, 0x20, 0x69, 0x73, 0x20, 0x6E, 0x6F,
+			  0x74, 0x20, 0x42, 0x00};

 /* Illegal utf-8 strings */
 static const char j1[] = {0x6a, 0x31, 0xa1, 0x6c, 0x00};
@@ -631,6 +634,81 @@ static int unicode_test_utf_to_cp(struct unit_test_state *uts)
 }
 UNICODE_TEST(unicode_test_utf_to_cp);

+static void utf8_to_cp437_stream_helper(const char *in, char *out)
+{
+	char buffer[5];
+	int ret;
+
+	*buffer = 0;
+	for (; *in; ++in) {
+		ret = utf8_to_cp437_stream(*in, buffer);
+		if (ret)
+			*out++ = ret;
+	}
+	*out = 0;
+}
+
+static int unicode_test_utf8_to_cp437_stream(struct unit_test_state *uts)
+{
+	char buf[16];
+
+	utf8_to_cp437_stream_helper(d1, buf);
+	ut_asserteq_str("U-Boot", buf);
+	utf8_to_cp437_stream_helper(d2, buf);
+	ut_asserteq_str("kafb\xa0tur", buf);
+	utf8_to_cp437_stream_helper(d5, buf);
+	ut_asserteq_str("? is not B", buf);
+	utf8_to_cp437_stream_helper(j2, buf);
+	ut_asserteq_str("j2l", buf);
+
+	return 0;
+}
+UNICODE_TEST(unicode_test_utf8_to_cp437_stream);
+
+static void utf8_to_utf32_stream_helper(const char *in, s32 *out)
+{
+	char buffer[5];
+	int ret;
+
+	*buffer = 0;
+	for (; *in; ++in) {
+		ret = utf8_to_utf32_stream(*in, buffer);
+		if (ret)
+			*out++ = ret;
+	}
+	*out = 0;
+}
+
+static int unicode_test_utf8_to_utf32_stream(struct unit_test_state *uts)
+{
+	s32 buf[16];
+
+	const u32 u1[] = {0x55, 0x2D, 0x42, 0x6F, 0x6F, 0x74, 0x0000};
+	const u32 u2[] = {0x6B, 0x61, 0x66, 0x62, 0xE1, 0x74, 0x75, 0x72, 0x00};
+	const u32 u3[] = {0x0392, 0x20, 0x69, 0x73, 0x20, 0x6E, 0x6F, 0x74,
+			  0x20, 0x42, 0x00};
+	const u32 u4[] = {0x6A, 0x32, 0x6C, 0x00};
+
+	memset(buf, 0, sizeof(buf));
+	utf8_to_utf32_stream_helper(d1, buf);
+	ut_asserteq_mem(u1, buf, sizeof(u1));
+
+	memset(buf, 0, sizeof(buf));
+	utf8_to_utf32_stream_helper(d2, buf);
+	ut_asserteq_mem(u2, buf, sizeof(u2));
+
+	memset(buf, 0, sizeof(buf));
+	utf8_to_utf32_stream_helper(d5, buf);
+	ut_asserteq_mem(u3, buf, sizeof(u3));
+
+	memset(buf, 0, sizeof(buf));
+	utf8_to_utf32_stream_helper(j2, buf);
+	ut_asserteq_mem(u4, buf, sizeof(u4));
+
+	return 0;
+}
+UNICODE_TEST(unicode_test_utf8_to_utf32_stream);
+
 #ifdef CONFIG_EFI_LOADER
 static int unicode_test_efi_create_indexed_name(struct unit_test_state *uts)
 {
--
2.30.0

^ permalink raw reply related	[flat|nested] 7+ messages in thread

* [PATCH 5/6] video: use int for character in putc_xy()
  2021-02-27 13:08 [PATCH 0/6] efi_loader: Unicode output in UEFI applications Heinrich Schuchardt
                   ` (3 preceding siblings ...)
  2021-02-27 13:08 ` [PATCH 4/6] lib/charset: UTF-8 stream conversion Heinrich Schuchardt
@ 2021-02-27 13:08 ` Heinrich Schuchardt
  2021-02-27 13:08 ` [PATCH 6/6] video: support Unicode in video console Heinrich Schuchardt
  5 siblings, 0 replies; 7+ messages in thread
From: Heinrich Schuchardt @ 2021-02-27 13:08 UTC (permalink / raw)
  To: u-boot

The truetype console expects the character to be a Unicode code point. This
value cannot be passed as char. Use int instead.

Signed-off-by: Heinrich Schuchardt <xypron.glpk@gmx.de>
---
 drivers/video/console_normal.c    | 2 +-
 drivers/video/console_rotate.c    | 6 +++---
 drivers/video/console_truetype.c  | 2 +-
 drivers/video/vidconsole-uclass.c | 9 +++++++++
 include/video_console.h           | 2 +-
 5 files changed, 15 insertions(+), 6 deletions(-)

diff --git a/drivers/video/console_normal.c b/drivers/video/console_normal.c
index 04f022491e..9cfd11ae41 100644
--- a/drivers/video/console_normal.c
+++ b/drivers/video/console_normal.c
@@ -80,7 +80,7 @@ static int console_normal_move_rows(struct udevice *dev, uint rowdst,
 }

 static int console_normal_putc_xy(struct udevice *dev, uint x_frac, uint y,
-				  char ch)
+				  int ch)
 {
 	struct vidconsole_priv *vc_priv = dev_get_uclass_priv(dev);
 	struct udevice *vid = dev->parent;
diff --git a/drivers/video/console_rotate.c b/drivers/video/console_rotate.c
index 36c8d0609d..78ca36431f 100644
--- a/drivers/video/console_rotate.c
+++ b/drivers/video/console_rotate.c
@@ -86,7 +86,7 @@ static int console_move_rows_1(struct udevice *dev, uint rowdst, uint rowsrc,
 	return 0;
 }

-static int console_putc_xy_1(struct udevice *dev, uint x_frac, uint y, char ch)
+static int console_putc_xy_1(struct udevice *dev, uint x_frac, uint y, int ch)
 {
 	struct vidconsole_priv *vc_priv = dev_get_uclass_priv(dev);
 	struct udevice *vid = dev->parent;
@@ -221,7 +221,7 @@ static int console_move_rows_2(struct udevice *dev, uint rowdst, uint rowsrc,
 	return 0;
 }

-static int console_putc_xy_2(struct udevice *dev, uint x_frac, uint y, char ch)
+static int console_putc_xy_2(struct udevice *dev, uint x_frac, uint y, int ch)
 {
 	struct vidconsole_priv *vc_priv = dev_get_uclass_priv(dev);
 	struct udevice *vid = dev->parent;
@@ -362,7 +362,7 @@ static int console_move_rows_3(struct udevice *dev, uint rowdst, uint rowsrc,
 	return 0;
 }

-static int console_putc_xy_3(struct udevice *dev, uint x_frac, uint y, char ch)
+static int console_putc_xy_3(struct udevice *dev, uint x_frac, uint y, int ch)
 {
 	struct vidconsole_priv *vc_priv = dev_get_uclass_priv(dev);
 	struct udevice *vid = dev->parent;
diff --git a/drivers/video/console_truetype.c b/drivers/video/console_truetype.c
index fa11b3bbef..293b3a5ef4 100644
--- a/drivers/video/console_truetype.c
+++ b/drivers/video/console_truetype.c
@@ -198,7 +198,7 @@ static int console_truetype_move_rows(struct udevice *dev, uint rowdst,
 }

 static int console_truetype_putc_xy(struct udevice *dev, uint x, uint y,
-				    char ch)
+				    int ch)
 {
 	struct vidconsole_priv *vc_priv = dev_get_uclass_priv(dev);
 	struct udevice *vid = dev->parent;
diff --git a/drivers/video/vidconsole-uclass.c b/drivers/video/vidconsole-uclass.c
index 81b65f5aae..a355328851 100644
--- a/drivers/video/vidconsole-uclass.c
+++ b/drivers/video/vidconsole-uclass.c
@@ -8,6 +8,7 @@
  */

 #include <common.h>
+#include <charset.h>
 #include <command.h>
 #include <console.h>
 #include <log.h>
@@ -509,6 +510,14 @@ int vidconsole_put_char(struct udevice *dev, char ch)
 	struct vidconsole_priv *priv = dev_get_uclass_priv(dev);
 	int ret;

+	if (IS_ENABLED(CONFIG_EFI_LOADER)) {
+		static char buffer[5];
+
+		ch = utf8_to_cp437_stream(ch, buffer);
+		if (!ch)
+			return 0;
+	}
+
 	if (priv->escape) {
 		vidconsole_escape_char(dev, ch);
 		return 0;
diff --git a/include/video_console.h b/include/video_console.h
index 06b798ef10..5e6eb3cc81 100644
--- a/include/video_console.h
+++ b/include/video_console.h
@@ -106,7 +106,7 @@ struct vidconsole_ops {
 	 * if all is OK, -EAGAIN if we ran out of space on this line, other -ve
 	 * on error
 	 */
-	int (*putc_xy)(struct udevice *dev, uint x_frac, uint y, char ch);
+	int (*putc_xy)(struct udevice *dev, uint x_frac, uint y, int ch);

 	/**
 	 * move_rows() - Move text rows from one place to another
--
2.30.0

^ permalink raw reply related	[flat|nested] 7+ messages in thread

* [PATCH 6/6] video: support Unicode in video console
  2021-02-27 13:08 [PATCH 0/6] efi_loader: Unicode output in UEFI applications Heinrich Schuchardt
                   ` (4 preceding siblings ...)
  2021-02-27 13:08 ` [PATCH 5/6] video: use int for character in putc_xy() Heinrich Schuchardt
@ 2021-02-27 13:08 ` Heinrich Schuchardt
  5 siblings, 0 replies; 7+ messages in thread
From: Heinrich Schuchardt @ 2021-02-27 13:08 UTC (permalink / raw)
  To: u-boot

UEFI programs use Unicode for console output, e.g. GRUB uses characters
from the 0x2500 code block to draw a box around the menu.

The TrueType console supports UTF-32. The normal console supports code page
437. We have to convert the UTF-8 stream passed to putc() accordingly.

Signed-off-by: Heinrich Schuchardt <xypron.glpk@gmx.de>
---
 drivers/video/vidconsole-uclass.c | 22 +++++++++++++++++-----
 include/video_console.h           |  2 +-
 2 files changed, 18 insertions(+), 6 deletions(-)

diff --git a/drivers/video/vidconsole-uclass.c b/drivers/video/vidconsole-uclass.c
index a355328851..d5095f69e0 100644
--- a/drivers/video/vidconsole-uclass.c
+++ b/drivers/video/vidconsole-uclass.c
@@ -32,7 +32,7 @@ struct vid_rgb {
 #define CONFIG_CONSOLE_SCROLL_LINES 1
 #endif

-int vidconsole_putc_xy(struct udevice *dev, uint x, uint y, char ch)
+int vidconsole_putc_xy(struct udevice *dev, uint x, uint y, int ch)
 {
 	struct vidconsole_ops *ops = vidconsole_get_ops(dev);

@@ -479,8 +479,14 @@ error:
 	priv->escape = 0;
 }

-/* Put that actual character on the screen (using the CP437 code page). */
-static int vidconsole_output_glyph(struct udevice *dev, char ch)
+/*
+ * vidconsole_output_glyph() - put the actual character on the screen
+ *
+ * @dev:	video device
+ * @ch:		character: Unicode for Truetype, codepage 437 otherwise
+ * Return:	0 for success
+ */
+static int vidconsole_output_glyph(struct udevice *dev, int ch)
 {
 	struct vidconsole_priv *priv = dev_get_uclass_priv(dev);
 	int ret;
@@ -505,17 +511,23 @@ static int vidconsole_output_glyph(struct udevice *dev, char ch)
 	return 0;
 }

-int vidconsole_put_char(struct udevice *dev, char ch)
+int vidconsole_put_char(struct udevice *dev, char c)
 {
 	struct vidconsole_priv *priv = dev_get_uclass_priv(dev);
+	int ch;
 	int ret;

 	if (IS_ENABLED(CONFIG_EFI_LOADER)) {
 		static char buffer[5];

-		ch = utf8_to_cp437_stream(ch, buffer);
+		if (IS_ENABLED(CONFIG_CONSOLE_TRUETYPE))
+			ch = utf8_to_utf32_stream(c, buffer);
+		else
+			ch = utf8_to_cp437_stream(c, buffer);
 		if (!ch)
 			return 0;
+	} else {
+		ch = c;
 	}

 	if (priv->escape) {
diff --git a/include/video_console.h b/include/video_console.h
index 5e6eb3cc81..8747299d61 100644
--- a/include/video_console.h
+++ b/include/video_console.h
@@ -174,7 +174,7 @@ struct vidconsole_ops {
  * if all is OK, -EAGAIN if we ran out of space on this line, other -ve
  * on error
  */
-int vidconsole_putc_xy(struct udevice *dev, uint x, uint y, char ch);
+int vidconsole_putc_xy(struct udevice *dev, uint x, uint y, int ch);

 /**
  * vidconsole_move_rows() - Move text rows from one place to another
--
2.30.0

^ permalink raw reply related	[flat|nested] 7+ messages in thread

end of thread, other threads:[~2021-02-27 13:08 UTC | newest]

Thread overview: 7+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2021-02-27 13:08 [PATCH 0/6] efi_loader: Unicode output in UEFI applications Heinrich Schuchardt
2021-02-27 13:08 ` [PATCH 1/6] efi_loader: move codepage 437 table Heinrich Schuchardt
2021-02-27 13:08 ` [PATCH 2/6] efi_loader: carve out utf_to_cp() Heinrich Schuchardt
2021-02-27 13:08 ` [PATCH 3/6] lib/charset: utf8_get() should return error Heinrich Schuchardt
2021-02-27 13:08 ` [PATCH 4/6] lib/charset: UTF-8 stream conversion Heinrich Schuchardt
2021-02-27 13:08 ` [PATCH 5/6] video: use int for character in putc_xy() Heinrich Schuchardt
2021-02-27 13:08 ` [PATCH 6/6] video: support Unicode in video console Heinrich Schuchardt

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.