diff options
| author | Rami Ylimäki | 2017-02-18 13:04:55 +0200 |
|---|---|---|
| committer | Eli Zaretskii | 2017-02-18 13:04:55 +0200 |
| commit | e463e5762bbe628be3d15da066a90f079a8468b3 (patch) | |
| tree | 2aa517f3626acbe0dbc73dc7ad5a8ec7d81656c9 | |
| parent | 464a51ed46990554bed8a9443168c976d6c3c6d3 (diff) | |
| download | emacs-e463e5762bbe628be3d15da066a90f079a8468b3.tar.gz emacs-e463e5762bbe628be3d15da066a90f079a8468b3.zip | |
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.
| -rw-r--r-- | doc/misc/efaq.texi | 33 | ||||
| -rw-r--r-- | etc/NEWS | 6 | ||||
| -rw-r--r-- | lisp/term/tty-colors.el | 19 | ||||
| -rw-r--r-- | lisp/term/xterm.el | 8 | ||||
| -rw-r--r-- | src/term.c | 14 | ||||
| -rw-r--r-- | src/tparam.h | 4 |
6 files changed, 82 insertions, 2 deletions
diff --git a/doc/misc/efaq.texi b/doc/misc/efaq.texi index f7a47f8675a..e9cfe7afce9 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. | |||
| 1491 | 1491 | ||
| 1492 | Syntax highlighting is on by default since version 22.1. | 1492 | Syntax highlighting is on by default since version 22.1. |
| 1493 | 1493 | ||
| 1494 | Emacs 26.1 and later support direct color mode in terminals. If Emacs | ||
| 1495 | finds Terminfo capabilities @samp{setb24} and @samp{setf24}, 24-bit | ||
| 1496 | direct color mode is used. The capability strings are expected to | ||
| 1497 | take one 24-bit pixel value as argument and transform the pixel to a | ||
| 1498 | string that can be used to send 24-bit colors to the terminal. | ||
| 1499 | |||
| 1500 | There aren't yet any standard terminal type definitions that would | ||
| 1501 | support the capabilities, but Emacs can be invoked with a custom | ||
| 1502 | definition as shown below. | ||
| 1503 | |||
| 1504 | @example | ||
| 1505 | $ cat terminfo-24bit.src | ||
| 1506 | |||
| 1507 | # Use colon separators. | ||
| 1508 | xterm-24bit|xterm with 24-bit direct color mode, | ||
| 1509 | use=xterm-256color, | ||
| 1510 | setb24=\E[48:2:%p1%@{65536@}%/%d:%p1%@{256@}%/%@{255@}%&%d:%p1%@{255@}%&%dm, | ||
| 1511 | setf24=\E[38:2:%p1%@{65536@}%/%d:%p1%@{256@}%/%@{255@}%&%d:%p1%@{255@}%&%dm, | ||
| 1512 | # Use semicolon separators. | ||
| 1513 | xterm-24bits|xterm with 24-bit direct color mode, | ||
| 1514 | use=xterm-256color, | ||
| 1515 | setb24=\E[48;2;%p1%@{65536@}%/%d;%p1%@{256@}%/%@{255@}%&%d;%p1%@{255@}%&%dm, | ||
| 1516 | setf24=\E[38;2;%p1%@{65536@}%/%d;%p1%@{256@}%/%@{255@}%&%d;%p1%@{255@}%&%dm, | ||
| 1517 | |||
| 1518 | $ tic -x -o ~/.terminfo terminfo-24bit.src | ||
| 1519 | |||
| 1520 | $ TERM=xterm-24bit emacs -nw | ||
| 1521 | @end example | ||
| 1522 | |||
| 1523 | Currently there's no standard way to determine whether a terminal | ||
| 1524 | supports direct color mode. If such standard arises later on, support | ||
| 1525 | for @samp{setb24} and @samp{setf24} may be removed. | ||
| 1526 | |||
| 1494 | @node Debugging a customization file | 1527 | @node Debugging a customization file |
| 1495 | @section How do I debug a @file{.emacs} file? | 1528 | @section How do I debug a @file{.emacs} file? |
| 1496 | @cindex Debugging @file{.emacs} file | 1529 | @cindex Debugging @file{.emacs} file |
| @@ -77,6 +77,12 @@ modern init systems such as systemd, which manage many of the traditional | |||
| 77 | aspects of daemon behavior themselves. '--old-daemon' is now an alias | 77 | aspects of daemon behavior themselves. '--old-daemon' is now an alias |
| 78 | for '--daemon'. | 78 | for '--daemon'. |
| 79 | 79 | ||
| 80 | +++ | ||
| 81 | ** Emacs now supports 24-bit colors on capable text terminals | ||
| 82 | Terminal is automatically initialized to use 24-bit colors if the | ||
| 83 | required capabilities are found in terminfo. See the FAQ node | ||
| 84 | "Colors on a TTY" for more information. | ||
| 85 | |||
| 80 | 86 | ||
| 81 | * Changes in Emacs 26.1 | 87 | * Changes in Emacs 26.1 |
| 82 | 88 | ||
diff --git a/lisp/term/tty-colors.el b/lisp/term/tty-colors.el index 252a4301295..9cfe30a4630 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." | |||
| 824 | (replace-regexp-in-string " +" "" (downcase color)) | 824 | (replace-regexp-in-string " +" "" (downcase color)) |
| 825 | color))) | 825 | color))) |
| 826 | 826 | ||
| 827 | (defun tty-color-24bit (rgb) | ||
| 828 | "Return pixel value on 24-bit terminals. Return nil if RGB is | ||
| 829 | nil or not on 24-bit terminal." | ||
| 830 | (when (and rgb (= (display-color-cells) 16777216)) | ||
| 831 | (let ((r (lsh (car rgb) -8)) | ||
| 832 | (g (lsh (cadr rgb) -8)) | ||
| 833 | (b (lsh (nth 2 rgb) -8))) | ||
| 834 | (logior (lsh r 16) (lsh g 8) b)))) | ||
| 835 | |||
| 827 | (defun tty-color-define (name index &optional rgb frame) | 836 | (defun tty-color-define (name index &optional rgb frame) |
| 828 | "Specify a tty color by its NAME, terminal INDEX and RGB values. | 837 | "Specify a tty color by its NAME, terminal INDEX and RGB values. |
| 829 | NAME is a string, INDEX is typically a small integer used to send to | 838 | 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." | |||
| 840 | (and rgb (or (not (listp rgb)) (/= (length rgb) 3)))) | 849 | (and rgb (or (not (listp rgb)) (/= (length rgb) 3)))) |
| 841 | (error "Invalid specification for tty color \"%s\"" name)) | 850 | (error "Invalid specification for tty color \"%s\"" name)) |
| 842 | (tty-modify-color-alist | 851 | (tty-modify-color-alist |
| 843 | (append (list (tty-color-canonicalize name) index) rgb) frame)) | 852 | (append (list (tty-color-canonicalize name) |
| 853 | (or (tty-color-24bit rgb) index)) | ||
| 854 | rgb) | ||
| 855 | frame)) | ||
| 844 | 856 | ||
| 845 | (defun tty-color-clear (&optional _frame) | 857 | (defun tty-color-clear (&optional _frame) |
| 846 | "Clear the list of supported tty colors for frame FRAME. | 858 | "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." | |||
| 1013 | (let ((color (tty-color-canonicalize color))) | 1025 | (let ((color (tty-color-canonicalize color))) |
| 1014 | (or (assoc color (tty-color-alist frame)) | 1026 | (or (assoc color (tty-color-alist frame)) |
| 1015 | (let ((rgb (tty-color-standard-values color))) | 1027 | (let ((rgb (tty-color-standard-values color))) |
| 1016 | (and rgb (tty-color-approximate rgb frame))))))) | 1028 | (and rgb |
| 1029 | (let ((pixel (tty-color-24bit rgb))) | ||
| 1030 | (or (and pixel (cons color (cons pixel rgb))) | ||
| 1031 | (tty-color-approximate rgb frame))))))))) | ||
| 1017 | 1032 | ||
| 1018 | (defun tty-color-gray-shades (&optional display) | 1033 | (defun tty-color-gray-shades (&optional display) |
| 1019 | "Return the number of gray colors supported by DISPLAY's terminal. | 1034 | "Return the number of gray colors supported by DISPLAY's terminal. |
diff --git a/lisp/term/xterm.el b/lisp/term/xterm.el index 339d05d9728..e6d224dd3de 100644 --- a/lisp/term/xterm.el +++ b/lisp/term/xterm.el | |||
| @@ -930,6 +930,14 @@ versions of xterm." | |||
| 930 | ;; are more colors to support, compute them now. | 930 | ;; are more colors to support, compute them now. |
| 931 | (when (> ncolors 0) | 931 | (when (> ncolors 0) |
| 932 | (cond | 932 | (cond |
| 933 | ((= ncolors 16777200) ; 24-bit xterm | ||
| 934 | ;; all named tty colors | ||
| 935 | (let ((idx (length xterm-standard-colors))) | ||
| 936 | (mapc (lambda (color) | ||
| 937 | (unless (assoc (car color) xterm-standard-colors) | ||
| 938 | (tty-color-define (car color) idx (cdr color)) | ||
| 939 | (setq idx (1+ idx)))) | ||
| 940 | color-name-rgb-alist))) | ||
| 933 | ((= ncolors 240) ; 256-color xterm | 941 | ((= ncolors 240) ; 256-color xterm |
| 934 | ;; 216 non-gray colors first | 942 | ;; 216 non-gray colors first |
| 935 | (let ((r 0) (g 0) (b 0)) | 943 | (let ((r 0) (g 0) (b 0)) |
diff --git a/src/term.c b/src/term.c index b0ff9cb546d..35fa8c931c1 100644 --- a/src/term.c +++ b/src/term.c | |||
| @@ -4131,6 +4131,20 @@ use the Bourne shell command 'TERM=...; export TERM' (C-shell:\n\ | |||
| 4131 | 4131 | ||
| 4132 | tty->TN_max_colors = tgetnum ("Co"); | 4132 | tty->TN_max_colors = tgetnum ("Co"); |
| 4133 | 4133 | ||
| 4134 | #ifdef TERMINFO | ||
| 4135 | /* Non-standard support for 24-bit colors. */ | ||
| 4136 | { | ||
| 4137 | const char* fg = tigetstr ("setf24"); | ||
| 4138 | const char* bg = tigetstr ("setb24"); | ||
| 4139 | if (fg && bg && fg != (char *)-1 && bg != (char *)-1) | ||
| 4140 | { | ||
| 4141 | tty->TS_set_foreground = fg; | ||
| 4142 | tty->TS_set_background = bg; | ||
| 4143 | tty->TN_max_colors = 16777216; | ||
| 4144 | } | ||
| 4145 | } | ||
| 4146 | #endif | ||
| 4147 | |||
| 4134 | tty->TN_no_color_video = tgetnum ("NC"); | 4148 | tty->TN_no_color_video = tgetnum ("NC"); |
| 4135 | if (tty->TN_no_color_video == -1) | 4149 | if (tty->TN_no_color_video == -1) |
| 4136 | tty->TN_no_color_video = 0; | 4150 | tty->TN_no_color_video = 0; |
diff --git a/src/tparam.h b/src/tparam.h index 15664d68bdb..02136b6ca58 100644 --- a/src/tparam.h +++ b/src/tparam.h | |||
| @@ -36,4 +36,8 @@ extern char PC; | |||
| 36 | extern char *BC; | 36 | extern char *BC; |
| 37 | extern char *UP; | 37 | extern char *UP; |
| 38 | 38 | ||
| 39 | #ifdef TERMINFO | ||
| 40 | char *tigetstr(const char *); | ||
| 41 | #endif | ||
| 42 | |||
| 39 | #endif /* EMACS_TPARAM_H */ | 43 | #endif /* EMACS_TPARAM_H */ |