Merged from sys/dev/syscons/syscons.c revisions 1.367 and 1.368.
This commit is contained in:
parent
c569c0b5d2
commit
8ea2602a0d
@ -172,6 +172,8 @@ static int do_switch_scr(sc_softc_t *sc, int s);
|
||||
static int vt_proc_alive(scr_stat *scp);
|
||||
static int signal_vt_rel(scr_stat *scp);
|
||||
static int signal_vt_acq(scr_stat *scp);
|
||||
static int finish_vt_rel(scr_stat *scp, int release, int *s);
|
||||
static int finish_vt_acq(scr_stat *scp);
|
||||
static void exchange_scr(sc_softc_t *sc);
|
||||
static void update_cursor_image(scr_stat *scp);
|
||||
static int save_kbd_state(scr_stat *scp);
|
||||
@ -508,18 +510,10 @@ scclose(dev_t dev, int flag, int mode, struct proc *p)
|
||||
s = spltty();
|
||||
if ((scp == scp->sc->cur_scp) && (scp->sc->unit == sc_console_unit))
|
||||
cons_unavail = FALSE;
|
||||
if (scp->status & SWITCH_WAIT_REL) {
|
||||
/* assert(scp == scp->sc->cur_scp) */
|
||||
if (finish_vt_rel(scp, TRUE, &s) == 0) /* force release */
|
||||
DPRINTF(5, ("reset WAIT_REL, "));
|
||||
scp->status &= ~SWITCH_WAIT_REL;
|
||||
do_switch_scr(scp->sc, s);
|
||||
}
|
||||
if (scp->status & SWITCH_WAIT_ACQ) {
|
||||
/* assert(scp == scp->sc->cur_scp) */
|
||||
if (finish_vt_acq(scp) == 0) /* force acknowledge */
|
||||
DPRINTF(5, ("reset WAIT_ACQ, "));
|
||||
scp->status &= ~SWITCH_WAIT_ACQ;
|
||||
scp->sc->switch_in_progress = 0;
|
||||
}
|
||||
#if not_yet_done
|
||||
if (scp == &main_console) {
|
||||
scp->pid = 0;
|
||||
@ -877,18 +871,10 @@ scioctl(dev_t dev, u_long cmd, caddr_t data, int flag, struct proc *p)
|
||||
if ((scp == sc->cur_scp) && (sc->unit == sc_console_unit))
|
||||
cons_unavail = FALSE;
|
||||
/* were we in the middle of the vty switching process? */
|
||||
if (scp->status & SWITCH_WAIT_REL) {
|
||||
/* assert(scp == scp->sc->cur_scp) */
|
||||
if (finish_vt_rel(scp, TRUE, &s) == 0)
|
||||
DPRINTF(5, ("reset WAIT_REL, "));
|
||||
scp->status &= ~SWITCH_WAIT_REL;
|
||||
s = do_switch_scr(sc, s);
|
||||
}
|
||||
if (scp->status & SWITCH_WAIT_ACQ) {
|
||||
/* assert(scp == scp->sc->cur_scp) */
|
||||
if (finish_vt_acq(scp) == 0)
|
||||
DPRINTF(5, ("reset WAIT_ACQ, "));
|
||||
scp->status &= ~SWITCH_WAIT_ACQ;
|
||||
sc->switch_in_progress = 0;
|
||||
}
|
||||
} else {
|
||||
if (!ISSIGVALID(mode->relsig) || !ISSIGVALID(mode->acqsig)
|
||||
|| !ISSIGVALID(mode->frsig)) {
|
||||
@ -930,32 +916,17 @@ scioctl(dev_t dev, u_long cmd, caddr_t data, int flag, struct proc *p)
|
||||
error = EINVAL;
|
||||
switch(*(int *)data) {
|
||||
case VT_FALSE: /* user refuses to release screen, abort */
|
||||
if ((scp == sc->old_scp) && (scp->status & SWITCH_WAIT_REL)) {
|
||||
sc->old_scp->status &= ~SWITCH_WAIT_REL;
|
||||
sc->switch_in_progress = 0;
|
||||
if ((error = finish_vt_rel(scp, FALSE, &s)) == 0)
|
||||
DPRINTF(5, ("sc%d: VT_FALSE\n", sc->unit));
|
||||
error = 0;
|
||||
}
|
||||
break;
|
||||
|
||||
case VT_TRUE: /* user has released screen, go on */
|
||||
if ((scp == sc->old_scp) && (scp->status & SWITCH_WAIT_REL)) {
|
||||
scp->status &= ~SWITCH_WAIT_REL;
|
||||
s = do_switch_scr(sc, s);
|
||||
if ((error = finish_vt_rel(scp, TRUE, &s)) == 0)
|
||||
DPRINTF(5, ("sc%d: VT_TRUE\n", sc->unit));
|
||||
error = 0;
|
||||
}
|
||||
break;
|
||||
|
||||
case VT_ACKACQ: /* acquire acknowledged, switch completed */
|
||||
if ((scp == sc->new_scp) && (scp->status & SWITCH_WAIT_ACQ)) {
|
||||
scp->status &= ~SWITCH_WAIT_ACQ;
|
||||
sc->switch_in_progress = 0;
|
||||
if ((error = finish_vt_acq(scp)) == 0)
|
||||
DPRINTF(5, ("sc%d: VT_ACKACQ\n", sc->unit));
|
||||
error = 0;
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
@ -973,22 +944,22 @@ scioctl(dev_t dev, u_long cmd, caddr_t data, int flag, struct proc *p)
|
||||
return EINVAL;
|
||||
|
||||
case VT_ACTIVATE: /* switch to screen *data */
|
||||
i = (*(int *)data == 0) ? scp->index : (*(int *)data - 1);
|
||||
s = spltty();
|
||||
sc_clean_up(sc->cur_scp);
|
||||
splx(s);
|
||||
return sc_switch_scr(sc, *(int *)data - 1);
|
||||
return sc_switch_scr(sc, i);
|
||||
|
||||
case VT_WAITACTIVE: /* wait for switch to occur */
|
||||
if ((*(int *)data >= sc->first_vty + sc->vtys)
|
||||
|| (*(int *)data < sc->first_vty))
|
||||
i = (*(int *)data == 0) ? scp->index : (*(int *)data - 1);
|
||||
if ((i < sc->first_vty) || (i >= sc->first_vty + sc->vtys))
|
||||
return EINVAL;
|
||||
s = spltty();
|
||||
error = sc_clean_up(sc->cur_scp);
|
||||
splx(s);
|
||||
if (error)
|
||||
return error;
|
||||
if (*(int *)data != 0)
|
||||
scp = SC_STAT(SC_DEV(sc, *(int *)data - 1));
|
||||
scp = SC_STAT(SC_DEV(sc, i));
|
||||
if (scp == scp->sc->cur_scp)
|
||||
return 0;
|
||||
while ((error=tsleep((caddr_t)&scp->smode, PZERO|PCATCH,
|
||||
@ -2098,6 +2069,7 @@ sc_touch_scrn_saver(void)
|
||||
int
|
||||
sc_switch_scr(sc_softc_t *sc, u_int next_scr)
|
||||
{
|
||||
scr_stat *cur_scp;
|
||||
struct tty *tp;
|
||||
struct proc *p;
|
||||
int s;
|
||||
@ -2114,13 +2086,14 @@ sc_switch_scr(sc_softc_t *sc, u_int next_scr)
|
||||
}
|
||||
|
||||
s = spltty();
|
||||
cur_scp = sc->cur_scp;
|
||||
|
||||
/* we are in the middle of the vty switching process... */
|
||||
if (sc->switch_in_progress
|
||||
&& (sc->cur_scp->smode.mode == VT_PROCESS)
|
||||
&& sc->cur_scp->proc) {
|
||||
p = pfind(sc->cur_scp->pid);
|
||||
if (sc->cur_scp->proc != p) {
|
||||
&& (cur_scp->smode.mode == VT_PROCESS)
|
||||
&& cur_scp->proc) {
|
||||
p = pfind(cur_scp->pid);
|
||||
if (cur_scp->proc != p) {
|
||||
if (p)
|
||||
PROC_UNLOCK(p);
|
||||
/*
|
||||
@ -2129,23 +2102,21 @@ sc_switch_scr(sc_softc_t *sc, u_int next_scr)
|
||||
* are not reset here yet; they will be cleared later.
|
||||
*/
|
||||
DPRINTF(5, ("cur_scp controlling process %d died, ",
|
||||
sc->cur_scp->pid));
|
||||
if (sc->cur_scp->status & SWITCH_WAIT_REL) {
|
||||
cur_scp->pid));
|
||||
if (cur_scp->status & SWITCH_WAIT_REL) {
|
||||
/*
|
||||
* Force the previous switch to finish, but return now
|
||||
* with error.
|
||||
*/
|
||||
DPRINTF(5, ("reset WAIT_REL, "));
|
||||
sc->cur_scp->status &= ~SWITCH_WAIT_REL;
|
||||
s = do_switch_scr(sc, s);
|
||||
finish_vt_rel(cur_scp, TRUE, &s);
|
||||
splx(s);
|
||||
DPRINTF(5, ("finishing previous switch\n"));
|
||||
return EINVAL;
|
||||
} else if (sc->cur_scp->status & SWITCH_WAIT_ACQ) {
|
||||
} else if (cur_scp->status & SWITCH_WAIT_ACQ) {
|
||||
/* let's assume screen switch has been completed. */
|
||||
DPRINTF(5, ("reset WAIT_ACQ, "));
|
||||
sc->cur_scp->status &= ~SWITCH_WAIT_ACQ;
|
||||
sc->switch_in_progress = 0;
|
||||
finish_vt_acq(cur_scp);
|
||||
} else {
|
||||
/*
|
||||
* We are in between screen release and acquisition, and
|
||||
@ -2163,13 +2134,13 @@ sc_switch_scr(sc_softc_t *sc, u_int next_scr)
|
||||
* The following code is a gross kludge to cope with this
|
||||
* problem for which there is no clean solution. XXX
|
||||
*/
|
||||
if (sc->cur_scp->status & SWITCH_WAIT_REL) {
|
||||
if (cur_scp->status & SWITCH_WAIT_REL) {
|
||||
switch (sc->switch_in_progress++) {
|
||||
case 1:
|
||||
break;
|
||||
case 2:
|
||||
DPRINTF(5, ("sending relsig again, "));
|
||||
signal_vt_rel(sc->cur_scp);
|
||||
signal_vt_rel(cur_scp);
|
||||
break;
|
||||
case 3:
|
||||
break;
|
||||
@ -2180,19 +2151,18 @@ sc_switch_scr(sc_softc_t *sc, u_int next_scr)
|
||||
* VT_FALSE.
|
||||
*/
|
||||
DPRINTF(5, ("force reset WAIT_REL, "));
|
||||
sc->cur_scp->status &= ~SWITCH_WAIT_REL;
|
||||
sc->switch_in_progress = 0;
|
||||
finish_vt_rel(cur_scp, FALSE, &s);
|
||||
splx(s);
|
||||
DPRINTF(5, ("act as if VT_FALSE was seen\n"));
|
||||
return EINVAL;
|
||||
}
|
||||
} else if (sc->cur_scp->status & SWITCH_WAIT_ACQ) {
|
||||
} else if (cur_scp->status & SWITCH_WAIT_ACQ) {
|
||||
switch (sc->switch_in_progress++) {
|
||||
case 1:
|
||||
break;
|
||||
case 2:
|
||||
DPRINTF(5, ("sending acqsig again, "));
|
||||
signal_vt_acq(sc->cur_scp);
|
||||
signal_vt_acq(cur_scp);
|
||||
break;
|
||||
case 3:
|
||||
break;
|
||||
@ -2200,8 +2170,7 @@ sc_switch_scr(sc_softc_t *sc, u_int next_scr)
|
||||
default:
|
||||
/* clear the flag and finish the previous switch */
|
||||
DPRINTF(5, ("force reset WAIT_ACQ, "));
|
||||
sc->cur_scp->status &= ~SWITCH_WAIT_ACQ;
|
||||
sc->switch_in_progress = 0;
|
||||
finish_vt_acq(cur_scp);
|
||||
break;
|
||||
}
|
||||
}
|
||||
@ -2215,7 +2184,7 @@ sc_switch_scr(sc_softc_t *sc, u_int next_scr)
|
||||
if ((next_scr < sc->first_vty) || (next_scr >= sc->first_vty + sc->vtys)
|
||||
|| sc->switch_in_progress) {
|
||||
splx(s);
|
||||
sc_bell(sc->cur_scp, bios_value.bell_pitch, BELL_DURATION);
|
||||
sc_bell(cur_scp, bios_value.bell_pitch, BELL_DURATION);
|
||||
DPRINTF(5, ("error 1\n"));
|
||||
return EINVAL;
|
||||
}
|
||||
@ -2225,13 +2194,13 @@ sc_switch_scr(sc_softc_t *sc, u_int next_scr)
|
||||
* if the switch mode is VT_AUTO, unless the next vty is the same
|
||||
* as the current or the current vty has been closed (but showing).
|
||||
*/
|
||||
tp = VIRTUAL_TTY(sc, sc->cur_scp->index);
|
||||
if ((sc->cur_scp->index != next_scr)
|
||||
tp = VIRTUAL_TTY(sc, cur_scp->index);
|
||||
if ((cur_scp->index != next_scr)
|
||||
&& ISTTYOPEN(tp)
|
||||
&& (sc->cur_scp->smode.mode == VT_AUTO)
|
||||
&& ISGRAPHSC(sc->cur_scp)) {
|
||||
&& (cur_scp->smode.mode == VT_AUTO)
|
||||
&& ISGRAPHSC(cur_scp)) {
|
||||
splx(s);
|
||||
sc_bell(sc->cur_scp, bios_value.bell_pitch, BELL_DURATION);
|
||||
sc_bell(cur_scp, bios_value.bell_pitch, BELL_DURATION);
|
||||
DPRINTF(5, ("error, graphics mode\n"));
|
||||
return EINVAL;
|
||||
}
|
||||
@ -2246,7 +2215,7 @@ sc_switch_scr(sc_softc_t *sc, u_int next_scr)
|
||||
tp = VIRTUAL_TTY(sc, next_scr);
|
||||
if (!ISTTYOPEN(tp)) {
|
||||
splx(s);
|
||||
sc_bell(sc->cur_scp, bios_value.bell_pitch, BELL_DURATION);
|
||||
sc_bell(cur_scp, bios_value.bell_pitch, BELL_DURATION);
|
||||
DPRINTF(5, ("error 2, requested vty isn't open!\n"));
|
||||
return EINVAL;
|
||||
}
|
||||
@ -2260,7 +2229,7 @@ sc_switch_scr(sc_softc_t *sc, u_int next_scr)
|
||||
/* this is the start of vty switching process... */
|
||||
++sc->switch_in_progress;
|
||||
sc->delayed_next_scr = 0;
|
||||
sc->old_scp = sc->cur_scp;
|
||||
sc->old_scp = cur_scp;
|
||||
sc->new_scp = SC_STAT(SC_DEV(sc, next_scr));
|
||||
if (sc->new_scp == sc->old_scp) {
|
||||
sc->switch_in_progress = 0;
|
||||
@ -2369,6 +2338,31 @@ signal_vt_acq(scr_stat *scp)
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static int
|
||||
finish_vt_rel(scr_stat *scp, int release, int *s)
|
||||
{
|
||||
if (scp == scp->sc->old_scp && scp->status & SWITCH_WAIT_REL) {
|
||||
scp->status &= ~SWITCH_WAIT_REL;
|
||||
if (release)
|
||||
*s = do_switch_scr(scp->sc, *s);
|
||||
else
|
||||
scp->sc->switch_in_progress = 0;
|
||||
return 0;
|
||||
}
|
||||
return EINVAL;
|
||||
}
|
||||
|
||||
static int
|
||||
finish_vt_acq(scr_stat *scp)
|
||||
{
|
||||
if (scp == scp->sc->new_scp && scp->status & SWITCH_WAIT_ACQ) {
|
||||
scp->status &= ~SWITCH_WAIT_ACQ;
|
||||
scp->sc->switch_in_progress = 0;
|
||||
return 0;
|
||||
}
|
||||
return EINVAL;
|
||||
}
|
||||
|
||||
static void
|
||||
exchange_scr(sc_softc_t *sc)
|
||||
{
|
||||
|
Loading…
Reference in New Issue
Block a user