Difference between revisions of "Ncurses"

From dankwiki
(add note about ESCDELAY and notimeout)
(5 intermediate revisions by the same user not shown)
Line 1: Line 1:
 +
Quality character cell graphics since [https://invisible-island.net/ncurses/ncurses.faq.html 1982].
 +
 
==Escape==
 
==Escape==
You can get Escape with no delay by using <tt>notimeout(3ncurses)</tt>, but this eliminates use of the function and arrow keys on terminals where those sequences are composed with Escape. You probably don't want that. You can use the ESCDELAY environment variable (see <tt>ncurses(3ncurses)</tt>) to change this (ncurses also provides a global of the same name). [[Vim]] uses a 25ms default. The ncurses default appears to be 1s (1000ms), which makes one's application feel kinda seasick when running on any reasonable connection (not to mention locally). This seems difficult to manipulate programaticly, though. :/
+
You can get Escape with no delay by using <tt>notimeout(3ncurses)</tt>, but this eliminates use of the function and arrow keys on terminals where those sequences are composed with Escape. You probably don't want that. You can use the ESCDELAY environment variable (see <tt>ncurses(3ncurses)</tt>) to change this (ncurses also provides a global of the same name). In a threaded environment, <tt>set_escdelay()</tt> ought be preferred. [[Vim]] uses a 25ms default. The ncurses default appears to be 1s (1000ms), which makes one's application feel kinda seasick when running on any reasonable connection (not to mention locally). This seems difficult to manipulate programaticly, though. :/
  
 
==Colors==
 
==Colors==
Line 28: Line 30:
 
| ncurses-term
 
| ncurses-term
 
|}
 
|}
 +
 +
===Color attributes===
 +
Using color pairs beyond 256 requires a 16-bit attribute. By default, only 8 bits are provided (see <tt>A_COLOR</tt>). Thus for instance <tt>wattron(w, COLOR_PAIR(260))</tt> is equivalent to <tt>wattron(w, COLOR_PAIR(4))</tt>. In order to use pairs above 256, drop <tt>COLOR_PAIR</tt>, and always refer to the pair via pointer using the <tt>void* opts</tt> parameter to functions like <tt>wattron</tt>. What, there is not such parameter? Ahhh, of course; you need to use <tt>wattr_on</tt>. Note the underscore, and hate life.
 +
 +
As of 2019-11, here are the relevant definitions from my installation of ncurses:
 +
<pre>
 +
#ifdef __cplusplus
 +
