Subject: bug#69598: 29.2; colour support based on $TERM value not terminfo database

From: [email-masked]
Date: Thu, 07 Mar 2024 21:45:44 +0000

Eli Zaretskii writes:
> > From: [email-masked]
> > cc: [email-masked], [email-masked]
> > Comments: In-reply-to Eli Zaretskii <[email-masked]>
> >    message dated "Thu, 07 Mar 2024 21:26:32 +0200."
> > Date: Thu, 07 Mar 2024 19:59:17 +0000
> > 
> > But the problem is not with the terminfo entry itself. The new entry
> > is an exact duplicate of a working terminfo entry (where working
> > means that list-colors-display lists 256 named colours) and it only
> > works if the new entry has a name which begins "xterm-".
> > 
> > This means that somewhere between running the code above which does
> > detect that 16M colours are available, emacs discards that information
> > and instead (seems to) decide that support is there based on the
> > name of the terminal in $TERM.
>
> If you or someone else could establish that tty->TN_max_colors
> receives the correct value of the number of supported colors during
> initialization, and yet Emacs still doesn't realize those colors
> unless the TERM name begins with "xterm", we could make some progress,
> because it could point us to the code which is responsible for this
> lossage.  Right now, I don't know where to look.

I have (eventually, see below) followed this sequence of steps:

        $ cd ~/src/emacs-29.2
        $ ./configure
        $ gmake

launch xterm, and then within it:

        $ rm -fr ~/.terminfo
        $ echo 'notworking|Non-working clone,use=xterm-direct,' > new.info
        $ echo 'xterm-working|Working clone,use=xterm-direct,' >> new.info
        $ tic new.info

# pre-patch compiled binary:

        $ export TERM=xterm-direct
        $ ~/src/emacs-29.2/src/emacs -nw
        $ M-x list-colors-display # confirm 256 named colours
        $ export TERM=notworking
        $ ~/src/emacs-29.2/src/emacs -nw
        $ M-x list-colors-display # confirm only 8 colours
        $ export TERM=xterm-working
        $ emacs -nw               # system xterm
        $ M-x list-colors-display # confirm 256 named colours

# patch:
--- src/term.c~	Sat Jan  6 12:56:31 2024
+++ src/term.c	Thu Mar  7 20:56:36 2024
@@ -4235,6 +4235,15 @@
         tty->TN_no_color_video = 0;
     }
 
+  {
+    int bug = open("/tmp/debug", O_WRONLY | O_CREAT);
+    dprintf(bug, "pair: %s\n", tty->TS_orig_pair);
+    dprintf(bug, "bg: %s\n", tty->TS_set_background);
+    dprintf(bug, "fg: %s\n", tty->TS_set_foreground);
+    dprintf(bug, "max: %zu\n", tty->TN_max_colors);
+    close(bug);
+  }
+
   tty_default_color_capabilities (tty, 1);
 
   MagicWrap (tty) = tgetflag ("xn");

        $ gmake -C ~/src/emacs-29.2
        $ export TERM=xterm-direct
        $ ~/src/emacs-29.2/src/emacs -nw
        $ M-x list-colors-display $ # confirm 256 named colours
        $ doas cat /tmp/debug # doas because umask 0
        pair: 
        bg: 1%{8}%<%t4%p1%d%e48:2::%p1%{65536}%/%d:%p1%{256}%/%{255}%&%d:%p1%{255}%&%d%;m
        fg: 1%{8}%<%t3%p1%d%e38:2::%p1%{65536}%/%d:%p1%{256}%/%{255}%&%d:%p1%{255}%&%d%;m
        max: 16777216
        $ rm -f /tmp/debug # just in case
        $ export TERM=notworking
        $ ~/src/emacs-29.2/src/emacs -nw
        $ M-x list-colors-display # confirm only 8 colours
        $ doas cat /tmp/debug
        pair: 
        bg: 1%{8}%<%t4%p1%d%e48:2::%p1%{65536}%/%d:%p1%{256}%/%{255}%&%d:%p1%{255}%&%d%;m
        fg: 1%{8}%<%t3%p1%d%e38:2::%p1%{65536}%/%d:%p1%{256}%/%{255}%&%d:%p1%{255}%&%d%;m
        max: 16777216
        $ rm -f /tmp/debug
        $ export TERM=xterm-working
        $ ~/src/emacs-29.2/src/emacs -nw
        $ M-x list-colors-display # confirm 256 named colours
        $ doas cat /tmp/debug
        pair: 
        bg: 1%{8}%<%t4%p1%d%e48:2::%p1%{65536}%/%d:%p1%{256}%/%{255}%&%d:%p1%{255}%&%d%;m
        fg: 1%{8}%<%t3%p1%d%e38:2::%p1%{65536}%/%d:%p1%{256}%/%{255}%&%d:%p1%{255}%&%d%;m
        max: 16777216

Notably TS_orig_pair is printed here as an empty string in all cases
(NULL would print as "(null)"? and there there are no extra spaces),
created by requesting the op capability which *is* defined in
xterm-direct.

        $ infocmp dumb xterm-direct | grep op: 
                op: NULL, '\E[39;49m'.

In fact before getting the patch to this stage I included the print
statements within the block you suggested but of course this was
not reached because of op not being detected.

It didn't make any sense to me why tgetstr would return an empty
string in that instance. address where tgetstr gets its data from
is another name for tty->termcap_strings_buffer so changing the
print statement to print that and setting $TERM to xterm-direct
reveals:

        $ doas hexdump -C /tmp/debug
        00000000  60 60 60 1b 5b 4c 27 27  27 0a                    |```.[L'''.|
        0000000a

I tried to replicate this on the Debian box but emacs wouldn't build
despite the configure script being satisfied (not relevant here,
but it couldn't find mpz_* despite libgmp-dev and then libgmp3-dev
being installed).

Matthew