Skip to content

Instantly share code, notes, and snippets.

@adinapoli
Last active January 10, 2017 13:57
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save adinapoli/625d5fa7c21c10543f2cb52303b90b50 to your computer and use it in GitHub Desktop.
Save adinapoli/625d5fa7c21c10543f2cb52303b90b50 to your computer and use it in GitHub Desktop.
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. */
@biocyberman
Copy link

Hi
Does this work? I applied this patch and could not compile emacs-25.1 on Ubuntu 14.04

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment