Fix: SE031 Problem: Colours don't work properly under Linux (affects Debian's xterms and both Debian and RedHat's consoles, possibly others). There are a number of problems here. Firstly, the termcap code was using hardcoded ANSI escape sequences for colours, but using the HE value read from the termcap database to clear them. This causes the infamous "leaky colours" if HE does not change the colours. I've gone for the sledgehammer approach of using ESC [ 0 m to clear them since this should work on just about any terminal which understands ANSI escape sequences. It would break any attempt by NetHack/Slash'EM to clear colour while preserving some other attribute (bold, standout etc.), but as far as I know, this never happens. Secondly, the terminfo code assumes that the Sf and AF codes to set the foreground colour are equivalent. At least under version 4.2 of ncurses (which Linux uses), this is not the case. AF sets the colours according to a RGB model and Sf according to a BGR model. curses.h defines the COLOR_FOO macros according to the RGB model regardless causing reds and blues to be switched around. We solve this by manually swapping red and blue if we decide to use Sf under ncurses. Finally, I believe AF should be preferred over Sf, because other curses packages may have similar characteristics to ncurses and the swapping code is only active for an ncurses implementation. Note that the terminfo code (enabled with TERMINFO in config.h) is the better option for Linux. Thanks to the following for their help in testing my theories and/or for providing patches to address the problem: Matt Reishus David Damerell Peter Makholm Kalle Sandstroem Kresimir Kukulj Compatible with: Slash'EM 0.0.5E5 through 0.0.5E7 NetHack 3.2.2 plus SE008 Author: J. Ali Harlow, ali@avrc.city.ac.uk Date: 7 Dec 1999 *** win/tty/termcap.c.orig Sun Dec 5 16:17:57 1999 --- win/tty/termcap.c Tue Dec 7 15:53:13 1999 *************** *** 816,822 **** # endif #define COLOR_BLACK COLOR_BLUE ! const int ti_map[8] = { COLOR_BLACK, COLOR_RED, COLOR_GREEN, COLOR_YELLOW, COLOR_BLUE, COLOR_MAGENTA, COLOR_CYAN, COLOR_WHITE }; --- 816,825 ---- # endif #define COLOR_BLACK COLOR_BLUE ! #ifndef NCURSES_VERSION ! const ! #endif ! int ti_map[8] = { COLOR_BLACK, COLOR_RED, COLOR_GREEN, COLOR_YELLOW, COLOR_BLUE, COLOR_MAGENTA, COLOR_CYAN, COLOR_WHITE }; *************** *** 824,831 **** init_hilite() { register int c; ! char *setf, *scratch; extern char *tparm(); for (c = 0; c < SIZE(hilites); c++) hilites[c] = HI; --- 827,836 ---- init_hilite() { register int c; ! char *setf, *setaf, *scratch; ! #ifndef NCURSES_VERSION extern char *tparm(); + #endif for (c = 0; c < SIZE(hilites); c++) hilites[c] = HI; *************** *** 834,842 **** if (tgetnum("Co") < 8) return; ! if ((setf = tgetstr("Sf", (char **)0)) == (char *)0 ! && (setf = tgetstr("AF", (char **)0)) == (char *)0) return; for (c = 0; c < CLR_MAX / 2; c++) { scratch = tparm(setf, ti_map[c]); --- 839,872 ---- if (tgetnum("Co") < 8) return; ! setf = tgetstr("Sf", (char **)0); ! setaf = tgetstr("AF", (char **)0); ! if (!setf && !setaf) return; + /* + * Prefer ANSI version if defined in case other curses packages + * do similar colour re-mappings to ncurses. + */ + if (setaf) + setf=setaf; + #ifdef NCURSES_VERSION + else + { + /* + * ALI + * + * ncurses seems to switch from RGB to BGR if + * you use setf rather than setaf. This is despite + * the values for COLOR_FOO in curses.h which + * always remain RGB. Tested against ncurses v4.2 + */ + #define SWAP_COLOR(c1,c2) (c=ti_map[c1],ti_map[c1]=ti_map[c2],ti_map[c2]=c) + SWAP_COLOR(CLR_RED,CLR_BLUE); + SWAP_COLOR(CLR_CYAN,CLR_YELLOW); + ti_map[CLR_BLACK]=ti_map[CLR_BLUE]; + #undef SWAP_COLOR + } + #endif for (c = 0; c < CLR_MAX / 2; c++) { scratch = tparm(setf, ti_map[c]); *************** *** 970,976 **** for (c = 0; c < SIZE(hilites); c++) hilites[c] = HI; hilites[CLR_GRAY] = hilites[NO_COLOR] = (char *)0; ! hilite_end = HE; analyze_seq(HI, &hi_foreg, &hi_backg); analyze_seq(HE, &foreg, &backg); --- 1000,1006 ---- for (c = 0; c < SIZE(hilites); c++) hilites[c] = HI; hilites[CLR_GRAY] = hilites[NO_COLOR] = (char *)0; ! hilite_end = "\033[0m"; analyze_seq(HI, &hi_foreg, &hi_backg); analyze_seq(HE, &foreg, &backg);