extern "C" {
 +
#define NCURSES_CAST(type,value) static_cast<type>(value)
 +
#else
 +
#define NCURSES_CAST(type,value) (type)(value)
 +
#endif
 +
#define NCURSES_ATTR_SHIFT      8
 +
#define NCURSES_BITS(mask,shift) (NCURSES_CAST(chtype,(mask)) << ((shift) + NCURSES_ATTR_SHIFT))
 +
#define A_COLOR  NCURSES_BITS(((1U) << 8) - 1U,0)
 +
#define COLOR_PAIR(n) (NCURSES_BITS((n), 0) & A_COLOR)
 +
#define PAIR_NUMBER(a)  (NCURSES_CAST(int,((NCURSES_CAST(unsigned long,(a)) & A_COLOR) >> NCURSES_ATTR_SHIFT)))
 +
</pre>
 +
 +
The default colors built into ncurses can be dumped with <tt>color_content -p</tt>.
 +
 +
===True Color===
 +
Test for terminal support (courtesy [https://gist.github.com/XVilka/8346728 XVilka]:
 +
<pre>awk 'BEGIN{
 +
    s="/\\/\\/\\/\\/\\"; s=s s s s s s s s;
 +
    for (colnum = 0; colnum<77; colnum++) {
 +
        r = 255-(colnum*255/76);
 +
        g = (colnum*510/76);
 +
        b = (colnum*255/76);
 +
        if (g>255) g = 510-g;
 +
        printf "\033[48;2;%d;%d;%dm", r,g,b;
 +
        printf "\033[38;2;%d;%d;%dm", 255-r,255-g,255-b;
 +
        printf "%s\033[0m", substr(s,colnum+1,1);
 +
    }
 +
    printf "\n";
 +
}'</pre>
  
 
==[[Unicode]]==
 
==[[Unicode]]==

Revision as of 23:29, 10 November 2019

Quality character cell graphics since 1982.

Escape

You can get Escape with no delay by using notimeout(3ncurses), but this eliminates use of the function and arrow keys on terminals where those sequences are composed with Escape. You probably don't want that. You can use the ESCDELAY environment variable (see ncurses(3ncurses)) to change this (ncurses also provides a global of the same name). In a threaded environment, set_escdelay() ought be preferred. Vim uses a 25ms default. The ncurses default appears to be 1s (1000ms), which makes one's application feel kinda seasick when running on any reasonable connection (not to mention locally). This seems difficult to manipulate programaticly, though. :/

Colors

  • When modifying the palette via init_color(), this only affects the normal form of the color. Using A_BOLD with the color, for instance, will not reflect palette changes.
  • Modifying the palette requires a terminal that supports it, like "linux" or "xterm-256color"
    • The latter can be had from the ncurses-term package on Debian.
  • ncurses will need have been compiled with --enable-ext-colors
Terminal emulator Default terminfo 256-color terminfo Debian package
xterm xterm xterm-256color ncurses-base
Gnome-Terminal gnome gnome-256color ncurses-term
Konsole konsole konsole-256color ncurses-term

Color attributes

Using color pairs beyond 256 requires a 16-bit attribute. By default, only 8 bits are provided (see A_COLOR). Thus for instance wattron(w, COLOR_PAIR(260)) is equivalent to wattron(w, COLOR_PAIR(4)). In order to use pairs above 256, drop COLOR_PAIR, and always refer to the pair via pointer using the void* opts parameter to functions like wattron. What, there is not such parameter? Ahhh, of course; you need to use wattr_on. Note the underscore, and hate life.

As of 2019-11, here are the relevant definitions from my installation of ncurses:

#ifdef __cplusplus
extern "C" {
#define NCURSES_CAST(type,value) static_cast<type>(value)
#else
#define NCURSES_CAST(type,value) (type)(value)
#endif
#define NCURSES_ATTR_SHIFT       8
#define NCURSES_BITS(mask,shift) (NCURSES_CAST(chtype,(mask)) << ((shift) + NCURSES_ATTR_SHIFT))
#define A_COLOR   NCURSES_BITS(((1U) << 8) - 1U,0)
#define COLOR_PAIR(n) (NCURSES_BITS((n), 0) & A_COLOR)
#define PAIR_NUMBER(a)  (NCURSES_CAST(int,((NCURSES_CAST(unsigned long,(a)) & A_COLOR) >> NCURSES_ATTR_SHIFT)))

The default colors built into ncurses can be dumped with color_content -p.

True Color

Test for terminal support (courtesy XVilka:

awk 'BEGIN{
    s="/\\/\\/\\/\\/\\"; s=s s s s s s s s;
    for (colnum = 0; colnum<77; colnum++) {
        r = 255-(colnum*255/76);
        g = (colnum*510/76);
        b = (colnum*255/76);
        if (g>255) g = 510-g;
        printf "\033[48;2;%d;%d;%dm", r,g,b;
        printf "\033[38;2;%d;%d;%dm", 255-r,255-g,255-b;
        printf "%s\033[0m", substr(s,colnum+1,1);
    }
    printf "\n";
}'

Unicode

  • You need use ncursesw, which ought have been built with --enable-widec
  • _XOPEN_SOURCE_EXTENDED must be #defined prior to including any ncurses headers (use -D_XOPEN_SOURCE_EXTENDED with gcc)
  • setlocale() needs have been called prior to calling any ncurses functions
    • ncurses assumes that the locale does not change once started