Mason Watmough
Mason Watmough

Reputation: 495

How could I guarantee a terminal has Unicode/wide character support with NCURSES?

I am developing an NCURSES application for a little TUI (text user interface) exercise. Unfortunately, I do not have the option of using the ever-so-wonderful-and-faithful ASCII. My program uses a LOT of Unicode box drawing characters.

My program can already detect if the terminal is color-capable. I need to do something like:

if(!supportsUnicode()) //I prefer camel-case, it's just the way I am.
{
    fprintf(stderr, "This program requires a Unicode-capable terminal.\n\r");
    exit(1);
}
else
{
    //Yay, we have Unicode! some random UI-related code goes here.
}

This isn't just a matter of simply including ncursesw and just setting the locale. I need to get specific terminal info and actually throw an error if it's not gonna happen. I need to, for example, throw an error when the user tries to run the program in the lovely XTerm rather than the Unicode-capable UXTerm.

Upvotes: 5

Views: 1462

Answers (3)

manav m-n
manav m-n

Reputation: 11394

The nl_langinfo() function shall return a pointer to a string containing information relevant to the particular language or cultural area defined in the current locale.

#include <langinfo.h>
#include <locale.h>
#include <stdbool.h>
#include <string.h>

bool supportsUnicode()
{
        /* Set a locale for the ctype and multibyte functions.
         * This controls recognition of upper and lower case,
         * alphabetic or non-alphabetic characters, and so on.
         */
        setlocale(LC_CTYPE, "en_US.UTF-8");
        return (strcmp(nl_langinfo(CODESET), "UTF-8") == 0) ? true : false;
}

Refer to htop source code which can draw lines with/without Unicode.

Upvotes: 0

Thomas Dickey
Thomas Dickey

Reputation: 54515

As noted, you cannot detect the terminal's capabilities reliably. For that matter, you cannot detect the terminal's support for color either. In either case, your application can only detect what you have configured, which is not the same thing.

Some people have had partial success detecting Unicode support by writing a UTF-encoded character and using the cursor-position report to see where the cursor is (see for example Detect how much of Unicode my terminal supports, even through screen).

Compiling/linking with ncursesw relies upon having your locale configured properly, with some workarounds for terminals (such as PuTTY) which do not support VT100 line-graphics when in UTF-8 mode.

Further reading:

Upvotes: 2

user149341
user149341

Reputation:

You can't. ncurses(w) uses termcap to determine what capabilities a terminal has, and that looks at the $TERM environment variable to determine what terminal is being used. There is no special value of that variable that indicates that a terminal supports Unicode; both XTerm and UXTerm set TERM=xterm. Many other terminal applications use that value of $TERM as well, including both ones that support Unicode and ones that don't. (Indeed, in many terminal emulators, it's possible to enable and disable Unicode support at runtime.)

If you want to start outputting Unicode text to the terminal, you will just have to take it on faith that the user's terminal will support that.

If all you want to do is output box drawing characters, though, you may not need Unicode at all — those characters are available as part of the VT100 graphical character set. You can output these characters in a ncurses application using the ACS_* constants (e.g, ACS_ULCORNER for ), or use a function like box() to draw a larger figure for you.

Upvotes: 1

Related Questions