Support 24-bit TrueColor on MS-Windows console
* src/w32console.c (DEFAULTP, SSPRINTF, w32con_write_vt_seq) (w32con_get_cursor_coords): New functions and macros. (w32con_write_glyphs): Hide cursor before writing to the console. Add code for writing in virtual-terminal mode when 'w32_use_virtual_terminal' is non-zero. (w32con_write_glyphs_with_face): Add code for writing in virtual-terminal mode when 'w32_use_virtual_terminal' is non-zero. (w32con_setup_virtual_terminal): New function. (w32con_set_terminal_modes): Call it. (turn_on_face, turn_off_face): New functions. (initialize_w32_display): Save background and foreground, and the current TTY. (Fset_screen_color): Accept an additional optional argument VTP; if non-nil, arrange for 24-bit display to use the specified colors. (Fget_screen_color): Accept an additional optional argument VTP; if non-nil, return colors used by 24-bit display. (Fw32_use_virtual_terminal, Fw32_use_virtual_terminal_p): New functions. * src/term.c (tty_setup_colors) [WINDOWSNT]: Set up virtual-terminal sequences for colors. (init_tty) [WINDOWSNT]: Set up terminfo capabilities for Windows virtual-terminal. * src/xdisp.c (redisplay_internal): Don't call set_tty_color_mode for WINDOWSNT. * lisp/term/w32console.el (w32-tty-set-base-colors) (w32-tty-define-base-colors, w32-tty-define-8bit-colors) (w32-tty-define-24bit-colors, w32-tty-get-pixel): New functions. (terminal-init-w32console): Remove color setup. (w32-tty-setup-colors): New function. * lisp/term/tty-colors.el (tty-color-mode-alist): Add --color modes for 256 and 24-bit color modes. * lisp/startup.el (tty-handle-args): Fix --color handling. * lisp/faces.el (tty-set-up-initial-frame-faces): Set up colors for MS-Windows consoles. * etc/NEWS: * doc/emacs/msdos.texi (Windows Misc): * doc/emacs/cmdargs.texi (Colors X): Document 24-bit color support on MS-Windows. (Bug#79298)
This commit is contained in:
@@ -1024,19 +1024,26 @@ colored display.
|
|||||||
@itemx ansi8
|
@itemx ansi8
|
||||||
Turn on the color support unconditionally, and use color commands
|
Turn on the color support unconditionally, and use color commands
|
||||||
specified by the ANSI escape sequences for the 8 standard colors.
|
specified by the ANSI escape sequences for the 8 standard colors.
|
||||||
|
@item 8bit
|
||||||
|
Turn on support for 8-bit (256 color) display if available.
|
||||||
|
Currently this option is effective on MS-Windows (10+) only.
|
||||||
|
On other systems, maximal color support is enabled automatically.
|
||||||
|
@item 24bit
|
||||||
|
Turn on support for 24-bit (true color) display if available.
|
||||||
|
Currently this option is effective on MS-Windows (10+) only.
|
||||||
|
On other systems, 24-bit color is enabled automatically if supported.
|
||||||
@item @var{num}
|
@item @var{num}
|
||||||
Use color mode for @var{num} colors. If @var{num} is @minus{}1, turn off
|
Use color mode for @var{num} colors. If @var{num} is @minus{}1, turn off
|
||||||
color support (equivalent to @samp{never}); if it is 0, use the
|
color support (equivalent to @samp{never}); if it is 0, use the
|
||||||
default color support for this terminal (equivalent to @samp{auto});
|
default color support for this terminal (equivalent to @samp{auto});
|
||||||
otherwise use an appropriate standard mode for @var{num} colors.
|
otherwise use an appropriate standard mode for @var{num} colors.
|
||||||
Depending on your terminal's capabilities, Emacs might be able to turn
|
Depending on your terminal's capabilities, Emacs might be able to turn
|
||||||
on a color mode for 8, 16, 88, or 256 as the value of @var{num}. If
|
on a color mode for 8, 16, 88, 256, or 16777216 as the value of @var{num}.
|
||||||
there is no mode that supports @var{num} colors, Emacs acts as if
|
If there is no mode that supports @var{num} colors, Emacs acts as if
|
||||||
@var{num} were 0, i.e., it uses the terminal's default color support
|
@var{num} were 0, i.e., it uses the terminal's default color support mode.
|
||||||
mode.
|
|
||||||
@end table
|
@end table
|
||||||
|
|
||||||
This option has no effect on MS-Windows and MS-DOS.
|
This option has no effect on MS-DOS, nor MS-Windows prior to Windows 10.
|
||||||
|
|
||||||
@cindex colors on character terminal, changing during session
|
@cindex colors on character terminal, changing during session
|
||||||
@cindex character terminal, change color mode
|
@cindex character terminal, change color mode
|
||||||
|
|||||||
@@ -1200,6 +1200,33 @@ you should set its value in your init file (@pxref{Init File}), either
|
|||||||
directly or via @kbd{M-x customize-variable}, which lets you save the
|
directly or via @kbd{M-x customize-variable}, which lets you save the
|
||||||
customized value, see @ref{Saving Customizations}.
|
customized value, see @ref{Saving Customizations}.
|
||||||
|
|
||||||
|
@findex w32-use-virtual-terminal
|
||||||
|
@cindex Windows Terminal, Windows Console, MS-Windows
|
||||||
|
The implementation of display functionality for Windows Console
|
||||||
|
differs from the implementation for other terminal emulators,
|
||||||
|
because historically, Windows required use of an idiosyncractic API.
|
||||||
|
That API limited Windows Console display of Emacs to 16 basic colors.
|
||||||
|
With the introduction of Windows Terminal, Microsoft implemented
|
||||||
|
support for ANSI control sequences, modelled on the VT100 and Xterm,
|
||||||
|
as well as 24-bit RBG color display.
|
||||||
|
|
||||||
|
The functions @code{w32-use-virtual-terminal} and
|
||||||
|
@code{w32-use-virtual-terminal-p} can be used to set and inspect
|
||||||
|
(respectively) an internal variable which determines whether this newer
|
||||||
|
mechanism is used for display, or the older one. The internal variable is
|
||||||
|
automatically set based on your terminal's capabilities on startup.
|
||||||
|
By default, 24-bit RGB color will be used, but other (8, 16, 256) color
|
||||||
|
spaces may be used, by passing the @code{--color} command line argument,
|
||||||
|
or setting the value of the @code{tty-color-mode} frame parameter.
|
||||||
|
|
||||||
|
@code{'(w32-use-virtual-terminal-p)} evaluates to @code{t} if and only if
|
||||||
|
the internal variable has a non-zero numerical value, and otherwise to
|
||||||
|
@code{nil}. If it evaluates to @code{t}, ANSI escape sequences are used
|
||||||
|
for color, otherwise, the older mechanism is used. The internal variable
|
||||||
|
can be set by evaluating @code{(w32-use-virtual-terminal x)}, where @code{x} is
|
||||||
|
@code{t} or @code{nil}: if @code{x} is @code{t} and the feature is supported by
|
||||||
|
your terminal, it will be enabled. Otherwise, the feature will be disabled.
|
||||||
|
|
||||||
@ifnottex
|
@ifnottex
|
||||||
@include msdos-xtra.texi
|
@include msdos-xtra.texi
|
||||||
@end ifnottex
|
@end ifnottex
|
||||||
|
|||||||
12
etc/NEWS
12
etc/NEWS
@@ -4630,6 +4630,18 @@ Accordingly, we have revised our recommendations for a suitable DJGPP
|
|||||||
toolchain to GCC 14.2.0 and Binutils 2.35.1 in lieu of GCC 3.4.x and
|
toolchain to GCC 14.2.0 and Binutils 2.35.1 in lieu of GCC 3.4.x and
|
||||||
Binutils 2.26.
|
Binutils 2.26.
|
||||||
|
|
||||||
|
+++
|
||||||
|
** Windows Terminal can now display 256 and 24-bit RGB color.
|
||||||
|
Previously, terminal sessions on Windows supported display of 16 colors.
|
||||||
|
There is now support for 8-bit (256 color) and 24-bit RGB (true color).
|
||||||
|
The new mechanism will be enabled automatically when supported.
|
||||||
|
It defaults to 24-bit RGB color, but can be set to 8, 16, '8bit, or '24bit
|
||||||
|
by passing the '--color' flag or setting the 'tty-color-mode' frame parameter.
|
||||||
|
Use of the new mechanism is controlled by an internal variable that can be
|
||||||
|
set and inspected via the functions 'w32-use-virtual-terminal' and
|
||||||
|
'w32-use-virtual-terminal-p' (respectively). See the manual entry specific
|
||||||
|
to MS-Windows for more details.
|
||||||
|
|
||||||
|
|
||||||
----------------------------------------------------------------------
|
----------------------------------------------------------------------
|
||||||
This file is part of GNU Emacs.
|
This file is part of GNU Emacs.
|
||||||
|
|||||||
@@ -2405,11 +2405,15 @@ If you set `term-file-prefix' to nil, this function does nothing."
|
|||||||
|
|
||||||
;; Called from C function init_display to initialize faces of the
|
;; Called from C function init_display to initialize faces of the
|
||||||
;; dumped terminal frame on startup.
|
;; dumped terminal frame on startup.
|
||||||
|
(declare-function w32-tty-setup-colors "term/w32console" ())
|
||||||
(defun tty-set-up-initial-frame-faces ()
|
(defun tty-set-up-initial-frame-faces ()
|
||||||
(let ((frame (selected-frame)))
|
(progn
|
||||||
(frame-set-background-mode frame t)
|
(when (and (eq system-type 'windows-nt)
|
||||||
(face-set-after-frame-default frame)))
|
(featurep 'term/w32console))
|
||||||
|
(w32-tty-setup-colors))
|
||||||
|
(let ((frame (selected-frame)))
|
||||||
|
(frame-set-background-mode frame t)
|
||||||
|
(face-set-after-frame-default frame))))
|
||||||
|
|
||||||
|
|
||||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||||
|
|||||||
@@ -958,7 +958,7 @@ to prepare for opening the first frame (e.g. open a connection to an X server)."
|
|||||||
(push (cons 'tty-color-mode
|
(push (cons 'tty-color-mode
|
||||||
(cond
|
(cond
|
||||||
((numberp argval) argval)
|
((numberp argval) argval)
|
||||||
((string-match "-?[0-9]+" argval)
|
((string-match "-?[0-9]+$" argval)
|
||||||
(string-to-number argval))
|
(string-to-number argval))
|
||||||
(t (intern argval))))
|
(t (intern argval))))
|
||||||
default-frame-alist))
|
default-frame-alist))
|
||||||
|
|||||||
@@ -764,7 +764,9 @@
|
|||||||
(auto . 0)
|
(auto . 0)
|
||||||
(ansi8 . 8)
|
(ansi8 . 8)
|
||||||
(always . 8)
|
(always . 8)
|
||||||
(yes . 8))
|
(yes . 8)
|
||||||
|
(8bit . 256)
|
||||||
|
(24bit . 16777216))
|
||||||
"An alist of supported standard tty color modes and their aliases.")
|
"An alist of supported standard tty color modes and their aliases.")
|
||||||
|
|
||||||
(defun tty-color-alist (&optional _frame)
|
(defun tty-color-alist (&optional _frame)
|
||||||
|
|||||||
@@ -46,9 +46,77 @@
|
|||||||
"A list of VGA console colors, their indices and 16-bit RGB values.")
|
"A list of VGA console colors, their indices and 16-bit RGB values.")
|
||||||
|
|
||||||
(declare-function x-setup-function-keys "term/common-win" (frame))
|
(declare-function x-setup-function-keys "term/common-win" (frame))
|
||||||
(declare-function get-screen-color "w32console.c" ())
|
(declare-function get-screen-color "w32console.c" (&optional vtp))
|
||||||
|
(declare-function set-screen-color "w32console.c" (&optional vtp))
|
||||||
(declare-function w32-get-console-codepage "w32proc.c" ())
|
(declare-function w32-get-console-codepage "w32proc.c" ())
|
||||||
(declare-function w32-get-console-output-codepage "w32proc.c" ())
|
(declare-function w32-get-console-output-codepage "w32proc.c" ())
|
||||||
|
(declare-function w32-use-virtual-terminal "w32console.c" (enable))
|
||||||
|
(declare-function w32-use-virtual-terminal-p "w32console.c" ())
|
||||||
|
|
||||||
|
(defun w32-tty-set-base-colors (vtp)
|
||||||
|
"Re-order `w32-tty-standard-colors' based on the value of VTP."
|
||||||
|
(let ((seq
|
||||||
|
(if vtp
|
||||||
|
'("black" "red" "green" "brown"
|
||||||
|
"blue" "magenta" "cyan" "lightgray"
|
||||||
|
"darkgray" "lightred" "lightgreen" "yellow"
|
||||||
|
"lightblue" "lightmagenta" "lightcyan" "white")
|
||||||
|
'("black" "blue" "green" "cyan"
|
||||||
|
"red" "magenta" "brown" "lightgray"
|
||||||
|
"darkgray" "lightblue" "lightgreen" "lightcyan"
|
||||||
|
"lightred" "lightmagenta" "yellow" "white"))))
|
||||||
|
(setq w32-tty-standard-colors
|
||||||
|
(mapcar
|
||||||
|
(lambda (n) (let ((c (assoc n w32-tty-standard-colors)))
|
||||||
|
(cons n (cons (seq-position seq n) (cddr c)))))
|
||||||
|
seq))))
|
||||||
|
|
||||||
|
(defun w32-tty-define-base-colors ()
|
||||||
|
"Defines base 16-color space for w32 tty display."
|
||||||
|
(let* ((colors w32-tty-standard-colors)
|
||||||
|
(nbase (length colors))
|
||||||
|
(color (car colors)))
|
||||||
|
(progn (while colors
|
||||||
|
(tty-color-define (car color) (cadr color) (cddr color))
|
||||||
|
(setq colors (cdr colors)
|
||||||
|
color (car colors)))
|
||||||
|
nbase)))
|
||||||
|
|
||||||
|
(defun w32-tty-define-8bit-colors ()
|
||||||
|
"Defines 8-bit color space for w32 tty display."
|
||||||
|
(let ((r 0) (b 0) (g 0)
|
||||||
|
(n (- 256 (w32-tty-define-base-colors)))
|
||||||
|
(convert-to-16bit (lambda (prim) (logior prim (ash prim 8)))))
|
||||||
|
(while (> n 24) ; non-grey
|
||||||
|
(let ((i (- 256 n))
|
||||||
|
(c (mapcar convert-to-16bit
|
||||||
|
(mapcar (lambda (x) (if (zerop x) 0 (+ (* x 40) 55)))
|
||||||
|
(list r g b)))))
|
||||||
|
(tty-color-define (format "color-%d" i) i c))
|
||||||
|
(setq b (1+ b))
|
||||||
|
(when (> b 5) (setq g (1+ g) b 0))
|
||||||
|
(when (> g 5) (setq r (1+ r) g 0))
|
||||||
|
(setq n (1- n)))
|
||||||
|
(while (> n 0) ; all-grey
|
||||||
|
(let* ((i (- 256 n))
|
||||||
|
(v (funcall convert-to-16bit (+ 8 (* (- 24 n) 10))))
|
||||||
|
(c (list v v v)))
|
||||||
|
(tty-color-define (format "color-%d" i) i c))
|
||||||
|
(setq n (1- n)))))
|
||||||
|
|
||||||
|
(defun w32-tty-define-24bit-colors ()
|
||||||
|
"Defines 24-bit color space for w32 tty display."
|
||||||
|
(let ((i (w32-tty-define-base-colors)))
|
||||||
|
(mapc (lambda (c) (unless (assoc (car c) w32-tty-standard-colors)
|
||||||
|
(tty-color-define (car c) i (cdr c))
|
||||||
|
(setq i (1+ i))))
|
||||||
|
color-name-rgb-alist)))
|
||||||
|
|
||||||
|
;; tty-color-define swaps indices for pixel values on 24bit display
|
||||||
|
(defun w32-tty-get-pixel (index)
|
||||||
|
"Convert a legacy color INDEX (0..15) into a pixel value."
|
||||||
|
(let ((color (nth index w32-tty-standard-colors)))
|
||||||
|
(or (tty-color-24bit (cddr color)) index)))
|
||||||
|
|
||||||
(defun terminal-init-w32console ()
|
(defun terminal-init-w32console ()
|
||||||
"Terminal initialization function for w32 console."
|
"Terminal initialization function for w32 console."
|
||||||
@@ -56,43 +124,53 @@
|
|||||||
(x-setup-function-keys (selected-frame))
|
(x-setup-function-keys (selected-frame))
|
||||||
;; Set terminal and keyboard encodings to the current OEM codepage.
|
;; Set terminal and keyboard encodings to the current OEM codepage.
|
||||||
(let ((oem-code-page-coding
|
(let ((oem-code-page-coding
|
||||||
(intern (format "cp%d" (w32-get-console-codepage))))
|
(intern (format "cp%d" (w32-get-console-codepage))))
|
||||||
(oem-code-page-output-coding
|
(oem-code-page-output-coding
|
||||||
(intern (format "cp%d" (w32-get-console-output-codepage))))
|
(intern (format "cp%d" (w32-get-console-output-codepage))))
|
||||||
oem-cs-p oem-o-cs-p)
|
oem-cs-p oem-o-cs-p)
|
||||||
(setq oem-cs-p (coding-system-p oem-code-page-coding))
|
(setq oem-cs-p (coding-system-p oem-code-page-coding))
|
||||||
(setq oem-o-cs-p (coding-system-p oem-code-page-output-coding))
|
(setq oem-o-cs-p (coding-system-p oem-code-page-output-coding))
|
||||||
(when oem-cs-p
|
(when oem-cs-p
|
||||||
(set-keyboard-coding-system oem-code-page-coding)
|
(set-keyboard-coding-system oem-code-page-coding)
|
||||||
(set-terminal-coding-system
|
(set-terminal-coding-system
|
||||||
(if oem-o-cs-p oem-code-page-output-coding oem-code-page-coding))
|
(if oem-o-cs-p oem-code-page-output-coding oem-code-page-coding))
|
||||||
;; Since we changed the terminal encoding, we need to repeat
|
;; Since we changed the terminal encoding, we need to repeat
|
||||||
;; the test for Unicode quotes being displayable.
|
;; the test for Unicode quotes being displayable.
|
||||||
(startup--setup-quote-display)))
|
(startup--setup-quote-display)))
|
||||||
(let* ((colors w32-tty-standard-colors)
|
|
||||||
(color (car colors)))
|
|
||||||
(tty-color-clear)
|
|
||||||
(while colors
|
|
||||||
(tty-color-define (car color) (cadr color) (cddr color))
|
|
||||||
(setq colors (cdr colors)
|
|
||||||
color (car colors))))
|
|
||||||
(clear-face-cache)
|
|
||||||
;; Figure out what are the colors of the console window, and set up
|
|
||||||
;; the background-mode correspondingly.
|
|
||||||
(let* ((screen-color (get-screen-color))
|
|
||||||
(bg (cadr screen-color))
|
|
||||||
(descr (tty-color-by-index bg))
|
|
||||||
r g b bg-mode)
|
|
||||||
(setq r (nth 2 descr)
|
|
||||||
g (nth 3 descr)
|
|
||||||
b (nth 4 descr))
|
|
||||||
(if (< (+ r g b) (* .6 (+ 65535 65535 65535)))
|
|
||||||
(setq bg-mode 'dark)
|
|
||||||
(setq bg-mode 'light))
|
|
||||||
(set-terminal-parameter nil 'background-mode bg-mode))
|
|
||||||
(tty-set-up-initial-frame-faces)
|
(tty-set-up-initial-frame-faces)
|
||||||
(run-hooks 'terminal-init-w32-hook))
|
(run-hooks 'terminal-init-w32-hook))
|
||||||
|
|
||||||
|
;; Called from tty-set-up-initial-frame-faces in faces.el
|
||||||
|
(defun w32-tty-setup-colors ()
|
||||||
|
"Set up color definitions and frame parameters for w32 tty display."
|
||||||
|
(tty-color-clear)
|
||||||
|
(let ((ncolors (display-color-cells))
|
||||||
|
(vtp (w32-use-virtual-terminal-p)))
|
||||||
|
(w32-tty-set-base-colors vtp)
|
||||||
|
(if vtp
|
||||||
|
(cond ((= ncolors 16777216) (w32-tty-define-24bit-colors))
|
||||||
|
((= ncolors 256) (w32-tty-define-8bit-colors))
|
||||||
|
(t (w32-tty-define-base-colors)))
|
||||||
|
(w32-tty-define-base-colors))
|
||||||
|
(clear-face-cache)
|
||||||
|
(let* ((screen-color (get-screen-color vtp))
|
||||||
|
(fg (car screen-color))
|
||||||
|
(bg (cadr screen-color))
|
||||||
|
(bootstrap (and vtp (= ncolors 16777216)
|
||||||
|
(< fg 16) (< bg 16) (not (= 0 fg bg))))
|
||||||
|
(fallback (and vtp (< ncolors 16777216)
|
||||||
|
(or (< ncolors fg) (< ncolors bg))))
|
||||||
|
(screen-color (if fallback (get-screen-color t) screen-color))
|
||||||
|
(fg (if bootstrap (w32-tty-get-pixel fg) (car screen-color)))
|
||||||
|
(bg (if bootstrap (w32-tty-get-pixel bg) (cadr screen-color)))
|
||||||
|
(bg-col (tty-color-by-index bg))
|
||||||
|
(bg-dark (< (+ (nth 2 bg-col) (nth 3 bg-col) (nth 4 bg-col))
|
||||||
|
(* .6 (+ 65535 65535 65535))))
|
||||||
|
(bg-mode (if bg-dark 'dark 'light)))
|
||||||
|
(set-terminal-parameter nil 'background-mode bg-mode)
|
||||||
|
(when (or bootstrap fallback)
|
||||||
|
(set-screen-color fg bg t)))))
|
||||||
|
|
||||||
(provide 'term/w32console)
|
(provide 'term/w32console)
|
||||||
|
|
||||||
;;; w32console.el ends here
|
;;; w32console.el ends here
|
||||||
|
|||||||
51
src/term.c
51
src/term.c
@@ -2207,7 +2207,7 @@ TERMINAL does not refer to a text terminal. */)
|
|||||||
return make_fixnum (t ? t->display_info.tty->TN_max_colors : 0);
|
return make_fixnum (t ? t->display_info.tty->TN_max_colors : 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
#if !defined DOS_NT && !defined HAVE_ANDROID
|
#if !defined MSDOS && !defined HAVE_ANDROID
|
||||||
|
|
||||||
/* Declare here rather than in the function, as in the rest of Emacs,
|
/* Declare here rather than in the function, as in the rest of Emacs,
|
||||||
to work around an HPUX compiler bug (?). See
|
to work around an HPUX compiler bug (?). See
|
||||||
@@ -2246,7 +2246,7 @@ tty_default_color_capabilities (struct tty_display_info *tty, bool save)
|
|||||||
MODE's value is generally the number of colors which we want to
|
MODE's value is generally the number of colors which we want to
|
||||||
support; zero means set up for the default capabilities, the ones
|
support; zero means set up for the default capabilities, the ones
|
||||||
we saw at init_tty time; -1 means turn off color support. */
|
we saw at init_tty time; -1 means turn off color support. */
|
||||||
static void
|
void
|
||||||
tty_setup_colors (struct tty_display_info *tty, int mode)
|
tty_setup_colors (struct tty_display_info *tty, int mode)
|
||||||
{
|
{
|
||||||
/* Canonicalize all negative values of MODE. */
|
/* Canonicalize all negative values of MODE. */
|
||||||
@@ -2269,6 +2269,10 @@ tty_setup_colors (struct tty_display_info *tty, int mode)
|
|||||||
#ifdef TERMINFO
|
#ifdef TERMINFO
|
||||||
tty->TS_set_foreground = "\033[3%p1%dm";
|
tty->TS_set_foreground = "\033[3%p1%dm";
|
||||||
tty->TS_set_background = "\033[4%p1%dm";
|
tty->TS_set_background = "\033[4%p1%dm";
|
||||||
|
#elif WINDOWSNT
|
||||||
|
tty->TS_orig_pair = "\x1b[39m\x1b[49m";
|
||||||
|
tty->TS_set_foreground = "\x1b[%lum";
|
||||||
|
tty->TS_set_background = "\x1b[%lum";
|
||||||
#else
|
#else
|
||||||
tty->TS_set_foreground = "\033[3%dm";
|
tty->TS_set_foreground = "\033[3%dm";
|
||||||
tty->TS_set_background = "\033[4%dm";
|
tty->TS_set_background = "\033[4%dm";
|
||||||
@@ -2276,6 +2280,26 @@ tty_setup_colors (struct tty_display_info *tty, int mode)
|
|||||||
tty->TN_max_colors = 8;
|
tty->TN_max_colors = 8;
|
||||||
tty->TN_no_color_video = 0;
|
tty->TN_no_color_video = 0;
|
||||||
break;
|
break;
|
||||||
|
#ifdef WINDOWSNT
|
||||||
|
case 16:
|
||||||
|
tty->TN_max_colors = 16;
|
||||||
|
tty->TS_set_foreground = "\x1b[%lum";
|
||||||
|
tty->TS_set_background = "\x1b[%lum";
|
||||||
|
tty->TN_no_color_video = 0;
|
||||||
|
break;
|
||||||
|
case 256:
|
||||||
|
tty->TN_max_colors = 256;
|
||||||
|
tty->TS_set_foreground = "\x1b[38;5;%lum";
|
||||||
|
tty->TS_set_background = "\x1b[48;5;%lum";
|
||||||
|
tty->TN_no_color_video = 0;
|
||||||
|
break;
|
||||||
|
case 16777216:
|
||||||
|
tty->TN_max_colors = 16777216;
|
||||||
|
tty->TS_set_foreground = "\x1b[38;2;%lu;%lu;%lum";
|
||||||
|
tty->TS_set_background = "\x1b[48;2;%lu;%lu;%lum";
|
||||||
|
tty->TN_no_color_video = 0;
|
||||||
|
break;
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -2312,7 +2336,7 @@ set_tty_color_mode (struct tty_display_info *tty, struct frame *f)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif /* !DOS_NT && !HAVE_ANDROID */
|
#endif /* !MSDOS && !HAVE_ANDROID */
|
||||||
|
|
||||||
char *
|
char *
|
||||||
tty_type_name (Lisp_Object terminal)
|
tty_type_name (Lisp_Object terminal)
|
||||||
@@ -4644,6 +4668,22 @@ use the Bourne shell command 'TERM=...; export TERM' (C-shell:\n\
|
|||||||
|
|
||||||
initialize_w32_display (terminal, &width, &height);
|
initialize_w32_display (terminal, &width, &height);
|
||||||
|
|
||||||
|
tty->TN_no_color_video = 0;
|
||||||
|
tty->TN_max_colors = 16777216;
|
||||||
|
tty->TS_orig_pair = "\x1b[39m\x1b[49m";
|
||||||
|
tty->TS_set_foreground = "\x1b[38;2;%lu;%lu;%lum";
|
||||||
|
tty->TS_set_background = "\x1b[48;2;%lu;%lu;%lum";
|
||||||
|
|
||||||
|
/* Save default color capabilities */
|
||||||
|
tty_default_color_capabilities (tty, 1);
|
||||||
|
|
||||||
|
tty->TS_enter_bold_mode = "\x1b[1m";
|
||||||
|
tty->TS_enter_italic_mode = "\x1b[3m";
|
||||||
|
tty->TS_enter_strike_through_mode = "\x1b[9m";
|
||||||
|
tty->TS_enter_underline_mode = "\x1b[4m";
|
||||||
|
tty->TS_enter_reverse_mode = "\x1b[7m";
|
||||||
|
tty->TS_exit_attribute_mode = "\x1b[0m";
|
||||||
|
|
||||||
FrameRows (tty) = height;
|
FrameRows (tty) = height;
|
||||||
FrameCols (tty) = width;
|
FrameCols (tty) = width;
|
||||||
tty->specified_window = height;
|
tty->specified_window = height;
|
||||||
@@ -4689,7 +4729,6 @@ use the Bourne shell command 'TERM=...; export TERM' (C-shell:\n\
|
|||||||
don't think we're losing anything by turning it off. */
|
don't think we're losing anything by turning it off. */
|
||||||
tty->line_ins_del_ok = 0;
|
tty->line_ins_del_ok = 0;
|
||||||
|
|
||||||
tty->TN_max_colors = 16; /* Must be non-zero for tty-display-color-p. */
|
|
||||||
#endif /* DOS_NT */
|
#endif /* DOS_NT */
|
||||||
|
|
||||||
#ifdef HAVE_GPM
|
#ifdef HAVE_GPM
|
||||||
@@ -5205,11 +5244,11 @@ non-nil to enable this optimization. */);
|
|||||||
defsubr (&Stty_display_pixel_width);
|
defsubr (&Stty_display_pixel_width);
|
||||||
defsubr (&Stty_display_pixel_height);
|
defsubr (&Stty_display_pixel_height);
|
||||||
|
|
||||||
#if !defined DOS_NT && !defined HAVE_ANDROID
|
#if !defined MSDOS && !defined HAVE_ANDROID
|
||||||
default_orig_pair = NULL;
|
default_orig_pair = NULL;
|
||||||
default_set_foreground = NULL;
|
default_set_foreground = NULL;
|
||||||
default_set_background = NULL;
|
default_set_background = NULL;
|
||||||
#endif /* !DOS_NT && !HAVE_ANDROID */
|
#endif /* !MSDOS && !HAVE_ANDROID */
|
||||||
|
|
||||||
#ifndef HAVE_ANDROID
|
#ifndef HAVE_ANDROID
|
||||||
encode_terminal_src = NULL;
|
encode_terminal_src = NULL;
|
||||||
|
|||||||
@@ -249,4 +249,6 @@ struct input_event;
|
|||||||
extern Lisp_Object tty_handle_tab_bar_click (struct frame *, int, int, bool,
|
extern Lisp_Object tty_handle_tab_bar_click (struct frame *, int, int, bool,
|
||||||
struct input_event *);
|
struct input_event *);
|
||||||
|
|
||||||
|
extern void tty_setup_colors (struct tty_display_info *tty, int mode);
|
||||||
|
|
||||||
#endif /* EMACS_TERMCHAR_H */
|
#endif /* EMACS_TERMCHAR_H */
|
||||||
|
|||||||
348
src/w32console.c
348
src/w32console.c
@@ -19,6 +19,9 @@ along with GNU Emacs. If not, see <https://www.gnu.org/licenses/>. */
|
|||||||
/*
|
/*
|
||||||
Tim Fleehart (apollo@online.com) 1-17-92
|
Tim Fleehart (apollo@online.com) 1-17-92
|
||||||
Geoff Voelker (voelker@cs.washington.edu) 9-12-93
|
Geoff Voelker (voelker@cs.washington.edu) 9-12-93
|
||||||
|
Ewan Townshend (ewan@etown.dev) 2025-08
|
||||||
|
* c. ~ 2025: 24bit RGB support in Windows (10+) Terminal
|
||||||
|
* https://learn.microsoft.com/en-us/windows/console/console-virtual-terminal-sequences
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
||||||
@@ -53,11 +56,17 @@ static void w32con_set_terminal_modes (struct terminal *t);
|
|||||||
static void w32con_update_begin (struct frame * f);
|
static void w32con_update_begin (struct frame * f);
|
||||||
static void w32con_update_end (struct frame * f);
|
static void w32con_update_end (struct frame * f);
|
||||||
static WORD w32_face_attributes (struct frame *f, int face_id);
|
static WORD w32_face_attributes (struct frame *f, int face_id);
|
||||||
|
static int w32con_write_vt_seq (const char *);
|
||||||
|
static void turn_on_face (struct frame *, int face_id);
|
||||||
|
static void turn_off_face (struct frame *, int face_id);
|
||||||
|
static COORD w32con_get_cursor_coords ();
|
||||||
|
|
||||||
static COORD cursor_coords;
|
static COORD cursor_coords;
|
||||||
static HANDLE prev_screen, cur_screen;
|
static HANDLE prev_screen, cur_screen;
|
||||||
static WORD char_attr_normal;
|
static WORD char_attr_normal;
|
||||||
static DWORD prev_console_mode;
|
static DWORD prev_console_mode;
|
||||||
|
static int bg_normal;
|
||||||
|
static int fg_normal;
|
||||||
|
|
||||||
static CONSOLE_CURSOR_INFO console_cursor_info;
|
static CONSOLE_CURSOR_INFO console_cursor_info;
|
||||||
#ifndef USE_SEPARATE_SCREEN
|
#ifndef USE_SEPARATE_SCREEN
|
||||||
@@ -67,7 +76,10 @@ static CONSOLE_CURSOR_INFO prev_console_cursor;
|
|||||||
extern HANDLE keyboard_handle;
|
extern HANDLE keyboard_handle;
|
||||||
HANDLE keyboard_handle;
|
HANDLE keyboard_handle;
|
||||||
int w32_console_unicode_input;
|
int w32_console_unicode_input;
|
||||||
|
extern int w32_use_virtual_terminal;
|
||||||
|
int w32_use_virtual_terminal = 1;
|
||||||
|
extern struct tty_display_info *current_tty;
|
||||||
|
struct tty_display_info *current_tty = NULL;
|
||||||
|
|
||||||
/* Setting this as the ctrl handler prevents emacs from being killed when
|
/* Setting this as the ctrl handler prevents emacs from being killed when
|
||||||
someone hits ^C in a 'suspended' session (child shell).
|
someone hits ^C in a 'suspended' session (child shell).
|
||||||
@@ -83,6 +95,38 @@ ctrl_c_handler (unsigned long type)
|
|||||||
&& (type == CTRL_C_EVENT || type == CTRL_BREAK_EVENT));
|
&& (type == CTRL_C_EVENT || type == CTRL_BREAK_EVENT));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#define DEFAULTP(p) \
|
||||||
|
(p == FACE_TTY_DEFAULT_COLOR \
|
||||||
|
|| p == FACE_TTY_DEFAULT_FG_COLOR \
|
||||||
|
|| p == FACE_TTY_DEFAULT_BG_COLOR)
|
||||||
|
|
||||||
|
#define SEQMAX 256 /* Arbitrary upper limit on VT sequence size */
|
||||||
|
|
||||||
|
#define SSPRINTF(buf, i, sz, fmt, ...) \
|
||||||
|
do { \
|
||||||
|
eassert (*i < sz && sz <= SEQMAX); \
|
||||||
|
if (fmt && *i < sz && sz <= SEQMAX) \
|
||||||
|
*i += snprintf (buf + *i, sz - *i, fmt, __VA_ARGS__); \
|
||||||
|
} while (0)
|
||||||
|
|
||||||
|
/* Writes virtual terminal sequence to screen */
|
||||||
|
static int
|
||||||
|
w32con_write_vt_seq (const char *seq)
|
||||||
|
{
|
||||||
|
char buf[SEQMAX];
|
||||||
|
DWORD n = 0, k = 0;
|
||||||
|
SSPRINTF (buf, &n, SEQMAX, seq, NULL);
|
||||||
|
if (n) WriteConsole (cur_screen, (LPCSTR) buf, n, &k, NULL);
|
||||||
|
return k;
|
||||||
|
}
|
||||||
|
|
||||||
|
static COORD
|
||||||
|
w32con_get_cursor_coords ()
|
||||||
|
{
|
||||||
|
CONSOLE_SCREEN_BUFFER_INFO info;
|
||||||
|
GetConsoleScreenBufferInfo (GetStdHandle (STD_OUTPUT_HANDLE), &info);
|
||||||
|
return info.dwCursorPosition;
|
||||||
|
}
|
||||||
|
|
||||||
/* Move the cursor to (ROW, COL) on FRAME. */
|
/* Move the cursor to (ROW, COL) on FRAME. */
|
||||||
static void
|
static void
|
||||||
@@ -309,10 +353,11 @@ w32con_write_glyphs (struct frame *f, register struct glyph *string,
|
|||||||
register int len)
|
register int len)
|
||||||
{
|
{
|
||||||
DWORD r;
|
DWORD r;
|
||||||
WORD char_attr;
|
|
||||||
LPCSTR conversion_buffer;
|
LPCSTR conversion_buffer;
|
||||||
struct coding_system *coding;
|
struct coding_system *coding;
|
||||||
|
|
||||||
|
w32con_hide_cursor();
|
||||||
|
|
||||||
if (len <= 0)
|
if (len <= 0)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
@@ -342,8 +387,6 @@ w32con_write_glyphs (struct frame *f, register struct glyph *string,
|
|||||||
|
|
||||||
/* w32con_clear_end_of_line sets frame of glyphs to NULL. */
|
/* w32con_clear_end_of_line sets frame of glyphs to NULL. */
|
||||||
struct frame *attr_frame = face_id_frame ? face_id_frame : f;
|
struct frame *attr_frame = face_id_frame ? face_id_frame : f;
|
||||||
/* Turn appearance modes of the face of the run on. */
|
|
||||||
char_attr = w32_face_attributes (attr_frame, face_id);
|
|
||||||
|
|
||||||
if (n == len)
|
if (n == len)
|
||||||
/* This is the last run. */
|
/* This is the last run. */
|
||||||
@@ -351,31 +394,45 @@ w32con_write_glyphs (struct frame *f, register struct glyph *string,
|
|||||||
conversion_buffer = (LPCSTR) encode_terminal_code (string, n, coding);
|
conversion_buffer = (LPCSTR) encode_terminal_code (string, n, coding);
|
||||||
if (coding->produced > 0)
|
if (coding->produced > 0)
|
||||||
{
|
{
|
||||||
/* Compute the string's width on display by accounting for
|
if (w32_use_virtual_terminal)
|
||||||
character's width. FIXME: this doesn't handle character
|
|
||||||
compositions. */
|
|
||||||
ptrdiff_t ncols = strwidth (coding->source, coding->src_bytes);
|
|
||||||
/* Set the attribute for these characters. */
|
|
||||||
if (!FillConsoleOutputAttribute (cur_screen, char_attr, ncols,
|
|
||||||
cursor_coords, &r))
|
|
||||||
{
|
{
|
||||||
printf ("Failed writing console attributes: %lu\n",
|
turn_on_face (f, face_id);
|
||||||
GetLastError ());
|
WriteConsole (cur_screen, conversion_buffer,
|
||||||
fflush (stdout);
|
coding->produced, &r, NULL);
|
||||||
|
turn_off_face (f, face_id);
|
||||||
|
cursor_coords = w32con_get_cursor_coords ();
|
||||||
}
|
}
|
||||||
|
else
|
||||||
/* Write the characters. */
|
|
||||||
if (!WriteConsoleOutputCharacter (cur_screen, conversion_buffer,
|
|
||||||
coding->produced, cursor_coords,
|
|
||||||
&r))
|
|
||||||
{
|
{
|
||||||
printf ("Failed writing console characters: %lu\n",
|
/* Account for character width.
|
||||||
GetLastError ());
|
FIXME: this doesn't handle character compositions. */
|
||||||
fflush (stdout);
|
ptrdiff_t ncols = strwidth (coding->source, coding->src_bytes);
|
||||||
}
|
|
||||||
|
|
||||||
cursor_coords.X += ncols;
|
/* Turn appearance modes of the face of the run on. */
|
||||||
w32con_move_cursor (f, cursor_coords.Y, cursor_coords.X);
|
WORD char_attr = w32_face_attributes (attr_frame, face_id);
|
||||||
|
|
||||||
|
/* Set the attribute for these characters. */
|
||||||
|
if (!FillConsoleOutputAttribute (cur_screen, char_attr, ncols,
|
||||||
|
cursor_coords, &r))
|
||||||
|
{
|
||||||
|
printf ("Failed writing console attributes: %lu\n",
|
||||||
|
GetLastError ());
|
||||||
|
fflush (stdout);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Write the characters. */
|
||||||
|
if (!WriteConsoleOutputCharacter (cur_screen, conversion_buffer,
|
||||||
|
coding->produced, cursor_coords,
|
||||||
|
&r))
|
||||||
|
{
|
||||||
|
printf ("Failed writing console characters: %lu\n",
|
||||||
|
GetLastError ());
|
||||||
|
fflush (stdout);
|
||||||
|
}
|
||||||
|
|
||||||
|
cursor_coords.X += ncols;
|
||||||
|
w32con_move_cursor (f, cursor_coords.Y, cursor_coords.X);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
len -= n;
|
len -= n;
|
||||||
string += n;
|
string += n;
|
||||||
@@ -391,6 +448,8 @@ w32con_write_glyphs_with_face (struct frame *f, register int x, register int y,
|
|||||||
LPCSTR conversion_buffer;
|
LPCSTR conversion_buffer;
|
||||||
struct coding_system *coding;
|
struct coding_system *coding;
|
||||||
|
|
||||||
|
w32con_hide_cursor();
|
||||||
|
|
||||||
if (len <= 0)
|
if (len <= 0)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
@@ -407,28 +466,42 @@ w32con_write_glyphs_with_face (struct frame *f, register int x, register int y,
|
|||||||
if (coding->produced > 0)
|
if (coding->produced > 0)
|
||||||
{
|
{
|
||||||
DWORD filled, written;
|
DWORD filled, written;
|
||||||
/* Compute the character attributes corresponding to the face. */
|
if (w32_use_virtual_terminal)
|
||||||
DWORD char_attr = w32_face_attributes (f, face_id);
|
{
|
||||||
COORD start_coords;
|
COORD saved_coords = cursor_coords;
|
||||||
/* Compute the string's width on display by accounting for
|
w32con_move_cursor(f, y, x);
|
||||||
character's width. FIXME: this doesn't handle character
|
turn_on_face (f, face_id);
|
||||||
compositions. */
|
WriteConsole (cur_screen, conversion_buffer,
|
||||||
ptrdiff_t ncols = strwidth (coding->source, coding->src_bytes);
|
coding->produced, &written, NULL);
|
||||||
|
turn_off_face (f, face_id);
|
||||||
start_coords.X = x;
|
w32con_move_cursor(f, saved_coords.Y, saved_coords.X);
|
||||||
start_coords.Y = y;
|
}
|
||||||
/* Set the attribute for these characters. */
|
|
||||||
if (!FillConsoleOutputAttribute (cur_screen, char_attr, ncols,
|
|
||||||
start_coords, &filled))
|
|
||||||
DebPrint (("Failed writing console attributes: %d\n", GetLastError ()));
|
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
/* Write the characters. */
|
/* Compute the character attributes corresponding to the face. */
|
||||||
if (!WriteConsoleOutputCharacter (cur_screen, conversion_buffer,
|
DWORD char_attr = w32_face_attributes (f, face_id);
|
||||||
coding->produced, start_coords,
|
COORD start_coords;
|
||||||
&written))
|
|
||||||
DebPrint (("Failed writing console characters: %d\n",
|
start_coords.X = x;
|
||||||
GetLastError ()));
|
start_coords.Y = y;
|
||||||
|
|
||||||
|
/* Account for character width.
|
||||||
|
FIXME: this doesn't handle character compositions. */
|
||||||
|
ptrdiff_t ncols = strwidth (coding->source, coding->src_bytes);
|
||||||
|
|
||||||
|
/* Set the attribute for these characters. */
|
||||||
|
if (!FillConsoleOutputAttribute (cur_screen, char_attr, ncols,
|
||||||
|
start_coords, &filled))
|
||||||
|
DebPrint (("Failed writing console attributes: %d\n", GetLastError ()));
|
||||||
|
else
|
||||||
|
{
|
||||||
|
/* Write the characters. */
|
||||||
|
if (!WriteConsoleOutputCharacter (cur_screen, conversion_buffer,
|
||||||
|
coding->produced, start_coords,
|
||||||
|
&written))
|
||||||
|
DebPrint (("Failed writing console characters: %d\n",
|
||||||
|
GetLastError ()));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -529,6 +602,33 @@ w32con_delete_glyphs (struct frame *f, int n)
|
|||||||
scroll_line (f, n, LEFT);
|
scroll_line (f, n, LEFT);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
w32con_setup_virtual_terminal (void)
|
||||||
|
{
|
||||||
|
/* Disable unless 24bit color is supported (v. > 10.0.15063). */
|
||||||
|
w32_use_virtual_terminal = w32_use_virtual_terminal
|
||||||
|
&& (w32_major_version > 10
|
||||||
|
|| (w32_major_version == 10
|
||||||
|
&& (w32_minor_version > 0 || w32_build_number > 15063)));
|
||||||
|
|
||||||
|
DWORD out_mode;
|
||||||
|
GetConsoleMode (cur_screen, &out_mode);
|
||||||
|
out_mode |= ENABLE_PROCESSED_OUTPUT;
|
||||||
|
out_mode |= DISABLE_NEWLINE_AUTO_RETURN;
|
||||||
|
|
||||||
|
if (w32_use_virtual_terminal)
|
||||||
|
out_mode |= ENABLE_VIRTUAL_TERMINAL_PROCESSING;
|
||||||
|
else
|
||||||
|
out_mode &= ~ENABLE_VIRTUAL_TERMINAL_PROCESSING;
|
||||||
|
|
||||||
|
int out_mode_set = SetConsoleMode (cur_screen, out_mode);
|
||||||
|
w32_use_virtual_terminal = w32_use_virtual_terminal && out_mode_set;
|
||||||
|
|
||||||
|
int max_colors = w32_use_virtual_terminal ? 16777216 : 16;
|
||||||
|
tty_setup_colors (current_tty, max_colors);
|
||||||
|
|
||||||
|
safe_calln (Qtty_set_up_initial_frame_faces);
|
||||||
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
w32con_reset_terminal_modes (struct terminal *t)
|
w32con_reset_terminal_modes (struct terminal *t)
|
||||||
@@ -585,6 +685,7 @@ w32con_set_terminal_modes (struct terminal *t)
|
|||||||
/* Initialize input mode: interrupt_input off, no flow control, allow
|
/* Initialize input mode: interrupt_input off, no flow control, allow
|
||||||
8 bit character input, standard quit char. */
|
8 bit character input, standard quit char. */
|
||||||
Fset_input_mode (Qnil, Qnil, make_fixnum (2), Qnil);
|
Fset_input_mode (Qnil, Qnil, make_fixnum (2), Qnil);
|
||||||
|
w32con_setup_virtual_terminal ();
|
||||||
}
|
}
|
||||||
|
|
||||||
/* hmmm... perhaps these let us bracket screen changes so that we can flush
|
/* hmmm... perhaps these let us bracket screen changes so that we can flush
|
||||||
@@ -631,8 +732,6 @@ sys_tgetstr (char *cap, char **area)
|
|||||||
stubs from cm.c
|
stubs from cm.c
|
||||||
***********************************************************************/
|
***********************************************************************/
|
||||||
|
|
||||||
extern struct tty_display_info *current_tty;
|
|
||||||
struct tty_display_info *current_tty = NULL;
|
|
||||||
extern int cost;
|
extern int cost;
|
||||||
int cost = 0;
|
int cost = 0;
|
||||||
|
|
||||||
@@ -736,6 +835,87 @@ w32_face_attributes (struct frame *f, int face_id)
|
|||||||
return char_attr;
|
return char_attr;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
turn_on_face (struct frame *f, int face_id)
|
||||||
|
{
|
||||||
|
struct face *face = FACE_FROM_ID (f, face_id);
|
||||||
|
struct tty_display_info *tty = FRAME_TTY (f);
|
||||||
|
unsigned long fg = face->foreground;
|
||||||
|
unsigned long bg = face->background;
|
||||||
|
|
||||||
|
/* construct combined VT sequence for face attributes */
|
||||||
|
DWORD n = 0;
|
||||||
|
size_t sz = SEQMAX;
|
||||||
|
char seq[sz];
|
||||||
|
sz--;
|
||||||
|
|
||||||
|
if (face->tty_bold_p)
|
||||||
|
SSPRINTF (seq, &n, sz, tty->TS_enter_bold_mode, NULL);
|
||||||
|
if (face->tty_italic_p)
|
||||||
|
SSPRINTF (seq, &n, sz, tty->TS_enter_italic_mode, NULL);
|
||||||
|
if (face->tty_strike_through_p)
|
||||||
|
SSPRINTF (seq, &n, sz, tty->TS_enter_strike_through_mode, NULL);
|
||||||
|
if (face->underline != 0)
|
||||||
|
SSPRINTF (seq, &n, sz, tty->TS_enter_underline_mode, NULL);
|
||||||
|
/* Note: when face->tty_reverse_p != 0 and fg and bg are specified,
|
||||||
|
their values are already swapped and reversing them here would swap
|
||||||
|
them back, but we need to handle the reversal when unspecified. */
|
||||||
|
if (face->tty_reverse_p && DEFAULTP (fg) && DEFAULTP (bg))
|
||||||
|
SSPRINTF (seq, &n, sz, tty->TS_enter_reverse_mode, NULL);
|
||||||
|
|
||||||
|
if (DEFAULTP (fg)) fg = fg_normal;
|
||||||
|
if (DEFAULTP (bg)) bg = bg_normal;
|
||||||
|
|
||||||
|
const char *set_fg = tty->TS_set_foreground;
|
||||||
|
const char *set_bg = tty->TS_set_background;
|
||||||
|
if (tty->TN_max_colors == 8 || tty->TN_max_colors == 16)
|
||||||
|
{
|
||||||
|
/* fg and bg are indices into 16 base colors (see link at top). */
|
||||||
|
unsigned long fgi = 0, bgi = 0;
|
||||||
|
|
||||||
|
fgi = (fg >= 0 && fg < 8)
|
||||||
|
? fg + 30
|
||||||
|
: (fg >= 8 && fg < 16)
|
||||||
|
? fg - 8 + 90
|
||||||
|
: 0;
|
||||||
|
if (fgi)
|
||||||
|
SSPRINTF (seq, &n, sz, set_fg, fgi);
|
||||||
|
|
||||||
|
bgi = (bg >= 0 && bg < 8)
|
||||||
|
? bg + 40
|
||||||
|
: (bg >= 8 && bg < 16)
|
||||||
|
? bg - 8 + 100
|
||||||
|
: 0;
|
||||||
|
if (bgi)
|
||||||
|
SSPRINTF (seq, &n, sz, set_bg, bgi);
|
||||||
|
}
|
||||||
|
else if (tty->TN_max_colors == 256)
|
||||||
|
{
|
||||||
|
/* fg and bg are xterm indices. */
|
||||||
|
if (fg >= 0 && fg < 256)
|
||||||
|
SSPRINTF (seq, &n, sz, set_fg, fg);
|
||||||
|
|
||||||
|
if (bg >= 0 && bg < 256)
|
||||||
|
SSPRINTF (seq, &n, sz, set_bg, bg);
|
||||||
|
}
|
||||||
|
else if (tty->TN_max_colors == 16777216)
|
||||||
|
{
|
||||||
|
/* fg and bg are pixel values -- decompose to rgb triples. */
|
||||||
|
unsigned long rf = fg/65536, gf = (fg/256)&255, bf = fg&255;
|
||||||
|
unsigned long rb = bg/65536, gb = (bg/256)&255, bb = bg&255;
|
||||||
|
SSPRINTF (seq, &n, sz, set_fg, rf, gf, bf);
|
||||||
|
SSPRINTF (seq, &n, sz, set_bg, rb, gb, bb);
|
||||||
|
}
|
||||||
|
w32con_write_vt_seq ((const char *) seq);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
turn_off_face (struct frame *f, int face_id)
|
||||||
|
{
|
||||||
|
struct tty_display_info *tty = FRAME_TTY (f);
|
||||||
|
w32con_write_vt_seq (tty->TS_exit_attribute_mode);
|
||||||
|
}
|
||||||
|
|
||||||
/* The IME window is needed to receive the session notifications
|
/* The IME window is needed to receive the session notifications
|
||||||
required to reset the low level keyboard hook state. */
|
required to reset the low level keyboard hook state. */
|
||||||
|
|
||||||
@@ -868,6 +1048,8 @@ initialize_w32_display (struct terminal *term, int *width, int *height)
|
|||||||
}
|
}
|
||||||
|
|
||||||
char_attr_normal = info.wAttributes;
|
char_attr_normal = info.wAttributes;
|
||||||
|
fg_normal = char_attr_normal & 0x000f;
|
||||||
|
bg_normal = (char_attr_normal >> 4) & 0x000f;
|
||||||
|
|
||||||
/* Determine if the info returned by GetConsoleScreenBufferInfo
|
/* Determine if the info returned by GetConsoleScreenBufferInfo
|
||||||
is realistic. Old MS Telnet servers used to only fill out
|
is realistic. Old MS Telnet servers used to only fill out
|
||||||
@@ -921,31 +1103,81 @@ initialize_w32_display (struct terminal *term, int *width, int *height)
|
|||||||
|
|
||||||
/* Set up the keyboard hook. */
|
/* Set up the keyboard hook. */
|
||||||
setup_w32_kbdhook (hwnd);
|
setup_w32_kbdhook (hwnd);
|
||||||
|
|
||||||
|
/* Set current_tty to the tty of this terminal */
|
||||||
|
current_tty = term->display_info.tty;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
DEFUN ("set-screen-color", Fset_screen_color, Sset_screen_color, 2, 2, 0,
|
DEFUN ("set-screen-color", Fset_screen_color, Sset_screen_color, 2, 3, 0,
|
||||||
doc: /* Set screen foreground and background colors.
|
doc: /* Set screen foreground and background colors.
|
||||||
|
|
||||||
Arguments should be indices between 0 and 15, see w32console.el. */)
|
Arguments should be indices for colors in the list returned by `tty-color-alist'.
|
||||||
(Lisp_Object foreground, Lisp_Object background)
|
If VTP is non-nil, settings affect virtual terminal processing only.
|
||||||
|
Otherwise, arguments should be between 0 and 15, and settings will
|
||||||
|
be effective only when virtual terminal processing is disabled.
|
||||||
|
|
||||||
|
See w32console.el and the documentation for `w32-use-virtual-terminal'. */)
|
||||||
|
(Lisp_Object foreground, Lisp_Object background, Lisp_Object vtp)
|
||||||
{
|
{
|
||||||
char_attr_normal = XFIXNAT (foreground) + (XFIXNAT (background) << 4);
|
int fg = XFIXNAT (foreground);
|
||||||
|
int bg = XFIXNAT (background);
|
||||||
|
|
||||||
|
if (NILP (vtp))
|
||||||
|
{
|
||||||
|
char_attr_normal = fg + (bg << 4);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
fg_normal = fg;
|
||||||
|
bg_normal = bg;
|
||||||
|
}
|
||||||
|
|
||||||
Frecenter (Qnil, Qt);
|
Frecenter (Qnil, Qt);
|
||||||
return Qt;
|
return Qt;
|
||||||
}
|
}
|
||||||
|
|
||||||
DEFUN ("get-screen-color", Fget_screen_color, Sget_screen_color, 0, 0, 0,
|
DEFUN ("get-screen-color", Fget_screen_color, Sget_screen_color, 0, 1, 0,
|
||||||
doc: /* Get color indices of the current screen foreground and background.
|
doc: /* Get color indices of the current screen foreground and background.
|
||||||
|
|
||||||
The colors are returned as a list of 2 indices (FOREGROUND BACKGROUND).
|
The colors are returned as a list of 2 indices (FOREGROUND BACKGROUND) for
|
||||||
See w32console.el and `tty-defined-color-alist' for mapping of indices
|
colors in the list returned by `tty-color-alist`.
|
||||||
to colors. */)
|
|
||||||
|
If VTP is non-nil, returns settings effective when virtual terminal
|
||||||
|
processing is enabled. Otherwise, returns settings effective when
|
||||||
|
virtual terminal processing is disabled.
|
||||||
|
|
||||||
|
See w32console.el and the documentation for `w32-use-virtual-terminal'. */)
|
||||||
|
(Lisp_Object vtp)
|
||||||
|
{
|
||||||
|
int fg = NILP (vtp) ? char_attr_normal & 0x000f : fg_normal;
|
||||||
|
int bg = NILP (vtp) ? (char_attr_normal >> 4) & 0x000f : bg_normal;
|
||||||
|
|
||||||
|
return Fcons (make_fixnum (fg), Fcons (make_fixnum (bg), Qnil));
|
||||||
|
}
|
||||||
|
|
||||||
|
DEFUN ("w32-use-virtual-terminal", Fw32_use_virtual_terminal, Sw32_use_virtual_terminal, 1, 1, 0,
|
||||||
|
doc: /* Enables (disables) virtual terminal sequence processing if argument is t (nil). */)
|
||||||
|
(Lisp_Object arg)
|
||||||
|
{
|
||||||
|
if (EQ (arg, Qt))
|
||||||
|
w32_use_virtual_terminal = 1;
|
||||||
|
else if (EQ (arg, Qnil))
|
||||||
|
w32_use_virtual_terminal = 0;
|
||||||
|
else {
|
||||||
|
error ("Invalid argument: expects t or nil.");
|
||||||
|
return Qnil;
|
||||||
|
}
|
||||||
|
|
||||||
|
w32con_setup_virtual_terminal ();
|
||||||
|
return Qt;
|
||||||
|
}
|
||||||
|
|
||||||
|
DEFUN ("w32-use-virtual-terminal-p", Fw32_use_virtual_terminal_p, Sw32_use_virtual_terminal_p, 0, 0, 0,
|
||||||
|
doc: /* Returns t (nil) if virtual terminal sequence processing is enabled (disabled). */)
|
||||||
(void)
|
(void)
|
||||||
{
|
{
|
||||||
return Fcons (make_fixnum (char_attr_normal & 0x000f),
|
return w32_use_virtual_terminal ? Qt : Qnil;
|
||||||
Fcons (make_fixnum ((char_attr_normal >> 4) & 0x000f), Qnil));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
DEFUN ("set-cursor-size", Fset_cursor_size, Sset_cursor_size, 1, 1, 0,
|
DEFUN ("set-cursor-size", Fset_cursor_size, Sset_cursor_size, 1, 1, 0,
|
||||||
@@ -974,5 +1206,7 @@ scroll-back buffer. */);
|
|||||||
|
|
||||||
defsubr (&Sset_screen_color);
|
defsubr (&Sset_screen_color);
|
||||||
defsubr (&Sget_screen_color);
|
defsubr (&Sget_screen_color);
|
||||||
|
defsubr (&Sw32_use_virtual_terminal);
|
||||||
|
defsubr (&Sw32_use_virtual_terminal_p);
|
||||||
defsubr (&Sset_cursor_size);
|
defsubr (&Sset_cursor_size);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -17387,7 +17387,7 @@ redisplay_internal (void)
|
|||||||
area, displaying a different frame means redisplay the
|
area, displaying a different frame means redisplay the
|
||||||
whole thing. */
|
whole thing. */
|
||||||
SET_FRAME_GARBAGED (sf);
|
SET_FRAME_GARBAGED (sf);
|
||||||
#if !defined DOS_NT && !defined HAVE_ANDROID
|
#if !defined MSDOS && !defined HAVE_ANDROID
|
||||||
set_tty_color_mode (FRAME_TTY (sf), sf);
|
set_tty_color_mode (FRAME_TTY (sf), sf);
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user