aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/tty/vt/vt.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/tty/vt/vt.c')
-rw-r--r--drivers/tty/vt/vt.c77
1 files changed, 52 insertions, 25 deletions
diff --git a/drivers/tty/vt/vt.c b/drivers/tty/vt/vt.c
index bba75560d11e..d34984aa646d 100644
--- a/drivers/tty/vt/vt.c
+++ b/drivers/tty/vt/vt.c
@@ -935,8 +935,11 @@ static void flush_scrollback(struct vc_data *vc)
{
WARN_CONSOLE_UNLOCKED();
+ set_origin(vc);
if (vc->vc_sw->con_flush_scrollback)
vc->vc_sw->con_flush_scrollback(vc);
+ else
+ vc->vc_sw->con_switch(vc);
}
/*
@@ -1342,6 +1345,8 @@ struct vc_data *vc_deallocate(unsigned int currcons)
* VT102 emulator
*/
+enum { EPecma = 0, EPdec, EPeq, EPgt, EPlt};
+
#define set_kbd(vc, x) vt_set_kbd_mode_bit((vc)->vc_num, (x))
#define clr_kbd(vc, x) vt_clr_kbd_mode_bit((vc)->vc_num, (x))
#define is_kbd(vc, x) vt_get_kbd_mode_bit((vc)->vc_num, (x))
@@ -1503,8 +1508,10 @@ static void csi_J(struct vc_data *vc, int vpar)
count = ((vc->vc_pos - vc->vc_origin) >> 1) + 1;
start = (unsigned short *)vc->vc_origin;
break;
+ case 3: /* include scrollback */
+ flush_scrollback(vc);
+ /* fallthrough */
case 2: /* erase whole display */
- case 3: /* (and scrollback buffer later) */
vc_uniscr_clear_lines(vc, 0, vc->vc_rows);
count = vc->vc_cols * vc->vc_rows;
start = (unsigned short *)vc->vc_origin;
@@ -1513,13 +1520,7 @@ static void csi_J(struct vc_data *vc, int vpar)
return;
}
scr_memsetw(start, vc->vc_video_erase_char, 2 * count);
- if (vpar == 3) {
- set_origin(vc);
- flush_scrollback(vc);
- if (con_is_visible(vc))
- update_screen(vc);
- } else if (con_should_update(vc))
- do_update_region(vc, (unsigned long) start, count);
+ update_region(vc, (unsigned long) start, count);
vc->vc_need_wrap = 0;
}
@@ -1628,9 +1629,9 @@ static void rgb_background(struct vc_data *vc, const struct rgb *c)
/*
* ITU T.416 Higher colour modes. They break the usual properties of SGR codes
- * and thus need to be detected and ignored by hand. Strictly speaking, that
- * standard also wants : rather than ; as separators, contrary to ECMA-48, but
- * no one produces such codes and almost no one accepts them.
+ * and thus need to be detected and ignored by hand. That standard also
+ * wants : rather than ; as separators but sequences containing : are currently
+ * completely ignored by the parser.
*
* Subcommands 3 (CMY) and 4 (CMYK) are so insane there's no point in
* supporting them.
@@ -1815,7 +1816,7 @@ static void set_mode(struct vc_data *vc, int on_off)
int i;
for (i = 0; i <= vc->vc_npar; i++)
- if (vc->vc_ques) {
+ if (vc->vc_priv == EPdec) {
switch(vc->vc_par[i]) { /* DEC private modes set/reset */
case 1: /* Cursor keys send ^[Ox/^[[x */
if (on_off)
@@ -2022,7 +2023,7 @@ static void restore_cur(struct vc_data *vc)
}
enum { ESnormal, ESesc, ESsquare, ESgetpars, ESfunckey,
- EShash, ESsetG0, ESsetG1, ESpercent, ESignore, ESnonstd,
+ EShash, ESsetG0, ESsetG1, ESpercent, EScsiignore, ESnonstd,
ESpalette, ESosc };
/* console_lock is held (except via vc_init()) */
@@ -2031,7 +2032,7 @@ static void reset_terminal(struct vc_data *vc, int do_clear)
vc->vc_top = 0;
vc->vc_bottom = vc->vc_rows;
vc->vc_state = ESnormal;
- vc->vc_ques = 0;
+ vc->vc_priv = EPecma;
vc->vc_translate = set_translate(LAT1_MAP, vc);
vc->vc_G0_charset = LAT1_MAP;
vc->vc_G1_charset = GRAF_MAP;
@@ -2112,6 +2113,7 @@ static void do_con_trol(struct tty_struct *tty, struct vc_data *vc, int c)
lf(vc);
if (!is_kbd(vc, lnm))
return;
+ /* fall through */
case 13:
cr(vc);
return;
@@ -2234,9 +2236,22 @@ static void do_con_trol(struct tty_struct *tty, struct vc_data *vc, int c)
vc->vc_state=ESfunckey;
return;
}
- vc->vc_ques = (c == '?');
- if (vc->vc_ques)
+ switch (c) {
+ case '?':
+ vc->vc_priv = EPdec;
+ return;
+ case '>':
+ vc->vc_priv = EPgt;
+ return;
+ case '=':
+ vc->vc_priv = EPeq;
return;
+ case '<':
+ vc->vc_priv = EPlt;
+ return;
+ }
+ vc->vc_priv = EPecma;
+ /* fall through */
case ESgetpars:
if (c == ';' && vc->vc_npar < NPAR - 1) {
vc->vc_npar++;
@@ -2246,16 +2261,22 @@ static void do_con_trol(struct tty_struct *tty, struct vc_data *vc, int c)
vc->vc_par[vc->vc_npar] += c - '0';
return;
}
+ if (c >= 0x20 && c <= 0x3f) { /* 0x2x, 0x3a and 0x3c - 0x3f */
+ vc->vc_state = EScsiignore;
+ return;
+ }
vc->vc_state = ESnormal;
switch(c) {
case 'h':
- set_mode(vc, 1);
+ if (vc->vc_priv <= EPdec)
+ set_mode(vc, 1);
return;
case 'l':
- set_mode(vc, 0);
+ if (vc->vc_priv <= EPdec)
+ set_mode(vc, 0);
return;
case 'c':
- if (vc->vc_ques) {
+ if (vc->vc_priv == EPdec) {
if (vc->vc_par[0])
vc->vc_cursor_type = vc->vc_par[0] | (vc->vc_par[1] << 8) | (vc->vc_par[2] << 16);
else
@@ -2264,7 +2285,7 @@ static void do_con_trol(struct tty_struct *tty, struct vc_data *vc, int c)
}
break;
case 'm':
- if (vc->vc_ques) {
+ if (vc->vc_priv == EPdec) {
clear_selection();
if (vc->vc_par[0])
vc->vc_complement_mask = vc->vc_par[0] << 8 | vc->vc_par[1];
@@ -2274,7 +2295,7 @@ static void do_con_trol(struct tty_struct *tty, struct vc_data *vc, int c)
}
break;
case 'n':
- if (!vc->vc_ques) {
+ if (vc->vc_priv == EPecma) {
if (vc->vc_par[0] == 5)
status_report(tty);
else if (vc->vc_par[0] == 6)
@@ -2282,8 +2303,8 @@ static void do_con_trol(struct tty_struct *tty, struct vc_data *vc, int c)
}
return;
}
- if (vc->vc_ques) {
- vc->vc_ques = 0;
+ if (vc->vc_priv != EPecma) {
+ vc->vc_priv = EPecma;
return;
}
switch(c) {
@@ -2406,6 +2427,11 @@ static void do_con_trol(struct tty_struct *tty, struct vc_data *vc, int c)
return;
}
return;
+ case EScsiignore:
+ if (c >= 20 && c <= 0x3f)
+ return;
+ vc->vc_state = ESnormal;
+ return;
case ESpercent:
vc->vc_state = ESnormal;
switch (c) {
@@ -4591,8 +4617,9 @@ EXPORT_SYMBOL_GPL(screen_pos);
void getconsxy(struct vc_data *vc, unsigned char *p)
{
- p[0] = vc->vc_x;
- p[1] = vc->vc_y;
+ /* clamp values if they don't fit */
+ p[0] = min(vc->vc_x, 0xFFu);
+ p[1] = min(vc->vc_y, 0xFFu);
}
void putconsxy(struct vc_data *vc, unsigned char *p)