Commit 7c1c9c14 authored by Jiri Slaby (SUSE)'s avatar Jiri Slaby (SUSE) Committed by Greg Kroah-Hartman

tty: vt: move CSI ECMA handling to a separate function

Similar to previous moves, move also "CSI ..." (i.e. vc_priv == EPecma)
handling to a separate function.

This is the last large move of code out of do_con_trol(). And despite it
is still 151 lines of code (down from 407!), it is now quite easy to
folllow the transitions of the state machine in there. ESnonstd and
ESpalette handling still can be moved away, but it won't improve that
much.
Signed-off-by: default avatar"Jiri Slaby (SUSE)" <jirislaby@kernel.org>
Link: https://lore.kernel.org/r/20240202065608.14019-15-jirislaby@kernel.orgSigned-off-by: default avatarGreg Kroah-Hartman <gregkh@linuxfoundation.org>
parent de0f61f3
......@@ -2375,150 +2375,57 @@ static void csi_DEC(struct tty_struct *tty, struct vc_data *vc, u8 c)
}
}
/* console_lock is held */
static void do_con_trol(struct tty_struct *tty, struct vc_data *vc, u8 c)
{
/*
* Control characters can be used in the _middle_
* of an escape sequence, aside from ANSI control strings.
/*
* Handle Control Sequence Introducer control characters. That is
* "ESC [ parameters char". Parameters are in @vc->vc_par and the char is in
* @c here.
*/
if (ansi_control_string(vc->vc_state) && c >= ASCII_IGNORE_FIRST &&
c <= ASCII_IGNORE_LAST)
return;
if (handle_ascii(tty, vc, c))
return;
switch(vc->vc_state) {
case ESesc:
handle_esc(tty, vc, c);
return;
case ESnonstd:
if (c=='P') { /* palette escape sequence */
for (vc->vc_npar = 0; vc->vc_npar < NPAR; vc->vc_npar++)
vc->vc_par[vc->vc_npar] = 0;
vc->vc_npar = 0;
vc->vc_state = ESpalette;
return;
} else if (c=='R') { /* reset palette */
reset_palette(vc);
vc->vc_state = ESnormal;
} else if (c>='0' && c<='9')
vc->vc_state = ESosc;
else
vc->vc_state = ESnormal;
return;
case ESpalette:
if (isxdigit(c)) {
vc->vc_par[vc->vc_npar++] = hex_to_bin(c);
if (vc->vc_npar == 7) {
int i = vc->vc_par[0] * 3, j = 1;
vc->vc_palette[i] = 16 * vc->vc_par[j++];
vc->vc_palette[i++] += vc->vc_par[j++];
vc->vc_palette[i] = 16 * vc->vc_par[j++];
vc->vc_palette[i++] += vc->vc_par[j++];
vc->vc_palette[i] = 16 * vc->vc_par[j++];
vc->vc_palette[i] += vc->vc_par[j];
set_palette(vc);
vc->vc_state = ESnormal;
}
} else
vc->vc_state = ESnormal;
return;
case ESsquare:
for (vc->vc_npar = 0; vc->vc_npar < NPAR; vc->vc_npar++)
vc->vc_par[vc->vc_npar] = 0;
vc->vc_npar = 0;
vc->vc_state = ESgetpars;
if (c == '[') { /* Function key */
vc->vc_state=ESfunckey;
return;
}
static void csi_ECMA(struct tty_struct *tty, struct vc_data *vc, u8 c)
{
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;
fallthrough;
case ESgetpars:
if (c == ';' && vc->vc_npar < NPAR - 1) {
vc->vc_npar++;
return;
} else if (c>='0' && c<='9') {
vc->vc_par[vc->vc_npar] *= 10;
vc->vc_par[vc->vc_npar] += c - '0';
return;
}
if (c >= ASCII_CSI_IGNORE_FIRST && c <= ASCII_CSI_IGNORE_LAST) {
vc->vc_state = EScsiignore;
return;
}
vc->vc_state = ESnormal;
switch (vc->vc_priv) {
case EPdec:
csi_DEC(tty, vc, c);
return;
case EPecma:
break;
default:
return;
}
switch(c) {
case 'G':
case '`':
if (vc->vc_par[0])
vc->vc_par[0]--;
gotoxy(vc, vc->vc_par[0], vc->state.y);
return;
break;
case 'A':
if (!vc->vc_par[0])
vc->vc_par[0]++;
gotoxy(vc, vc->state.x, vc->state.y - vc->vc_par[0]);
return;
break;
case 'B':
case 'e':
if (!vc->vc_par[0])
vc->vc_par[0]++;
gotoxy(vc, vc->state.x, vc->state.y + vc->vc_par[0]);
return;
break;
case 'C':
case 'a':
if (!vc->vc_par[0])
vc->vc_par[0]++;
gotoxy(vc, vc->state.x + vc->vc_par[0], vc->state.y);
return;
break;
case 'D':
if (!vc->vc_par[0])
vc->vc_par[0]++;
gotoxy(vc, vc->state.x - vc->vc_par[0], vc->state.y);
return;
break;
case 'E':
if (!vc->vc_par[0])
vc->vc_par[0]++;
gotoxy(vc, 0, vc->state.y + vc->vc_par[0]);
return;
break;
case 'F':
if (!vc->vc_par[0])
vc->vc_par[0]++;
gotoxy(vc, 0, vc->state.y - vc->vc_par[0]);
return;
break;
case 'd':
if (vc->vc_par[0])
vc->vc_par[0]--;
gotoxay(vc, vc->state.x ,vc->vc_par[0]);
return;
break;
case 'H':
case 'f':
if (vc->vc_par[0])
......@@ -2526,53 +2433,53 @@ static void do_con_trol(struct tty_struct *tty, struct vc_data *vc, u8 c)
if (vc->vc_par[1])
vc->vc_par[1]--;
gotoxay(vc, vc->vc_par[1], vc->vc_par[0]);
return;
break;
case 'J':
csi_J(vc, vc->vc_par[0]);
return;
break;
case 'K':
csi_K(vc);
return;
break;
case 'L':
csi_L(vc);
return;
break;
case 'M':
csi_M(vc);
return;
break;
case 'P':
csi_P(vc);
return;
break;
case 'c':
if (!vc->vc_par[0])
respond_ID(tty);
return;
break;
case 'g':
if (!vc->vc_par[0] && vc->state.x < VC_TABSTOPS_COUNT)
set_bit(vc->state.x, vc->vc_tab_stop);
else if (vc->vc_par[0] == 3)
bitmap_zero(vc->vc_tab_stop, VC_TABSTOPS_COUNT);
return;
break;
case 'h':
csi_hl(vc, true);
return;
break;
case 'l':
csi_hl(vc, false);
return;
break;
case 'm':
csi_m(vc);
return;
break;
case 'n':
if (vc->vc_par[0] == 5)
status_report(tty);
else if (vc->vc_par[0] == 6)
cursor_report(vc, tty);
return;
break;
case 'q': /* DECLL - but only 3 leds */
/* map 0,1,2,3 to 0,1,2,4 */
if (vc->vc_par[0] < 4)
vt_set_led_state(vc->vc_num,
(vc->vc_par[0] < 3) ? vc->vc_par[0] : 4);
return;
break;
case 'r':
if (!vc->vc_par[0])
vc->vc_par[0]++;
......@@ -2585,24 +2492,126 @@ static void do_con_trol(struct tty_struct *tty, struct vc_data *vc, u8 c)
vc->vc_bottom = vc->vc_par[1];
gotoxay(vc, 0, 0);
}
return;
break;
case 's':
save_cur(vc);
return;
break;
case 'u':
restore_cur(vc);
return;
break;
case 'X':
csi_X(vc);
return;
break;
case '@':
csi_at(vc, vc->vc_par[0]);
return;
break;
case ']':
csi_RSB(vc);
break;
}
}
/* console_lock is held */
static void do_con_trol(struct tty_struct *tty, struct vc_data *vc, u8 c)
{
/*
* Control characters can be used in the _middle_
* of an escape sequence, aside from ANSI control strings.
*/
if (ansi_control_string(vc->vc_state) && c >= ASCII_IGNORE_FIRST &&
c <= ASCII_IGNORE_LAST)
return;
if (handle_ascii(tty, vc, c))
return;
switch(vc->vc_state) {
case ESesc:
handle_esc(tty, vc, c);
return;
case ESnonstd:
if (c=='P') { /* palette escape sequence */
for (vc->vc_npar = 0; vc->vc_npar < NPAR; vc->vc_npar++)
vc->vc_par[vc->vc_npar] = 0;
vc->vc_npar = 0;
vc->vc_state = ESpalette;
return;
} else if (c=='R') { /* reset palette */
reset_palette(vc);
vc->vc_state = ESnormal;
} else if (c>='0' && c<='9')
vc->vc_state = ESosc;
else
vc->vc_state = ESnormal;
return;
case ESpalette:
if (isxdigit(c)) {
vc->vc_par[vc->vc_npar++] = hex_to_bin(c);
if (vc->vc_npar == 7) {
int i = vc->vc_par[0] * 3, j = 1;
vc->vc_palette[i] = 16 * vc->vc_par[j++];
vc->vc_palette[i++] += vc->vc_par[j++];
vc->vc_palette[i] = 16 * vc->vc_par[j++];
vc->vc_palette[i++] += vc->vc_par[j++];
vc->vc_palette[i] = 16 * vc->vc_par[j++];
vc->vc_palette[i] += vc->vc_par[j];
set_palette(vc);
vc->vc_state = ESnormal;
}
} else
vc->vc_state = ESnormal;
return;
case ESsquare:
for (vc->vc_npar = 0; vc->vc_npar < NPAR; vc->vc_npar++)
vc->vc_par[vc->vc_npar] = 0;
vc->vc_npar = 0;
vc->vc_state = ESgetpars;
if (c == '[') { /* Function key */
vc->vc_state=ESfunckey;
return;
}
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;
fallthrough;
case ESgetpars:
if (c == ';' && vc->vc_npar < NPAR - 1) {
vc->vc_npar++;
return;
} else if (c>='0' && c<='9') {
vc->vc_par[vc->vc_npar] *= 10;
vc->vc_par[vc->vc_npar] += c - '0';
return;
}
if (c >= ASCII_CSI_IGNORE_FIRST && c <= ASCII_CSI_IGNORE_LAST) {
vc->vc_state = EScsiignore;
return;
}
vc->vc_state = ESnormal;
switch (vc->vc_priv) {
case EPdec:
csi_DEC(tty, vc, c);
return;
case EPecma:
csi_ECMA(tty, vc, c);
return;
default:
return;
}
case EScsiignore:
if (c >= ASCII_CSI_IGNORE_FIRST && c <= ASCII_CSI_IGNORE_LAST)
return;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment