Re: Bugs when porting ncurses to a new platform

Thomas Dickey <[email protected]> Tue, 30 Jun 2026 20:31:49 -0400
Newsgroups gmane.comp.lib.ncurses.bugs
Message-ID <[email protected]>
--mpKxCKhEf6W+5njy
Content-Type: text/plain; charset=utf-8
Content-Disposition: inline
Content-Transfer-Encoding: quoted-printable

On Tue, Jun 30, 2026 at 05:37:55PM -0500, G. Branden Robinson wrote:
> Hi Antonio,
>=20
> At 2026-06-30T00:27:45+0000, Antonio Ni=C3=B1o D=C3=ADaz wrote:
> > I'm trying to get ncurses working in a new platform (Nintendo DS using
> > [BlocksDS](https://blocksds.skylyrac.net/)).
>=20
> Cool project!
>=20
> > 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.
>=20
> 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.
>=20
> 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.
>=20
> I applaud you for breaking with that tradition.
>=20
> > 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).
> >=20
> > ----------------
> >=20
> > 1) 16 color mode doesn't work properly
> >=20
> > 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:
>=20
> 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.
>=20
> I'll quote parts of terminfo(5), but there's much more in that man page.
>=20
>    Color Handling
>      The curses library functions init_pair and init_color manipulate
>      the color pairs and colors (color values or indices, such as
>      =E2=80=9C1=3Dred=E2=80=9D) discussed in this section (see color(3NCU=
RSES) 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:
>=20
>      =E2=80=A2   To change the current foreground or background color on a
>          Tektronix=E2=80=90type 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.
>=20
>      =E2=80=A2   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.
>=20
>      The setaf/setab and setf/setb capabilities take a single numeric
>      argument each.  Argument values 0=E2=80=907 of setaf/setab are porta=
bly
>      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.
>=20
>                Color      #define       Value        RGB
>               =E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=
=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=
=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=
=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=
=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=
=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80
>               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
>=20
>      The argument values of setf/setb historically correspond to a
>      different mapping, i.e.,
>=20
>                Color      #define       Value        RGB
>               =E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=
=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=
=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=
=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=
=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=
=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80
>               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
>=20
>      It is important to not confuse the two sets of color capabilities;
>      otherwise red/blue will be interchanged on the display.

:-)
=20
> 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.
>=20
> setf/setb vs. setaf/setab
>=20
> The "a"s here make a lot of difference.

yes... the terminal description says


	"Co#256:pa#1000:" // 256 colors, 1000 pairs
	"Sf=3D\E[38;5;%dm:"
	"Sb=3D\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
=66rom lib_color.c:

	/*
	 * SVr4 curses is known to interchange color codes (1,4) and (3,6), possib=
ly
	 * 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[] =3D
		{0, 4, 2, 6, 1, 5, 3, 7,
		 8, 12, 10, 14, 9, 13, 11, 15};
		c =3D 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=E2=80=90
                                                ing ANSI escape
       set_a_background           setab     AB  Set background color to #1,=
 us=E2=80=90
                                                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=3D\E[%d;%dH:\
		NP:\
		AX:\
		op=3D\E[39;49m:\
		E3=3D\E[2J:\
		U8#1:\
		Co#256:pa#1000:\
		AF=3D\E[38;5;%dm:\
		AB=3D\E[48;5;%dm:\
		md=3D\E[0;1m:\
		me=3D\E[0m:

	# Co#8:pa#64
	# Sf=3D\E[3%dm:
	# Sb=3D\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=3D\E[48;5;%dm:\
		:AF=3D\E[38;5;%dm:\
		:bl=3D^G:\
		:cm=3D\E[%d;%dH:\
		:cr=3D\r:\
		:do=3D\n:\
		:kb=3D^H:\
		:kd=3D\n:\
		:kl=3D^H:\
		:le=3D^H:\
		:md=3D\E[0;1m:\
		:me=3D\E[0m:\
		:nw=3D\r\n:\
		:op=3D\E[39;49m:\
		:sf=3D\n:\
		:ta=3D^I:\
		:E3=3D\E[2J:
	# Co#8:pa#64
	# Sf=3D\E[3%dm:
	# Sb=3D\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.
>=20
> 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
=20
> 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.  ;-)
>=20
> Regards,
> Branden



--=20
Thomas E. Dickey <[email protected]>
https://invisible-island.net

--mpKxCKhEf6W+5njy
Content-Type: application/pgp-signature; name="signature.asc"

-----BEGIN PGP SIGNATURE-----

iQGzBAABCgAdFiEEGYgtkt2kxADCLA1WzCr0RyFnvgMFAmpEX/IACgkQzCr0RyFn
vgN74QwAwKE+rXnfXmgJi+yUCKFASfPO2zga4/rSKQOlGgi4yL7EAjLM9bPz2RfW
Nho8WR+tMH6VCMYXLExFOKLmor2KuHG1U6chebyvXtT1xAlBF2sfV+ReStzf4jQM
KyUHLc6D8ImeWhKkIjqZSgeoSTFLEtDeN7iG/yZJSb6tdOgOzWuaDvkGGU6/V0dM
pDGBY/ToM0QpkCpulU5CbqPSLlniFLtiLFUmdEMkPBqvbqUGrrGDCa+ku+U4M5GQ
TrUsA+1fPeLdqPkHozLPJqusCROIftFFwtGnTUHr43E0zDDCzg79/lSMfxFyBtJv
acJzwoiCIi1c9yBiv9x6OG1Gv77Fh47DBFEcUYg0cmAPXkvCnLEL5Kx8f5VrtC94
h/tJC5DsQJvSAE2VpjaF3v201NV1x7Q6hzR6+9pSl2TkjQuP9UXzxOH3CmIcB5D+
vOUS7XFIiH2aavX3PWiEVOp9HgU2wRyQjyv0PpNSNhTA2C6d7yt6k2za23X5lb1P
BCqD8UeL
=LYE0
-----END PGP SIGNATURE-----

--mpKxCKhEf6W+5njy--