@@ -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
@@ -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;
@@ -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)
@@ -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';
@@ -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;
This detects and uses iconv to convert glyphs from the specified VGA font encoding to unicode. Signed-off-by: Samuel Thibault <samuel.thibault@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(+)