[vte/vte-0-36] emulation: Support 16 million colors
- From: Egmont Koblinger <egmontkob src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [vte/vte-0-36] emulation: Support 16 million colors
- Date: Wed, 8 Jan 2014 23:13:49 +0000 (UTC)
commit c5a32b491afe783b02eec49b1f02241163ba4367
Author: Egmont Koblinger <egmont gmail com>
Date: Thu Jan 9 00:12:33 2014 +0100
emulation: Support 16 million colors
https://bugzilla.gnome.org/show_bug.cgi?id=704449
perf/img.sh | 71 ++++++++++++++++++++++++
src/vte-private.h | 36 +++++++++---
src/vte.c | 155 +++++++++++++++++++++++++++++------------------------
src/vterowdata.h | 47 ++++++++++-------
src/vteseq.c | 151 ++++++++++++++++++++-------------------------------
5 files changed, 271 insertions(+), 189 deletions(-)
---
diff --git a/perf/img.sh b/perf/img.sh
new file mode 100755
index 0000000..7cc8254
--- /dev/null
+++ b/perf/img.sh
@@ -0,0 +1,71 @@
+#!/bin/bash
+
+# Image viewer for terminals that support true colors.
+# Copyright (C) 2014 Egmont Koblinger
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License along
+# with this program; if not, write to the Free Software Foundation, Inc.,
+# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+
+if [ $# != 1 -o "$1" = "--help" ]; then
+ echo 'Usage: img.sh imagefile' >&2
+ exit 1
+elif [ -z $(type -p convert) ]; then
+ echo 'Please install ImageMagick to run this script.' >&2
+ exit 1
+fi
+
+# This is so that "upper" is still visible after exiting the while loop.
+shopt -s lastpipe
+
+COLUMNS=$(tput cols)
+
+declare -a upper lower
+upper=()
+lower=()
+
+convert -thumbnail ${COLUMNS}x "$1" txt:- |
+while IFS=',:() ' read col row dummy red green blue rest; do
+ if [ "$col" = "#" ]; then
+ continue
+ fi
+
+ if [ $((row%2)) = 0 ]; then
+ upper[$col]="$red;$green;$blue"
+ else
+ lower[$col]="$red;$green;$blue"
+ fi
+
+ # After reading every second image row, print them out.
+ if [ $((row%2)) = 1 -a $col = $((COLUMNS-1)) ]; then
+ i=0
+ while [ $i -lt $COLUMNS ]; do
+ echo -ne "\\e[38;2;${upper[$i]};48;2;${lower[$i]}m▀"
+ i=$((i+1))
+ done
+ # \e[K is useful when you resize the terminal while this script is still running.
+ echo -e "\\e[0m\e[K"
+ upper=()
+ d=()
+ fi
+done
+
+# Print the last half line, if required.
+if [ "${upper[0]}" != "" ]; then
+ i=0
+ while [ $i -lt $COLUMNS ]; do
+ echo -ne "\\e[38;2;${upper[$i]}m▀"
+ i=$((i+1))
+ done
+ echo -e "\\e[0m\e[K"
+fi
diff --git a/src/vte-private.h b/src/vte-private.h
index 3b40060..c2c215d 100644
--- a/src/vte-private.h
+++ b/src/vte-private.h
@@ -56,11 +56,34 @@ G_BEGIN_DECLS
#define VTE_LINE_WIDTH 1
#define VTE_ROWS 24
#define VTE_COLUMNS 80
+
+/*
+ * Colors are encoded in 25 bits as follows:
+ *
+ * 0 .. 255:
+ * Colors set by SGR 256-color extension (38/48;5;index).
+ * These are direct indices into the color palette.
+ *
+ * 256 .. VTE_PALETTE_SIZE - 1 (261):
+ * Special values, such as default colors.
+ * These are direct indices into the color palette.
+ *
+ * VTE_LEGACY_COLORS_OFFSET (512) .. VTE_LEGACY_COLORS_OFFSET + VTE_LEGACY_FULL_COLOR_SET_SIZE - 1 (527):
+ * Colors set by legacy escapes (30..37/40..47, 90..97/100..107).
+ * These are translated to 0 .. 15 before looking up in the palette, taking bold into account.
+ *
+ * VTE_RGB_COLOR (2^24) .. VTE_RGB_COLOR + 16Mi - 1 (2^25 - 1):
+ * Colors set by SGR truecolor extension (38/48;2;red;green;blue)
+ * These are direct RGB values.
+ */
+#define VTE_LEGACY_COLORS_OFFSET 512
#define VTE_LEGACY_COLOR_SET_SIZE 8
+#define VTE_LEGACY_FULL_COLOR_SET_SIZE 16
#define VTE_COLOR_PLAIN_OFFSET 0
#define VTE_COLOR_BRIGHT_OFFSET 8
#define VTE_COLOR_DIM_OFFSET 16
-/* More color defines in ring.h */
+#define VTE_RGB_COLOR (1 << 24)
+/* More color defines in vterowdata.h */
#define VTE_SCROLLBACK_INIT 512
#define VTE_SATURATION_MAX 10000
@@ -223,19 +246,14 @@ struct _VteTerminalPrivate {
long insert_delta; /* insertion offset */
VteCell defaults; /* default characteristics
for insertion of any new
- characters; colors not yet
- adjusted for bold/dim/standout */
+ characters */
VteCell color_defaults; /* original defaults
plus the current
- fore/back already adjusted for
- bold/dim/standout */
+ fore/back */
VteCell fill_defaults; /* original defaults
plus the current
- fore/back already adjusted for
- bold/dim/standout with no
+ fore/back with no
character data */
- gboolean fg_sgr_extended, bg_sgr_extended; /* whether fg/bg were set by
- 256 color sequences */
gboolean alternate_charset;
gboolean status_line;
GString *status_line_contents;
diff --git a/src/vte.c b/src/vte.c
index b01a036..8d04ea6 100644
--- a/src/vte.c
+++ b/src/vte.c
@@ -319,6 +319,10 @@ G_DEFINE_TYPE(VteTerminal, vte_terminal, GTK_TYPE_WIDGET)
#endif
#endif /* GTK 3.0 */
+/* Indexes in the "palette" color array for the dim colors.
+ * Only the first %VTE_LEGACY_COLOR_SET_SIZE colors have dim versions. */
+static const guchar corresponding_dim_index[] = {16,88,28,100,18,90,30,102};
+
static void
vte_g_array_fill(GArray *array, gconstpointer item, guint final_size)
{
@@ -371,8 +375,6 @@ _vte_terminal_set_default_attributes(VteTerminal *terminal)
screen->defaults = basic_cell.cell;
screen->color_defaults = screen->defaults;
screen->fill_defaults = screen->defaults;
- screen->fg_sgr_extended = FALSE;
- screen->bg_sgr_extended = FALSE;
}
/* Cause certain cells to be repainted. */
@@ -6300,6 +6302,23 @@ vte_terminal_copy_cb(GtkClipboard *clipboard, GtkSelectionData *data,
}
}
+/* Convert the internal color code (either index or RGB, see vte-private.h) into RGB. */
+static void
+vte_terminal_get_rgb_from_index(const VteTerminal *terminal, guint index, PangoColor *color)
+{
+ if (index >= VTE_LEGACY_COLORS_OFFSET && index < VTE_LEGACY_COLORS_OFFSET +
VTE_LEGACY_FULL_COLOR_SET_SIZE)
+ index -= VTE_LEGACY_COLORS_OFFSET;
+ if (index < VTE_PALETTE_SIZE) {
+ memcpy(color, &terminal->pvt->palette[index], sizeof(PangoColor));
+ } else if (index & VTE_RGB_COLOR) {
+ color->red = ((index >> 16) & 0xFF) * 257;
+ color->green = ((index >> 8) & 0xFF) * 257;
+ color->blue = (index & 0xFF) * 257;
+ } else {
+ g_assert_not_reached();
+ }
+}
+
/**
* VteSelectionFunc:
* @terminal: terminal in which the cell is.
@@ -6368,7 +6387,7 @@ vte_terminal_get_text_range_maybe_wrapped(VteTerminal *terminal,
const VteCell *pcell = NULL;
GString *string;
struct _VteCharAttributes attr;
- PangoColor fore, back, *palette;
+ PangoColor fore, back;
if (!is_selected)
is_selected = always_selected;
@@ -6381,7 +6400,6 @@ vte_terminal_get_text_range_maybe_wrapped(VteTerminal *terminal,
string = g_string_new(NULL);
memset(&attr, 0, sizeof(attr));
- palette = terminal->pvt->palette;
col = start_col;
for (row = start_row; row < end_row + 1; row++, col = 0) {
const VteRowData *row_data = _vte_terminal_find_row_data (terminal, row);
@@ -6401,8 +6419,8 @@ vte_terminal_get_text_range_maybe_wrapped(VteTerminal *terminal,
* the selection. */
if (!pcell->attr.fragment && is_selected(terminal, col, row, data)) {
/* Store the attributes of this character. */
- fore = palette[pcell->attr.fore];
- back = palette[pcell->attr.back];
+ vte_terminal_get_rgb_from_index(terminal, pcell->attr.fore, &fore);
+ vte_terminal_get_rgb_from_index(terminal, pcell->attr.back, &back);
attr.fore.red = fore.red;
attr.fore.green = fore.green;
attr.fore.blue = fore.blue;
@@ -9407,6 +9425,29 @@ vte_terminal_determine_colors_internal(VteTerminal *terminal,
back = VTE_DEF_FG;
}
+ /* Handle bold by using set bold color or brightening */
+ if (cell->attr.bold) {
+ if (fore == VTE_DEF_FG)
+ fore = VTE_BOLD_FG;
+ else if (fore >= VTE_LEGACY_COLORS_OFFSET && fore < VTE_LEGACY_COLORS_OFFSET +
VTE_LEGACY_COLOR_SET_SIZE) {
+ fore += VTE_COLOR_BRIGHT_OFFSET;
+ }
+ }
+
+ /* Handle half similarly */
+ if (cell->attr.half) {
+ if (fore == VTE_DEF_FG)
+ fore = VTE_DIM_FG;
+ else if (fore >= VTE_LEGACY_COLORS_OFFSET && fore < VTE_LEGACY_COLORS_OFFSET +
VTE_LEGACY_COLOR_SET_SIZE)
+ fore = corresponding_dim_index[fore - VTE_LEGACY_COLORS_OFFSET];
+ }
+
+ /* And standout */
+ if (cell->attr.standout) {
+ if (fore >= VTE_LEGACY_COLORS_OFFSET && back < VTE_LEGACY_COLORS_OFFSET +
VTE_LEGACY_COLOR_SET_SIZE)
+ back += VTE_COLOR_BRIGHT_OFFSET;
+ }
+
/* Reverse cell? */
if (cell->attr.reverse) {
swap (&fore, &back);
@@ -9527,18 +9568,22 @@ vte_terminal_draw_graphic(VteTerminal *terminal, vteunistr c,
double adjust;
cairo_t *cr = _vte_draw_get_context (terminal->pvt->draw);
+ PangoColor fg, bg;
+ vte_terminal_get_rgb_from_index(terminal, fore, &fg);
+ vte_terminal_get_rgb_from_index(terminal, back, &bg);
+
width = column_width * columns;
if ((back != VTE_DEF_BG) || draw_default_bg) {
vte_terminal_fill_rectangle(terminal,
- &terminal->pvt->palette[back],
+ &bg,
x, y, width, row_height);
}
cairo_save (cr);
cairo_set_operator(cr, CAIRO_OPERATOR_OVER);
- _vte_draw_set_source_color_alpha (terminal->pvt->draw, &terminal->pvt->palette[fore],
VTE_DRAW_OPAQUE);
+ _vte_draw_set_source_color_alpha (terminal->pvt->draw, &fg, VTE_DRAW_OPAQUE);
// FIXME wtf!?
x += terminal->pvt->inner_border.left;
@@ -10020,9 +10065,9 @@ vte_terminal_draw_graphic(VteTerminal *terminal, vteunistr c,
/* Now take the inside out */
cairo_set_source_rgba (cr,
- terminal->pvt->palette[back].red / 65535.,
- terminal->pvt->palette[back].green / 65535.,
- terminal->pvt->palette[back].blue / 65535.,
+ bg.red / 65535.,
+ bg.green / 65535.,
+ bg.blue / 65535.,
1.);
cairo_set_line_width(cr, inner_line_width);
cairo_set_line_join(cr, CAIRO_LINE_JOIN_MITER);
@@ -10177,9 +10222,9 @@ vte_terminal_draw_graphic(VteTerminal *terminal, vteunistr c,
case 0x2592: /* medium shade */
case 0x2593: /* dark shade */
cairo_set_source_rgba (cr,
- terminal->pvt->palette[fore].red / 65535.,
- terminal->pvt->palette[fore].green / 65535.,
- terminal->pvt->palette[fore].blue / 65535.,
+ fg.red / 65535.,
+ fg.green / 65535.,
+ fg.blue / 65535.,
(c - 0x2590) / 4.);
cairo_rectangle(cr, x, y, width, row_height);
cairo_fill (cr);
@@ -10284,7 +10329,7 @@ vte_terminal_draw_cells(VteTerminal *terminal,
{
int i, x, y, ascent;
gint columns = 0;
- PangoColor *fg, *bg, *defbg;
+ PangoColor fg, bg, *defbg;
g_assert(n > 0);
_VTE_DEBUG_IF(VTE_DEBUG_CELLS) {
@@ -10302,8 +10347,8 @@ vte_terminal_draw_cells(VteTerminal *terminal,
}
bold = bold && terminal->pvt->allow_bold;
- fg = &terminal->pvt->palette[fore];
- bg = &terminal->pvt->palette[back];
+ vte_terminal_get_rgb_from_index(terminal, fore, &fg);
+ vte_terminal_get_rgb_from_index(terminal, back, &bg);
defbg = &terminal->pvt->palette[VTE_DEF_BG];
ascent = terminal->char_ascent;
@@ -10318,20 +10363,20 @@ vte_terminal_draw_cells(VteTerminal *terminal,
items[i].y += terminal->pvt->inner_border.top;
columns += items[i].columns;
}
- if (clear && (draw_default_bg || bg != defbg)) {
+ if (clear && (draw_default_bg || back != VTE_DEF_BG)) {
gint bold_offset = _vte_draw_has_bold(terminal->pvt->draw,
VTE_DRAW_BOLD) ? 0 : bold;
_vte_draw_fill_rectangle(terminal->pvt->draw,
x + terminal->pvt->inner_border.left,
y + terminal->pvt->inner_border.top,
columns * column_width + bold_offset, row_height,
- bg, VTE_DRAW_OPAQUE);
+ &bg, VTE_DRAW_OPAQUE);
}
} while (i < n);
_vte_draw_text(terminal->pvt->draw,
items, n,
- fg, VTE_DRAW_OPAQUE,
+ &fg, VTE_DRAW_OPAQUE,
_vte_draw_get_style(bold, italic));
for (i = 0; i < n; i++) {
@@ -10351,7 +10396,7 @@ vte_terminal_draw_cells(VteTerminal *terminal,
}
if (underline) {
vte_terminal_draw_line(terminal,
- &terminal->pvt->palette[fore],
+ &fg,
x,
y + terminal->pvt->underline_position,
x + (columns * column_width) - 1,
@@ -10359,7 +10404,7 @@ vte_terminal_draw_cells(VteTerminal *terminal,
}
if (strikethrough) {
vte_terminal_draw_line(terminal,
- &terminal->pvt->palette[fore],
+ &fg,
x,
y + terminal->pvt->strikethrough_position,
x + (columns * column_width) - 1,
@@ -10367,7 +10412,7 @@ vte_terminal_draw_cells(VteTerminal *terminal,
}
if (hilite) {
vte_terminal_draw_line(terminal,
- &terminal->pvt->palette[fore],
+ &fg,
x,
y + row_height - 1,
x + (columns * column_width) - 1,
@@ -10375,7 +10420,7 @@ vte_terminal_draw_cells(VteTerminal *terminal,
}
if (boxed) {
vte_terminal_draw_rectangle(terminal,
- &terminal->pvt->palette[fore],
+ &fg,
x, y,
MAX(0, (columns * column_width)),
MAX(0, row_height));
@@ -10384,44 +10429,6 @@ vte_terminal_draw_cells(VteTerminal *terminal,
}
}
-/* Try to map a PangoColor to a palette entry and return its index. */
-static guint
-_vte_terminal_map_pango_color(VteTerminal *terminal, PangoColor *color)
-{
- long distance[G_N_ELEMENTS(terminal->pvt->palette)];
- guint i, ret;
-
- /* Calculate a "distance" value. Could stand to be improved a bit. */
- for (i = 0; i < G_N_ELEMENTS(distance); i++) {
- const PangoColor *entry = &terminal->pvt->palette[i];
- distance[i] = 0;
- distance[i] += ((entry->red >> 8) - (color->red >> 8)) *
- ((entry->red >> 8) - (color->red >> 8));
- distance[i] += ((entry->blue >> 8) - (color->blue >> 8)) *
- ((entry->blue >> 8) - (color->blue >> 8));
- distance[i] += ((entry->green >> 8) - (color->green >> 8)) *
- ((entry->green >> 8) - (color->green >> 8));
- }
-
- /* Find the index of the minimum value. */
- ret = 0;
- for (i = 1; i < G_N_ELEMENTS(distance); i++) {
- if (distance[i] < distance[ret]) {
- ret = i;
- }
- }
-
- _vte_debug_print(VTE_DEBUG_UPDATES,
- "mapped PangoColor(%04x,%04x,%04x) to "
- "palette entry (%04x,%04x,%04x)\n",
- color->red, color->green, color->blue,
- terminal->pvt->palette[ret].red,
- terminal->pvt->palette[ret].green,
- terminal->pvt->palette[ret].blue);
-
- return ret;
-}
-
/* FIXME: we don't have a way to tell GTK+ what the default text attributes
* should be, so for now at least it's assuming white-on-black is the norm and
* is using "black-on-white" to signify "inverse". Pick up on that state and
@@ -10510,8 +10517,10 @@ _vte_terminal_apply_pango_attr(VteTerminal *terminal, PangoAttribute *attr,
case PANGO_ATTR_FOREGROUND:
case PANGO_ATTR_BACKGROUND:
attrcolor = (PangoAttrColor*) attr;
- ival = _vte_terminal_map_pango_color(terminal,
- &attrcolor->color);
+ ival = VTE_RGB_COLOR |
+ ((attrcolor->color.red & 0xFF00) << 8) |
+ ((attrcolor->color.green & 0xFF00)) |
+ ((attrcolor->color.blue & 0xFF00) >> 8);
for (i = attr->start_index;
i < attr->end_index && i < n_cells;
i++) {
@@ -10726,15 +10735,17 @@ vte_terminal_draw_rows(VteTerminal *terminal,
j += cell ? cell->attr.columns : 1;
}
if (back != VTE_DEF_BG) {
+ PangoColor bg;
gint bold_offset = _vte_draw_has_bold(terminal->pvt->draw,
VTE_DRAW_BOLD) ? 0 :
bold;
+ vte_terminal_get_rgb_from_index(terminal, back, &bg);
_vte_draw_fill_rectangle (
terminal->pvt->draw,
x + i * column_width,
y,
(j - i) * column_width + bold_offset,
row_height,
- &terminal->pvt->palette[back], VTE_DRAW_OPAQUE);
+ &bg, VTE_DRAW_OPAQUE);
}
/* We'll need to continue at the first cell which didn't
* match the first one in this set. */
@@ -10753,12 +10764,14 @@ vte_terminal_draw_rows(VteTerminal *terminal,
}
vte_terminal_determine_colors(terminal, NULL, selected, &fore, &back);
if (back != VTE_DEF_BG) {
+ PangoColor bg;
+ vte_terminal_get_rgb_from_index(terminal, back, &bg);
_vte_draw_fill_rectangle (terminal->pvt->draw,
x + i *column_width,
y,
(j - i) * column_width,
row_height,
- &terminal->pvt->palette[back],
VTE_DRAW_OPAQUE);
+ &bg, VTE_DRAW_OPAQUE);
}
i = j;
} while (i < end_column);
@@ -11084,6 +11097,7 @@ vte_terminal_paint_cursor(VteTerminal *terminal)
int row, drow, col;
long width, height, delta, cursor_width;
guint fore, back;
+ PangoColor bg;
int x, y;
gboolean blink, selected, focus;
@@ -11133,6 +11147,7 @@ vte_terminal_paint_cursor(VteTerminal *terminal)
selected = vte_cell_is_selected(terminal, col, drow, NULL);
vte_terminal_determine_cursor_colors(terminal, cell, selected, &fore, &back);
+ vte_terminal_get_rgb_from_index(terminal, back, &bg);
x = item.x;
y = item.y;
@@ -11145,7 +11160,7 @@ vte_terminal_paint_cursor(VteTerminal *terminal)
stem_width = (int) (((float) height) * terminal->pvt->cursor_aspect_ratio + 0.5);
stem_width = CLAMP (stem_width, VTE_LINE_WIDTH, cursor_width);
- vte_terminal_fill_rectangle(terminal, &terminal->pvt->palette[back],
+ vte_terminal_fill_rectangle(terminal, &bg,
x, y, stem_width, height);
break;
}
@@ -11158,7 +11173,7 @@ vte_terminal_paint_cursor(VteTerminal *terminal)
line_height = (int) (((float) height) * terminal->pvt->cursor_aspect_ratio + 0.5);
line_height = CLAMP (line_height, VTE_LINE_WIDTH, height);
- vte_terminal_fill_rectangle(terminal, &terminal->pvt->palette[back],
+ vte_terminal_fill_rectangle(terminal, &bg,
x, y + height - line_height,
cursor_width, line_height);
break;
@@ -11169,7 +11184,7 @@ vte_terminal_paint_cursor(VteTerminal *terminal)
if (focus) {
/* just reverse the character under the cursor */
vte_terminal_fill_rectangle (terminal,
- &terminal->pvt->palette[back],
+ &bg,
x, y,
cursor_width, height);
@@ -11211,7 +11226,7 @@ vte_terminal_paint_cursor(VteTerminal *terminal)
/* draw a box around the character */
vte_terminal_draw_rectangle (terminal,
- &terminal->pvt->palette[back],
+ &bg,
x - VTE_LINE_WIDTH,
y - VTE_LINE_WIDTH,
cursor_width + 2*VTE_LINE_WIDTH,
diff --git a/src/vterowdata.h b/src/vterowdata.h
index a37302e..d8f833f 100644
--- a/src/vterowdata.h
+++ b/src/vterowdata.h
@@ -35,6 +35,14 @@ G_BEGIN_DECLS
#define VTE_PALETTE_SIZE 262
+#if __GNUC__ > 2 || (__GNUC__ == 2 && __GNUC_MINOR__ > 6)
+#define VTE_GNUC_PACKED \
+ __attribute__((__packed__))
+#else
+#define VTE_GNUC_PACKED
+#endif /* !__GNUC__ */
+
+
/*
* VteCellAttr: A single cell style attributes
*
@@ -45,32 +53,33 @@ G_BEGIN_DECLS
*/
typedef struct _VteCellAttr {
- guint32 fragment: 1; /* A continuation cell. */
- guint32 columns: 4; /* Number of visible columns
+ guint64 fragment: 1; /* A continuation cell. */
+ guint64 columns: 4; /* Number of visible columns
(as determined by g_unicode_iswide(c)).
Also abused for tabs; bug 353610
Keep at least 4 for tabs to work
*/
- guint32 bold: 1;
- guint32 italic: 1;
- guint32 fore: 9; /* Index into color palette */
- guint32 back: 9; /* Index into color palette. */
+ guint64 bold: 1;
+ guint64 italic: 1;
+ guint64 fore: 25; /* Index into color palette, or direct RGB, */
+ /* 4-byte boundary */
+ guint64 back: 25; /* see vte-private.h */
- guint32 standout: 1;
- guint32 underline: 1;
- guint32 strikethrough: 1;
+ guint64 standout: 1;
+ guint64 underline: 1;
+ guint64 strikethrough: 1;
- guint32 reverse: 1;
- guint32 blink: 1;
- guint32 half: 1;
+ guint64 reverse: 1;
+ guint64 blink: 1;
+ guint64 half: 1;
- guint32 invisible: 1;
+ guint64 invisible: 1;
} VteCellAttr;
-G_STATIC_ASSERT (sizeof (VteCellAttr) == 4);
+G_STATIC_ASSERT (sizeof (VteCellAttr) == 8);
typedef union _VteIntCellAttr {
VteCellAttr s;
- guint32 i;
+ guint64 i;
} VteIntCellAttr;
G_STATIC_ASSERT (sizeof (VteCellAttr) == sizeof (VteIntCellAttr));
@@ -78,17 +87,17 @@ G_STATIC_ASSERT (sizeof (VteCellAttr) == sizeof (VteIntCellAttr));
* VteCell: A single cell's data
*/
-typedef struct _VteCell {
+typedef struct VTE_GNUC_PACKED _VteCell {
vteunistr c;
VteCellAttr attr;
} VteCell;
-G_STATIC_ASSERT (sizeof (VteCell) == 8);
+G_STATIC_ASSERT (sizeof (VteCell) == 12);
typedef union _VteIntCell {
VteCell cell;
- struct {
+ struct VTE_GNUC_PACKED {
guint32 c;
- guint32 attr;
+ guint64 attr;
} i;
} VteIntCell;
G_STATIC_ASSERT (sizeof (VteCell) == sizeof (VteIntCell));
diff --git a/src/vteseq.c b/src/vteseq.c
index ed0c75d..d0c6ac4 100644
--- a/src/vteseq.c
+++ b/src/vteseq.c
@@ -493,53 +493,6 @@ vte_sequence_handler_set_mode_internal(VteTerminal *terminal,
}
-/* Indexes in the "palette" color array for the dim colors.
- * Only the first %VTE_LEGACY_COLOR_SET_SIZE colors have dim versions. */
-static const guchar corresponding_dim_index[] = {16,88,28,100,18,90,30,102};
-
-static void
-vte_adjust_colors(VteTerminal *terminal)
-{
- guint fore, back;
-
- fore = terminal->pvt->screen->defaults.attr.fore;
- back = terminal->pvt->screen->defaults.attr.back;
-
- /* Handle bold by using set bold color or brightening */
- if (terminal->pvt->screen->defaults.attr.bold) {
- if (fore == VTE_DEF_FG) {
- fore = VTE_BOLD_FG;
- } else if (!terminal->pvt->screen->fg_sgr_extended
- && fore < VTE_LEGACY_COLOR_SET_SIZE) {
- fore += VTE_COLOR_BRIGHT_OFFSET;
- }
- }
-
- /* Handle half similarly */
- if (terminal->pvt->screen->defaults.attr.half) {
- if (fore == VTE_DEF_FG) {
- fore = VTE_DIM_FG;
- } else if (!terminal->pvt->screen->fg_sgr_extended
- && fore < VTE_LEGACY_COLOR_SET_SIZE) {
- fore = corresponding_dim_index[fore];
- }
- }
-
- /* And standout */
- if (terminal->pvt->screen->defaults.attr.standout) {
- if (!terminal->pvt->screen->bg_sgr_extended
- && back < VTE_LEGACY_COLOR_SET_SIZE) {
- back += VTE_COLOR_BRIGHT_OFFSET;
- }
- }
-
- /* Save the adjusted colors. */
- terminal->pvt->screen->color_defaults.attr.fore = fore;
- terminal->pvt->screen->color_defaults.attr.back = back;
- terminal->pvt->screen->fill_defaults.attr.fore = fore;
- terminal->pvt->screen->fill_defaults.attr.back = back;
-}
-
/*
* Sequence handling boilerplate
*/
@@ -2456,33 +2409,66 @@ vte_sequence_handler_character_attributes (VteTerminal *terminal, GValueArray *p
case 35:
case 36:
case 37:
- terminal->pvt->screen->fg_sgr_extended = FALSE;
- terminal->pvt->screen->defaults.attr.fore = param - 30;
+ terminal->pvt->screen->defaults.attr.fore = VTE_LEGACY_COLORS_OFFSET + param - 30;
break;
case 38:
+ case 48:
{
- /* The format looks like: ^[[38;5;COLORNUMBERm,
- so look for COLORNUMBER here. */
- if ((i + 2) < params->n_values){
- GValue *value1, *value2;
- long param1, param2;
+ /* The format looks like: ^[[38;5;COLORNUMBERm or ^[[38;2;RED;GREEN;BLUEm
+ so look for the parameters here. */
+ if ((i + 1) < params->n_values) {
+ GValue *value1, *value2, *value3, *value4;
+ long param1, param2, param3, param4;
value1 = g_value_array_get_nth(params, i + 1);
- value2 = g_value_array_get_nth(params, i + 2);
- if (G_UNLIKELY (!(G_VALUE_HOLDS_LONG(value1) && G_VALUE_HOLDS_LONG(value2))))
+ if (G_UNLIKELY (!G_VALUE_HOLDS_LONG(value1)))
break;
param1 = g_value_get_long(value1);
- param2 = g_value_get_long(value2);
- if (G_LIKELY (param1 == 5 && param2 >= 0 && param2 < 256)) {
- terminal->pvt->screen->fg_sgr_extended = TRUE;
- terminal->pvt->screen->defaults.attr.fore = param2;
+ switch (param1) {
+ case 2:
+ if (G_UNLIKELY ((i + 4) >= params->n_values))
+ break;
+ value2 = g_value_array_get_nth(params, i + 2);
+ value3 = g_value_array_get_nth(params, i + 3);
+ value4 = g_value_array_get_nth(params, i + 4);
+ if (G_UNLIKELY (!(G_VALUE_HOLDS_LONG(value2) &&
G_VALUE_HOLDS_LONG(value3) && G_VALUE_HOLDS_LONG(value4))))
+ break;
+ param2 = g_value_get_long(value2);
+ param3 = g_value_get_long(value3);
+ param4 = g_value_get_long(value4);
+ if (G_LIKELY (param2 >= 0 && param2 < 256 && param3 >= 0 && param3 <
256 && param4 >= 0 && param4 < 256)) {
+ guint32 value = (1 << 24) | (param2 << 16) | (param3 << 8) |
param4;
+ if (param == 38) {
+ terminal->pvt->screen->defaults.attr.fore = value;
+ } else {
+ terminal->pvt->screen->defaults.attr.back = value;
+ }
+ }
+ i += 4;
+ break;
+ case 5:
+ if (G_UNLIKELY ((i + 2) >= params->n_values))
+ break;
+ value2 = g_value_array_get_nth(params, i + 2);
+ if (G_UNLIKELY (!G_VALUE_HOLDS_LONG(value2)))
+ break;
+ param2 = g_value_get_long(value2);
+ if (G_LIKELY (param2 >= 0 && param2 < 256)) {
+ if (param == 38) {
+ terminal->pvt->screen->defaults.attr.fore = param2;
+ } else {
+ terminal->pvt->screen->defaults.attr.back = param2;
+ }
+ }
+ i += 2;
+ break;
+ default:
+ break;
}
- i += 2;
}
break;
}
case 39:
/* default foreground */
- terminal->pvt->screen->fg_sgr_extended = FALSE;
terminal->pvt->screen->defaults.attr.fore = VTE_DEF_FG;
break;
case 40:
@@ -2493,33 +2479,11 @@ vte_sequence_handler_character_attributes (VteTerminal *terminal, GValueArray *p
case 45:
case 46:
case 47:
- terminal->pvt->screen->bg_sgr_extended = FALSE;
- terminal->pvt->screen->defaults.attr.back = param - 40;
- break;
- case 48:
- {
- /* The format looks like: ^[[48;5;COLORNUMBERm,
- so look for COLORNUMBER here. */
- if ((i + 2) < params->n_values){
- GValue *value1, *value2;
- long param1, param2;
- value1 = g_value_array_get_nth(params, i + 1);
- value2 = g_value_array_get_nth(params, i + 2);
- if (G_UNLIKELY (!(G_VALUE_HOLDS_LONG(value1) && G_VALUE_HOLDS_LONG(value2))))
- break;
- param1 = g_value_get_long(value1);
- param2 = g_value_get_long(value2);
- if (G_LIKELY (param1 == 5 && param2 >= 0 && param2 < 256)) {
- terminal->pvt->screen->bg_sgr_extended = TRUE;
- terminal->pvt->screen->defaults.attr.back = param2;
- }
- i += 2;
- }
+ terminal->pvt->screen->defaults.attr.back = VTE_LEGACY_COLORS_OFFSET + param - 40;
break;
- }
+ /* case 48: was handled above at 38 to avoid code duplication */
case 49:
/* default background */
- terminal->pvt->screen->bg_sgr_extended = FALSE;
terminal->pvt->screen->defaults.attr.back = VTE_DEF_BG;
break;
case 90:
@@ -2530,8 +2494,7 @@ vte_sequence_handler_character_attributes (VteTerminal *terminal, GValueArray *p
case 95:
case 96:
case 97:
- terminal->pvt->screen->fg_sgr_extended = FALSE;
- terminal->pvt->screen->defaults.attr.fore = param - 90 + VTE_COLOR_BRIGHT_OFFSET;
+ terminal->pvt->screen->defaults.attr.fore = VTE_LEGACY_COLORS_OFFSET + param - 90 +
VTE_COLOR_BRIGHT_OFFSET;
break;
case 100:
case 101:
@@ -2541,8 +2504,7 @@ vte_sequence_handler_character_attributes (VteTerminal *terminal, GValueArray *p
case 105:
case 106:
case 107:
- terminal->pvt->screen->bg_sgr_extended = FALSE;
- terminal->pvt->screen->defaults.attr.back = param - 100 + VTE_COLOR_BRIGHT_OFFSET;
+ terminal->pvt->screen->defaults.attr.back = VTE_LEGACY_COLORS_OFFSET + param - 100 +
VTE_COLOR_BRIGHT_OFFSET;
break;
}
}
@@ -2551,7 +2513,14 @@ vte_sequence_handler_character_attributes (VteTerminal *terminal, GValueArray *p
_vte_terminal_set_default_attributes(terminal);
}
/* Save the new colors. */
- vte_adjust_colors(terminal);
+ terminal->pvt->screen->color_defaults.attr.fore =
+ terminal->pvt->screen->defaults.attr.fore;
+ terminal->pvt->screen->color_defaults.attr.back =
+ terminal->pvt->screen->defaults.attr.back;
+ terminal->pvt->screen->fill_defaults.attr.fore =
+ terminal->pvt->screen->defaults.attr.fore;
+ terminal->pvt->screen->fill_defaults.attr.back =
+ terminal->pvt->screen->defaults.attr.back;
}
/* Move the cursor to the given column, 1-based. */
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]