* [Qemu-devel] [PATCHv3 0/2] ui/curses: BSD portability fixes
@ 2019-04-27 16:30 ` Samuel Thibault
0 siblings, 0 replies; 13+ messages in thread
From: Samuel Thibault @ 2019-04-27 16:30 UTC (permalink / raw)
To: qemu-devel; +Cc: Samuel Thibault, kraxel, kamil
BSD needs a few fixes for wide character manipulations.
Difference with v1:
- Fix unitialized value in error message
Difference with v2:
- Add cchar_t manipulation fix
Samuel Thibault (2):
ui/curses: do not assume wchar_t contains unicode
ui/curses: manipulate cchar_t with standard curses functions
ui/curses.c | 188 +++++++++++++++++++++++++++++++++-------------------
1 file changed, 120 insertions(+), 68 deletions(-)
--
2.20.1
^ permalink raw reply [flat|nested] 13+ messages in thread
* [Qemu-devel] [PATCHv3 0/2] ui/curses: BSD portability fixes
@ 2019-04-27 16:30 ` Samuel Thibault
0 siblings, 0 replies; 13+ messages in thread
From: Samuel Thibault @ 2019-04-27 16:30 UTC (permalink / raw)
To: qemu-devel; +Cc: Samuel Thibault, kamil, kraxel
BSD needs a few fixes for wide character manipulations.
Difference with v1:
- Fix unitialized value in error message
Difference with v2:
- Add cchar_t manipulation fix
Samuel Thibault (2):
ui/curses: do not assume wchar_t contains unicode
ui/curses: manipulate cchar_t with standard curses functions
ui/curses.c | 188 +++++++++++++++++++++++++++++++++-------------------
1 file changed, 120 insertions(+), 68 deletions(-)
--
2.20.1
^ permalink raw reply [flat|nested] 13+ messages in thread
* [Qemu-devel] [PATCH] curses: do not assume wchar_t contains unicode
@ 2019-04-27 16:30 ` Samuel Thibault
0 siblings, 0 replies; 13+ messages in thread
From: Samuel Thibault @ 2019-04-27 16:30 UTC (permalink / raw)
To: qemu-devel; +Cc: Samuel Thibault, kraxel, kamil
E.g. BSD and Solaris even use locale-specific encoding there.
We thus have to go through the native multibyte representation and use
mbtowc/wctomb to make a proper conversion.
Signed-off-by: Samuel Thibault <samuel.thibault@ens-lyon.org>
---
ui/curses.c | 151 ++++++++++++++++++++++++++++++++--------------------
1 file changed, 94 insertions(+), 57 deletions(-)
diff --git a/ui/curses.c b/ui/curses.c
index fb63945188..395f9545e9 100644
--- a/ui/curses.c
+++ b/ui/curses.c
@@ -400,65 +400,102 @@ static void curses_atexit(void)
endwin();
}
+/*
+ * In the following:
+ * - fch is the font glyph number
+ * - uch is the unicode value
+ * - wch is the wchar_t value (may not be unicode, e.g. on BSD/solaris)
+ * - mbch is the native local-dependent multibyte representation
+ */
+
/* Setup wchar glyph for one UCS-2 char */
-static void convert_ucs(int glyph, uint16_t ch, iconv_t conv)
+static void convert_ucs(unsigned char fch, uint16_t uch, iconv_t conv)
{
+ char mbch[MB_CUR_MAX];
wchar_t wch;
- char *pch, *pwch;
- size_t sch, swch;
-
- pch = (char *) &ch;
- pwch = (char *) &wch;
- sch = sizeof(ch);
- swch = sizeof(wch);
+ char *puch, *pmbch;
+ size_t such, smbch;
+
+ puch = (char *) &uch;
+ pmbch = (char *) mbch;
+ such = sizeof(uch);
+ smbch = sizeof(mbch);
+
+ if (iconv(conv, &puch, &such, &pmbch, &smbch) == (size_t) -1) {
+ fprintf(stderr, "Could not convert 0x%04x "
+ "from UCS-2 to a multibyte character: %s\n",
+ uch, strerror(errno));
+ return;
+ }
- if (iconv(conv, &pch, &sch, &pwch, &swch) == (size_t) -1) {
- fprintf(stderr, "Could not convert 0x%04x from UCS-2 to WCHAR_T: %s\n",
- ch, strerror(errno));
- } else {
- vga_to_curses[glyph].chars[0] = wch;
+ if (mbtowc(&wch, mbch, sizeof(mbch) - smbch) == -1) {
+ fprintf(stderr, "Could not convert 0x%04x "
+ "from a multibyte character to wchar_t: %s\n",
+ uch, strerror(errno));
+ return;
}
+ vga_to_curses[fch].chars[0] = wch;
}
/* Setup wchar glyph for one font character */
-static void convert_font(unsigned char ch, iconv_t conv)
+static void convert_font(unsigned char fch, iconv_t conv)
{
+ char mbch[MB_CUR_MAX];
wchar_t wch;
- char *pch, *pwch;
- size_t sch, swch;
-
- pch = (char *) &ch;
- pwch = (char *) &wch;
- sch = sizeof(ch);
- swch = sizeof(wch);
+ char *pfch, *pmbch;
+ size_t sfch, smbch;
+
+ pfch = (char *) &fch;
+ pmbch = (char *) &mbch;
+ sfch = sizeof(fch);
+ smbch = sizeof(mbch);
+
+ if (iconv(conv, &pfch, &sfch, &pmbch, &smbch) == (size_t) -1) {
+ fprintf(stderr, "Could not convert font glyph 0x%02x "
+ "from %s to a multibyte character: %s\n",
+ fch, font_charset, strerror(errno));
+ return;
+ }
- if (iconv(conv, &pch, &sch, &pwch, &swch) == (size_t) -1) {
- fprintf(stderr, "Could not convert 0x%02x from %s to WCHAR_T: %s\n",
- ch, font_charset, strerror(errno));
- } else {
- vga_to_curses[ch].chars[0] = wch;
+ if (mbtowc(&wch, mbch, sizeof(mbch) - smbch) == -1) {
+ fprintf(stderr, "Could not convert font glyph 0x%02x "
+ "from a multibyte character to wchar_t: %s\n",
+ fch, strerror(errno));
+ return;
}
+ vga_to_curses[fch].chars[0] = wch;
}
/* Convert one wchar to UCS-2 */
static uint16_t get_ucs(wchar_t wch, iconv_t conv)
{
- uint16_t ch;
- char *pch, *pwch;
- size_t sch, swch;
-
- pch = (char *) &ch;
- pwch = (char *) &wch;
- sch = sizeof(ch);
- swch = sizeof(wch);
-
- if (iconv(conv, &pwch, &swch, &pch, &sch) == (size_t) -1) {
- fprintf(stderr, "Could not convert 0x%02lx from WCHAR_T to UCS-2: %s\n",
- (unsigned long)wch, strerror(errno));
+ char mbch[MB_CUR_MAX];
+ uint16_t uch;
+ char *pmbch, *puch;
+ size_t smbch, such;
+ int ret;
+
+ ret = wctomb(mbch, wch);
+ if (ret == -1) {
+ fprintf(stderr, "Could not convert 0x%04x "
+ "from wchar_t to a multibyte character: %s\n",
+ wch, strerror(errno));
+ return 0xFFFD;
+ }
+
+ pmbch = (char *) mbch;
+ puch = (char *) &uch;
+ smbch = ret;
+ such = sizeof(uch);
+
+ if (iconv(conv, &pmbch, &smbch, &puch, &such) == (size_t) -1) {
+ fprintf(stderr, "Could not convert 0x%04x "
+ "from a multibyte character to UCS-2 : %s\n",
+ wch, strerror(errno));
return 0xFFFD;
}
- return ch;
+ return uch;
}
/*
@@ -466,6 +503,11 @@ static uint16_t get_ucs(wchar_t wch, iconv_t conv)
*/
static void font_setup(void)
{
+ iconv_t ucs2_to_nativecharset;
+ iconv_t nativecharset_to_ucs2;
+ iconv_t font_conv;
+ int i;
+
/*
* Control characters are normally non-printable, but VGA does have
* well-known glyphs for them.
@@ -505,30 +547,25 @@ static void font_setup(void)
0x25bc
};
- iconv_t ucs_to_wchar_conv;
- iconv_t wchar_to_ucs_conv;
- iconv_t font_conv;
- int i;
-
- ucs_to_wchar_conv = iconv_open("WCHAR_T", "UCS-2");
- if (ucs_to_wchar_conv == (iconv_t) -1) {
+ ucs2_to_nativecharset = iconv_open(nl_langinfo(CODESET), "UCS-2");
+ if (ucs2_to_nativecharset == (iconv_t) -1) {
fprintf(stderr, "Could not convert font glyphs from UCS-2: '%s'\n",
strerror(errno));
exit(1);
}
- wchar_to_ucs_conv = iconv_open("UCS-2", "WCHAR_T");
- if (wchar_to_ucs_conv == (iconv_t) -1) {
- iconv_close(ucs_to_wchar_conv);
+ nativecharset_to_ucs2 = iconv_open("UCS-2", nl_langinfo(CODESET));
+ if (nativecharset_to_ucs2 == (iconv_t) -1) {
+ iconv_close(ucs2_to_nativecharset);
fprintf(stderr, "Could not convert font glyphs to UCS-2: '%s'\n",
strerror(errno));
exit(1);
}
- font_conv = iconv_open("WCHAR_T", font_charset);
+ font_conv = iconv_open(nl_langinfo(CODESET), font_charset);
if (font_conv == (iconv_t) -1) {
- iconv_close(ucs_to_wchar_conv);
- iconv_close(wchar_to_ucs_conv);
+ iconv_close(ucs2_to_nativecharset);
+ iconv_close(nativecharset_to_ucs2);
fprintf(stderr, "Could not convert font glyphs from %s: '%s'\n",
font_charset, strerror(errno));
exit(1);
@@ -536,7 +573,7 @@ static void font_setup(void)
/* Control characters */
for (i = 0; i <= 0x1F; i++) {
- convert_ucs(i, control_characters[i], ucs_to_wchar_conv);
+ convert_ucs(i, control_characters[i], ucs2_to_nativecharset);
}
for (i = 0x20; i <= 0xFF; i++) {
@@ -544,12 +581,12 @@ static void font_setup(void)
}
/* DEL */
- convert_ucs(0x7F, 0x2302, ucs_to_wchar_conv);
+ convert_ucs(0x7F, 0x2302, ucs2_to_nativecharset);
if (strcmp(nl_langinfo(CODESET), "UTF-8")) {
/* Non-Unicode capable, use termcap equivalents for those available */
for (i = 0; i <= 0xFF; i++) {
- switch (get_ucs(vga_to_curses[i].chars[0], wchar_to_ucs_conv)) {
+ switch (get_ucs(vga_to_curses[i].chars[0], nativecharset_to_ucs2)) {
case 0x00a3:
vga_to_curses[i] = *WACS_STERLING;
break;
@@ -649,8 +686,8 @@ static void font_setup(void)
}
}
}
- iconv_close(ucs_to_wchar_conv);
- iconv_close(wchar_to_ucs_conv);
+ iconv_close(ucs2_to_nativecharset);
+ iconv_close(nativecharset_to_ucs2);
iconv_close(font_conv);
}
--
2.20.1
^ permalink raw reply related [flat|nested] 13+ messages in thread
* [Qemu-devel] [PATCH] curses: do not assume wchar_t contains unicode
@ 2019-04-27 16:30 ` Samuel Thibault
0 siblings, 0 replies; 13+ messages in thread
From: Samuel Thibault @ 2019-04-27 16:30 UTC (permalink / raw)
To: qemu-devel; +Cc: Samuel Thibault, kamil, kraxel
E.g. BSD and Solaris even use locale-specific encoding there.
We thus have to go through the native multibyte representation and use
mbtowc/wctomb to make a proper conversion.
Signed-off-by: Samuel Thibault <samuel.thibault@ens-lyon.org>
---
ui/curses.c | 151 ++++++++++++++++++++++++++++++++--------------------
1 file changed, 94 insertions(+), 57 deletions(-)
diff --git a/ui/curses.c b/ui/curses.c
index fb63945188..395f9545e9 100644
--- a/ui/curses.c
+++ b/ui/curses.c
@@ -400,65 +400,102 @@ static void curses_atexit(void)
endwin();
}
+/*
+ * In the following:
+ * - fch is the font glyph number
+ * - uch is the unicode value
+ * - wch is the wchar_t value (may not be unicode, e.g. on BSD/solaris)
+ * - mbch is the native local-dependent multibyte representation
+ */
+
/* Setup wchar glyph for one UCS-2 char */
-static void convert_ucs(int glyph, uint16_t ch, iconv_t conv)
+static void convert_ucs(unsigned char fch, uint16_t uch, iconv_t conv)
{
+ char mbch[MB_CUR_MAX];
wchar_t wch;
- char *pch, *pwch;
- size_t sch, swch;
-
- pch = (char *) &ch;
- pwch = (char *) &wch;
- sch = sizeof(ch);
- swch = sizeof(wch);
+ char *puch, *pmbch;
+ size_t such, smbch;
+
+ puch = (char *) &uch;
+ pmbch = (char *) mbch;
+ such = sizeof(uch);
+ smbch = sizeof(mbch);
+
+ if (iconv(conv, &puch, &such, &pmbch, &smbch) == (size_t) -1) {
+ fprintf(stderr, "Could not convert 0x%04x "
+ "from UCS-2 to a multibyte character: %s\n",
+ uch, strerror(errno));
+ return;
+ }
- if (iconv(conv, &pch, &sch, &pwch, &swch) == (size_t) -1) {
- fprintf(stderr, "Could not convert 0x%04x from UCS-2 to WCHAR_T: %s\n",
- ch, strerror(errno));
- } else {
- vga_to_curses[glyph].chars[0] = wch;
+ if (mbtowc(&wch, mbch, sizeof(mbch) - smbch) == -1) {
+ fprintf(stderr, "Could not convert 0x%04x "
+ "from a multibyte character to wchar_t: %s\n",
+ uch, strerror(errno));
+ return;
}
+ vga_to_curses[fch].chars[0] = wch;
}
/* Setup wchar glyph for one font character */
-static void convert_font(unsigned char ch, iconv_t conv)
+static void convert_font(unsigned char fch, iconv_t conv)
{
+ char mbch[MB_CUR_MAX];
wchar_t wch;
- char *pch, *pwch;
- size_t sch, swch;
-
- pch = (char *) &ch;
- pwch = (char *) &wch;
- sch = sizeof(ch);
- swch = sizeof(wch);
+ char *pfch, *pmbch;
+ size_t sfch, smbch;
+
+ pfch = (char *) &fch;
+ pmbch = (char *) &mbch;
+ sfch = sizeof(fch);
+ smbch = sizeof(mbch);
+
+ if (iconv(conv, &pfch, &sfch, &pmbch, &smbch) == (size_t) -1) {
+ fprintf(stderr, "Could not convert font glyph 0x%02x "
+ "from %s to a multibyte character: %s\n",
+ fch, font_charset, strerror(errno));
+ return;
+ }
- if (iconv(conv, &pch, &sch, &pwch, &swch) == (size_t) -1) {
- fprintf(stderr, "Could not convert 0x%02x from %s to WCHAR_T: %s\n",
- ch, font_charset, strerror(errno));
- } else {
- vga_to_curses[ch].chars[0] = wch;
+ if (mbtowc(&wch, mbch, sizeof(mbch) - smbch) == -1) {
+ fprintf(stderr, "Could not convert font glyph 0x%02x "
+ "from a multibyte character to wchar_t: %s\n",
+ fch, strerror(errno));
+ return;
}
+ vga_to_curses[fch].chars[0] = wch;
}
/* Convert one wchar to UCS-2 */
static uint16_t get_ucs(wchar_t wch, iconv_t conv)
{
- uint16_t ch;
- char *pch, *pwch;
- size_t sch, swch;
-
- pch = (char *) &ch;
- pwch = (char *) &wch;
- sch = sizeof(ch);
- swch = sizeof(wch);
-
- if (iconv(conv, &pwch, &swch, &pch, &sch) == (size_t) -1) {
- fprintf(stderr, "Could not convert 0x%02lx from WCHAR_T to UCS-2: %s\n",
- (unsigned long)wch, strerror(errno));
+ char mbch[MB_CUR_MAX];
+ uint16_t uch;
+ char *pmbch, *puch;
+ size_t smbch, such;
+ int ret;
+
+ ret = wctomb(mbch, wch);
+ if (ret == -1) {
+ fprintf(stderr, "Could not convert 0x%04x "
+ "from wchar_t to a multibyte character: %s\n",
+ wch, strerror(errno));
+ return 0xFFFD;
+ }
+
+ pmbch = (char *) mbch;
+ puch = (char *) &uch;
+ smbch = ret;
+ such = sizeof(uch);
+
+ if (iconv(conv, &pmbch, &smbch, &puch, &such) == (size_t) -1) {
+ fprintf(stderr, "Could not convert 0x%04x "
+ "from a multibyte character to UCS-2 : %s\n",
+ wch, strerror(errno));
return 0xFFFD;
}
- return ch;
+ return uch;
}
/*
@@ -466,6 +503,11 @@ static uint16_t get_ucs(wchar_t wch, iconv_t conv)
*/
static void font_setup(void)
{
+ iconv_t ucs2_to_nativecharset;
+ iconv_t nativecharset_to_ucs2;
+ iconv_t font_conv;
+ int i;
+
/*
* Control characters are normally non-printable, but VGA does have
* well-known glyphs for them.
@@ -505,30 +547,25 @@ static void font_setup(void)
0x25bc
};
- iconv_t ucs_to_wchar_conv;
- iconv_t wchar_to_ucs_conv;
- iconv_t font_conv;
- int i;
-
- ucs_to_wchar_conv = iconv_open("WCHAR_T", "UCS-2");
- if (ucs_to_wchar_conv == (iconv_t) -1) {
+ ucs2_to_nativecharset = iconv_open(nl_langinfo(CODESET), "UCS-2");
+ if (ucs2_to_nativecharset == (iconv_t) -1) {
fprintf(stderr, "Could not convert font glyphs from UCS-2: '%s'\n",
strerror(errno));
exit(1);
}
- wchar_to_ucs_conv = iconv_open("UCS-2", "WCHAR_T");
- if (wchar_to_ucs_conv == (iconv_t) -1) {
- iconv_close(ucs_to_wchar_conv);
+ nativecharset_to_ucs2 = iconv_open("UCS-2", nl_langinfo(CODESET));
+ if (nativecharset_to_ucs2 == (iconv_t) -1) {
+ iconv_close(ucs2_to_nativecharset);
fprintf(stderr, "Could not convert font glyphs to UCS-2: '%s'\n",
strerror(errno));
exit(1);
}
- font_conv = iconv_open("WCHAR_T", font_charset);
+ font_conv = iconv_open(nl_langinfo(CODESET), font_charset);
if (font_conv == (iconv_t) -1) {
- iconv_close(ucs_to_wchar_conv);
- iconv_close(wchar_to_ucs_conv);
+ iconv_close(ucs2_to_nativecharset);
+ iconv_close(nativecharset_to_ucs2);
fprintf(stderr, "Could not convert font glyphs from %s: '%s'\n",
font_charset, strerror(errno));
exit(1);
@@ -536,7 +573,7 @@ static void font_setup(void)
/* Control characters */
for (i = 0; i <= 0x1F; i++) {
- convert_ucs(i, control_characters[i], ucs_to_wchar_conv);
+ convert_ucs(i, control_characters[i], ucs2_to_nativecharset);
}
for (i = 0x20; i <= 0xFF; i++) {
@@ -544,12 +581,12 @@ static void font_setup(void)
}
/* DEL */
- convert_ucs(0x7F, 0x2302, ucs_to_wchar_conv);
+ convert_ucs(0x7F, 0x2302, ucs2_to_nativecharset);
if (strcmp(nl_langinfo(CODESET), "UTF-8")) {
/* Non-Unicode capable, use termcap equivalents for those available */
for (i = 0; i <= 0xFF; i++) {
- switch (get_ucs(vga_to_curses[i].chars[0], wchar_to_ucs_conv)) {
+ switch (get_ucs(vga_to_curses[i].chars[0], nativecharset_to_ucs2)) {
case 0x00a3:
vga_to_curses[i] = *WACS_STERLING;
break;
@@ -649,8 +686,8 @@ static void font_setup(void)
}
}
}
- iconv_close(ucs_to_wchar_conv);
- iconv_close(wchar_to_ucs_conv);
+ iconv_close(ucs2_to_nativecharset);
+ iconv_close(nativecharset_to_ucs2);
iconv_close(font_conv);
}
--
2.20.1
^ permalink raw reply related [flat|nested] 13+ messages in thread
* [Qemu-devel] [PATCHv3 1/2] ui/curses: Do not assume wchar_t contains unicode
@ 2019-04-27 16:30 ` Samuel Thibault
0 siblings, 0 replies; 13+ messages in thread
From: Samuel Thibault @ 2019-04-27 16:30 UTC (permalink / raw)
To: qemu-devel; +Cc: Samuel Thibault, kraxel, kamil
E.g. BSD and Solaris even use locale-specific encoding there.
We thus have to go through the native multibyte representation and use
mbtowc/wctomb to make a proper conversion.
Signed-off-by: Samuel Thibault <samuel.thibault@ens-lyon.org>
---
ui/curses.c | 151 ++++++++++++++++++++++++++++++++--------------------
1 file changed, 94 insertions(+), 57 deletions(-)
diff --git a/ui/curses.c b/ui/curses.c
index fb63945188..395f9545e9 100644
--- a/ui/curses.c
+++ b/ui/curses.c
@@ -400,65 +400,102 @@ static void curses_atexit(void)
endwin();
}
+/*
+ * In the following:
+ * - fch is the font glyph number
+ * - uch is the unicode value
+ * - wch is the wchar_t value (may not be unicode, e.g. on BSD/solaris)
+ * - mbch is the native local-dependent multibyte representation
+ */
+
/* Setup wchar glyph for one UCS-2 char */
-static void convert_ucs(int glyph, uint16_t ch, iconv_t conv)
+static void convert_ucs(unsigned char fch, uint16_t uch, iconv_t conv)
{
+ char mbch[MB_CUR_MAX];
wchar_t wch;
- char *pch, *pwch;
- size_t sch, swch;
-
- pch = (char *) &ch;
- pwch = (char *) &wch;
- sch = sizeof(ch);
- swch = sizeof(wch);
+ char *puch, *pmbch;
+ size_t such, smbch;
+
+ puch = (char *) &uch;
+ pmbch = (char *) mbch;
+ such = sizeof(uch);
+ smbch = sizeof(mbch);
+
+ if (iconv(conv, &puch, &such, &pmbch, &smbch) == (size_t) -1) {
+ fprintf(stderr, "Could not convert 0x%04x "
+ "from UCS-2 to a multibyte character: %s\n",
+ uch, strerror(errno));
+ return;
+ }
- if (iconv(conv, &pch, &sch, &pwch, &swch) == (size_t) -1) {
- fprintf(stderr, "Could not convert 0x%04x from UCS-2 to WCHAR_T: %s\n",
- ch, strerror(errno));
- } else {
- vga_to_curses[glyph].chars[0] = wch;
+ if (mbtowc(&wch, mbch, sizeof(mbch) - smbch) == -1) {
+ fprintf(stderr, "Could not convert 0x%04x "
+ "from a multibyte character to wchar_t: %s\n",
+ uch, strerror(errno));
+ return;
}
+ vga_to_curses[fch].chars[0] = wch;
}
/* Setup wchar glyph for one font character */
-static void convert_font(unsigned char ch, iconv_t conv)
+static void convert_font(unsigned char fch, iconv_t conv)
{
+ char mbch[MB_CUR_MAX];
wchar_t wch;
- char *pch, *pwch;
- size_t sch, swch;
-
- pch = (char *) &ch;
- pwch = (char *) &wch;
- sch = sizeof(ch);
- swch = sizeof(wch);
+ char *pfch, *pmbch;
+ size_t sfch, smbch;
+
+ pfch = (char *) &fch;
+ pmbch = (char *) &mbch;
+ sfch = sizeof(fch);
+ smbch = sizeof(mbch);
+
+ if (iconv(conv, &pfch, &sfch, &pmbch, &smbch) == (size_t) -1) {
+ fprintf(stderr, "Could not convert font glyph 0x%02x "
+ "from %s to a multibyte character: %s\n",
+ fch, font_charset, strerror(errno));
+ return;
+ }
- if (iconv(conv, &pch, &sch, &pwch, &swch) == (size_t) -1) {
- fprintf(stderr, "Could not convert 0x%02x from %s to WCHAR_T: %s\n",
- ch, font_charset, strerror(errno));
- } else {
- vga_to_curses[ch].chars[0] = wch;
+ if (mbtowc(&wch, mbch, sizeof(mbch) - smbch) == -1) {
+ fprintf(stderr, "Could not convert font glyph 0x%02x "
+ "from a multibyte character to wchar_t: %s\n",
+ fch, strerror(errno));
+ return;
}
+ vga_to_curses[fch].chars[0] = wch;
}
/* Convert one wchar to UCS-2 */
static uint16_t get_ucs(wchar_t wch, iconv_t conv)
{
- uint16_t ch;
- char *pch, *pwch;
- size_t sch, swch;
-
- pch = (char *) &ch;
- pwch = (char *) &wch;
- sch = sizeof(ch);
- swch = sizeof(wch);
-
- if (iconv(conv, &pwch, &swch, &pch, &sch) == (size_t) -1) {
- fprintf(stderr, "Could not convert 0x%02lx from WCHAR_T to UCS-2: %s\n",
- (unsigned long)wch, strerror(errno));
+ char mbch[MB_CUR_MAX];
+ uint16_t uch;
+ char *pmbch, *puch;
+ size_t smbch, such;
+ int ret;
+
+ ret = wctomb(mbch, wch);
+ if (ret == -1) {
+ fprintf(stderr, "Could not convert 0x%04x "
+ "from wchar_t to a multibyte character: %s\n",
+ wch, strerror(errno));
+ return 0xFFFD;
+ }
+
+ pmbch = (char *) mbch;
+ puch = (char *) &uch;
+ smbch = ret;
+ such = sizeof(uch);
+
+ if (iconv(conv, &pmbch, &smbch, &puch, &such) == (size_t) -1) {
+ fprintf(stderr, "Could not convert 0x%04x "
+ "from a multibyte character to UCS-2 : %s\n",
+ wch, strerror(errno));
return 0xFFFD;
}
- return ch;
+ return uch;
}
/*
@@ -466,6 +503,11 @@ static uint16_t get_ucs(wchar_t wch, iconv_t conv)
*/
static void font_setup(void)
{
+ iconv_t ucs2_to_nativecharset;
+ iconv_t nativecharset_to_ucs2;
+ iconv_t font_conv;
+ int i;
+
/*
* Control characters are normally non-printable, but VGA does have
* well-known glyphs for them.
@@ -505,30 +547,25 @@ static void font_setup(void)
0x25bc
};
- iconv_t ucs_to_wchar_conv;
- iconv_t wchar_to_ucs_conv;
- iconv_t font_conv;
- int i;
-
- ucs_to_wchar_conv = iconv_open("WCHAR_T", "UCS-2");
- if (ucs_to_wchar_conv == (iconv_t) -1) {
+ ucs2_to_nativecharset = iconv_open(nl_langinfo(CODESET), "UCS-2");
+ if (ucs2_to_nativecharset == (iconv_t) -1) {
fprintf(stderr, "Could not convert font glyphs from UCS-2: '%s'\n",
strerror(errno));
exit(1);
}
- wchar_to_ucs_conv = iconv_open("UCS-2", "WCHAR_T");
- if (wchar_to_ucs_conv == (iconv_t) -1) {
- iconv_close(ucs_to_wchar_conv);
+ nativecharset_to_ucs2 = iconv_open("UCS-2", nl_langinfo(CODESET));
+ if (nativecharset_to_ucs2 == (iconv_t) -1) {
+ iconv_close(ucs2_to_nativecharset);
fprintf(stderr, "Could not convert font glyphs to UCS-2: '%s'\n",
strerror(errno));
exit(1);
}
- font_conv = iconv_open("WCHAR_T", font_charset);
+ font_conv = iconv_open(nl_langinfo(CODESET), font_charset);
if (font_conv == (iconv_t) -1) {
- iconv_close(ucs_to_wchar_conv);
- iconv_close(wchar_to_ucs_conv);
+ iconv_close(ucs2_to_nativecharset);
+ iconv_close(nativecharset_to_ucs2);
fprintf(stderr, "Could not convert font glyphs from %s: '%s'\n",
font_charset, strerror(errno));
exit(1);
@@ -536,7 +573,7 @@ static void font_setup(void)
/* Control characters */
for (i = 0; i <= 0x1F; i++) {
- convert_ucs(i, control_characters[i], ucs_to_wchar_conv);
+ convert_ucs(i, control_characters[i], ucs2_to_nativecharset);
}
for (i = 0x20; i <= 0xFF; i++) {
@@ -544,12 +581,12 @@ static void font_setup(void)
}
/* DEL */
- convert_ucs(0x7F, 0x2302, ucs_to_wchar_conv);
+ convert_ucs(0x7F, 0x2302, ucs2_to_nativecharset);
if (strcmp(nl_langinfo(CODESET), "UTF-8")) {
/* Non-Unicode capable, use termcap equivalents for those available */
for (i = 0; i <= 0xFF; i++) {
- switch (get_ucs(vga_to_curses[i].chars[0], wchar_to_ucs_conv)) {
+ switch (get_ucs(vga_to_curses[i].chars[0], nativecharset_to_ucs2)) {
case 0x00a3:
vga_to_curses[i] = *WACS_STERLING;
break;
@@ -649,8 +686,8 @@ static void font_setup(void)
}
}
}
- iconv_close(ucs_to_wchar_conv);
- iconv_close(wchar_to_ucs_conv);
+ iconv_close(ucs2_to_nativecharset);
+ iconv_close(nativecharset_to_ucs2);
iconv_close(font_conv);
}
--
2.20.1
^ permalink raw reply related [flat|nested] 13+ messages in thread
* [Qemu-devel] [PATCHv3 1/2] ui/curses: Do not assume wchar_t contains unicode
@ 2019-04-27 16:30 ` Samuel Thibault
0 siblings, 0 replies; 13+ messages in thread
From: Samuel Thibault @ 2019-04-27 16:30 UTC (permalink / raw)
To: qemu-devel; +Cc: Samuel Thibault, kamil, kraxel
E.g. BSD and Solaris even use locale-specific encoding there.
We thus have to go through the native multibyte representation and use
mbtowc/wctomb to make a proper conversion.
Signed-off-by: Samuel Thibault <samuel.thibault@ens-lyon.org>
---
ui/curses.c | 151 ++++++++++++++++++++++++++++++++--------------------
1 file changed, 94 insertions(+), 57 deletions(-)
diff --git a/ui/curses.c b/ui/curses.c
index fb63945188..395f9545e9 100644
--- a/ui/curses.c
+++ b/ui/curses.c
@@ -400,65 +400,102 @@ static void curses_atexit(void)
endwin();
}
+/*
+ * In the following:
+ * - fch is the font glyph number
+ * - uch is the unicode value
+ * - wch is the wchar_t value (may not be unicode, e.g. on BSD/solaris)
+ * - mbch is the native local-dependent multibyte representation
+ */
+
/* Setup wchar glyph for one UCS-2 char */
-static void convert_ucs(int glyph, uint16_t ch, iconv_t conv)
+static void convert_ucs(unsigned char fch, uint16_t uch, iconv_t conv)
{
+ char mbch[MB_CUR_MAX];
wchar_t wch;
- char *pch, *pwch;
- size_t sch, swch;
-
- pch = (char *) &ch;
- pwch = (char *) &wch;
- sch = sizeof(ch);
- swch = sizeof(wch);
+ char *puch, *pmbch;
+ size_t such, smbch;
+
+ puch = (char *) &uch;
+ pmbch = (char *) mbch;
+ such = sizeof(uch);
+ smbch = sizeof(mbch);
+
+ if (iconv(conv, &puch, &such, &pmbch, &smbch) == (size_t) -1) {
+ fprintf(stderr, "Could not convert 0x%04x "
+ "from UCS-2 to a multibyte character: %s\n",
+ uch, strerror(errno));
+ return;
+ }
- if (iconv(conv, &pch, &sch, &pwch, &swch) == (size_t) -1) {
- fprintf(stderr, "Could not convert 0x%04x from UCS-2 to WCHAR_T: %s\n",
- ch, strerror(errno));
- } else {
- vga_to_curses[glyph].chars[0] = wch;
+ if (mbtowc(&wch, mbch, sizeof(mbch) - smbch) == -1) {
+ fprintf(stderr, "Could not convert 0x%04x "
+ "from a multibyte character to wchar_t: %s\n",
+ uch, strerror(errno));
+ return;
}
+ vga_to_curses[fch].chars[0] = wch;
}
/* Setup wchar glyph for one font character */
-static void convert_font(unsigned char ch, iconv_t conv)
+static void convert_font(unsigned char fch, iconv_t conv)
{
+ char mbch[MB_CUR_MAX];
wchar_t wch;
- char *pch, *pwch;
- size_t sch, swch;
-
- pch = (char *) &ch;
- pwch = (char *) &wch;
- sch = sizeof(ch);
- swch = sizeof(wch);
+ char *pfch, *pmbch;
+ size_t sfch, smbch;
+
+ pfch = (char *) &fch;
+ pmbch = (char *) &mbch;
+ sfch = sizeof(fch);
+ smbch = sizeof(mbch);
+
+ if (iconv(conv, &pfch, &sfch, &pmbch, &smbch) == (size_t) -1) {
+ fprintf(stderr, "Could not convert font glyph 0x%02x "
+ "from %s to a multibyte character: %s\n",
+ fch, font_charset, strerror(errno));
+ return;
+ }
- if (iconv(conv, &pch, &sch, &pwch, &swch) == (size_t) -1) {
- fprintf(stderr, "Could not convert 0x%02x from %s to WCHAR_T: %s\n",
- ch, font_charset, strerror(errno));
- } else {
- vga_to_curses[ch].chars[0] = wch;
+ if (mbtowc(&wch, mbch, sizeof(mbch) - smbch) == -1) {
+ fprintf(stderr, "Could not convert font glyph 0x%02x "
+ "from a multibyte character to wchar_t: %s\n",
+ fch, strerror(errno));
+ return;
}
+ vga_to_curses[fch].chars[0] = wch;
}
/* Convert one wchar to UCS-2 */
static uint16_t get_ucs(wchar_t wch, iconv_t conv)
{
- uint16_t ch;
- char *pch, *pwch;
- size_t sch, swch;
-
- pch = (char *) &ch;
- pwch = (char *) &wch;
- sch = sizeof(ch);
- swch = sizeof(wch);
-
- if (iconv(conv, &pwch, &swch, &pch, &sch) == (size_t) -1) {
- fprintf(stderr, "Could not convert 0x%02lx from WCHAR_T to UCS-2: %s\n",
- (unsigned long)wch, strerror(errno));
+ char mbch[MB_CUR_MAX];
+ uint16_t uch;
+ char *pmbch, *puch;
+ size_t smbch, such;
+ int ret;
+
+ ret = wctomb(mbch, wch);
+ if (ret == -1) {
+ fprintf(stderr, "Could not convert 0x%04x "
+ "from wchar_t to a multibyte character: %s\n",
+ wch, strerror(errno));
+ return 0xFFFD;
+ }
+
+ pmbch = (char *) mbch;
+ puch = (char *) &uch;
+ smbch = ret;
+ such = sizeof(uch);
+
+ if (iconv(conv, &pmbch, &smbch, &puch, &such) == (size_t) -1) {
+ fprintf(stderr, "Could not convert 0x%04x "
+ "from a multibyte character to UCS-2 : %s\n",
+ wch, strerror(errno));
return 0xFFFD;
}
- return ch;
+ return uch;
}
/*
@@ -466,6 +503,11 @@ static uint16_t get_ucs(wchar_t wch, iconv_t conv)
*/
static void font_setup(void)
{
+ iconv_t ucs2_to_nativecharset;
+ iconv_t nativecharset_to_ucs2;
+ iconv_t font_conv;
+ int i;
+
/*
* Control characters are normally non-printable, but VGA does have
* well-known glyphs for them.
@@ -505,30 +547,25 @@ static void font_setup(void)
0x25bc
};
- iconv_t ucs_to_wchar_conv;
- iconv_t wchar_to_ucs_conv;
- iconv_t font_conv;
- int i;
-
- ucs_to_wchar_conv = iconv_open("WCHAR_T", "UCS-2");
- if (ucs_to_wchar_conv == (iconv_t) -1) {
+ ucs2_to_nativecharset = iconv_open(nl_langinfo(CODESET), "UCS-2");
+ if (ucs2_to_nativecharset == (iconv_t) -1) {
fprintf(stderr, "Could not convert font glyphs from UCS-2: '%s'\n",
strerror(errno));
exit(1);
}
- wchar_to_ucs_conv = iconv_open("UCS-2", "WCHAR_T");
- if (wchar_to_ucs_conv == (iconv_t) -1) {
- iconv_close(ucs_to_wchar_conv);
+ nativecharset_to_ucs2 = iconv_open("UCS-2", nl_langinfo(CODESET));
+ if (nativecharset_to_ucs2 == (iconv_t) -1) {
+ iconv_close(ucs2_to_nativecharset);
fprintf(stderr, "Could not convert font glyphs to UCS-2: '%s'\n",
strerror(errno));
exit(1);
}
- font_conv = iconv_open("WCHAR_T", font_charset);
+ font_conv = iconv_open(nl_langinfo(CODESET), font_charset);
if (font_conv == (iconv_t) -1) {
- iconv_close(ucs_to_wchar_conv);
- iconv_close(wchar_to_ucs_conv);
+ iconv_close(ucs2_to_nativecharset);
+ iconv_close(nativecharset_to_ucs2);
fprintf(stderr, "Could not convert font glyphs from %s: '%s'\n",
font_charset, strerror(errno));
exit(1);
@@ -536,7 +573,7 @@ static void font_setup(void)
/* Control characters */
for (i = 0; i <= 0x1F; i++) {
- convert_ucs(i, control_characters[i], ucs_to_wchar_conv);
+ convert_ucs(i, control_characters[i], ucs2_to_nativecharset);
}
for (i = 0x20; i <= 0xFF; i++) {
@@ -544,12 +581,12 @@ static void font_setup(void)
}
/* DEL */
- convert_ucs(0x7F, 0x2302, ucs_to_wchar_conv);
+ convert_ucs(0x7F, 0x2302, ucs2_to_nativecharset);
if (strcmp(nl_langinfo(CODESET), "UTF-8")) {
/* Non-Unicode capable, use termcap equivalents for those available */
for (i = 0; i <= 0xFF; i++) {
- switch (get_ucs(vga_to_curses[i].chars[0], wchar_to_ucs_conv)) {
+ switch (get_ucs(vga_to_curses[i].chars[0], nativecharset_to_ucs2)) {
case 0x00a3:
vga_to_curses[i] = *WACS_STERLING;
break;
@@ -649,8 +686,8 @@ static void font_setup(void)
}
}
}
- iconv_close(ucs_to_wchar_conv);
- iconv_close(wchar_to_ucs_conv);
+ iconv_close(ucs2_to_nativecharset);
+ iconv_close(nativecharset_to_ucs2);
iconv_close(font_conv);
}
--
2.20.1
^ permalink raw reply related [flat|nested] 13+ messages in thread
* [Qemu-devel] [PATCHv3 2/2] ui/curses: manipulate cchar_t with standard curses functions
@ 2019-04-27 16:30 ` Samuel Thibault
0 siblings, 0 replies; 13+ messages in thread
From: Samuel Thibault @ 2019-04-27 16:30 UTC (permalink / raw)
To: qemu-devel; +Cc: Samuel Thibault, kraxel, kamil
The chars/attr fields are curses internals, setcchar and getcchar have
to be used instead.
Signed-off-by: Samuel Thibault <samuel.thibault@ens-lyon.org>
---
ui/curses.c | 43 +++++++++++++++++++++++++++++--------------
1 file changed, 29 insertions(+), 14 deletions(-)
diff --git a/ui/curses.c b/ui/curses.c
index 395f9545e9..bc0d77a2a8 100644
--- a/ui/curses.c
+++ b/ui/curses.c
@@ -66,20 +66,22 @@ static void curses_update(DisplayChangeListener *dcl,
{
console_ch_t *line;
cchar_t curses_line[width];
+ wchar_t wch[CCHARW_MAX];
+ attr_t attrs;
+ short colors;
+ int ret;
line = screen + y * width;
for (h += y; y < h; y ++, line += width) {
for (x = 0; x < width; x++) {
chtype ch = line[x] & 0xff;
chtype at = line[x] & ~0xff;
- if (vga_to_curses[ch].chars[0]) {
- curses_line[x] = vga_to_curses[ch];
- } else {
- curses_line[x] = (cchar_t) {
- .chars[0] = ch,
- };
+ ret = getcchar(&vga_to_curses[ch], wch, &attrs, &colors, NULL);
+ if (ret == ERR || wch[0] == 0) {
+ wch[0] = ch;
+ wch[1] = 0;
}
- curses_line[x].attr |= at;
+ setcchar(&curses_line[x], wch, at, 0, NULL);
}
mvwadd_wchnstr(screenpad, y, 0, curses_line, width);
}
@@ -412,7 +414,7 @@ static void curses_atexit(void)
static void convert_ucs(unsigned char fch, uint16_t uch, iconv_t conv)
{
char mbch[MB_CUR_MAX];
- wchar_t wch;
+ wchar_t wch[2];
char *puch, *pmbch;
size_t such, smbch;
@@ -428,20 +430,22 @@ static void convert_ucs(unsigned char fch, uint16_t uch, iconv_t conv)
return;
}
- if (mbtowc(&wch, mbch, sizeof(mbch) - smbch) == -1) {
+ if (mbtowc(&wch[0], mbch, sizeof(mbch) - smbch) == -1) {
fprintf(stderr, "Could not convert 0x%04x "
"from a multibyte character to wchar_t: %s\n",
uch, strerror(errno));
return;
}
- vga_to_curses[fch].chars[0] = wch;
+
+ wch[1] = 0;
+ setcchar(&vga_to_curses[fch], wch, 0, 0, NULL);
}
/* Setup wchar glyph for one font character */
static void convert_font(unsigned char fch, iconv_t conv)
{
char mbch[MB_CUR_MAX];
- wchar_t wch;
+ wchar_t wch[2];
char *pfch, *pmbch;
size_t sfch, smbch;
@@ -457,13 +461,15 @@ static void convert_font(unsigned char fch, iconv_t conv)
return;
}
- if (mbtowc(&wch, mbch, sizeof(mbch) - smbch) == -1) {
+ if (mbtowc(&wch[0], mbch, sizeof(mbch) - smbch) == -1) {
fprintf(stderr, "Could not convert font glyph 0x%02x "
"from a multibyte character to wchar_t: %s\n",
fch, strerror(errno));
return;
}
- vga_to_curses[fch].chars[0] = wch;
+
+ wch[1] = 0;
+ setcchar(&vga_to_curses[fch], wch, 0, 0, NULL);
}
/* Convert one wchar to UCS-2 */
@@ -586,7 +592,16 @@ static void font_setup(void)
if (strcmp(nl_langinfo(CODESET), "UTF-8")) {
/* Non-Unicode capable, use termcap equivalents for those available */
for (i = 0; i <= 0xFF; i++) {
- switch (get_ucs(vga_to_curses[i].chars[0], nativecharset_to_ucs2)) {
+ wchar_t wch[CCHARW_MAX];
+ attr_t attr;
+ short color;
+ int ret;
+
+ ret = getcchar(&vga_to_curses[i], wch, &attr, &color, NULL);
+ if (ret == ERR)
+ continue;
+
+ switch (get_ucs(wch[0], nativecharset_to_ucs2)) {
case 0x00a3:
vga_to_curses[i] = *WACS_STERLING;
break;
--
2.20.1
^ permalink raw reply related [flat|nested] 13+ messages in thread
* [Qemu-devel] [PATCHv3 2/2] ui/curses: manipulate cchar_t with standard curses functions
@ 2019-04-27 16:30 ` Samuel Thibault
0 siblings, 0 replies; 13+ messages in thread
From: Samuel Thibault @ 2019-04-27 16:30 UTC (permalink / raw)
To: qemu-devel; +Cc: Samuel Thibault, kamil, kraxel
The chars/attr fields are curses internals, setcchar and getcchar have
to be used instead.
Signed-off-by: Samuel Thibault <samuel.thibault@ens-lyon.org>
---
ui/curses.c | 43 +++++++++++++++++++++++++++++--------------
1 file changed, 29 insertions(+), 14 deletions(-)
diff --git a/ui/curses.c b/ui/curses.c
index 395f9545e9..bc0d77a2a8 100644
--- a/ui/curses.c
+++ b/ui/curses.c
@@ -66,20 +66,22 @@ static void curses_update(DisplayChangeListener *dcl,
{
console_ch_t *line;
cchar_t curses_line[width];
+ wchar_t wch[CCHARW_MAX];
+ attr_t attrs;
+ short colors;
+ int ret;
line = screen + y * width;
for (h += y; y < h; y ++, line += width) {
for (x = 0; x < width; x++) {
chtype ch = line[x] & 0xff;
chtype at = line[x] & ~0xff;
- if (vga_to_curses[ch].chars[0]) {
- curses_line[x] = vga_to_curses[ch];
- } else {
- curses_line[x] = (cchar_t) {
- .chars[0] = ch,
- };
+ ret = getcchar(&vga_to_curses[ch], wch, &attrs, &colors, NULL);
+ if (ret == ERR || wch[0] == 0) {
+ wch[0] = ch;
+ wch[1] = 0;
}
- curses_line[x].attr |= at;
+ setcchar(&curses_line[x], wch, at, 0, NULL);
}
mvwadd_wchnstr(screenpad, y, 0, curses_line, width);
}
@@ -412,7 +414,7 @@ static void curses_atexit(void)
static void convert_ucs(unsigned char fch, uint16_t uch, iconv_t conv)
{
char mbch[MB_CUR_MAX];
- wchar_t wch;
+ wchar_t wch[2];
char *puch, *pmbch;
size_t such, smbch;
@@ -428,20 +430,22 @@ static void convert_ucs(unsigned char fch, uint16_t uch, iconv_t conv)
return;
}
- if (mbtowc(&wch, mbch, sizeof(mbch) - smbch) == -1) {
+ if (mbtowc(&wch[0], mbch, sizeof(mbch) - smbch) == -1) {
fprintf(stderr, "Could not convert 0x%04x "
"from a multibyte character to wchar_t: %s\n",
uch, strerror(errno));
return;
}
- vga_to_curses[fch].chars[0] = wch;
+
+ wch[1] = 0;
+ setcchar(&vga_to_curses[fch], wch, 0, 0, NULL);
}
/* Setup wchar glyph for one font character */
static void convert_font(unsigned char fch, iconv_t conv)
{
char mbch[MB_CUR_MAX];
- wchar_t wch;
+ wchar_t wch[2];
char *pfch, *pmbch;
size_t sfch, smbch;
@@ -457,13 +461,15 @@ static void convert_font(unsigned char fch, iconv_t conv)
return;
}
- if (mbtowc(&wch, mbch, sizeof(mbch) - smbch) == -1) {
+ if (mbtowc(&wch[0], mbch, sizeof(mbch) - smbch) == -1) {
fprintf(stderr, "Could not convert font glyph 0x%02x "
"from a multibyte character to wchar_t: %s\n",
fch, strerror(errno));
return;
}
- vga_to_curses[fch].chars[0] = wch;
+
+ wch[1] = 0;
+ setcchar(&vga_to_curses[fch], wch, 0, 0, NULL);
}
/* Convert one wchar to UCS-2 */
@@ -586,7 +592,16 @@ static void font_setup(void)
if (strcmp(nl_langinfo(CODESET), "UTF-8")) {
/* Non-Unicode capable, use termcap equivalents for those available */
for (i = 0; i <= 0xFF; i++) {
- switch (get_ucs(vga_to_curses[i].chars[0], nativecharset_to_ucs2)) {
+ wchar_t wch[CCHARW_MAX];
+ attr_t attr;
+ short color;
+ int ret;
+
+ ret = getcchar(&vga_to_curses[i], wch, &attr, &color, NULL);
+ if (ret == ERR)
+ continue;
+
+ switch (get_ucs(wch[0], nativecharset_to_ucs2)) {
case 0x00a3:
vga_to_curses[i] = *WACS_STERLING;
break;
--
2.20.1
^ permalink raw reply related [flat|nested] 13+ messages in thread
* Re: [Qemu-devel] [PATCHv3 1/2] ui/curses: Do not assume wchar_t contains unicode
@ 2019-04-27 17:36 ` Kamil Rytarowski
0 siblings, 0 replies; 13+ messages in thread
From: Kamil Rytarowski @ 2019-04-27 17:36 UTC (permalink / raw)
To: Samuel Thibault, qemu-devel; +Cc: kraxel, kamil
[-- Attachment #1: Type: text/plain, Size: 11293 bytes --]
On 27.04.2019 18:30, Samuel Thibault wrote:
> E.g. BSD and Solaris even use locale-specific encoding there.
>
> We thus have to go through the native multibyte representation and use
> mbtowc/wctomb to make a proper conversion.
>
> Signed-off-by: Samuel Thibault <samuel.thibault@ens-lyon.org>
Both patches work for me on NetBSD/amd64 8.99.37 for qemu-system-x86_64.
Borders are printed correctly.
Regarding the patch I'm not sure whether to use MB_LEN_MAX or MB_CUR_MAX?
I'm also unsure whether to reset conversion state between a multibyte
character and wide character, with: `mbtowc(NULL, 0, 0);`. It's
recommended to use in code examples examples. I think it doesn't make
any harm to use it.
I'm not sure if this is related, but "qemu-system-hppa -curses" is
broken for me. I didn't use it in the past as it just recently acquired
NetBSD guest support.
(lldb) bt
* thread #1, stop reason = signal SIGSEGV
frame #0: 0x00007f7ff6c1fb98
libcurses.so.7`wmove(win=0x0000000000000000, y=0, x=0) at move.c:71
frame #1: 0x00007f7ff6c0ca9b
libcurses.so.7`mvwadd_wchnstr(win=0x0000000000000000, y=<unavailable>,
x=<unavailable>, wchstr=0x00007f7fffffe020, n=0) at add_wchstr.c:123
* frame #2: 0x000000000078629e
qemu-system-hppa`curses_update(dcl=0x00007f7ff7bd8bc0, x=0, y=0, w=79,
h=24) at curses.c:86:9
frame #3: 0x0000000000753dae
qemu-system-hppa`dpy_text_update(con=0x00007f7ff7bae580, x=0, y=0, w=79,
h=24) at console.c:1658:13
frame #4: 0x0000000000758abe
qemu-system-hppa`text_console_update(opaque=0x00007f7ff7bae580,
chardata=0x000000000118e490) at console.c:1264:9
frame #5: 0x0000000000751ef8
qemu-system-hppa`graphic_hw_text_update(con=0x00007f7ff7bae580,
chardata=0x000000000118c690) at console.c:389:9
frame #6: 0x0000000000785bcb
qemu-system-hppa`curses_refresh(dcl=0x00007f7ff7bd8bc0) at curses.c:273:5
frame #7: 0x0000000000758248
qemu-system-hppa`dpy_refresh(s=0x00007f7ff7bd8770) at console.c:1622:13
frame #8: 0x000000000075809d
qemu-system-hppa`gui_update(opaque=0x00007f7ff7bd8770) at console.c:205:5
frame #9: 0x00000000008d9f4d
qemu-system-hppa`timerlist_run_timers(timer_list=0x00007f7ff7e57d20) at
qemu-timer.c:574:9
frame #10: 0x00000000008da01d
qemu-system-hppa`qemu_clock_run_timers(type=QEMU_CLOCK_REALTIME) at
qemu-timer.c:588:12
frame #11: 0x00000000008da4ea
qemu-system-hppa`qemu_clock_run_all_timers at qemu-timer.c:708:25
frame #12: 0x00000000008da962
qemu-system-hppa`main_loop_wait(nonblocking=0) at main-loop.c:519:5
frame #13: 0x00000000005570a4 qemu-system-hppa`main_loop at vl.c:1970:9
frame #14: 0x0000000000551fa4 qemu-system-hppa`main(argc=2,
argv=0x00007f7fffffe768, envp=0x00007f7fffffe780) at vl.c:4604:5
frame #15: 0x000000000040e7ad qemu-system-hppa`___start + 280
(lldb) p screenpad
(WINDOW *) $2 = 0x0000000000000000
We pass NULL window argument to mvwadd_wchnstr(3) and crash. Can you
reproduce it locally?
I will try to investigate it.
> ---
> ui/curses.c | 151 ++++++++++++++++++++++++++++++++--------------------
> 1 file changed, 94 insertions(+), 57 deletions(-)
>
> diff --git a/ui/curses.c b/ui/curses.c
> index fb63945188..395f9545e9 100644
> --- a/ui/curses.c
> +++ b/ui/curses.c
> @@ -400,65 +400,102 @@ static void curses_atexit(void)
> endwin();
> }
>
> +/*
> + * In the following:
> + * - fch is the font glyph number
> + * - uch is the unicode value
> + * - wch is the wchar_t value (may not be unicode, e.g. on BSD/solaris)
> + * - mbch is the native local-dependent multibyte representation
> + */
> +
> /* Setup wchar glyph for one UCS-2 char */
> -static void convert_ucs(int glyph, uint16_t ch, iconv_t conv)
> +static void convert_ucs(unsigned char fch, uint16_t uch, iconv_t conv)
> {
> + char mbch[MB_CUR_MAX];
> wchar_t wch;
> - char *pch, *pwch;
> - size_t sch, swch;
> -
> - pch = (char *) &ch;
> - pwch = (char *) &wch;
> - sch = sizeof(ch);
> - swch = sizeof(wch);
> + char *puch, *pmbch;
> + size_t such, smbch;
> +
> + puch = (char *) &uch;
> + pmbch = (char *) mbch;
> + such = sizeof(uch);
> + smbch = sizeof(mbch);
> +
> + if (iconv(conv, &puch, &such, &pmbch, &smbch) == (size_t) -1) {
> + fprintf(stderr, "Could not convert 0x%04x "
> + "from UCS-2 to a multibyte character: %s\n",
> + uch, strerror(errno));
> + return;
> + }
>
> - if (iconv(conv, &pch, &sch, &pwch, &swch) == (size_t) -1) {
> - fprintf(stderr, "Could not convert 0x%04x from UCS-2 to WCHAR_T: %s\n",
> - ch, strerror(errno));
> - } else {
> - vga_to_curses[glyph].chars[0] = wch;
> + if (mbtowc(&wch, mbch, sizeof(mbch) - smbch) == -1) {
> + fprintf(stderr, "Could not convert 0x%04x "
> + "from a multibyte character to wchar_t: %s\n",
> + uch, strerror(errno));
> + return;
> }
> + vga_to_curses[fch].chars[0] = wch;
> }
>
> /* Setup wchar glyph for one font character */
> -static void convert_font(unsigned char ch, iconv_t conv)
> +static void convert_font(unsigned char fch, iconv_t conv)
> {
> + char mbch[MB_CUR_MAX];
> wchar_t wch;
> - char *pch, *pwch;
> - size_t sch, swch;
> -
> - pch = (char *) &ch;
> - pwch = (char *) &wch;
> - sch = sizeof(ch);
> - swch = sizeof(wch);
> + char *pfch, *pmbch;
> + size_t sfch, smbch;
> +
> + pfch = (char *) &fch;
> + pmbch = (char *) &mbch;
> + sfch = sizeof(fch);
> + smbch = sizeof(mbch);
> +
> + if (iconv(conv, &pfch, &sfch, &pmbch, &smbch) == (size_t) -1) {
> + fprintf(stderr, "Could not convert font glyph 0x%02x "
> + "from %s to a multibyte character: %s\n",
> + fch, font_charset, strerror(errno));
> + return;
> + }
>
> - if (iconv(conv, &pch, &sch, &pwch, &swch) == (size_t) -1) {
> - fprintf(stderr, "Could not convert 0x%02x from %s to WCHAR_T: %s\n",
> - ch, font_charset, strerror(errno));
> - } else {
> - vga_to_curses[ch].chars[0] = wch;
> + if (mbtowc(&wch, mbch, sizeof(mbch) - smbch) == -1) {
> + fprintf(stderr, "Could not convert font glyph 0x%02x "
> + "from a multibyte character to wchar_t: %s\n",
> + fch, strerror(errno));
> + return;
> }
> + vga_to_curses[fch].chars[0] = wch;
> }
>
> /* Convert one wchar to UCS-2 */
> static uint16_t get_ucs(wchar_t wch, iconv_t conv)
> {
> - uint16_t ch;
> - char *pch, *pwch;
> - size_t sch, swch;
> -
> - pch = (char *) &ch;
> - pwch = (char *) &wch;
> - sch = sizeof(ch);
> - swch = sizeof(wch);
> -
> - if (iconv(conv, &pwch, &swch, &pch, &sch) == (size_t) -1) {
> - fprintf(stderr, "Could not convert 0x%02lx from WCHAR_T to UCS-2: %s\n",
> - (unsigned long)wch, strerror(errno));
> + char mbch[MB_CUR_MAX];
> + uint16_t uch;
> + char *pmbch, *puch;
> + size_t smbch, such;
> + int ret;
> +
> + ret = wctomb(mbch, wch);
> + if (ret == -1) {
> + fprintf(stderr, "Could not convert 0x%04x "
> + "from wchar_t to a multibyte character: %s\n",
> + wch, strerror(errno));
> + return 0xFFFD;
> + }
> +
> + pmbch = (char *) mbch;
> + puch = (char *) &uch;
> + smbch = ret;
> + such = sizeof(uch);
> +
> + if (iconv(conv, &pmbch, &smbch, &puch, &such) == (size_t) -1) {
> + fprintf(stderr, "Could not convert 0x%04x "
> + "from a multibyte character to UCS-2 : %s\n",
> + wch, strerror(errno));
> return 0xFFFD;
> }
>
> - return ch;
> + return uch;
> }
>
> /*
> @@ -466,6 +503,11 @@ static uint16_t get_ucs(wchar_t wch, iconv_t conv)
> */
> static void font_setup(void)
> {
> + iconv_t ucs2_to_nativecharset;
> + iconv_t nativecharset_to_ucs2;
> + iconv_t font_conv;
> + int i;
> +
> /*
> * Control characters are normally non-printable, but VGA does have
> * well-known glyphs for them.
> @@ -505,30 +547,25 @@ static void font_setup(void)
> 0x25bc
> };
>
> - iconv_t ucs_to_wchar_conv;
> - iconv_t wchar_to_ucs_conv;
> - iconv_t font_conv;
> - int i;
> -
> - ucs_to_wchar_conv = iconv_open("WCHAR_T", "UCS-2");
> - if (ucs_to_wchar_conv == (iconv_t) -1) {
> + ucs2_to_nativecharset = iconv_open(nl_langinfo(CODESET), "UCS-2");
> + if (ucs2_to_nativecharset == (iconv_t) -1) {
> fprintf(stderr, "Could not convert font glyphs from UCS-2: '%s'\n",
> strerror(errno));
> exit(1);
> }
>
> - wchar_to_ucs_conv = iconv_open("UCS-2", "WCHAR_T");
> - if (wchar_to_ucs_conv == (iconv_t) -1) {
> - iconv_close(ucs_to_wchar_conv);
> + nativecharset_to_ucs2 = iconv_open("UCS-2", nl_langinfo(CODESET));
> + if (nativecharset_to_ucs2 == (iconv_t) -1) {
> + iconv_close(ucs2_to_nativecharset);
> fprintf(stderr, "Could not convert font glyphs to UCS-2: '%s'\n",
> strerror(errno));
> exit(1);
> }
>
> - font_conv = iconv_open("WCHAR_T", font_charset);
> + font_conv = iconv_open(nl_langinfo(CODESET), font_charset);
> if (font_conv == (iconv_t) -1) {
> - iconv_close(ucs_to_wchar_conv);
> - iconv_close(wchar_to_ucs_conv);
> + iconv_close(ucs2_to_nativecharset);
> + iconv_close(nativecharset_to_ucs2);
> fprintf(stderr, "Could not convert font glyphs from %s: '%s'\n",
> font_charset, strerror(errno));
> exit(1);
> @@ -536,7 +573,7 @@ static void font_setup(void)
>
> /* Control characters */
> for (i = 0; i <= 0x1F; i++) {
> - convert_ucs(i, control_characters[i], ucs_to_wchar_conv);
> + convert_ucs(i, control_characters[i], ucs2_to_nativecharset);
> }
>
> for (i = 0x20; i <= 0xFF; i++) {
> @@ -544,12 +581,12 @@ static void font_setup(void)
> }
>
> /* DEL */
> - convert_ucs(0x7F, 0x2302, ucs_to_wchar_conv);
> + convert_ucs(0x7F, 0x2302, ucs2_to_nativecharset);
>
> if (strcmp(nl_langinfo(CODESET), "UTF-8")) {
> /* Non-Unicode capable, use termcap equivalents for those available */
> for (i = 0; i <= 0xFF; i++) {
> - switch (get_ucs(vga_to_curses[i].chars[0], wchar_to_ucs_conv)) {
> + switch (get_ucs(vga_to_curses[i].chars[0], nativecharset_to_ucs2)) {
> case 0x00a3:
> vga_to_curses[i] = *WACS_STERLING;
> break;
> @@ -649,8 +686,8 @@ static void font_setup(void)
> }
> }
> }
> - iconv_close(ucs_to_wchar_conv);
> - iconv_close(wchar_to_ucs_conv);
> + iconv_close(ucs2_to_nativecharset);
> + iconv_close(nativecharset_to_ucs2);
> iconv_close(font_conv);
> }
>
>
[-- Attachment #2: OpenPGP digital signature --]
[-- Type: application/pgp-signature, Size: 850 bytes --]
^ permalink raw reply [flat|nested] 13+ messages in thread
* Re: [Qemu-devel] [PATCHv3 1/2] ui/curses: Do not assume wchar_t contains unicode
@ 2019-04-27 17:36 ` Kamil Rytarowski
0 siblings, 0 replies; 13+ messages in thread
From: Kamil Rytarowski @ 2019-04-27 17:36 UTC (permalink / raw)
To: Samuel Thibault, qemu-devel; +Cc: kamil, kraxel
[-- Attachment #1: Type: text/plain, Size: 11293 bytes --]
On 27.04.2019 18:30, Samuel Thibault wrote:
> E.g. BSD and Solaris even use locale-specific encoding there.
>
> We thus have to go through the native multibyte representation and use
> mbtowc/wctomb to make a proper conversion.
>
> Signed-off-by: Samuel Thibault <samuel.thibault@ens-lyon.org>
Both patches work for me on NetBSD/amd64 8.99.37 for qemu-system-x86_64.
Borders are printed correctly.
Regarding the patch I'm not sure whether to use MB_LEN_MAX or MB_CUR_MAX?
I'm also unsure whether to reset conversion state between a multibyte
character and wide character, with: `mbtowc(NULL, 0, 0);`. It's
recommended to use in code examples examples. I think it doesn't make
any harm to use it.
I'm not sure if this is related, but "qemu-system-hppa -curses" is
broken for me. I didn't use it in the past as it just recently acquired
NetBSD guest support.
(lldb) bt
* thread #1, stop reason = signal SIGSEGV
frame #0: 0x00007f7ff6c1fb98
libcurses.so.7`wmove(win=0x0000000000000000, y=0, x=0) at move.c:71
frame #1: 0x00007f7ff6c0ca9b
libcurses.so.7`mvwadd_wchnstr(win=0x0000000000000000, y=<unavailable>,
x=<unavailable>, wchstr=0x00007f7fffffe020, n=0) at add_wchstr.c:123
* frame #2: 0x000000000078629e
qemu-system-hppa`curses_update(dcl=0x00007f7ff7bd8bc0, x=0, y=0, w=79,
h=24) at curses.c:86:9
frame #3: 0x0000000000753dae
qemu-system-hppa`dpy_text_update(con=0x00007f7ff7bae580, x=0, y=0, w=79,
h=24) at console.c:1658:13
frame #4: 0x0000000000758abe
qemu-system-hppa`text_console_update(opaque=0x00007f7ff7bae580,
chardata=0x000000000118e490) at console.c:1264:9
frame #5: 0x0000000000751ef8
qemu-system-hppa`graphic_hw_text_update(con=0x00007f7ff7bae580,
chardata=0x000000000118c690) at console.c:389:9
frame #6: 0x0000000000785bcb
qemu-system-hppa`curses_refresh(dcl=0x00007f7ff7bd8bc0) at curses.c:273:5
frame #7: 0x0000000000758248
qemu-system-hppa`dpy_refresh(s=0x00007f7ff7bd8770) at console.c:1622:13
frame #8: 0x000000000075809d
qemu-system-hppa`gui_update(opaque=0x00007f7ff7bd8770) at console.c:205:5
frame #9: 0x00000000008d9f4d
qemu-system-hppa`timerlist_run_timers(timer_list=0x00007f7ff7e57d20) at
qemu-timer.c:574:9
frame #10: 0x00000000008da01d
qemu-system-hppa`qemu_clock_run_timers(type=QEMU_CLOCK_REALTIME) at
qemu-timer.c:588:12
frame #11: 0x00000000008da4ea
qemu-system-hppa`qemu_clock_run_all_timers at qemu-timer.c:708:25
frame #12: 0x00000000008da962
qemu-system-hppa`main_loop_wait(nonblocking=0) at main-loop.c:519:5
frame #13: 0x00000000005570a4 qemu-system-hppa`main_loop at vl.c:1970:9
frame #14: 0x0000000000551fa4 qemu-system-hppa`main(argc=2,
argv=0x00007f7fffffe768, envp=0x00007f7fffffe780) at vl.c:4604:5
frame #15: 0x000000000040e7ad qemu-system-hppa`___start + 280
(lldb) p screenpad
(WINDOW *) $2 = 0x0000000000000000
We pass NULL window argument to mvwadd_wchnstr(3) and crash. Can you
reproduce it locally?
I will try to investigate it.
> ---
> ui/curses.c | 151 ++++++++++++++++++++++++++++++++--------------------
> 1 file changed, 94 insertions(+), 57 deletions(-)
>
> diff --git a/ui/curses.c b/ui/curses.c
> index fb63945188..395f9545e9 100644
> --- a/ui/curses.c
> +++ b/ui/curses.c
> @@ -400,65 +400,102 @@ static void curses_atexit(void)
> endwin();
> }
>
> +/*
> + * In the following:
> + * - fch is the font glyph number
> + * - uch is the unicode value
> + * - wch is the wchar_t value (may not be unicode, e.g. on BSD/solaris)
> + * - mbch is the native local-dependent multibyte representation
> + */
> +
> /* Setup wchar glyph for one UCS-2 char */
> -static void convert_ucs(int glyph, uint16_t ch, iconv_t conv)
> +static void convert_ucs(unsigned char fch, uint16_t uch, iconv_t conv)
> {
> + char mbch[MB_CUR_MAX];
> wchar_t wch;
> - char *pch, *pwch;
> - size_t sch, swch;
> -
> - pch = (char *) &ch;
> - pwch = (char *) &wch;
> - sch = sizeof(ch);
> - swch = sizeof(wch);
> + char *puch, *pmbch;
> + size_t such, smbch;
> +
> + puch = (char *) &uch;
> + pmbch = (char *) mbch;
> + such = sizeof(uch);
> + smbch = sizeof(mbch);
> +
> + if (iconv(conv, &puch, &such, &pmbch, &smbch) == (size_t) -1) {
> + fprintf(stderr, "Could not convert 0x%04x "
> + "from UCS-2 to a multibyte character: %s\n",
> + uch, strerror(errno));
> + return;
> + }
>
> - if (iconv(conv, &pch, &sch, &pwch, &swch) == (size_t) -1) {
> - fprintf(stderr, "Could not convert 0x%04x from UCS-2 to WCHAR_T: %s\n",
> - ch, strerror(errno));
> - } else {
> - vga_to_curses[glyph].chars[0] = wch;
> + if (mbtowc(&wch, mbch, sizeof(mbch) - smbch) == -1) {
> + fprintf(stderr, "Could not convert 0x%04x "
> + "from a multibyte character to wchar_t: %s\n",
> + uch, strerror(errno));
> + return;
> }
> + vga_to_curses[fch].chars[0] = wch;
> }
>
> /* Setup wchar glyph for one font character */
> -static void convert_font(unsigned char ch, iconv_t conv)
> +static void convert_font(unsigned char fch, iconv_t conv)
> {
> + char mbch[MB_CUR_MAX];
> wchar_t wch;
> - char *pch, *pwch;
> - size_t sch, swch;
> -
> - pch = (char *) &ch;
> - pwch = (char *) &wch;
> - sch = sizeof(ch);
> - swch = sizeof(wch);
> + char *pfch, *pmbch;
> + size_t sfch, smbch;
> +
> + pfch = (char *) &fch;
> + pmbch = (char *) &mbch;
> + sfch = sizeof(fch);
> + smbch = sizeof(mbch);
> +
> + if (iconv(conv, &pfch, &sfch, &pmbch, &smbch) == (size_t) -1) {
> + fprintf(stderr, "Could not convert font glyph 0x%02x "
> + "from %s to a multibyte character: %s\n",
> + fch, font_charset, strerror(errno));
> + return;
> + }
>
> - if (iconv(conv, &pch, &sch, &pwch, &swch) == (size_t) -1) {
> - fprintf(stderr, "Could not convert 0x%02x from %s to WCHAR_T: %s\n",
> - ch, font_charset, strerror(errno));
> - } else {
> - vga_to_curses[ch].chars[0] = wch;
> + if (mbtowc(&wch, mbch, sizeof(mbch) - smbch) == -1) {
> + fprintf(stderr, "Could not convert font glyph 0x%02x "
> + "from a multibyte character to wchar_t: %s\n",
> + fch, strerror(errno));
> + return;
> }
> + vga_to_curses[fch].chars[0] = wch;
> }
>
> /* Convert one wchar to UCS-2 */
> static uint16_t get_ucs(wchar_t wch, iconv_t conv)
> {
> - uint16_t ch;
> - char *pch, *pwch;
> - size_t sch, swch;
> -
> - pch = (char *) &ch;
> - pwch = (char *) &wch;
> - sch = sizeof(ch);
> - swch = sizeof(wch);
> -
> - if (iconv(conv, &pwch, &swch, &pch, &sch) == (size_t) -1) {
> - fprintf(stderr, "Could not convert 0x%02lx from WCHAR_T to UCS-2: %s\n",
> - (unsigned long)wch, strerror(errno));
> + char mbch[MB_CUR_MAX];
> + uint16_t uch;
> + char *pmbch, *puch;
> + size_t smbch, such;
> + int ret;
> +
> + ret = wctomb(mbch, wch);
> + if (ret == -1) {
> + fprintf(stderr, "Could not convert 0x%04x "
> + "from wchar_t to a multibyte character: %s\n",
> + wch, strerror(errno));
> + return 0xFFFD;
> + }
> +
> + pmbch = (char *) mbch;
> + puch = (char *) &uch;
> + smbch = ret;
> + such = sizeof(uch);
> +
> + if (iconv(conv, &pmbch, &smbch, &puch, &such) == (size_t) -1) {
> + fprintf(stderr, "Could not convert 0x%04x "
> + "from a multibyte character to UCS-2 : %s\n",
> + wch, strerror(errno));
> return 0xFFFD;
> }
>
> - return ch;
> + return uch;
> }
>
> /*
> @@ -466,6 +503,11 @@ static uint16_t get_ucs(wchar_t wch, iconv_t conv)
> */
> static void font_setup(void)
> {
> + iconv_t ucs2_to_nativecharset;
> + iconv_t nativecharset_to_ucs2;
> + iconv_t font_conv;
> + int i;
> +
> /*
> * Control characters are normally non-printable, but VGA does have
> * well-known glyphs for them.
> @@ -505,30 +547,25 @@ static void font_setup(void)
> 0x25bc
> };
>
> - iconv_t ucs_to_wchar_conv;
> - iconv_t wchar_to_ucs_conv;
> - iconv_t font_conv;
> - int i;
> -
> - ucs_to_wchar_conv = iconv_open("WCHAR_T", "UCS-2");
> - if (ucs_to_wchar_conv == (iconv_t) -1) {
> + ucs2_to_nativecharset = iconv_open(nl_langinfo(CODESET), "UCS-2");
> + if (ucs2_to_nativecharset == (iconv_t) -1) {
> fprintf(stderr, "Could not convert font glyphs from UCS-2: '%s'\n",
> strerror(errno));
> exit(1);
> }
>
> - wchar_to_ucs_conv = iconv_open("UCS-2", "WCHAR_T");
> - if (wchar_to_ucs_conv == (iconv_t) -1) {
> - iconv_close(ucs_to_wchar_conv);
> + nativecharset_to_ucs2 = iconv_open("UCS-2", nl_langinfo(CODESET));
> + if (nativecharset_to_ucs2 == (iconv_t) -1) {
> + iconv_close(ucs2_to_nativecharset);
> fprintf(stderr, "Could not convert font glyphs to UCS-2: '%s'\n",
> strerror(errno));
> exit(1);
> }
>
> - font_conv = iconv_open("WCHAR_T", font_charset);
> + font_conv = iconv_open(nl_langinfo(CODESET), font_charset);
> if (font_conv == (iconv_t) -1) {
> - iconv_close(ucs_to_wchar_conv);
> - iconv_close(wchar_to_ucs_conv);
> + iconv_close(ucs2_to_nativecharset);
> + iconv_close(nativecharset_to_ucs2);
> fprintf(stderr, "Could not convert font glyphs from %s: '%s'\n",
> font_charset, strerror(errno));
> exit(1);
> @@ -536,7 +573,7 @@ static void font_setup(void)
>
> /* Control characters */
> for (i = 0; i <= 0x1F; i++) {
> - convert_ucs(i, control_characters[i], ucs_to_wchar_conv);
> + convert_ucs(i, control_characters[i], ucs2_to_nativecharset);
> }
>
> for (i = 0x20; i <= 0xFF; i++) {
> @@ -544,12 +581,12 @@ static void font_setup(void)
> }
>
> /* DEL */
> - convert_ucs(0x7F, 0x2302, ucs_to_wchar_conv);
> + convert_ucs(0x7F, 0x2302, ucs2_to_nativecharset);
>
> if (strcmp(nl_langinfo(CODESET), "UTF-8")) {
> /* Non-Unicode capable, use termcap equivalents for those available */
> for (i = 0; i <= 0xFF; i++) {
> - switch (get_ucs(vga_to_curses[i].chars[0], wchar_to_ucs_conv)) {
> + switch (get_ucs(vga_to_curses[i].chars[0], nativecharset_to_ucs2)) {
> case 0x00a3:
> vga_to_curses[i] = *WACS_STERLING;
> break;
> @@ -649,8 +686,8 @@ static void font_setup(void)
> }
> }
> }
> - iconv_close(ucs_to_wchar_conv);
> - iconv_close(wchar_to_ucs_conv);
> + iconv_close(ucs2_to_nativecharset);
> + iconv_close(nativecharset_to_ucs2);
> iconv_close(font_conv);
> }
>
>
[-- Attachment #2: OpenPGP digital signature --]
[-- Type: application/pgp-signature, Size: 850 bytes --]
^ permalink raw reply [flat|nested] 13+ messages in thread
* Re: [Qemu-devel] [PATCHv3 1/2] ui/curses: Do not assume wchar_t contains unicode
@ 2019-04-27 17:57 ` Samuel Thibault
0 siblings, 0 replies; 13+ messages in thread
From: Samuel Thibault @ 2019-04-27 17:57 UTC (permalink / raw)
To: Kamil Rytarowski; +Cc: qemu-devel, kraxel, kamil
Kamil Rytarowski, le sam. 27 avril 2019 19:36:40 +0200, a ecrit:
> On 27.04.2019 18:30, Samuel Thibault wrote:
> > E.g. BSD and Solaris even use locale-specific encoding there.
> >
> > We thus have to go through the native multibyte representation and use
> > mbtowc/wctomb to make a proper conversion.
> >
> > Signed-off-by: Samuel Thibault <samuel.thibault@ens-lyon.org>
>
> Both patches work for me on NetBSD/amd64 8.99.37 for qemu-system-x86_64.
> Borders are printed correctly.
>
> Regarding the patch I'm not sure whether to use MB_LEN_MAX or MB_CUR_MAX?
I don't know if qemu can afford VLA?
> I'm also unsure whether to reset conversion state between a multibyte
> character and wide character, with: `mbtowc(NULL, 0, 0);`. It's
> recommended to use in code examples examples. I think it doesn't make
> any harm to use it.
Mmm, better yet, we should actually use mbrtowc and wcrtomb. I have
fixed this in my tree.
> I'm not sure if this is related, but "qemu-system-hppa -curses" is
> broken for me. I didn't use it in the past as it just recently acquired
> NetBSD guest support.
>
> (lldb) bt
> libcurses.so.7`mvwadd_wchnstr(win=0x0000000000000000, y=<unavailable>,
> x=<unavailable>, wchstr=0x00007f7fffffe020, n=0) at add_wchstr.c:123
> * frame #2: 0x000000000078629e
> qemu-system-hppa`curses_update(dcl=0x00007f7ff7bd8bc0, x=0, y=0, w=79,
> h=24) at curses.c:86:9
> frame #3: 0x0000000000753dae
> qemu-system-hppa`dpy_text_update(con=0x00007f7ff7bae580, x=0, y=0, w=79,
> (lldb) p screenpad
> (WINDOW *) $2 = 0x0000000000000000
I don't think this is related at all, screenpad management is another
matter.
Samuel
^ permalink raw reply [flat|nested] 13+ messages in thread
* Re: [Qemu-devel] [PATCHv3 1/2] ui/curses: Do not assume wchar_t contains unicode
@ 2019-04-27 17:57 ` Samuel Thibault
0 siblings, 0 replies; 13+ messages in thread
From: Samuel Thibault @ 2019-04-27 17:57 UTC (permalink / raw)
To: Kamil Rytarowski; +Cc: kamil, qemu-devel, kraxel
Kamil Rytarowski, le sam. 27 avril 2019 19:36:40 +0200, a ecrit:
> On 27.04.2019 18:30, Samuel Thibault wrote:
> > E.g. BSD and Solaris even use locale-specific encoding there.
> >
> > We thus have to go through the native multibyte representation and use
> > mbtowc/wctomb to make a proper conversion.
> >
> > Signed-off-by: Samuel Thibault <samuel.thibault@ens-lyon.org>
>
> Both patches work for me on NetBSD/amd64 8.99.37 for qemu-system-x86_64.
> Borders are printed correctly.
>
> Regarding the patch I'm not sure whether to use MB_LEN_MAX or MB_CUR_MAX?
I don't know if qemu can afford VLA?
> I'm also unsure whether to reset conversion state between a multibyte
> character and wide character, with: `mbtowc(NULL, 0, 0);`. It's
> recommended to use in code examples examples. I think it doesn't make
> any harm to use it.
Mmm, better yet, we should actually use mbrtowc and wcrtomb. I have
fixed this in my tree.
> I'm not sure if this is related, but "qemu-system-hppa -curses" is
> broken for me. I didn't use it in the past as it just recently acquired
> NetBSD guest support.
>
> (lldb) bt
> libcurses.so.7`mvwadd_wchnstr(win=0x0000000000000000, y=<unavailable>,
> x=<unavailable>, wchstr=0x00007f7fffffe020, n=0) at add_wchstr.c:123
> * frame #2: 0x000000000078629e
> qemu-system-hppa`curses_update(dcl=0x00007f7ff7bd8bc0, x=0, y=0, w=79,
> h=24) at curses.c:86:9
> frame #3: 0x0000000000753dae
> qemu-system-hppa`dpy_text_update(con=0x00007f7ff7bae580, x=0, y=0, w=79,
> (lldb) p screenpad
> (WINDOW *) $2 = 0x0000000000000000
I don't think this is related at all, screenpad management is another
matter.
Samuel
^ permalink raw reply [flat|nested] 13+ messages in thread
* Re: [Qemu-devel] [PATCHv3 1/2] ui/curses: Do not assume wchar_t contains unicode
2019-04-27 17:57 ` Samuel Thibault
(?)
@ 2019-04-27 18:05 ` Kamil Rytarowski
-1 siblings, 0 replies; 13+ messages in thread
From: Kamil Rytarowski @ 2019-04-27 18:05 UTC (permalink / raw)
To: Samuel Thibault; +Cc: kamil, qemu-devel, kraxel
[-- Attachment #1: Type: text/plain, Size: 1937 bytes --]
On 27.04.2019 19:57, Samuel Thibault wrote:
> Kamil Rytarowski, le sam. 27 avril 2019 19:36:40 +0200, a ecrit:
>> On 27.04.2019 18:30, Samuel Thibault wrote:
>>> E.g. BSD and Solaris even use locale-specific encoding there.
>>>
>>> We thus have to go through the native multibyte representation and use
>>> mbtowc/wctomb to make a proper conversion.
>>>
>>> Signed-off-by: Samuel Thibault <samuel.thibault@ens-lyon.org>
>>
>> Both patches work for me on NetBSD/amd64 8.99.37 for qemu-system-x86_64.
>> Borders are printed correctly.
>>
>> Regarding the patch I'm not sure whether to use MB_LEN_MAX or MB_CUR_MAX?
>
> I don't know if qemu can afford VLA?
>
It's better to avoid VLA and pick MB_LEN_MAX.
>> I'm also unsure whether to reset conversion state between a multibyte
>> character and wide character, with: `mbtowc(NULL, 0, 0);`. It's
>> recommended to use in code examples examples. I think it doesn't make
>> any harm to use it.
>
> Mmm, better yet, we should actually use mbrtowc and wcrtomb. I have
> fixed this in my tree.
>
This is even better.
>> I'm not sure if this is related, but "qemu-system-hppa -curses" is
>> broken for me. I didn't use it in the past as it just recently acquired
>> NetBSD guest support.
>>
>> (lldb) bt
>> libcurses.so.7`mvwadd_wchnstr(win=0x0000000000000000, y=<unavailable>,
>> x=<unavailable>, wchstr=0x00007f7fffffe020, n=0) at add_wchstr.c:123
>> * frame #2: 0x000000000078629e
>> qemu-system-hppa`curses_update(dcl=0x00007f7ff7bd8bc0, x=0, y=0, w=79,
>> h=24) at curses.c:86:9
>> frame #3: 0x0000000000753dae
>> qemu-system-hppa`dpy_text_update(con=0x00007f7ff7bae580, x=0, y=0, w=79,
>
>> (lldb) p screenpad
>> (WINDOW *) $2 = 0x0000000000000000
>
> I don't think this is related at all, screenpad management is another
> matter.
>
OK! I will treat it as an independent issue and try to address it.
> Samuel
>
[-- Attachment #2: OpenPGP digital signature --]
[-- Type: application/pgp-signature, Size: 850 bytes --]
^ permalink raw reply [flat|nested] 13+ messages in thread
end of thread, other threads:[~2019-04-27 18:05 UTC | newest]
Thread overview: 13+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2019-04-27 16:30 [Qemu-devel] [PATCHv3 0/2] ui/curses: BSD portability fixes Samuel Thibault
2019-04-27 16:30 ` Samuel Thibault
2019-04-27 16:30 ` [Qemu-devel] [PATCH] curses: do not assume wchar_t contains unicode Samuel Thibault
2019-04-27 16:30 ` Samuel Thibault
2019-04-27 16:30 ` [Qemu-devel] [PATCHv3 1/2] ui/curses: Do " Samuel Thibault
2019-04-27 16:30 ` Samuel Thibault
2019-04-27 17:36 ` Kamil Rytarowski
2019-04-27 17:36 ` Kamil Rytarowski
2019-04-27 17:57 ` Samuel Thibault
2019-04-27 17:57 ` Samuel Thibault
2019-04-27 18:05 ` Kamil Rytarowski
2019-04-27 16:30 ` [Qemu-devel] [PATCHv3 2/2] ui/curses: manipulate cchar_t with standard curses functions Samuel Thibault
2019-04-27 16:30 ` Samuel Thibault
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.