Last active
January 10, 2017 13:57
-
-
Save adinapoli/625d5fa7c21c10543f2cb52303b90b50 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
diff --git lisp/term/xterm.el lisp/term/xterm.el | |
index 19eb37a..6298d88 100644 | |
--- lisp/term/xterm.el | |
+++ lisp/term/xterm.el | |
@@ -917,6 +917,15 @@ versions of xterm." | |
;; are more colors to support, compute them now. | |
(when (> ncolors 0) | |
(cond | |
+ ((= (display-color-cells (selected-frame)) 16777216) ; 24-bit xterm | |
+ (let ((idx (length xterm-standard-colors))) | |
+ ;; Insert standard X colors after the standard xterm ones | |
+ (mapc (lambda (color) | |
+ (if (not (assoc (car color) xterm-standard-colors)) | |
+ (progn | |
+ (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 src/dispextern.h src/dispextern.h | |
index 7b9ae78..99445a5 100644 | |
--- src/dispextern.h | |
+++ src/dispextern.h | |
@@ -1107,6 +1107,13 @@ struct glyph_row *matrix_row (struct glyph_matrix *, int); | |
+ (MATRIX)->nrows \ | |
- (WINDOW_WANTS_MODELINE_P ((W)) ? 1 : 0)) | |
+INLINE bool | |
+face_tty_specified_24_bit_color (unsigned long color) | |
+{ | |
+ /* 24 bit colors have 24th but not 25th bit set */ | |
+ return ((color & (0x03 << 24)) == (0x01 << 24)); | |
+} | |
+ | |
/* Non-zero if the face of the last glyph in ROW's text area has | |
to be drawn to the end of the text area. */ | |
@@ -1756,7 +1763,7 @@ struct face | |
INLINE bool | |
face_tty_specified_color (unsigned long color) | |
{ | |
- return color < FACE_TTY_DEFAULT_BG_COLOR; | |
+ return (color < FACE_TTY_DEFAULT_BG_COLOR); | |
} | |
/* Non-zero if FACE was realized for unibyte use. */ | |
diff --git src/term.c src/term.c | |
index 4397210..23669cf 100644 | |
--- src/term.c | |
+++ src/term.c | |
@@ -1927,18 +1927,39 @@ turn_on_face (struct frame *f, int face_id) | |
const char *ts; | |
char *p; | |
- ts = tty->standout_mode ? tty->TS_set_background : tty->TS_set_foreground; | |
+ if (face_tty_specified_24_bit_color(fg)) | |
+ ts = tty->standout_mode ? tty->TS_set_rgb_background : tty->TS_set_rgb_foreground; | |
+ else | |
+ ts = tty->standout_mode ? tty->TS_set_background : tty->TS_set_foreground; | |
if (face_tty_specified_color (fg) && ts) | |
{ | |
+ if (!face_tty_specified_24_bit_color(fg)) | |
p = tparam (ts, NULL, 0, fg, 0, 0, 0); | |
+ else | |
+ { | |
+ const unsigned char r = (fg >> 16) & 0xFF, | |
+ g = (fg >> 8) & 0xFF, | |
+ b = fg & 0xFF; | |
+ p = tparam (ts, NULL, 0, (int)r, (int)g, (int)b, 0); | |
+ } | |
OUTPUT (tty, p); | |
xfree (p); | |
} | |
- ts = tty->standout_mode ? tty->TS_set_foreground : tty->TS_set_background; | |
+ if (face_tty_specified_24_bit_color(bg)) | |
+ ts = tty->standout_mode ? tty->TS_set_rgb_foreground : tty->TS_set_rgb_background; | |
+ else | |
+ ts = tty->standout_mode ? tty->TS_set_foreground : tty->TS_set_background; | |
if (face_tty_specified_color (bg) && ts) | |
{ | |
+ if (!face_tty_specified_24_bit_color(bg)) | |
p = tparam (ts, NULL, 0, bg, 0, 0, 0); | |
+ else | |
+ { | |
+ const unsigned char r = (bg >> 16) & 0xFF, | |
+ g = (bg >> 8) & 0xFF, | |
+ b = bg & 0xFF; | |
+ p = tparam (ts, NULL, 0, (int)r, (int)g, (int)b, 0); | |
OUTPUT (tty, p); | |
xfree (p); | |
} | |
@@ -2037,7 +2058,13 @@ TERMINAL does not refer to a text terminal. */) | |
{ | |
struct terminal *t = decode_tty_terminal (terminal); | |
- return make_number (t ? t->display_info.tty->TN_max_colors : 0); | |
+ if (!t) | |
+ return make_number (0); | |
+ else if (t->display_info.tty->TS_set_rgb_foreground) | |
+ return make_number (16777216); /* 24 bit True Color */ | |
+ else | |
+ return make_number (t->display_info.tty->TN_max_colors); | |
+ | |
} | |
#ifndef DOS_NT | |
@@ -2051,6 +2078,8 @@ static int default_no_color_video; | |
static char *default_orig_pair; | |
static char *default_set_foreground; | |
static char *default_set_background; | |
+static char *default_set_rgb_foreground; | |
+static char *default_set_rgb_background; | |
/* Save or restore the default color-related capabilities of this | |
terminal. */ | |
@@ -2063,6 +2092,8 @@ tty_default_color_capabilities (struct tty_display_info *tty, bool save) | |
dupstring (&default_orig_pair, tty->TS_orig_pair); | |
dupstring (&default_set_foreground, tty->TS_set_foreground); | |
dupstring (&default_set_background, tty->TS_set_background); | |
+ dupstring (&default_set_rgb_foreground, tty->TS_set_rgb_foreground); | |
+ dupstring (&default_set_rgb_background, tty->TS_set_rgb_background); | |
default_max_colors = tty->TN_max_colors; | |
default_max_pairs = tty->TN_max_pairs; | |
default_no_color_video = tty->TN_no_color_video; | |
@@ -2072,6 +2103,8 @@ tty_default_color_capabilities (struct tty_display_info *tty, bool save) | |
tty->TS_orig_pair = default_orig_pair; | |
tty->TS_set_foreground = default_set_foreground; | |
tty->TS_set_background = default_set_background; | |
+ tty->TS_set_rgb_foreground = default_set_rgb_foreground; | |
+ tty->TS_set_rgb_background = default_set_rgb_background; | |
tty->TN_max_colors = default_max_colors; | |
tty->TN_max_pairs = default_max_pairs; | |
tty->TN_no_color_video = default_no_color_video; | |
@@ -2096,6 +2129,7 @@ tty_setup_colors (struct tty_display_info *tty, int mode) | |
tty->TN_max_pairs = 0; | |
tty->TN_no_color_video = 0; | |
tty->TS_set_foreground = tty->TS_set_background = tty->TS_orig_pair = NULL; | |
+ tty->TS_set_rgb_foreground = tty->TS_set_rgb_background = NULL; | |
break; | |
case 0: /* default colors, if any */ | |
default: | |
@@ -2110,10 +2144,29 @@ tty_setup_colors (struct tty_display_info *tty, int mode) | |
tty->TS_set_foreground = "\033[3%dm"; | |
tty->TS_set_background = "\033[4%dm"; | |
#endif | |
+ tty->TS_set_rgb_foreground = NULL; | |
+ tty->TS_set_rgb_background = NULL; | |
tty->TN_max_colors = 8; | |
tty->TN_max_pairs = 64; | |
tty->TN_no_color_video = 0; | |
break; | |
+ case 16777216: /* RGB colors */ | |
+ tty->TS_orig_pair = "\033[0m"; | |
+#ifdef TERMINFO | |
+ tty->TS_set_foreground = "\033[3%p1%dm"; | |
+ tty->TS_set_background = "\033[4%p1%dm"; | |
+ tty->TS_set_rgb_foreground = "\033[38;2;%p1%d;%p2%d;%p3%dm"; | |
+ tty->TS_set_rgb_background = "\033[48;2;%p1%d;%p2%d;%p3%dm"; | |
+#else | |
+ tty->TS_set_foreground = "\033[3%dm"; | |
+ tty->TS_set_background = "\033[4%dm"; | |
+ tty->TS_set_rgb_foreground = "\033[38;2;%d;%d;%dm"; | |
+ tty->TS_set_rgb_background = "\033[48;2;%d;%d;%dm"; | |
+#endif | |
+ tty->TN_max_colors = 16777216; | |
+ /*tty->TN_max_pairs = 64; TODO */ | |
+ tty->TN_no_color_video = 0; | |
+ break; | |
} | |
} | |
@@ -4134,6 +4187,36 @@ use the Bourne shell command 'TERM=...; export TERM' (C-shell:\n\ | |
tty->TN_no_color_video = tgetnum ("NC"); | |
if (tty->TN_no_color_video == -1) | |
tty->TN_no_color_video = 0; | |
+ | |
+ /* TODO Reliable way to detect: Konsole, iTerm2, st */ | |
+ if (getenv ("KONSOLE_DBUS_SESSION")) | |
+ { | |
+ /* TODO This should be extracted from terminfo/termcap. */ | |
+#ifdef TERMINFO | |
+ tty->TS_set_rgb_foreground = "\033[38;2;%p1%d;%p2%d;%p3%dm"; | |
+ tty->TS_set_rgb_background = "\033[48;2;%p1%d;%p2%d;%p3%dm"; | |
+#else | |
+ tty->TS_set_rgb_foreground = "\033[38;2;%d;%d;%dm"; | |
+ tty->TS_set_rgb_background = "\033[48;2;%d;%d;%dm"; | |
+#endif | |
+ } | |
+ else if (getenv ("ITERM_24BIT")) | |
+ { | |
+ /* XXX chopps use ITU T.421 ':' separator */ | |
+ /* TODO This should be extracted from terminfo/termcap. */ | |
+#ifdef TERMINFO | |
+ tty->TS_set_rgb_foreground = "\033[38:2:%p1%d:%p2%d:%p3%dm"; | |
+ tty->TS_set_rgb_background = "\033[48:2:%p1%d:%p2%d:%p3%dm"; | |
+#else | |
+ tty->TS_set_rgb_foreground = "\033[38:2:%d:%d:%dm"; | |
+ tty->TS_set_rgb_background = "\033[48:2:%d:%d:%dm"; | |
+#endif | |
+ } | |
+ else | |
+ { | |
+ tty->TS_set_rgb_foreground = NULL; | |
+ tty->TS_set_rgb_background = NULL; | |
+ } | |
} | |
tty_default_color_capabilities (tty, 1); | |
diff --git src/termchar.h src/termchar.h | |
index 35b30fb..f930b1c 100644 | |
--- src/termchar.h | |
+++ src/termchar.h | |
@@ -161,6 +161,10 @@ struct tty_display_info | |
const char *TS_set_foreground; | |
const char *TS_set_background; | |
+ /* Support for 24bit RGB color terminals. */ | |
+ const char *TS_set_rgb_foreground; | |
+ const char *TS_set_rgb_background; | |
+ | |
int TF_hazeltine; /* termcap hz flag. */ | |
int TF_insmode_motion; /* termcap mi flag: can move while in insert mode. */ | |
int TF_standout_motion; /* termcap mi flag: can move while in standout mode. */ | |
diff --git src/xfaces.c src/xfaces.c | |
index 5077cb2..9c7e32b 100644 | |
--- src/xfaces.c | |
+++ src/xfaces.c | |
@@ -848,54 +848,80 @@ tty_lookup_color (struct frame *f, Lisp_Object color, XColor *tty_color, | |
if (!STRINGP (color) || NILP (Ffboundp (Qtty_color_desc))) | |
return false; | |
- XSETFRAME (frame, f); | |
- | |
- color_desc = call2 (Qtty_color_desc, color, frame); | |
- if (CONSP (color_desc) && CONSP (XCDR (color_desc))) | |
- { | |
- Lisp_Object rgb; | |
- | |
- if (! INTEGERP (XCAR (XCDR (color_desc)))) | |
- return false; | |
+ if (f->output_method == output_termcap | |
+ && f->output_data.tty->display_info->TS_set_rgb_foreground | |
+ && !NILP (Ffboundp (Qtty_color_standard_values))) | |
+ { | |
+ /* Terminal supports 3 byte RGB colors. */ | |
+ if (!NILP (Ffboundp (Qtty_color_canonicalize))) | |
+ color = call1(Qtty_color_canonicalize, color); | |
- tty_color->pixel = XINT (XCAR (XCDR (color_desc))); | |
+ color_desc = call1 (Qtty_color_standard_values, color); | |
+ if (! parse_rgb_list (color_desc, tty_color)) | |
+ return false; | |
- rgb = XCDR (XCDR (color_desc)); | |
- if (! parse_rgb_list (rgb, tty_color)) | |
- return false; | |
+ /* Map XColor to 3 byte values. */ | |
+ tty_color->pixel = 1 << 24 /* Set bit 24 to mark RGB values. */ | |
+ | (tty_color->red / 256) << 16 | |
+ | (tty_color->green / 256) << 8 | |
+ | (tty_color->blue / 256); | |
- /* Should we fill in STD_COLOR too? */ | |
if (std_color) | |
- { | |
- /* Default STD_COLOR to the same as TTY_COLOR. */ | |
- *std_color = *tty_color; | |
- | |
- /* Do a quick check to see if the returned descriptor is | |
- actually _exactly_ equal to COLOR, otherwise we have to | |
- lookup STD_COLOR separately. If it's impossible to lookup | |
- a standard color, we just give up and use TTY_COLOR. */ | |
- if ((!STRINGP (XCAR (color_desc)) | |
- || NILP (Fstring_equal (color, XCAR (color_desc)))) | |
- && !NILP (Ffboundp (Qtty_color_standard_values))) | |
- { | |
- /* Look up STD_COLOR separately. */ | |
- rgb = call1 (Qtty_color_standard_values, color); | |
- if (! parse_rgb_list (rgb, std_color)) | |
- return false; | |
- } | |
- } | |
+ *std_color = *tty_color; | |
return true; | |
- } | |
- else if (NILP (Fsymbol_value (intern ("tty-defined-color-alist")))) | |
- /* We were called early during startup, and the colors are not | |
- yet set up in tty-defined-color-alist. Don't return a failure | |
- indication, since this produces the annoying "Unable to | |
- load color" messages in the *Messages* buffer. */ | |
- return true; | |
+ } | |
else | |
- /* tty-color-desc seems to have returned a bad value. */ | |
- return false; | |
+ { | |
+ XSETFRAME (frame, f); | |
+ | |
+ color_desc = call2 (Qtty_color_desc, color, frame); | |
+ if (CONSP (color_desc) && CONSP (XCDR (color_desc))) | |
+ { | |
+ Lisp_Object rgb; | |
+ | |
+ if (! INTEGERP (XCAR (XCDR (color_desc)))) | |
+ return false; | |
+ | |
+ tty_color->pixel = XINT (XCAR (XCDR (color_desc))); | |
+ | |
+ rgb = XCDR (XCDR (color_desc)); | |
+ if (! parse_rgb_list (rgb, tty_color)) | |
+ return false; | |
+ | |
+ /* Should we fill in STD_COLOR too? */ | |
+ if (std_color) | |
+ { | |
+ /* Default STD_COLOR to the same as TTY_COLOR. */ | |
+ *std_color = *tty_color; | |
+ | |
+ /* Do a quick check to see if the returned descriptor is | |
+ actually _exactly_ equal to COLOR, otherwise we have to | |
+ lookup STD_COLOR separately. If it's impossible to lookup | |
+ a standard color, we just give up and use TTY_COLOR. */ | |
+ if ((!STRINGP (XCAR (color_desc)) | |
+ || NILP (Fstring_equal (color, XCAR (color_desc)))) | |
+ && !NILP (Ffboundp (Qtty_color_standard_values))) | |
+ { | |
+ /* Look up STD_COLOR separately. */ | |
+ rgb = call1 (Qtty_color_standard_values, color); | |
+ if (! parse_rgb_list (rgb, std_color)) | |
+ return false; | |
+ } | |
+ } | |
+ | |
+ return true; | |
+ } | |
+ else if (NILP (Fsymbol_value (intern ("tty-defined-color-alist")))) | |
+ /* We were called early during startup, and the colors are not | |
+ yet set up in tty-defined-color-alist. Don't return a failure | |
+ indication, since this produces the annoying "Unable to | |
+ load color" messages in the *Messages* buffer. */ | |
+ return true; | |
+ else | |
+ /* tty-color-desc seems to have returned a bad value. */ | |
+ return false; | |
+ } | |
} | |
/* A version of defined_color for non-X frames. */ | |
@@ -5700,6 +5726,7 @@ map_tty_color (struct frame *f, struct face *face, | |
unsigned long default_pixel = | |
foreground_p ? FACE_TTY_DEFAULT_FG_COLOR : FACE_TTY_DEFAULT_BG_COLOR; | |
unsigned long pixel = default_pixel; | |
+ XColor true_color; | |
#ifdef MSDOS | |
unsigned long default_other_pixel = | |
foreground_p ? FACE_TTY_DEFAULT_BG_COLOR : FACE_TTY_DEFAULT_FG_COLOR; | |
@@ -5718,7 +5745,18 @@ map_tty_color (struct frame *f, struct face *face, | |
{ | |
/* Associations in tty-defined-color-alist are of the form | |
(NAME INDEX R G B). We need the INDEX part. */ | |
- pixel = XINT (XCAR (XCDR (def))); | |
+ if (f->output_method == output_termcap | |
+ && f->output_data.tty->display_info->TS_set_rgb_foreground | |
+ && parse_rgb_list (XCDR (XCDR(def)), &true_color)) | |
+ { | |
+ /* Map XColor to 3 byte values. */ | |
+ pixel = 1 << 24 /* Set bit 24 to mark RGB values. */ | |
+ | (true_color.red / 256) << 16 | |
+ | (true_color.green / 256) << 8 | |
+ | (true_color.blue / 256); | |
+ } | |
+ else | |
+ pixel = XINT (XCAR (XCDR (def))); | |
} | |
if (pixel == default_pixel && STRINGP (color)) | |
@@ -6407,6 +6445,7 @@ syms_of_xfaces (void) | |
DEFSYM (Qwindow_divider_last_pixel, "window-divider-last-pixel"); | |
DEFSYM (Qtty_color_desc, "tty-color-desc"); | |
DEFSYM (Qtty_color_standard_values, "tty-color-standard-values"); | |
+ DEFSYM (Qtty_color_canonicalize, "tty-color-canonicalize"); | |
DEFSYM (Qtty_color_by_index, "tty-color-by-index"); | |
/* The name of the function used to compute colors on TTYs. */ |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Hi
Does this work? I applied this patch and could not compile emacs-25.1 on Ubuntu 14.04