A command that causes a line feed while a background color is active, such as perl -e 'print "x" x 60, "\e[44m", "x" x 40, "\e[0m\n"' and perl -e 'print "x" x 40, "\e[44m\n", "x" x 40, "\e[0m\n"' causes the line that was started as a result of the line feed to be completely filled with the currently active background color instead of the default color. When scrolling, part of the current screen is memcpy'd/memmove'd to the new region, and the new line(s) that will appear as a result are cleared using memset. However, the lines are cleared with vc->vc_video_erase_char, causing them to be colored with the currently active background color. This is different from X11 terminal emulators which always paint the new lines with the default background color (e.g. `xterm -bg black`). The clear operation (\e[1J and \e[2J) also use vc_video_erase_char, so a new vc->vc_scrl_erase_char is introduced with contains the erase character used for scrolling, which is built from vc->vc_def_color instead of vc->vc_color.
Unified · Split
| @@ -301,7 +301,7 @@ static void scrup(struct vc_data *vc, unsigned int t, unsigned int b, int nr) · 300 unmodified lines | ||
| 301 | 301 | d = (unsigned short *)(vc->vc_origin + vc->vc_size_row * t); |
| 302 | 302 | s = (unsigned short *)(vc->vc_origin + vc->vc_size_row * (t + nr)); |
| 303 | 303 | scr_memmovew(d, s, (b - t - nr) * vc->vc_size_row); |
| 304 | − scr_memsetw(d + (b - t - nr) * vc->vc_cols, vc->vc_video_erase_char, | |
| 304 | + scr_memsetw(d + (b - t - nr) * vc->vc_cols, vc->vc_scrl_erase_char, | |
| 305 | 305 | vc->vc_size_row * nr); |
| 306 | 306 | } |
| 307 | 307 | |
| @@ -319,7 +319,7 @@ static void scrdown(struct vc_data *vc, unsigned int t, unsigned int b, int nr) · 11 unmodified lines | ||
| 319 | 319 | s = (unsigned short *)(vc->vc_origin + vc->vc_size_row * t); |
| 320 | 320 | step = vc->vc_cols * nr; |
| 321 | 321 | scr_memmovew(s + step, s, (b - t - nr) * vc->vc_size_row); |
| 322 | − scr_memsetw(s, vc->vc_video_erase_char, 2 * step); | |
| 322 | + scr_memsetw(s, vc->vc_scrl_erase_char, 2 * step); | |
| 323 | 323 | } |
| 324 | 324 | |
| 325 | 325 | static void do_update_region(struct vc_data *vc, unsigned long start, int count) |
| @@ -400,7 +400,7 @@ static u8 build_attr(struct vc_data *vc, u8 _color, u8 _intensity, u8 _blink, · 74 unmodified lines | ||
| 400 | 400 | * Bit 7 : blink |
| 401 | 401 | */ |
| 402 | 402 | { |
| 403 | − u8 a = vc->vc_color; | |
| 403 | + u8 a = _color; | |
| 404 | 404 | if (!vc->vc_can_do_color) |
| 405 | 405 | return _intensity | |
| 406 | 406 | (_italic ? 2 : 0) | |
| @@ -434,6 +434,7 @@ static void update_attr(struct vc_data *vc) · 27 unmodified lines | ||
| 434 | 434 | vc->vc_blink, vc->vc_underline, |
| 435 | 435 | vc->vc_reverse ^ vc->vc_decscnm, vc->vc_italic); |
| 436 | 436 | vc->vc_video_erase_char = (build_attr(vc, vc->vc_color, 1, vc->vc_blink, 0, vc->vc_decscnm, 0) << 8) | ' '; |
| 437 | + vc->vc_scrl_erase_char = (build_attr(vc, vc->vc_def_color, 1, false, false, false, false) << 8) | ' '; | |
| 437 | 438 | } |
| 438 | 439 | |
| 439 | 440 | /* Note: inverting the screen twice should revert to the original state */ |
| @@ -1881,7 +1881,7 @@ static int fbcon_scroll(struct vc_data *vc, int t, int b, int dir, · 1880 unmodified lines | ||
| 1881 | 1881 | scr_memsetw((unsigned short *) (vc->vc_origin + |
| 1882 | 1882 | vc->vc_size_row * |
| 1883 | 1883 | (b - count)), |
| 1884 | − vc->vc_video_erase_char, | |
| 1884 | + vc->vc_scrl_erase_char, | |
| 1885 | 1885 | vc->vc_size_row * count); |
| 1886 | 1886 | return 1; |
| 1887 | 1887 | break; |
| @@ -1953,7 +1953,7 @@ static int fbcon_scroll(struct vc_data *vc, int t, int b, int dir, · 65 unmodified lines | ||
| 1953 | 1953 | scr_memsetw((unsigned short *) (vc->vc_origin + |
| 1954 | 1954 | vc->vc_size_row * |
| 1955 | 1955 | (b - count)), |
| 1956 | − vc->vc_video_erase_char, | |
| 1956 | + vc->vc_scrl_erase_char, | |
| 1957 | 1957 | vc->vc_size_row * count); |
| 1958 | 1958 | return 1; |
| 1959 | 1959 | } |
| @@ -1972,7 +1972,7 @@ static int fbcon_scroll(struct vc_data *vc, int t, int b, int dir, · 12 unmodified lines | ||
| 1972 | 1972 | scr_memsetw((unsigned short *) (vc->vc_origin + |
| 1973 | 1973 | vc->vc_size_row * |
| 1974 | 1974 | t), |
| 1975 | − vc->vc_video_erase_char, | |
| 1975 | + vc->vc_scrl_erase_char, | |
| 1976 | 1976 | vc->vc_size_row * count); |
| 1977 | 1977 | return 1; |
| 1978 | 1978 | break; |
| @@ -2042,7 +2042,7 @@ static int fbcon_scroll(struct vc_data *vc, int t, int b, int dir, · 63 unmodified lines | ||
| 2042 | 2042 | scr_memsetw((unsigned short *) (vc->vc_origin + |
| 2043 | 2043 | vc->vc_size_row * |
| 2044 | 2044 | t), |
| 2045 | − vc->vc_video_erase_char, | |
| 2045 | + vc->vc_scrl_erase_char, | |
| 2046 | 2046 | vc->vc_size_row * count); |
| 2047 | 2047 | return 1; |
| 2048 | 2048 | } |
| @@ -531,7 +531,7 @@ static void mdacon_cursor(struct vc_data *c, int mode) · 530 unmodified lines | ||
| 531 | 531 | |
| 532 | 532 | static int mdacon_scroll(struct vc_data *c, int t, int b, int dir, int lines) |
| 533 | 533 | { |
| 534 | − u16 eattr = mda_convert_attr(c->vc_video_erase_char); | |
| 534 | + u16 eattr = mda_convert_attr(c->vc_scrl_erase_char); | |
| 535 | 535 | |
| 536 | 536 | if (!lines) |
| 537 | 537 | return 0; |
| @@ -170,12 +170,12 @@ static int sticon_scroll(struct vc_data *conp, int t, int b, int dir, int count) · 169 unmodified lines | ||
| 170 | 170 | switch (dir) { |
| 171 | 171 | case SM_UP: |
| 172 | 172 | sti_bmove(sti, t + count, 0, t, 0, b - t - count, conp->vc_cols); |
| 173 | − sti_clear(sti, b - count, 0, count, conp->vc_cols, conp->vc_video_erase_char); | |
| 173 | + sti_clear(sti, b - count, 0, count, conp->vc_cols, conp->vc_scrl_erase_char); | |
| 174 | 174 | break; |
| 175 | 175 | |
| 176 | 176 | case SM_DOWN: |
| 177 | 177 | sti_bmove(sti, t, 0, t + count, 0, b - t - count, conp->vc_cols); |
| 178 | − sti_clear(sti, t, 0, count, conp->vc_cols, conp->vc_video_erase_char); | |
| 178 | + sti_clear(sti, t, 0, count, conp->vc_cols, conp->vc_scrl_erase_char); | |
| 179 | 179 | break; |
| 180 | 180 | } |
| 181 | 181 | |
| @@ -1350,7 +1350,7 @@ static int vgacon_scroll(struct vc_data *c, int t, int b, int dir, · 1349 unmodified lines | ||
| 1350 | 1350 | } else |
| 1351 | 1351 | c->vc_origin += delta; |
| 1352 | 1352 | scr_memsetw((u16 *) (c->vc_origin + c->vc_screenbuf_size - |
| 1353 | − delta), c->vc_video_erase_char, | |
| 1353 | + delta), c->vc_scrl_erase_char, | |
| 1354 | 1354 | delta); |
| 1355 | 1355 | } else { |
| 1356 | 1356 | if (oldo - delta < vga_vram_base) { |
| @@ -1363,7 +1363,7 @@ static int vgacon_scroll(struct vc_data *c, int t, int b, int dir, · 6 unmodified lines | ||
| 1363 | 1363 | } else |
| 1364 | 1364 | c->vc_origin -= delta; |
| 1365 | 1365 | c->vc_scr_end = c->vc_origin + c->vc_screenbuf_size; |
| 1366 | − scr_memsetw((u16 *) (c->vc_origin), c->vc_video_erase_char, | |
| 1366 | + scr_memsetw((u16 *) (c->vc_origin), c->vc_scrl_erase_char, | |
| 1367 | 1367 | delta); |
| 1368 | 1368 | } |
| 1369 | 1369 | c->vc_scr_end = c->vc_origin + c->vc_screenbuf_size; |
| @@ -53,6 +53,7 @@ struct vc_data { · 52 unmodified lines | ||
| 53 | 53 | unsigned short vc_hi_font_mask; /* [#] Attribute set for upper 256 chars of font or 0 if not supported */ |
| 54 | 54 | struct console_font vc_font; /* Current VC font set */ |
| 55 | 55 | unsigned short vc_video_erase_char; /* Background erase character */ |
| 56 | + unsigned short vc_scrl_erase_char; /* Erase character for scroll */ | |
| 56 | 57 | /* VT terminal data */ |
| 57 | 58 | unsigned int vc_state; /* Escape sequence parser state */ |
| 58 | 59 | unsigned int vc_npar,vc_par[NPAR]; /* Parameters of current escape sequence */ |