diff options
Diffstat (limited to 'drivers/tty/vt/vt.c')
-rw-r--r-- | drivers/tty/vt/vt.c | 77 |
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) |