summaryrefslogtreecommitdiff
path: root/src/terminal.c
diff options
context:
space:
mode:
authorBram Moolenaar <Bram@vim.org>2017-08-17 20:31:48 +0200
committerBram Moolenaar <Bram@vim.org>2017-08-17 20:31:48 +0200
commitcfce71710b6a2e1fb7f7f27d2a359e4b926f3af9 (patch)
treee9f5fa03d3b04268324bde07d5e87bb3de026369 /src/terminal.c
parent82de3c2c036bc89c2d9bdea236e0a7f1208a5571 (diff)
downloadvim-cfce71710b6a2e1fb7f7f27d2a359e4b926f3af9.zip
patch 8.0.0956: scrolling in a terminal window has flicker
Problem: Scrolling in a terminal hwindow as flicker when the Normal background differs from the terminal window background. Solution: Set the attribute to clear with.
Diffstat (limited to 'src/terminal.c')
-rw-r--r--src/terminal.c346
1 files changed, 180 insertions, 166 deletions
diff --git a/src/terminal.c b/src/terminal.c
index 304a7ba43..5878db793 100644
--- a/src/terminal.c
+++ b/src/terminal.c
@@ -1483,6 +1483,169 @@ may_toggle_cursor(term_T *term)
}
}
+/*
+ * Reverse engineer the RGB value into a cterm color index.
+ * First color is 1. Return 0 if no match found.
+ */
+ static int
+color2index(VTermColor *color, int fg, int *boldp)
+{
+ int red = color->red;
+ int blue = color->blue;
+ int green = color->green;
+
+ /* The argument for lookup_color() is for the color_names[] table. */
+ if (red == 0)
+ {
+ if (green == 0)
+ {
+ if (blue == 0)
+ return lookup_color(0, fg, boldp) + 1; /* black */
+ if (blue == 224)
+ return lookup_color(1, fg, boldp) + 1; /* dark blue */
+ }
+ else if (green == 224)
+ {
+ if (blue == 0)
+ return lookup_color(2, fg, boldp) + 1; /* dark green */
+ if (blue == 224)
+ return lookup_color(3, fg, boldp) + 1; /* dark cyan */
+ }
+ }
+ else if (red == 224)
+ {
+ if (green == 0)
+ {
+ if (blue == 0)
+ return lookup_color(4, fg, boldp) + 1; /* dark red */
+ if (blue == 224)
+ return lookup_color(5, fg, boldp) + 1; /* dark magenta */
+ }
+ else if (green == 224)
+ {
+ if (blue == 0)
+ return lookup_color(6, fg, boldp) + 1; /* dark yellow / brown */
+ if (blue == 224)
+ return lookup_color(8, fg, boldp) + 1; /* white / light grey */
+ }
+ }
+ else if (red == 128)
+ {
+ if (green == 128 && blue == 128)
+ return lookup_color(12, fg, boldp) + 1; /* high intensity black / dark grey */
+ }
+ else if (red == 255)
+ {
+ if (green == 64)
+ {
+ if (blue == 64)
+ return lookup_color(20, fg, boldp) + 1; /* light red */
+ if (blue == 255)
+ return lookup_color(22, fg, boldp) + 1; /* light magenta */
+ }
+ else if (green == 255)
+ {
+ if (blue == 64)
+ return lookup_color(24, fg, boldp) + 1; /* yellow */
+ if (blue == 255)
+ return lookup_color(26, fg, boldp) + 1; /* white */
+ }
+ }
+ else if (red == 64)
+ {
+ if (green == 64)
+ {
+ if (blue == 255)
+ return lookup_color(14, fg, boldp) + 1; /* light blue */
+ }
+ else if (green == 255)
+ {
+ if (blue == 64)
+ return lookup_color(16, fg, boldp) + 1; /* light green */
+ if (blue == 255)
+ return lookup_color(18, fg, boldp) + 1; /* light cyan */
+ }
+ }
+ if (t_colors >= 256)
+ {
+ if (red == blue && red == green)
+ {
+ /* 24-color greyscale */
+ static int cutoff[23] = {
+ 0x05, 0x10, 0x1B, 0x26, 0x31, 0x3C, 0x47, 0x52,
+ 0x5D, 0x68, 0x73, 0x7F, 0x8A, 0x95, 0xA0, 0xAB,
+ 0xB6, 0xC1, 0xCC, 0xD7, 0xE2, 0xED, 0xF9};
+ int i;
+
+ for (i = 0; i < 23; ++i)
+ if (red < cutoff[i])
+ return i + 233;
+ return 256;
+ }
+
+ /* 216-color cube */
+ return 17 + ((red + 25) / 0x33) * 36
+ + ((green + 25) / 0x33) * 6
+ + (blue + 25) / 0x33;
+ }
+ return 0;
+}
+
+/*
+ * Convert the attributes of a vterm cell into an attribute index.
+ */
+ static int
+cell2attr(VTermScreenCellAttrs cellattrs, VTermColor cellfg, VTermColor cellbg)
+{
+ int attr = 0;
+
+ if (cellattrs.bold)
+ attr |= HL_BOLD;
+ if (cellattrs.underline)
+ attr |= HL_UNDERLINE;
+ if (cellattrs.italic)
+ attr |= HL_ITALIC;
+ if (cellattrs.strike)
+ attr |= HL_STANDOUT;
+ if (cellattrs.reverse)
+ attr |= HL_INVERSE;
+
+#ifdef FEAT_GUI
+ if (gui.in_use)
+ {
+ guicolor_T fg, bg;
+
+ fg = gui_mch_get_rgb_color(cellfg.red, cellfg.green, cellfg.blue);
+ bg = gui_mch_get_rgb_color(cellbg.red, cellbg.green, cellbg.blue);
+ return get_gui_attr_idx(attr, fg, bg);
+ }
+ else
+#endif
+#ifdef FEAT_TERMGUICOLORS
+ if (p_tgc)
+ {
+ guicolor_T fg, bg;
+
+ fg = gui_get_rgb_color_cmn(cellfg.red, cellfg.green, cellfg.blue);
+ bg = gui_get_rgb_color_cmn(cellbg.red, cellbg.green, cellbg.blue);
+
+ return get_tgc_attr_idx(attr, fg, bg);
+ }
+ else
+#endif
+ {
+ int bold = MAYBE;
+ int fg = color2index(&cellfg, TRUE, &bold);
+ int bg = color2index(&cellbg, FALSE, &bold);
+
+ /* with 8 colors set the bold attribute to get a bright foreground */
+ if (bold == TRUE)
+ attr |= HL_BOLD;
+ return get_cterm_attr_idx(attr, fg, bg);
+ }
+ return 0;
+}
+
static int
handle_damage(VTermRect rect, void *user)
{
@@ -1498,18 +1661,32 @@ handle_damage(VTermRect rect, void *user)
handle_moverect(VTermRect dest, VTermRect src, void *user)
{
term_T *term = (term_T *)user;
- win_T *wp;
+ /* Scrolling up is done much more efficiently by deleting lines instead of
+ * redrawing the text. */
if (dest.start_col == src.start_col
&& dest.end_col == src.end_col
&& dest.start_row < src.start_row)
+ {
+ win_T *wp;
+ VTermColor fg, bg;
+ VTermScreenCellAttrs attr;
+ int clear_attr;
+
+ /* Set the color to clear lines with. */
+ vterm_state_get_default_colors(vterm_obtain_state(term->tl_vterm),
+ &fg, &bg);
+ vim_memset(&attr, 0, sizeof(attr));
+ clear_attr = cell2attr(attr, fg, bg);
+
FOR_ALL_WINDOWS(wp)
{
if (wp->w_buffer == term->tl_buffer)
- /* scrolling up is much more efficient when deleting lines */
win_del_lines(wp, dest.start_row,
- src.start_row - dest.start_row, FALSE, FALSE);
+ src.start_row - dest.start_row, FALSE, FALSE,
+ clear_attr);
}
+ }
redraw_buf_later(term->tl_buffer, NOT_VALID);
return 1;
}
@@ -1774,169 +1951,6 @@ term_channel_closed(channel_T *ch)
}
/*
- * Reverse engineer the RGB value into a cterm color index.
- * First color is 1. Return 0 if no match found.
- */
- static int
-color2index(VTermColor *color, int fg, int *boldp)
-{
- int red = color->red;
- int blue = color->blue;
- int green = color->green;
-
- /* The argument for lookup_color() is for the color_names[] table. */
- if (red == 0)
- {
- if (green == 0)
- {
- if (blue == 0)
- return lookup_color(0, fg, boldp) + 1; /* black */
- if (blue == 224)
- return lookup_color(1, fg, boldp) + 1; /* dark blue */
- }
- else if (green == 224)
- {
- if (blue == 0)
- return lookup_color(2, fg, boldp) + 1; /* dark green */
- if (blue == 224)
- return lookup_color(3, fg, boldp) + 1; /* dark cyan */
- }
- }
- else if (red == 224)
- {
- if (green == 0)
- {
- if (blue == 0)
- return lookup_color(4, fg, boldp) + 1; /* dark red */
- if (blue == 224)
- return lookup_color(5, fg, boldp) + 1; /* dark magenta */
- }
- else if (green == 224)
- {
- if (blue == 0)
- return lookup_color(6, fg, boldp) + 1; /* dark yellow / brown */
- if (blue == 224)
- return lookup_color(8, fg, boldp) + 1; /* white / light grey */
- }
- }
- else if (red == 128)
- {
- if (green == 128 && blue == 128)
- return lookup_color(12, fg, boldp) + 1; /* high intensity black / dark grey */
- }
- else if (red == 255)
- {
- if (green == 64)
- {
- if (blue == 64)
- return lookup_color(20, fg, boldp) + 1; /* light red */
- if (blue == 255)
- return lookup_color(22, fg, boldp) + 1; /* light magenta */
- }
- else if (green == 255)
- {
- if (blue == 64)
- return lookup_color(24, fg, boldp) + 1; /* yellow */
- if (blue == 255)
- return lookup_color(26, fg, boldp) + 1; /* white */
- }
- }
- else if (red == 64)
- {
- if (green == 64)
- {
- if (blue == 255)
- return lookup_color(14, fg, boldp) + 1; /* light blue */
- }
- else if (green == 255)
- {
- if (blue == 64)
- return lookup_color(16, fg, boldp) + 1; /* light green */
- if (blue == 255)
- return lookup_color(18, fg, boldp) + 1; /* light cyan */
- }
- }
- if (t_colors >= 256)
- {
- if (red == blue && red == green)
- {
- /* 24-color greyscale */
- static int cutoff[23] = {
- 0x05, 0x10, 0x1B, 0x26, 0x31, 0x3C, 0x47, 0x52,
- 0x5D, 0x68, 0x73, 0x7F, 0x8A, 0x95, 0xA0, 0xAB,
- 0xB6, 0xC1, 0xCC, 0xD7, 0xE2, 0xED, 0xF9};
- int i;
-
- for (i = 0; i < 23; ++i)
- if (red < cutoff[i])
- return i + 233;
- return 256;
- }
-
- /* 216-color cube */
- return 17 + ((red + 25) / 0x33) * 36
- + ((green + 25) / 0x33) * 6
- + (blue + 25) / 0x33;
- }
- return 0;
-}
-
-/*
- * Convert the attributes of a vterm cell into an attribute index.
- */
- static int
-cell2attr(VTermScreenCellAttrs cellattrs, VTermColor cellfg, VTermColor cellbg)
-{
- int attr = 0;
-
- if (cellattrs.bold)
- attr |= HL_BOLD;
- if (cellattrs.underline)
- attr |= HL_UNDERLINE;
- if (cellattrs.italic)
- attr |= HL_ITALIC;
- if (cellattrs.strike)
- attr |= HL_STANDOUT;
- if (cellattrs.reverse)
- attr |= HL_INVERSE;
-
-#ifdef FEAT_GUI
- if (gui.in_use)
- {
- guicolor_T fg, bg;
-
- fg = gui_mch_get_rgb_color(cellfg.red, cellfg.green, cellfg.blue);
- bg = gui_mch_get_rgb_color(cellbg.red, cellbg.green, cellbg.blue);
- return get_gui_attr_idx(attr, fg, bg);
- }
- else
-#endif
-#ifdef FEAT_TERMGUICOLORS
- if (p_tgc)
- {
- guicolor_T fg, bg;
-
- fg = gui_get_rgb_color_cmn(cellfg.red, cellfg.green, cellfg.blue);
- bg = gui_get_rgb_color_cmn(cellbg.red, cellbg.green, cellbg.blue);
-
- return get_tgc_attr_idx(attr, fg, bg);
- }
- else
-#endif
- {
- int bold = MAYBE;
- int fg = color2index(&cellfg, TRUE, &bold);
- int bg = color2index(&cellbg, FALSE, &bold);
-
- /* with 8 colors set the bold attribute to get a bright foreground */
- if (bold == TRUE)
- attr |= HL_BOLD;
- return get_cterm_attr_idx(attr, fg, bg);
- }
- return 0;
-}
-
-/*
* Called to update a window that contains an active terminal.
* Returns FAIL when there is no terminal running in this window or in
* Terminal-Normal mode.