I know that ncurses supports 16-bit colors with the init_pair
function and friends. But is it possible to display characters in full RGB color (aka True Color)?

- 133
- 1
- 11
-
Does this answer your question? [Terminal color using terminfo?](https://stackoverflow.com/questions/36158093/terminal-color-using-terminfo) – Thomas Dickey Aug 25 '20 at 07:56
2 Answers
The ncurses FAQ Why only 16 (or 256) colors? goes into some detail, giving the history of this feature, pointing out that the proper term is direct color (since that is based on a standard, while true color is in other places said to be a special case of direct color). Likewise, the xterm FAQ Can I set a color by its number? provides corresponding detail on the history of this feature in xterm.
ncurses 6.1 (January 2018) introduced support for direct color, as illustrated in a recap of the ncurses versus slang history. That includes an example program picsmap which uses the RGB extension (documented in user_caps(5)).
Because the number of colors in 24-bit RGB is larger than the range of numbers supported in the original (signed!) 16-bit numbers (see term(5)), it was necessary to provide for larger numbers. ncurses 6.1 does this with minimal change to existing applications by adding to the opaque TERMINAL structure, and adding functions which can manipulate the extended numbers. It was not necessary to change the ABI (currently 6 since August 2015), because none of the documented features changed their binary interface.
To use the RGB
feature in ncurses it is necessary to have the proper terminal description. xterm-direct is used for xterm. This example sets the RGB
flag and overrides the color features (but reserves the first 8 ANSI colors, making it a workable hybrid):
xterm+direct|xterm with direct-color indexing,
RGB,
colors#0x1000000, pairs#0x10000, CO#8,
initc@, op=\E[39;49m,
setab=\E[%?%p1%{8}%<%t4%p1%d%e48\:2\:\:%p1%{65536}%/%d\:%p1
%{256}%/%{255}%&%d\:%p1%{255}%&%d%;m,
setaf=\E[%?%p1%{8}%<%t3%p1%d%e38\:2\:\:%p1%{65536}%/%d\:%p1
%{256}%/%{255}%&%d\:%p1%{255}%&%d%;m,
setb@, setf@,
Other terminals have their corresponding flavors. Because the feature is documented, with examples, it is possible for others to customize terminal descriptions as needed.
picsmap
is one of the test-programs for ncurses, which is available separately as "ncurses-examples". Tutorials are off-topic; the source-code is readily available.

- 51,086
- 7
- 70
- 105
“True Color” is a bit of a misnomer—it does not exist.
Ncurses lets you redefine the values of the standard 16 colors, but does not support arbitrary RBG colors at arbitrary positions. Fortunately, many terminals do support 8-bit RGB (sometimes called “true color”) if you wish to do it yourself—to be clear, this means not using ncurses.
The sequences are:
ESC[ 38;2;⟨r⟩;⟨g⟩;⟨b⟩ m
: Select RGB foreground colorESC[ 48;2;⟨r⟩;⟨g⟩;⟨b⟩ m
: Select RGB background color
(From ANSI Escape Code)
Here, “ESC” is just the character ‘\x1b’ and you replace r, g, and b with values from 0-255. Something like this:
printf("\x1b[38;2;%d,%d,%dm", r, g, b);
This does not work on all terminals but there are plenty that do support it.
Why Not Ncurses?
Why doesn’t Ncurses support this? It turns out that Ncurses is not just a library for styling text and placing it at different locations on the terminal, but it also tries to be clever and minimize the amount of data transmitted over stdout when the on-screen text changes. Ncurses does this by keeping its own text buffer internally, and transmitting deltas over stdout.
This is a really nice feature to have if you’re running over a 14.4 kbit/s modem or a slow serial connection back in 1993, back when Ncurses was originally made. However, Ncurses has made an implementation tradeoff of not supporting additional colors.

- 205,541
- 37
- 345
- 415
-
1As far as I'm aware, raw escape sequences cannot be used within an ncurses session...right? – Kied Llaentenn Aug 25 '20 at 01:19
-
I see your edit now. Welp, guess I'll have to do some color reduction. – Kied Llaentenn Aug 25 '20 at 01:23
-
@KiedLlaentenn: That is correct, I've clarified the answer to include that. I’ve also tried to explain why Ncurses doesn’t support this. I will say—if you just need to display text and don’t need to handle input, it’s not too hard to do it yourself without Ncurses. The real *hard* parts that Ncurses do is handle user input, work on lots of terminals, and compute deltas to make the interface faster for slow remote links. – Dietrich Epp Aug 25 '20 at 01:29
-
That's a lot of interesting misinformation. The [ncurses FAQ](https://invisible-island.net/ncurses/ncurses.faq.html#xterm_16MegaColors) is a better source for this. – Thomas Dickey Aug 25 '20 at 08:03
-
1
-
@ThomasDickey: You are free to comment or propose edits if there are inaccuracies in the post. Linking to a FAQ is unhelpful. – Dietrich Epp Aug 26 '20 at 21:30
-
I already pointed out that the ***question*** is a duplicate. You could ask a regular question to list the various problems in your answer, if you're really curious. – Thomas Dickey Aug 26 '20 at 21:55
-
@ThomasDickey: You're coming off a bit strong, aren't you? You say that an answer has misinformation but don't provide any justification, then tell me to ask a question myself if I'm curious. Not sure what you're trying to achieve here, besides telling people that they are wrong. – Dietrich Epp Aug 26 '20 at 22:22
-
well, if you delete the entire comments about RGB and modems, that would be an improvement. since both are less than half factual (the former's addressed in the FAQ, the latter is ...interesting). If you don't like discussing it here, the [bug-ncurses](https://lists.gnu.org/mailman/listinfo/bug-ncurses) mailing list is suitable. – Thomas Dickey Aug 26 '20 at 23:16
-
@ThomasDickey: If you can't provide any reasoning for your arguments then it doesn't really matter, does it? – Dietrich Epp Aug 27 '20 at 02:42