diff --git a/caca/driver_ncurses.c b/caca/driver_ncurses.c index 7d475ab..16023f0 100644 --- a/caca/driver_ncurses.c +++ b/caca/driver_ncurses.c @@ -21,7 +21,11 @@ #if defined(USE_NCURSES) -#if defined(HAVE_NCURSES_H) +#if defined(HAVE_NCURSESW_NCURSES_H) +# include +#elif defined(HAVE_NCURSES_NCURSES_H) +# include +#elif defined(HAVE_NCURSES_H) # include #else # include @@ -53,6 +57,7 @@ static caca_t *sigwinch_kk; /* FIXME: we ought to get rid of this */ #if defined(HAVE_GETENV) && defined(HAVE_PUTENV) static void ncurses_check_terminal(void); #endif +static void ncurses_write_utf32(uint32_t); struct driver_private { @@ -192,13 +197,8 @@ static void ncurses_display(caca_t *kk) move(y, 0); for(x = kk->qq->width; x--; ) { - uint32_t c = *chars++; - attrset(kk->drv.p->attr[*attr++]); - if(c > 0x00000020 && c < 0x00000080) - addch((char)c); - else - addch(' '); + ncurses_write_utf32(*chars++); } } refresh(); @@ -453,6 +453,49 @@ static void ncurses_check_terminal(void) } #endif +static void ncurses_write_utf32(uint32_t c) +{ +#if defined(HAVE_NCURSESW_NCURSES_H) + static const uint8_t mark[7] = + { + 0x00, 0x00, 0xC0, 0xE0, 0xF0, 0xF8, 0xFC + }; + + char buf[10], *parser; + int bytes; +#endif + + if(c < 0x80) + { + addch(c); + return; + } + +#if defined(HAVE_NCURSESW_NCURSES_H) + if(c < 0x10000) + { + addch(c); /* FIXME: doesn't work either */ + return; + } + + bytes = (c < 0x800) ? 2 : (c < 0x10000) ? 3 : 4; + buf[bytes] = '\0'; + parser = buf + bytes; + + switch(bytes) + { + case 4: *--parser = (c | 0x80) & 0xbf; c >>= 6; + case 3: *--parser = (c | 0x80) & 0xbf; c >>= 6; + case 2: *--parser = (c | 0x80) & 0xbf; c >>= 6; + } + *--parser = c | mark[bytes]; + + addstr(buf); +#else + addch(' '); +#endif +} + /* * Driver initialisation */ diff --git a/configure.ac b/configure.ac index f9bae02..9cdd782 100644 --- a/configure.ac +++ b/configure.ac @@ -158,17 +158,24 @@ fi if test "${enable_ncurses}" != "no"; then ac_cv_my_have_ncurses="no" - AC_CHECK_HEADERS(curses.h ncurses.h, - [AC_CHECK_LIB(ncurses, initscr, - [ac_cv_my_have_ncurses="yes" - AC_DEFINE(USE_NCURSES, 1, Define to 1 to activate the ncurses backend driver) - CACA_LIBS="${CACA_LIBS} -lncurses" - CACA_DRIVERS="${CACA_DRIVERS} ncurses" - dnl Check for resizeterm or resize_term - SAVED_LIBS="${LIBS}" - LIBS="${LIBS} -lncurses" - AC_CHECK_FUNCS(resizeterm resize_term) - LIBS="${SAVED_LIBS}"]) + AC_CHECK_HEADERS(ncursesw/ncurses.h ncurses/ncurses.h ncurses.h curses.h, + [ncurses="no" + AC_CHECK_LIB(ncursesw, initscr, + [ncurses="-lncursesw"], + [AC_CHECK_LIB(ncurses, initscr, + [ncurses="-lncurses"])]) + if test "${ncurses}" = "no"; then + continue + fi + ac_cv_my_have_ncurses="yes" + AC_DEFINE(USE_NCURSES, 1, Define to 1 to activate the ncurses backend driver) + CACA_LIBS="${CACA_LIBS} ${ncurses}" + CACA_DRIVERS="${CACA_DRIVERS} ncurses" + dnl Check for resizeterm or resize_term + SAVED_LIBS="${LIBS}" + LIBS="${LIBS} ${ncurses}" + AC_CHECK_FUNCS(resizeterm resize_term) + LIBS="${SAVED_LIBS}" break]) if test "${ac_cv_my_have_ncurses}" = "no" -a "${enable_ncurses}" = "yes"; then AC_MSG_ERROR([cannot find ncurses development files])