Hi, when I switched to xterm-direct for running Emacs, I noticed that it does 
not work correctly under trunk of screen with "truecolor on", with all the 
colors being shifted like blue instead of green and so on, if I set TERM to 
xterm-direct inside screen.

Reason for that is,  official ANSI Escape sequence for truecolor have extra 
parameter after 38;2, so full sequence looks like this:  
esc;38;2;colorspace:r:g:b

There is a very detailed explanation on how this came to be in 
https://github.com/ThomasDickey/xterm-snapshots/blob/master/charproc.c#L1976

The xterm-direct terminal description that Emacs uses (tbh I don't know where 
this comes from , ncurses or terminfo?) has the foreground/background color 
change sequences defined with this extra colorspace parameter, so Emacs sends 
extra parameter as 0 when changing colors with TERM=xterm-direct.  So under 
screen, the sequence is interpreted as r,g,b being 0,r,g with b ignored, thus 
the shifted colors.

Below patch implements the same fix as XTerm uses for screen, that is to skip 
the colorspace parameter if its specified. With this patch Emacs inside screen 
with xterm-direct produces correct color for me


diff --git a/src/ansi.c b/src/ansi.c
index 9ee4ffa..4913243 100644
--- a/src/ansi.c
+++ b/src/ansi.c
@@ -1734,16 +1734,17 @@ static void SelectRendition(Window *win)
                if ((j == 38 || j == 48) && i + 4 < win->w_NumArgs && 
win->w_args[i + 1] == 2) {
                        uint8_t r, g, b;

-                   r = win->w_args[i + 2];
-                   g = win->w_args[i + 3];
-                   b = win->w_args[i + 4];
+                 int have_colorspace = (i + 5 < win->w_NumArgs);
+                 r = win->w_args[i + 2 + have_colorspace];
+                 g = win->w_args[i + 3 + have_colorspace];
+                 b = win->w_args[i + 4 + have_colorspace];

                        if (j == 38) {
                                colorfg = 0x04000000 | (r << 16) | (g << 8) | b;
                        } else {
                                colorbg = 0x04000000 | (r << 16) | (g << 8) | b;
                        }
-                   i += 4;
+                 i += 4 + have_colorspace;
                        continue;
                }
                if (j >= 90 && j <= 97)




Reply via email to