5

I am writing a C++ class permitting the usage of color in terminal. I want it works on every terminal :

  • printing with true color (24 bits) on terminals that supports it,
  • with 256 color (6x6x6) on terminals that supports it,
  • else with the basic 16 colors.

I wrote once C functions using termcap, and I thought using it in this case. However, the man page says :

The termcap database is an obsolete facility for describing the capabilities of character-cell terminals and printers. It is retained only for capability with old programs; new ones should use the terminfo database and associated libraries.

So I tried to use terminfo, but I could not find how to do this. There is not terminfo.h in my system (I run on Debian).

My questions is :

How can I get the color possibilities of the current terminal in C/C++, using the newest tools (ie not termcap, according to manpage) ?

Thomas Dickey
  • 51,086
  • 7
  • 70
  • 105
Boiethios
  • 38,438
  • 19
  • 134
  • 183
  • 1
    AFAIK, you have to include `curses.h` and `term.h`. You should look for `man tgetent` on your system. – Serge Ballesta Mar 22 '16 at 15:17
  • Are not they termcap functions ? – Boiethios Mar 22 '16 at 15:29
  • 1
    Not necessarily on recent systems. [die.net] says for `man getent` *tgetent, tgetflag, tgetnum, tgetstr, tgoto, tputs - direct curses interface to the terminfo capability database*, and so does my FreeBSD 10.1 box. – Serge Ballesta Mar 22 '16 at 15:34
  • Ok : so, I already known that function. But, there is no way to have the truecolor possibility, as far as i can see, with this set of functions. – Boiethios Mar 22 '16 at 16:00

1 Answers1

6

The short answer is that you could not get the information from terminfo until ncurses 6.1 was released in January 2018.

The longer answer:

  • to effectively use TrueColor, you need an interface handling 3 parameters (for red, green, blue). Termcap cannot do this. Terminfo can handle multiple parameters, but...
  • there is no standard terminal capability (a name for a feature which may be a boolean, number or a string) dealing with TrueColor as such.
  • you could adapt existing capabilities, but they have limitations

Looking at the terminfo(5) manual, you might see these (strings):

   initialize_color          initc  Ic   initialize color #1
                                         to (#2,#3,#4)
   initialize_pair           initp  Ip   Initialize color
                                         pair #1 to
                                         fg=(#2,#3,#4),
                                         bg=(#5,#6,#7)

which are related to these (numbers):

   max_colors                colors Co   maximum number of
                                         colors on screen
   max_pairs                 pairs  pa   maximum number of
                                         color-pairs on the
                                         screen

ANSI colors and schemes compatible with those (such as 16-, 88- and 256-colors) assume you are coloring foreground and background in pairs. The reason for that was that long ago, hardware terminals just worked that way. The initialize_color capability is for a different scheme (Tektronix), which might seem useful.

However, terminfo is compiled, and the resulting binary files stored only signed 16-bit integers. You could not use the terminal description to store a suitable max_pairs or max_colors for 24-bit color. (termcap stores everything as strings, but as noted is unsuited for this application).

A couple of years after this question and answer were first written, terminfo was updated to use a new file format that uses signed 32-bit integers, which is enough for expressing the number of colours in 24-bit RGB colour.

More details can be found in release announcement for ncurses 6.1 and in the updated term(5) manual page, which latter notes that there are still restrictions in the old API used by some applications that access the terminfo data directly.

Further reading:

Thomas Dickey
  • 51,086
  • 7
  • 70
  • 105
  • > "signed 16-bit integers." Is this mentioned anywhere that it stores them in signed 16 bit rather than unsigned. I was hoping to find it somewhere but only search result is this answer for me. – Abhinav Gauniyal Dec 26 '16 at 20:26
  • man [term(5)](http://invisible-island.net/ncurses/man/term.5.html) refers to "short integers" (if they were unsigned, it would be noted there). – Thomas Dickey Dec 26 '16 at 20:32