This detects and uses iconv to convert glyphs from the specified VGA font encoding to unicode.
Signed-off-by: Samuel Thibault <samuel.thiba...@ens-lyon.org> --- configure | 37 +++++++++++++++++++++++++++++++++++++ include/sysemu/sysemu.h | 1 + qemu-options.hx | 20 ++++++++++++++++++++ ui/curses.c | 40 ++++++++++++++++++++++++++++++++++++++++ vl.c | 4 ++++ 5 files changed, 102 insertions(+) diff --git a/configure b/configure index ff10012..14e98f5 100755 --- a/configure +++ b/configure @@ -204,6 +204,7 @@ brlapi="" curl="" curses="" cursesw="" +iconv="" docs="" fdt="" netmap="no" @@ -983,6 +984,10 @@ for opt do ;; --enable-cursesw) cursesw="yes" ;; + --disable-iconv) iconv="no" + ;; + --enable-iconv) iconv="yes" + ;; --disable-curl) curl="no" ;; --enable-curl) curl="yes" @@ -1333,6 +1338,7 @@ disabled with --disable-FEATURE, default is enabled if available: vte vte support for the gtk UI curses curses UI cursesw cursesw 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 @@ -2968,6 +2974,33 @@ EOF fi ########################################## +# iconv probe +if test "$iconv" != "no" ; then + cat > $TMPC << EOF +#include <iconv.h> +int main(void) { + iconv_t conv = iconv_open("ISO-8859-1", "ISO-8859-1"); + return conv != (iconv_t) -1; +} +EOF + for iconv_lib in '' -liconv; do + if compile_prog "" "$iconv_lib" ; then + iconv_found=yes + libs_softmmu="$iconv_lib $libs_softmmu" + break + fi + done + if test "$iconv_found" = "yes" ; then + iconv=yes + else + if test "$iconv" = "yes" ; then + feature_not_found "iconv" "Install iconv devel" + fi + iconv=no + fi +fi + +########################################## # curl probe if test "$curl" != "no" ; then if $pkg_config libcurl --exists; then @@ -4859,6 +4892,7 @@ echo "nettle kdf $nettle_kdf" echo "libtasn1 $tasn1" echo "curses support $curses" echo "cursesw support $cursesw" +echo "iconv support $iconv" echo "virgl support $virglrenderer" echo "curl support $curl" echo "mingw32 support $mingw32" @@ -5120,6 +5154,9 @@ fi if test "$cursesw" = "yes" ; then echo "CONFIG_CURSESW=y" >> $config_host_mak fi +if test "$iconv" = "yes" ; then + echo "CONFIG_ICONV=y" >> $config_host_mak +fi if test "$utimens" = "yes" ; then echo "CONFIG_UTIMENSAT=y" >> $config_host_mak fi diff --git a/include/sysemu/sysemu.h b/include/sysemu/sysemu.h index 7313673..a690c18 100644 --- a/include/sysemu/sysemu.h +++ b/include/sysemu/sysemu.h @@ -147,6 +147,7 @@ extern int graphic_height; extern int graphic_depth; extern int display_opengl; extern const char *keyboard_layout; +extern const char *font_encoding; extern int win2k_install_hack; extern int alt_grab; extern int ctrl_grab; diff --git a/qemu-options.hx b/qemu-options.hx index ce535a9..2187886 100644 --- a/qemu-options.hx +++ b/qemu-options.hx @@ -321,6 +321,26 @@ The default is @code{en-us}. ETEXI +DEF("f", HAS_ARG, QEMU_OPTION_f, + "-f encoding use font encoding (for example 'CP850' for IBM CP850 encoding)\n", + QEMU_ARCH_ALL) +STEXI +@item -h @var{encoding} +@findex -h +Use font encoding @var{encoding} (for example @code{CP850} for +IBM CP/850 encoding). This option is only needed where output is text-only, i.e. +with the curses display, to convert from text-mode output from the guest to +proper text glyphs. + +The available encoding are provided by the libc, the full list can be obtained by +@example +iconv -l +@end example + +The default is @code{CP437}. +ETEXI + + DEF("audio-help", 0, QEMU_OPTION_audio_help, "-audio-help print list of audio drivers and their options\n", QEMU_ARCH_ALL) diff --git a/ui/curses.c b/ui/curses.c index 9ef54b5..a8dada9 100644 --- a/ui/curses.c +++ b/ui/curses.c @@ -33,6 +33,9 @@ #include <wchar.h> #include <langinfo.h> #endif +#ifdef CONFIG_ICONV +#include <iconv.h> +#endif #include "qemu-common.h" #include "ui/console.h" @@ -412,6 +415,43 @@ static void curses_setup(void) vga_to_curses[0x1e].chars[0] = L'\u25b2'; vga_to_curses[0x1f].chars[0] = L'\u25bc'; +#ifdef CONFIG_ICONV + if (font_encoding) { + unsigned char ch; + wchar_t wch; + char *pch, *pwch; + size_t sch, swch; + iconv_t conv; + + conv = iconv_open("WCHAR_T", font_encoding); + if (conv == (iconv_t) -1) { + fprintf(stderr, "Could not convert font glyphs from %s: '%s'\n", font_encoding, strerror(errno)); + exit(1); + } + + for (i = 0x20; i <= 0xff; i++) + { + ch = i; + pch = (char*) &ch; + pwch = (char*) &wch; + sch = sizeof(ch); + swch = sizeof(wch); + if (iconv(conv, &pch, &sch, &pwch, &swch) == (size_t) -1) { + fprintf(stderr,"Could not convert 0x%2x from %s: '%s'\n", ch, font_encoding, strerror(errno)); + } else { + vga_to_curses[ch].chars[0] = wch; + } + } + } else +#else + if (font_encoding) { + if (strcmp(font_encoding, "CP437")) + { + fprintf(stderr,"iconv support not enabled for converting from %s, only CP437 supported\n", font_encoding); + exit(1); + } + } +#endif { /* Hardcode CP437 to unicode */ vga_to_curses[0x80].chars[0] = L'\u00C7'; diff --git a/vl.c b/vl.c index 2f63eb4..508a59f 100644 --- a/vl.c +++ b/vl.c @@ -132,6 +132,7 @@ enum vga_retrace_method vga_retrace_method = VGA_RETRACE_DUMB; int request_opengl = -1; int display_opengl; const char* keyboard_layout = NULL; +const char* font_encoding = NULL; ram_addr_t ram_size; const char *mem_path = NULL; int mem_prealloc = 0; /* force preallocation of physical target memory */ @@ -3370,6 +3371,9 @@ int main(int argc, char **argv, char **envp) case QEMU_OPTION_k: keyboard_layout = optarg; break; + case QEMU_OPTION_f: + font_encoding = optarg; + break; case QEMU_OPTION_localtime: rtc_utc = 0; break; -- 2.8.1