On Tue, Jun 30, 2026 at 05:37:55PM -0500, G. Branden Robinson wrote: > Hi Antonio, > > At 2026-06-30T00:27:45+0000, Antonio Niño Díaz wrote: > > I'm trying to get ncurses working in a new platform (Nintendo DS using > > [BlocksDS](https://blocksds.skylyrac.net/)). > > Cool project! > > > I've created a terminal emulator that supports 16-color, 256-color and > > direct color commands (foreground and background), as well as a few > > other commands like "bold", "move cursor" and "clear screen". > > Basically, I'm cherry-picking terminfo configuration settings from > > other terminals to create my own configuration based on what I > > actually support, and I'm trying to understand every setting I use. > > I think you're taking an excellent approach here. It's a minority one; > most terminal emulator developers seem to copy all of xterm's > descriptions and some of its code--and/or chunks of other > emulators--name their terminal type entry "xterm-whatever" so that the > description will "work" without having to be present upstream in > ncurses's "terminfo.src" file, don't instruct their users in how to > maintain a local terminfo entry, don't point their users to existing > documentation ncurses provides in doing so, don't _test_ their terminal > emulator to verify that it correctly implements all of the features they > advertise for it in its terminfo description, and then when their, uh, > "high-assurance" approach goes wrong, they fulminate against terminfo, > curses, and Thomas Dickey personally as idiotic dinosaur Unix crap that > intelligent people like themselves will replace any day now. > > For bonus points, such emulator developers may appeal to their own > authority as being graduates of CalTech or MIT, to their advanced degree > in physics or quantum computing, and/or their own self-confidence as all > of the empirical support for their claims that anyone will ever need. > > I applaud you for breaking with that tradition. > > > So far I've managed to get 16 and 256 color modes working, as well as > > moving the cursor around and clearing the screen. However, I have two > > issues that I've spent a few days debugging with no success. I've even > > added printf logs in ncurses in many places (the trace system doesn't > > work for some reason) but ncurses has so many build options and code > > paths that it's hard to know what actually gets used (printf-debugging > > has helped to get color working, though). > > > > ---------------- > > > > 1) 16 color mode doesn't work properly > > > > The 8 color palette is shifted in a way that bits 0 and 2 are swapped > > when my terminal receives the commands. This is the regular list of > > defines: > > This _sounds_ like it might be a case of the notorious red/blue channel > swap arising from differing conventions between some terminal > manufacturers and the ISO 6429 standards committee. > > I'll quote parts of terminfo(5), but there's much more in that man page. > > Color Handling > The curses library functions init_pair and init_color manipulate > the color pairs and colors (color values or indices, such as > “1=red”) discussed in this section (see color(3NCURSES) for details > on these and related functions). > ... > While the curses library works with color pairs (reflecting the > inability of some devices to set foreground and background colors > independently), there are separate capabilities for setting these > features: > > • To change the current foreground or background color on a > Tektronix‐type terminal, use setaf (set ANSI foreground) and > setab (set ANSI background) or setf (set foreground) and setb > (set background). These take one parameter, the color number. > The SVr4 documentation describes only setaf/setab; the XPG4 > draft says that "If the terminal supports ANSI escape sequences > to set background and foreground, they should be coded as setaf > and setab, respectively. > > • If the terminal supports other escape sequences to set > background and foreground, they should be coded as setf and > setb, respectively. The vidputs and the refresh(3NCURSES) > functions use the setaf and setab capabilities if they are > defined. > > The setaf/setab and setf/setb capabilities take a single numeric > argument each. Argument values 0‐7 of setaf/setab are portably > defined as follows (the middle column is the symbolic #define > available in the header for the curses or ncurses libraries). The > terminal hardware is free to map these as it likes, but the RGB > values indicate normal locations in color space. > > Color #define Value RGB > ──────────────────────────────────────────────── > black COLOR_BLACK 0 0, 0, 0 > red COLOR_RED 1 max, 0, 0 > green COLOR_GREEN 2 0, max, 0 > yellow COLOR_YELLOW 3 max, max, 0 > blue COLOR_BLUE 4 0, 0, max > magenta COLOR_MAGENTA 5 max, 0, max > cyan COLOR_CYAN 6 0, max, max > white COLOR_WHITE 7 max, max, max > > The argument values of setf/setb historically correspond to a > different mapping, i.e., > > Color #define Value RGB > ──────────────────────────────────────────────── > black COLOR_BLACK 0 0, 0, 0 > blue COLOR_BLUE 1 0, 0, max > green COLOR_GREEN 2 0, max, 0 > cyan COLOR_CYAN 3 0, max, max > red COLOR_RED 4 max, 0, 0 > magenta COLOR_MAGENTA 5 max, 0, max > yellow COLOR_YELLOW 6 max, max, 0 > white COLOR_WHITE 7 max, max, max > > It is important to not confuse the two sets of color capabilities; > otherwise red/blue will be interchanged on the display.
:-)
> Therefore, the first thing I'd check is the bit ordering of your color
> channel assignments internally within your emulator, and then ensure
> that you've selected the corresponding pair of capability codes.
>
> setf/setb vs. setaf/setab
>
> The "a"s here make a lot of difference.
yes... the terminal description says
"Co#256:pa#1000:" // 256 colors, 1000 pairs
"Sf=\E[38;5;%dm:"
"Sb=\E[48;5;%dm:"
which (see man 5 terminfo):
set_foreground setf Sf Set foreground color #1
set_background setb Sb Set background color #1
tells ncurses that this is the non-ANSI flavor of color.
ncurses handles the non-ANSI colors specially, as seen in this chunk
from lib_color.c:
/*
* SVr4 curses is known to interchange color codes (1,4) and (3,6),
possibly
* to maintain compatibility with a pre-ANSI scheme. The same scheme is
* also used in the FreeBSD syscons.
*/
static int
toggled_colors(int c)
{
if (c < 16) {
static const int table[] =
{0, 4, 2, 6, 1, 5, 3, 7,
8, 12, 10, 14, 9, 13, 11, 15};
c = table[c];
}
return c;
}
That's part of some changes which I made in May 1997:
970503
+ correct color attributes in terminfo.src and lib_color.c to match
SVr4 behavior by interchanging codes 1,4, 3,6 in the setf/setb
capabilities.
If you change Sf to AF and Sb to AB, ncurses won't do that interchanging.
set_a_foreground setaf AF Set foreground color to #1, us‐
ing ANSI escape
set_a_background setab AB Set background color to #1, us‐
ing ANSI escape
Seeing the example is all in termcap, I copied the text into a file and ran
tic to check it (e.g., tic -cvx foo.ti), and it reminded me that U8 should
have a numeric value:
U8#1
and also that tic (and the underlying ncurses library) will fill in some
defaults for special keys, so this:
DS|libnds|libnds console:\
co#42:li#24:\
am:\
bs:\
cm=\E[%d;%dH:\
NP:\
AX:\
op=\E[39;49m:\
E3=\E[2J:\
U8#1:\
Co#256:pa#1000:\
AF=\E[38;5;%dm:\
AB=\E[48;5;%dm:\
md=\E[0;1m:\
me=\E[0m:
# Co#8:pa#64
# Sf=\E[3%dm:
# Sb=\E[4%dm:
is transformed to (using "tic -Cx1 foo.ti" to format it):
DS|libnds|libnds console:\
:NP:\
:am:\
:bs:\
:AX:\
:Co#256:\
:co#42:\
:li#24:\
:pa#1000:\
:U8#1:\
:AB=\E[48;5;%dm:\
:AF=\E[38;5;%dm:\
:bl=^G:\
:cm=\E[%d;%dH:\
:cr=\r:\
:do=\n:\
:kb=^H:\
:kd=\n:\
:kl=^H:\
:le=^H:\
:md=\E[0;1m:\
:me=\E[0m:\
:nw=\r\n:\
:op=\E[39;49m:\
:sf=\n:\
:ta=^I:\
:E3=\E[2J:
# Co#8:pa#64
# Sf=\E[3%dm:
# Sb=\E[4%dm:
> > I've double-checked the definitions used by my terminal and they match
> > the right set of definitions (the first one). This issue doesn't
> > happen with the 256-color palette for some reason. Any color over 16
> > is displayed correctly.
>
> I believe you don't see the problem in 256-color mode in _general_
> because there is no historical conflicting tradition for encoding of the
> RGB color channel values when more than one bit per channel is
> available. I think you continue to see the problem with the first 16
> colors in 256-color mode because those are allocated separately from the
> remainder of the 256-element color space to maintain consistent color
> rendering with the 3-bit RGB (and 4-bit RGBI) SGR escape sequences.
> That way, most _applications_ don't need to know how many colors the
> terminal emulator supports, but can inquire of this information if they
> desire, even applying their own color indexing system that they map to
> the ncurses/terminfo 8-bit color cube if and as they desire.
no - it's ncurses being helpful rather than the DS balking
> I'm afraid I have no insight to offer regarding the remaining issues.
> Maybe Thomas can--on top of correcting any howlers I made above. ;-)
>
> Regards,
> Branden
--
Thomas E. Dickey <[email protected]>
https://invisible-island.net
signature.asc
Description: PGP signature
