From nobody Sun Nov 9 17:55:26 2025 Delivered-To: importer@patchew.org Received-SPF: pass (zoho.com: domain of gnu.org designates 209.51.188.17 as permitted sender) client-ip=209.51.188.17; envelope-from=qemu-devel-bounces+importer=patchew.org@nongnu.org; helo=lists.gnu.org; Authentication-Results: mx.zohomail.com; spf=pass (zoho.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org Return-Path: Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) by mx.zohomail.com with SMTPS id 1551610011961171.3124727531191; Sun, 3 Mar 2019 02:46:51 -0800 (PST) Received: from localhost ([127.0.0.1]:36963 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1h0Odk-0006Cs-G8 for importer@patchew.org; Sun, 03 Mar 2019 05:46:40 -0500 Received: from eggs.gnu.org ([209.51.188.92]:39975) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1h0Obm-0005Ah-6P for qemu-devel@nongnu.org; Sun, 03 Mar 2019 05:44:39 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1h0Obl-0000jn-Ag for qemu-devel@nongnu.org; Sun, 03 Mar 2019 05:44:38 -0500 Received: from hera.aquilenet.fr ([185.233.100.1]:41424) by eggs.gnu.org with esmtps (TLS1.0:DHE_RSA_AES_256_CBC_SHA1:32) (Exim 4.71) (envelope-from ) id 1h0Obk-0000hr-UG for qemu-devel@nongnu.org; Sun, 03 Mar 2019 05:44:37 -0500 Received: from localhost (localhost [127.0.0.1]) by hera.aquilenet.fr (Postfix) with ESMTP id 83FF694AA; Sun, 3 Mar 2019 11:44:34 +0100 (CET) Received: from hera.aquilenet.fr ([127.0.0.1]) by localhost (hera.aquilenet.fr [127.0.0.1]) (amavisd-new, port 10024) with ESMTP id enn7MpeN0aqX; Sun, 3 Mar 2019 11:44:33 +0100 (CET) Received: from function (unknown [212.83.130.210]) by hera.aquilenet.fr (Postfix) with ESMTPSA id 5A4A294AC; Sun, 3 Mar 2019 11:44:33 +0100 (CET) Received: from samy by function with local (Exim 4.92-RC6) (envelope-from ) id 1h0Obf-00020p-1M; Sun, 03 Mar 2019 11:44:31 +0100 X-Virus-Scanned: Debian amavisd-new at aquilenet.fr From: Samuel Thibault To: qemu-devel@nongnu.org Date: Sun, 3 Mar 2019 11:44:29 +0100 Message-Id: <20190303104430.7692-2-samuel.thibault@ens-lyon.org> X-Mailer: git-send-email 2.20.1 In-Reply-To: <20190303104430.7692-1-samuel.thibault@ens-lyon.org> References: <20190303104430.7692-1-samuel.thibault@ens-lyon.org> MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable X-detected-operating-system: by eggs.gnu.org: GNU/Linux 2.2.x-3.x [generic] X-Received-From: 185.233.100.1 Subject: [Qemu-devel] [PATCH 1/2] iconv: detect and make curses depend on it X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.21 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: Eddie Kohler , armbru@redhat.com, kraxel@redhat.com, pbonzini@redhat.com, Samuel Thibault Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: "Qemu-devel" Content-Type: text/plain; charset="utf-8" curses will use it for proper wide output support. Signed-off-by: Samuel Thibault --- configure | 40 ++++++++++++++++++++++++++++++++++++++++ vl.c | 2 +- 2 files changed, 41 insertions(+), 1 deletion(-) diff --git a/configure b/configure index 540bee19ba..9979ca708d 100755 --- a/configure +++ b/configure @@ -1217,6 +1217,10 @@ for opt do ;; --enable-curses) curses=3D"yes" ;; + --disable-iconv) iconv=3D"no" + ;; + --enable-iconv) iconv=3D"yes" + ;; --disable-curl) curl=3D"no" ;; --enable-curl) curl=3D"yes" @@ -1718,6 +1722,7 @@ disabled with --disable-FEATURE, default is enabled i= f available: gtk gtk UI vte vte support for the gtk UI curses curses UI + iconv font glyph conversion support vnc VNC UI support vnc-sasl SASL encryption for VNC server vnc-jpeg JPEG lossy compression for VNC server @@ -3398,8 +3403,39 @@ EOF fi fi =20 +########################################## +# iconv probe +if test "$iconv" !=3D "no" ; then + cat > $TMPC << EOF +#include +int main(void) { + iconv_t conv =3D iconv_open("WCHAR_T", "UCS-2"); + return conv !=3D (iconv_t) -1; +} +EOF + for iconv_lib in '' -liconv; do + if compile_prog "" "$iconv_lib" ; then + iconv_found=3Dyes + libs_softmmu=3D"$iconv_lib $libs_softmmu" + break + fi + done + if test "$iconv_found" =3D "yes" ; then + iconv=3Dyes + else + if test "$iconv" =3D "yes" ; then + feature_not_found "iconv" "Install iconv devel" + fi + iconv=3Dno + fi +fi + ########################################## # curses probe +if test "$iconv" =3D "no" ; then + # curses will need iconv + curses=3Dno +fi if test "$curses" !=3D "no" ; then if test "$mingw32" =3D "yes" ; then curses_inc_list=3D"$($pkg_config --cflags ncurses 2>/dev/null):" @@ -6111,6 +6147,7 @@ echo "libgcrypt $gcrypt" echo "nettle $nettle $(echo_version $nettle $nettle_version)" echo "libtasn1 $tasn1" echo "PAM $auth_pam" +echo "iconv support $iconv" echo "curses support $curses" echo "virgl support $virglrenderer $(echo_version $virglrenderer $virg= l_version)" echo "curl support $curl" @@ -6435,6 +6472,9 @@ fi if test "$cocoa" =3D "yes" ; then echo "CONFIG_COCOA=3Dy" >> $config_host_mak fi +if test "$iconv" =3D "yes" ; then + echo "CONFIG_ICONV=3Dy" >> $config_host_mak +fi if test "$curses" =3D "yes" ; then echo "CONFIG_CURSES=3Dm" >> $config_host_mak echo "CURSES_CFLAGS=3D$curses_inc" >> $config_host_mak diff --git a/vl.c b/vl.c index 502857a176..c8594fc6d5 100644 --- a/vl.c +++ b/vl.c @@ -3171,7 +3171,7 @@ int main(int argc, char **argv, char **envp) #ifdef CONFIG_CURSES dpy.type =3D DISPLAY_TYPE_CURSES; #else - error_report("curses support is disabled"); + error_report("curses or iconv support is disabled"); exit(1); #endif break; --=20 2.20.1 From nobody Sun Nov 9 17:55:26 2025 Delivered-To: importer@patchew.org Received-SPF: pass (zoho.com: domain of gnu.org designates 209.51.188.17 as permitted sender) client-ip=209.51.188.17; envelope-from=qemu-devel-bounces+importer=patchew.org@nongnu.org; helo=lists.gnu.org; Authentication-Results: mx.zohomail.com; spf=pass (zoho.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org Return-Path: Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) by mx.zohomail.com with SMTPS id 1551610013837560.8743784001667; Sun, 3 Mar 2019 02:46:53 -0800 (PST) Received: from localhost ([127.0.0.1]:36965 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1h0Odo-0006EO-M8 for importer@patchew.org; Sun, 03 Mar 2019 05:46:44 -0500 Received: from eggs.gnu.org ([209.51.188.92]:39978) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1h0Obm-0005Aj-GR for qemu-devel@nongnu.org; Sun, 03 Mar 2019 05:44:40 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1h0Obk-0000jF-Sx for qemu-devel@nongnu.org; Sun, 03 Mar 2019 05:44:38 -0500 Received: from hera.aquilenet.fr ([185.233.100.1]:41438) by eggs.gnu.org with esmtps (TLS1.0:DHE_RSA_AES_256_CBC_SHA1:32) (Exim 4.71) (envelope-from ) id 1h0Obk-0000iE-IT for qemu-devel@nongnu.org; Sun, 03 Mar 2019 05:44:36 -0500 Received: from localhost (localhost [127.0.0.1]) by hera.aquilenet.fr (Postfix) with ESMTP id 790D094AC; Sun, 3 Mar 2019 11:44:35 +0100 (CET) Received: from hera.aquilenet.fr ([127.0.0.1]) by localhost (hera.aquilenet.fr [127.0.0.1]) (amavisd-new, port 10024) with ESMTP id mcdZ26EtXfAl; Sun, 3 Mar 2019 11:44:34 +0100 (CET) Received: from function (unknown [212.83.130.210]) by hera.aquilenet.fr (Postfix) with ESMTPSA id 6158D94AE; Sun, 3 Mar 2019 11:44:33 +0100 (CET) Received: from samy by function with local (Exim 4.92-RC6) (envelope-from ) id 1h0Obf-00020r-3r; Sun, 03 Mar 2019 11:44:31 +0100 X-Virus-Scanned: Debian amavisd-new at aquilenet.fr From: Samuel Thibault To: qemu-devel@nongnu.org Date: Sun, 3 Mar 2019 11:44:30 +0100 Message-Id: <20190303104430.7692-3-samuel.thibault@ens-lyon.org> X-Mailer: git-send-email 2.20.1 In-Reply-To: <20190303104430.7692-1-samuel.thibault@ens-lyon.org> References: <20190303104430.7692-1-samuel.thibault@ens-lyon.org> MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable X-detected-operating-system: by eggs.gnu.org: GNU/Linux 2.2.x-3.x [generic] X-Received-From: 185.233.100.1 Subject: [Qemu-devel] [PATCH 2/2] curses: add option to specify VGA font encoding X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.21 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: Eddie Kohler , armbru@redhat.com, kraxel@redhat.com, pbonzini@redhat.com, Samuel Thibault Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: "Qemu-devel" Content-Type: text/plain; charset="utf-8" This uses iconv to convert glyphs from the specified VGA font encoding to unicode, and makes use of cchar_t instead of chtype when using ncursesw, which allows to store all wide char as well as the WACS values. Signed-off-by: Samuel Thibault Cc: Eddie Kohler --- configure | 5 +- qapi/ui.json | 4 +- qemu-options.hx | 5 +- ui/curses.c | 315 ++++++++++++++++++++++++++++++++++++++++-------- 4 files changed, 279 insertions(+), 50 deletions(-) diff --git a/configure b/configure index 9979ca708d..1270dc8dc0 100755 --- a/configure +++ b/configure @@ -3449,14 +3449,17 @@ if test "$curses" !=3D "no" ; then #include #include #include +#include int main(void) { + const char *codeset; wchar_t wch =3D L'w'; setlocale(LC_ALL, ""); resize_term(0, 0); addwstr(L"wide chars\n"); addnwstr(&wch, 1); add_wch(WACS_DEGREE); - return 0; + codeset =3D nl_langinfo(CODESET); + return codeset !=3D 0; } EOF IFS=3D: diff --git a/qapi/ui.json b/qapi/ui.json index c5d1d7f099..12d3a2c751 100644 --- a/qapi/ui.json +++ b/qapi/ui.json @@ -1131,6 +1131,7 @@ # @full-screen: Start user interface in fullscreen mode (default: off). # @window-close: Allow to quit qemu with window close button (default: on= ). # @gl: Enable OpenGL support (default: off). +# @charset: Font charset used by guest (default: CP437). # # Since: 2.12 # @@ -1139,7 +1140,8 @@ 'base' : { 'type' : 'DisplayType', '*full-screen' : 'bool', '*window-close' : 'bool', - '*gl' : 'DisplayGLMode' }, + '*gl' : 'DisplayGLMode', + '*charset' : 'str' }, 'discriminator' : 'type', 'data' : { 'gtk' : 'DisplayGTK', 'egl-headless' : 'DisplayEGLHeadless'} } diff --git a/qemu-options.hx b/qemu-options.hx index 1cf9aac1fe..4bc4e736bb 100644 --- a/qemu-options.hx +++ b/qemu-options.hx @@ -1216,7 +1216,7 @@ DEF("display", HAS_ARG, QEMU_OPTION_display, " [,window_close=3Don|off][,gl=3Don|core|es|off]\n" "-display gtk[,grab_on_hover=3Don|off][,gl=3Don|off]|\n" "-display vnc=3D[,]\n" - "-display curses\n" + "-display curses[,charset=3D]\n" "-display none\n" "-display egl-headless[,rendernode=3D]" " select display type\n" @@ -1248,6 +1248,9 @@ support a text mode, QEMU can display this output usi= ng a curses/ncurses interface. Nothing is displayed when the graphics device is in graphical mode or if the graphics device does not support a text mode. Generally only the VGA device models support text mode. +The font charset used by the guest can be specified with the +@code{charset} option, for example @code{charset=3DCP850} for IBM CP850 +encoding. The default is @code{CP437}. @item none Do not display video output. The guest will still see an emulated graphics card, but its output will not be displayed to the QEMU diff --git a/ui/curses.c b/ui/curses.c index 1724dd57d4..203cc075d0 100644 --- a/ui/curses.c +++ b/ui/curses.c @@ -27,6 +27,10 @@ #include #include #endif +#include +#include +#include +#include =20 #include "qapi/error.h" #include "qemu-common.h" @@ -54,7 +58,8 @@ static WINDOW *screenpad =3D NULL; static int width, height, gwidth, gheight, invalidate; static int px, py, sminx, sminy, smaxx, smaxy; =20 -static chtype vga_to_curses[256]; +static const char *font_charset =3D "CP437"; +static cchar_t vga_to_curses[256]; =20 static wint_t console_getch(enum maybe_keycode *maybe_keycode) { @@ -77,19 +82,23 @@ static void curses_update(DisplayChangeListener *dcl, int x, int y, int w, int h) { console_ch_t *line; - chtype curses_line[width]; + cchar_t curses_line[width]; =20 line =3D screen + y * width; for (h +=3D y; y < h; y ++, line +=3D width) { for (x =3D 0; x < width; x++) { chtype ch =3D line[x] & 0xff; chtype at =3D line[x] & ~0xff; - if (vga_to_curses[ch]) { - ch =3D vga_to_curses[ch]; + if (vga_to_curses[ch].chars[0]) { + curses_line[x] =3D vga_to_curses[ch]; + } else { + curses_line[x].chars[0] =3D ch; + curses_line[x].chars[1] =3D 0; + curses_line[x].attr =3D 0; } - curses_line[x] =3D ch | at; + curses_line[x].attr |=3D at; } - mvwaddchnstr(screenpad, y, 0, curses_line, width); + mvwadd_wchnstr(screenpad, y, 0, curses_line, width); } =20 pnoutrefresh(screenpad, py, px, sminy, sminx, smaxy - 1, smaxx - 1); @@ -391,6 +400,254 @@ static void curses_atexit(void) endwin(); } =20 +/* Setup wchar glyph for one UCS-2 char */ +static void convert_ucs(int glyph, uint16_t ch, iconv_t conv) +{ + wchar_t wch; + char *pch, *pwch; + size_t sch, swch; + + pch =3D (char *) &ch; + pwch =3D (char *) &wch; + sch =3D sizeof(ch); + swch =3D sizeof(wch); + + if (iconv(conv, &pch, &sch, &pwch, &swch) =3D=3D (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] =3D wch; + } +} + +/* Setup wchar glyph for one font character */ +static void convert_font(unsigned char ch, iconv_t conv) +{ + wchar_t wch; + char *pch, *pwch; + size_t sch, swch; + + pch =3D (char *) &ch; + pwch =3D (char *) &wch; + sch =3D sizeof(ch); + swch =3D sizeof(wch); + + if (iconv(conv, &pch, &sch, &pwch, &swch) =3D=3D (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] =3D 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 =3D (char *) &ch; + pwch =3D (char *) &wch; + sch =3D sizeof(ch); + swch =3D sizeof(wch); + + if (iconv(conv, &pwch, &swch, &pch, &sch) =3D=3D (size_t) -1) { + fprintf(stderr, "Could not convert 0x%02x from WCHAR_T to UCS-2: %= s\n", + wch, strerror(errno)); + return 0xFFFD; + } + + return ch; +} + +/* + * Setup mapping for vga to curses line graphics. + */ +static void font_setup(void) +{ + /* + * Control characters are normally non-printable, but VGA does have + * well-known glyphs for them. + */ + static uint16_t control_characters[0x20] =3D { + 0x0020, + 0x263a, + 0x263b, + 0x2665, + 0x2666, + 0x2663, + 0x2660, + 0x2022, + 0x25d8, + 0x25cb, + 0x25d9, + 0x2642, + 0x2640, + 0x266a, + 0x266b, + 0x263c, + 0x25ba, + 0x25c4, + 0x2195, + 0x203c, + 0x00b6, + 0x00a7, + 0x25ac, + 0x21a8, + 0x2191, + 0x2193, + 0x2192, + 0x2190, + 0x221f, + 0x2194, + 0x25b2, + 0x25bc + }; + + iconv_t ucs_to_wchar_conv; + iconv_t wchar_to_ucs_conv; + iconv_t font_conv; + int i; + + ucs_to_wchar_conv =3D iconv_open("WCHAR_T", "UCS-2"); + if (ucs_to_wchar_conv =3D=3D (iconv_t) -1) { + fprintf(stderr, "Could not convert font glyphs from UCS-2: '%s'\n", + strerror(errno)); + exit(1); + } + + wchar_to_ucs_conv =3D iconv_open("UCS-2", "WCHAR_T"); + if (wchar_to_ucs_conv =3D=3D (iconv_t) -1) { + fprintf(stderr, "Could not convert font glyphs to UCS-2: '%s'\n", + strerror(errno)); + exit(1); + } + + font_conv =3D iconv_open("WCHAR_T", font_charset); + if (font_conv =3D=3D (iconv_t) -1) { + fprintf(stderr, "Could not convert font glyphs from %s: '%s'\n", + font_charset, strerror(errno)); + exit(1); + } + + /* Control characters */ + for (i =3D 0; i <=3D 0x1F; i++) { + convert_ucs(i, control_characters[i], ucs_to_wchar_conv); + } + + for (i =3D 0x20; i <=3D 0xFF; i++) { + convert_font(i, font_conv); + } + + /* DEL */ + convert_ucs(0x7F, 0x2302, ucs_to_wchar_conv); + + if (strcmp(nl_langinfo(CODESET), "UTF-8")) { + /* Non-Unicode capable, use termcap equivalents for those availabl= e */ + for (i =3D 0; i <=3D 0xFF; i++) { + switch (get_ucs(vga_to_curses[i].chars[0], wchar_to_ucs_conv))= { + case 0x00a3: + vga_to_curses[i] =3D *WACS_STERLING; + break; + case 0x2591: + vga_to_curses[i] =3D *WACS_BOARD; + break; + case 0x2592: + vga_to_curses[i] =3D *WACS_CKBOARD; + break; + case 0x2502: + vga_to_curses[i] =3D *WACS_VLINE; + break; + case 0x2524: + vga_to_curses[i] =3D *WACS_RTEE; + break; + case 0x2510: + vga_to_curses[i] =3D *WACS_URCORNER; + break; + case 0x2514: + vga_to_curses[i] =3D *WACS_LLCORNER; + break; + case 0x2534: + vga_to_curses[i] =3D *WACS_BTEE; + break; + case 0x252c: + vga_to_curses[i] =3D *WACS_TTEE; + break; + case 0x251c: + vga_to_curses[i] =3D *WACS_LTEE; + break; + case 0x2500: + vga_to_curses[i] =3D *WACS_HLINE; + break; + case 0x253c: + vga_to_curses[i] =3D *WACS_PLUS; + break; + case 0x256c: + vga_to_curses[i] =3D *WACS_LANTERN; + break; + case 0x256a: + vga_to_curses[i] =3D *WACS_NEQUAL; + break; + case 0x2518: + vga_to_curses[i] =3D *WACS_LRCORNER; + break; + case 0x250c: + vga_to_curses[i] =3D *WACS_ULCORNER; + break; + case 0x2588: + vga_to_curses[i] =3D *WACS_BLOCK; + break; + case 0x03c0: + vga_to_curses[i] =3D *WACS_PI; + break; + case 0x00b1: + vga_to_curses[i] =3D *WACS_PLMINUS; + break; + case 0x2265: + vga_to_curses[i] =3D *WACS_GEQUAL; + break; + case 0x2264: + vga_to_curses[i] =3D *WACS_LEQUAL; + break; + case 0x00b0: + vga_to_curses[i] =3D *WACS_DEGREE; + break; + case 0x25a0: + vga_to_curses[i] =3D *WACS_BULLET; + break; + case 0x2666: + vga_to_curses[i] =3D *WACS_DIAMOND; + break; + case 0x2192: + vga_to_curses[i] =3D *WACS_RARROW; + break; + case 0x2190: + vga_to_curses[i] =3D *WACS_LARROW; + break; + case 0x2191: + vga_to_curses[i] =3D *WACS_UARROW; + break; + case 0x2193: + vga_to_curses[i] =3D *WACS_DARROW; + break; + case 0x23ba: + vga_to_curses[i] =3D *WACS_S1; + break; + case 0x23bb: + vga_to_curses[i] =3D *WACS_S3; + break; + case 0x23bc: + vga_to_curses[i] =3D *WACS_S7; + break; + case 0x23bd: + vga_to_curses[i] =3D *WACS_S9; + break; + } + } + } +} + static void curses_setup(void) { int i, colour_default[8] =3D { @@ -419,47 +676,7 @@ static void curses_setup(void) init_pair(i, COLOR_WHITE, COLOR_BLACK); } =20 - /* - * Setup mapping for vga to curses line graphics. - * FIXME: for better font, have to use ncursesw and setlocale() - */ -#if 0 - /* FIXME: map from where? */ - ACS_S1; - ACS_S3; - ACS_S7; - ACS_S9; -#endif - /* ACS_* is not constant. So, we can't initialize statically. */ - vga_to_curses['\0'] =3D ' '; - vga_to_curses[0x04] =3D ACS_DIAMOND; - vga_to_curses[0x18] =3D ACS_UARROW; - vga_to_curses[0x19] =3D ACS_DARROW; - vga_to_curses[0x1a] =3D ACS_RARROW; - vga_to_curses[0x1b] =3D ACS_LARROW; - vga_to_curses[0x9c] =3D ACS_STERLING; - vga_to_curses[0xb0] =3D ACS_BOARD; - vga_to_curses[0xb1] =3D ACS_CKBOARD; - vga_to_curses[0xb3] =3D ACS_VLINE; - vga_to_curses[0xb4] =3D ACS_RTEE; - vga_to_curses[0xbf] =3D ACS_URCORNER; - vga_to_curses[0xc0] =3D ACS_LLCORNER; - vga_to_curses[0xc1] =3D ACS_BTEE; - vga_to_curses[0xc2] =3D ACS_TTEE; - vga_to_curses[0xc3] =3D ACS_LTEE; - vga_to_curses[0xc4] =3D ACS_HLINE; - vga_to_curses[0xc5] =3D ACS_PLUS; - vga_to_curses[0xce] =3D ACS_LANTERN; - vga_to_curses[0xd8] =3D ACS_NEQUAL; - vga_to_curses[0xd9] =3D ACS_LRCORNER; - vga_to_curses[0xda] =3D ACS_ULCORNER; - vga_to_curses[0xdb] =3D ACS_BLOCK; - vga_to_curses[0xe3] =3D ACS_PI; - vga_to_curses[0xf1] =3D ACS_PLMINUS; - vga_to_curses[0xf2] =3D ACS_GEQUAL; - vga_to_curses[0xf3] =3D ACS_LEQUAL; - vga_to_curses[0xf8] =3D ACS_DEGREE; - vga_to_curses[0xfe] =3D ACS_BULLET; + font_setup(); } =20 static void curses_keyboard_setup(void) @@ -492,6 +709,10 @@ static void curses_display_init(DisplayState *ds, Disp= layOptions *opts) } #endif =20 + setlocale(LC_CTYPE, ""); + if (opts->charset) { + font_charset =3D opts->charset; + } curses_setup(); curses_keyboard_setup(); atexit(curses_atexit); --=20 2.20.1