Compiling terminfo:
tic -x -o ~/.terminfo terminfo-24bit.src
Running emacs (i.e. osx):
TERM=xterm-24bits /Applications/Tools/Emacs.app/Contents/MacOS/Emacs -nw
Refs:
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.src
Running emacs (i.e. osx):
TERM=xterm-24bits /Applications/Tools/Emacs.app/Contents/MacOS/Emacs -nw
Refs: