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

Attachment: signature.asc
Description: PGP signature

Reply via email to