Compiling terminfo:
tic -x -o ~/.terminfo terminfo-24bit.srcRunning emacs (i.e. osx):
TERM=xterm-24bits /Applications/Tools/Emacs.app/Contents/MacOS/Emacs -nwRefs:
| diff --git a/doc/misc/efaq.texi b/doc/misc/efaq.texi | |
| index f7a47f8..e9cfe7a 100644 | |
| --- a/doc/misc/efaq.texi | |
| +++ b/doc/misc/efaq.texi | |
| @@ -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 | |
| diff --git a/lisp/term/tty-colors.el b/lisp/term/tty-colors.el | |
| index 237aa19..f9262ae 100644 | |
| --- a/lisp/term/tty-colors.el | |
| +++ b/lisp/term/tty-colors.el | |
| @@ -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. | |
| diff --git a/lisp/term/xterm.el b/lisp/term/xterm.el | |
| index 447f536..311638b 100644 | |
| --- a/lisp/term/xterm.el | |
| +++ b/lisp/term/xterm.el | |
| @@ -917,6 +917,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)) | |
| diff --git a/src/term.c b/src/term.c | |
| index 5554a00..3ec89bc 100644 | |
| --- a/src/term.c | |
| +++ b/src/term.c | |
| @@ -4131,6 +4131,20 @@ use the Bourne shell command 'TERM=...; export TERM' (C-shell:\n\ | |
| tty->TN_max_colors = tgetnum ("Co"); | |
| tty->TN_max_pairs = tgetnum ("pa"); | |
| +#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; | |
| diff --git a/src/tparam.h b/src/tparam.h | |
| index 15664d6..02136b6 100644 | |
| --- a/src/tparam.h | |
| +++ b/src/tparam.h | |
| @@ -36,4 +36,8 @@ extern char PC; | |
| extern char *BC; | |
| extern char *UP; | |
| +#ifdef TERMINFO | |
| +char *tigetstr(const char *); | |
| +#endif | |
| + | |
| #endif /* EMACS_TPARAM_H */ |
| # Replace semicolons with colons in setb24 and setf24 on terminals | |
| # that use ITU-T separators (iTerm2). A 24-bit integer (p1) is given | |
| # as a parameter to the control functions which calculate rgb | |
| # component values with following formulas: | |
| # r = p1 / 65536, g = (p1 / 256) & 255, b = p1 & 255 | |
| xterm-24bits|xterm with 16777216 colors, | |
| use=xterm-256color, | |
| setb24=\033[48;2;%p1%{65536}%/%d;%p1%{256}%/%{255}%&%d;%p1%{255}%&%dm, | |
| setf24=\033[38;2;%p1%{65536}%/%d;%p1%{256}%/%{255}%&%d;%p1%{255}%&%dm, |
Compiling terminfo:
tic -x -o ~/.terminfo terminfo-24bit.srcRunning emacs (i.e. osx):
TERM=xterm-24bits /Applications/Tools/Emacs.app/Contents/MacOS/Emacs -nwRefs: