Support 24-bit direct colors on text terminals
* src/term.c (init_tty): Use 24-bit terminal colors if corresponding foreground and background functions are present in terminal type definition. * src/tparam.h: Define prototype for tigetstr. * lisp/term/tty-colors.el (tty-color-define): Convert color palette index to pixel value on 16.7M color terminals. (tty-color-24bit): New function to convert color palette index to pixel value on 16.7M color terminals. (tty-color-desc): Don't approximate colors on 16.7M color terminals. * lisp/term/xterm.el (xterm-register-default-colors): Define all named TTY colors on 16.7M color terminals. * doc/misc/efaq.texi (Colors on a TTY): Add instructions on how to enable direct color TTY mode. * etc/NEWS: Mention direct color TTY mode and point to FAQ.
This commit is contained in:
parent
464a51ed46
commit
e463e5762b
6 changed files with 82 additions and 2 deletions
|
@ -1491,6 +1491,39 @@ exhibits all the colors Emacs knows about on the current display.
|
|||
|
||||
Syntax highlighting is on by default since version 22.1.
|
||||
|
||||
Emacs 26.1 and later support direct color mode in terminals. If Emacs
|
||||
finds Terminfo capabilities @samp{setb24} and @samp{setf24}, 24-bit
|
||||
direct color mode is used. The capability strings are expected to
|
||||
take one 24-bit pixel value as argument and transform the pixel to a
|
||||
string that can be used to send 24-bit colors to the terminal.
|
||||
|
||||
There aren't yet any standard terminal type definitions that would
|
||||
support the capabilities, but Emacs can be invoked with a custom
|
||||
definition as shown below.
|
||||
|
||||
@example
|
||||
$ cat terminfo-24bit.src
|
||||
|
||||
# Use colon separators.
|
||||
xterm-24bit|xterm with 24-bit direct color mode,
|
||||
use=xterm-256color,
|
||||
setb24=\E[48:2:%p1%@{65536@}%/%d:%p1%@{256@}%/%@{255@}%&%d:%p1%@{255@}%&%dm,
|
||||
setf24=\E[38:2:%p1%@{65536@}%/%d:%p1%@{256@}%/%@{255@}%&%d:%p1%@{255@}%&%dm,
|
||||
# Use semicolon separators.
|
||||
xterm-24bits|xterm with 24-bit direct color mode,
|
||||
use=xterm-256color,
|
||||
setb24=\E[48;2;%p1%@{65536@}%/%d;%p1%@{256@}%/%@{255@}%&%d;%p1%@{255@}%&%dm,
|
||||
setf24=\E[38;2;%p1%@{65536@}%/%d;%p1%@{256@}%/%@{255@}%&%d;%p1%@{255@}%&%dm,
|
||||
|
||||
$ tic -x -o ~/.terminfo terminfo-24bit.src
|
||||
|
||||
$ TERM=xterm-24bit emacs -nw
|
||||
@end example
|
||||
|
||||
Currently there's no standard way to determine whether a terminal
|
||||
supports direct color mode. If such standard arises later on, support
|
||||
for @samp{setb24} and @samp{setf24} may be removed.
|
||||
|
||||
@node Debugging a customization file
|
||||
@section How do I debug a @file{.emacs} file?
|
||||
@cindex Debugging @file{.emacs} file
|
||||
|
|
6
etc/NEWS
6
etc/NEWS
|
@ -77,6 +77,12 @@ modern init systems such as systemd, which manage many of the traditional
|
|||
aspects of daemon behavior themselves. '--old-daemon' is now an alias
|
||||
for '--daemon'.
|
||||
|
||||
+++
|
||||
** Emacs now supports 24-bit colors on capable text terminals
|
||||
Terminal is automatically initialized to use 24-bit colors if the
|
||||
required capabilities are found in terminfo. See the FAQ node
|
||||
"Colors on a TTY" for more information.
|
||||
|
||||
|
||||
* Changes in Emacs 26.1
|
||||
|
||||
|
|
|
@ -824,6 +824,15 @@ A canonicalized color name is all-lower case, with any blanks removed."
|
|||
(replace-regexp-in-string " +" "" (downcase color))
|
||||
color)))
|
||||
|
||||
(defun tty-color-24bit (rgb)
|
||||
"Return pixel value on 24-bit terminals. Return nil if RGB is
|
||||
nil or not on 24-bit terminal."
|
||||
(when (and rgb (= (display-color-cells) 16777216))
|
||||
(let ((r (lsh (car rgb) -8))
|
||||
(g (lsh (cadr rgb) -8))
|
||||
(b (lsh (nth 2 rgb) -8)))
|
||||
(logior (lsh r 16) (lsh g 8) b))))
|
||||
|
||||
(defun tty-color-define (name index &optional rgb frame)
|
||||
"Specify a tty color by its NAME, terminal INDEX and RGB values.
|
||||
NAME is a string, INDEX is typically a small integer used to send to
|
||||
|
@ -840,7 +849,10 @@ If FRAME is not specified or is nil, it defaults to the selected frame."
|
|||
(and rgb (or (not (listp rgb)) (/= (length rgb) 3))))
|
||||
(error "Invalid specification for tty color \"%s\"" name))
|
||||
(tty-modify-color-alist
|
||||
(append (list (tty-color-canonicalize name) index) rgb) frame))
|
||||
(append (list (tty-color-canonicalize name)
|
||||
(or (tty-color-24bit rgb) index))
|
||||
rgb)
|
||||
frame))
|
||||
|
||||
(defun tty-color-clear (&optional _frame)
|
||||
"Clear the list of supported tty colors for frame FRAME.
|
||||
|
@ -1013,7 +1025,10 @@ might need to be approximated if it is not supported directly."
|
|||
(let ((color (tty-color-canonicalize color)))
|
||||
(or (assoc color (tty-color-alist frame))
|
||||
(let ((rgb (tty-color-standard-values color)))
|
||||
(and rgb (tty-color-approximate rgb frame)))))))
|
||||
(and rgb
|
||||
(let ((pixel (tty-color-24bit rgb)))
|
||||
(or (and pixel (cons color (cons pixel rgb)))
|
||||
(tty-color-approximate rgb frame)))))))))
|
||||
|
||||
(defun tty-color-gray-shades (&optional display)
|
||||
"Return the number of gray colors supported by DISPLAY's terminal.
|
||||
|
|
|
@ -930,6 +930,14 @@ versions of xterm."
|
|||
;; are more colors to support, compute them now.
|
||||
(when (> ncolors 0)
|
||||
(cond
|
||||
((= ncolors 16777200) ; 24-bit xterm
|
||||
;; all named tty colors
|
||||
(let ((idx (length xterm-standard-colors)))
|
||||
(mapc (lambda (color)
|
||||
(unless (assoc (car color) xterm-standard-colors)
|
||||
(tty-color-define (car color) idx (cdr color))
|
||||
(setq idx (1+ idx))))
|
||||
color-name-rgb-alist)))
|
||||
((= ncolors 240) ; 256-color xterm
|
||||
;; 216 non-gray colors first
|
||||
(let ((r 0) (g 0) (b 0))
|
||||
|
|
14
src/term.c
14
src/term.c
|
@ -4131,6 +4131,20 @@ use the Bourne shell command 'TERM=...; export TERM' (C-shell:\n\
|
|||
|
||||
tty->TN_max_colors = tgetnum ("Co");
|
||||
|
||||
#ifdef TERMINFO
|
||||
/* Non-standard support for 24-bit colors. */
|
||||
{
|
||||
const char* fg = tigetstr ("setf24");
|
||||
const char* bg = tigetstr ("setb24");
|
||||
if (fg && bg && fg != (char *)-1 && bg != (char *)-1)
|
||||
{
|
||||
tty->TS_set_foreground = fg;
|
||||
tty->TS_set_background = bg;
|
||||
tty->TN_max_colors = 16777216;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
tty->TN_no_color_video = tgetnum ("NC");
|
||||
if (tty->TN_no_color_video == -1)
|
||||
tty->TN_no_color_video = 0;
|
||||
|
|
|
@ -36,4 +36,8 @@ extern char PC;
|
|||
extern char *BC;
|
||||
extern char *UP;
|
||||
|
||||
#ifdef TERMINFO
|
||||
char *tigetstr(const char *);
|
||||
#endif
|
||||
|
||||
#endif /* EMACS_TPARAM_H */
|
||||
|
|
Loading…
Add table
Reference in a new issue