Skip to content

Commit c9e587a

Browse files
Jan Engelhardttorvalds
authored andcommitted
vt: fix background color on line feed
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. Signed-off-by: Jan Engelhardt <jengelh@computergmbh.de> Cc: "Antonino A. Daplas" <adaplas@pol.net> Cc: "H. Peter Anvin" <hpa@zytor.com> Cc: Alan Cox <alan@lxorguk.ukuu.org.uk> Signed-off-by: Andrew Morton <akpm@linux-foundation.org> Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
1 parent 3265e66 commit c9e587a

File tree

6 files changed

+14
-12
lines changed

6 files changed

+14
-12
lines changed

drivers/char/vt.c

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -301,7 +301,7 @@ static void scrup(struct vc_data *vc, unsigned int t, unsigned int b, int nr)
301301
d = (unsigned short *)(vc->vc_origin + vc->vc_size_row * t);
302302
s = (unsigned short *)(vc->vc_origin + vc->vc_size_row * (t + nr));
303303
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,
305305
vc->vc_size_row * nr);
306306
}
307307

@@ -319,7 +319,7 @@ static void scrdown(struct vc_data *vc, unsigned int t, unsigned int b, int nr)
319319
s = (unsigned short *)(vc->vc_origin + vc->vc_size_row * t);
320320
step = vc->vc_cols * nr;
321321
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);
323323
}
324324

325325
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,
400400
* Bit 7 : blink
401401
*/
402402
{
403-
u8 a = vc->vc_color;
403+
u8 a = _color;
404404
if (!vc->vc_can_do_color)
405405
return _intensity |
406406
(_italic ? 2 : 0) |
@@ -434,6 +434,7 @@ static void update_attr(struct vc_data *vc)
434434
vc->vc_blink, vc->vc_underline,
435435
vc->vc_reverse ^ vc->vc_decscnm, vc->vc_italic);
436436
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) | ' ';
437438
}
438439

439440
/* Note: inverting the screen twice should revert to the original state */

drivers/video/console/fbcon.c

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1881,7 +1881,7 @@ static int fbcon_scroll(struct vc_data *vc, int t, int b, int dir,
18811881
scr_memsetw((unsigned short *) (vc->vc_origin +
18821882
vc->vc_size_row *
18831883
(b - count)),
1884-
vc->vc_video_erase_char,
1884+
vc->vc_scrl_erase_char,
18851885
vc->vc_size_row * count);
18861886
return 1;
18871887
break;
@@ -1953,7 +1953,7 @@ static int fbcon_scroll(struct vc_data *vc, int t, int b, int dir,
19531953
scr_memsetw((unsigned short *) (vc->vc_origin +
19541954
vc->vc_size_row *
19551955
(b - count)),
1956-
vc->vc_video_erase_char,
1956+
vc->vc_scrl_erase_char,
19571957
vc->vc_size_row * count);
19581958
return 1;
19591959
}
@@ -1972,7 +1972,7 @@ static int fbcon_scroll(struct vc_data *vc, int t, int b, int dir,
19721972
scr_memsetw((unsigned short *) (vc->vc_origin +
19731973
vc->vc_size_row *
19741974
t),
1975-
vc->vc_video_erase_char,
1975+
vc->vc_scrl_erase_char,
19761976
vc->vc_size_row * count);
19771977
return 1;
19781978
break;
@@ -2042,7 +2042,7 @@ static int fbcon_scroll(struct vc_data *vc, int t, int b, int dir,
20422042
scr_memsetw((unsigned short *) (vc->vc_origin +
20432043
vc->vc_size_row *
20442044
t),
2045-
vc->vc_video_erase_char,
2045+
vc->vc_scrl_erase_char,
20462046
vc->vc_size_row * count);
20472047
return 1;
20482048
}

drivers/video/console/mdacon.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -531,7 +531,7 @@ static void mdacon_cursor(struct vc_data *c, int mode)
531531

532532
static int mdacon_scroll(struct vc_data *c, int t, int b, int dir, int lines)
533533
{
534-
u16 eattr = mda_convert_attr(c->vc_video_erase_char);
534+
u16 eattr = mda_convert_attr(c->vc_scrl_erase_char);
535535

536536
if (!lines)
537537
return 0;

drivers/video/console/sticon.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -170,12 +170,12 @@ static int sticon_scroll(struct vc_data *conp, int t, int b, int dir, int count)
170170
switch (dir) {
171171
case SM_UP:
172172
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);
174174
break;
175175

176176
case SM_DOWN:
177177
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);
179179
break;
180180
}
181181

drivers/video/console/vgacon.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1350,7 +1350,7 @@ static int vgacon_scroll(struct vc_data *c, int t, int b, int dir,
13501350
} else
13511351
c->vc_origin += delta;
13521352
scr_memsetw((u16 *) (c->vc_origin + c->vc_screenbuf_size -
1353-
delta), c->vc_video_erase_char,
1353+
delta), c->vc_scrl_erase_char,
13541354
delta);
13551355
} else {
13561356
if (oldo - delta < vga_vram_base) {
@@ -1363,7 +1363,7 @@ static int vgacon_scroll(struct vc_data *c, int t, int b, int dir,
13631363
} else
13641364
c->vc_origin -= delta;
13651365
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,
13671367
delta);
13681368
}
13691369
c->vc_scr_end = c->vc_origin + c->vc_screenbuf_size;

include/linux/console_struct.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -53,6 +53,7 @@ struct vc_data {
5353
unsigned short vc_hi_font_mask; /* [#] Attribute set for upper 256 chars of font or 0 if not supported */
5454
struct console_font vc_font; /* Current VC font set */
5555
unsigned short vc_video_erase_char; /* Background erase character */
56+
unsigned short vc_scrl_erase_char; /* Erase character for scroll */
5657
/* VT terminal data */
5758
unsigned int vc_state; /* Escape sequence parser state */
5859
unsigned int vc_npar,vc_par[NPAR]; /* Parameters of current escape sequence */

0 commit comments

Comments
 (0)