Merged from sys/dev/syscons/syscons.c revisions 1.370, 1.371 and 1.372.

This commit is contained in:
nyan 2001-08-07 12:23:47 +00:00
parent 559b28363c
commit 57f485f211

View File

@ -1,5 +1,5 @@
/*-
* Copyright (c) 1992-1998 Sen Schmidt
* Copyright (c) 1992-1998 Sen Schmidt
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@ -28,8 +28,8 @@
* $FreeBSD$
*/
#include "splash.h"
#include "opt_syscons.h"
#include "opt_splash.h"
#include "opt_ddb.h"
#ifdef __i386__
#include "opt_apm.h"
@ -102,7 +102,7 @@ static char sc_malloc = FALSE;
static int saver_mode = CONS_NO_SAVER; /* LKM/user saver */
static int run_scrn_saver = FALSE; /* should run the saver? */
static long scrn_blank_time = 0; /* screen saver timeout value */
#if NSPLASH > 0
#ifdef DEV_SPLASH
static int scrn_blanked; /* # of blanked screen */
static int sticky_splash = FALSE;
@ -154,7 +154,7 @@ static timeout_t scrn_timer;
static int and_region(int *s1, int *e1, int s2, int e2);
static void scrn_update(scr_stat *scp, int show_cursor);
#if NSPLASH > 0
#ifdef DEV_SPLASH
static int scsplash_callback(int event, void *arg);
static void scsplash_saver(sc_softc_t *sc, int show);
static int add_scrn_saver(void (*this_saver)(sc_softc_t *, int));
@ -164,9 +164,9 @@ static int restore_scrn_saver_mode(scr_stat *scp, int changemode);
static void stop_scrn_saver(sc_softc_t *sc, void (*saver)(sc_softc_t *, int));
static int wait_scrn_saver_stop(sc_softc_t *sc);
#define scsplash_stick(stick) (sticky_splash = (stick))
#else /* !NSPLASH */
#else /* !DEV_SPLASH */
#define scsplash_stick(stick)
#endif /* NSPLASH */
#endif /* DEV_SPLASH */
static int do_switch_scr(sc_softc_t *sc, int s);
static int vt_proc_alive(scr_stat *scp);
@ -176,6 +176,7 @@ 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 void change_cursor_shape(scr_stat *scp, int flags, int base, int height);
static int save_kbd_state(scr_stat *scp);
static int update_kbd_state(scr_stat *scp, int state, int mask);
static int update_kbd_leds(scr_stat *scp, int which);
@ -225,7 +226,7 @@ sc_probe_unit(int unit, int flags)
{
if (!scvidprobe(unit, flags, FALSE)) {
if (bootverbose)
printf("sc%d: no video adapter is found.\n", unit);
printf("sc%d: no video adapter found.\n", unit);
return ENXIO;
}
@ -329,14 +330,14 @@ sc_attach_unit(int unit, int flags)
#ifdef SC_PIXEL_MODE
if ((sc->config & SC_VESA800X600)
&& ((*vidsw[sc->adapter]->get_info)(sc->adp, M_VESA_800x600, &info) == 0)) {
#if NSPLASH > 0
#ifdef DEV_SPLASH
if (sc->flags & SC_SPLASH_SCRN)
splash_term(sc->adp);
#endif
sc_set_graphics_mode(scp, NULL, M_VESA_800x600);
sc_set_pixel_mode(scp, NULL, COL, ROW, 16);
sc->initial_mode = M_VESA_800x600;
#if NSPLASH > 0
#ifdef DEV_SPLASH
/* put up the splash again! */
if (sc->flags & SC_SPLASH_SCRN)
splash_init(sc->adp, scsplash_callback, sc);
@ -699,26 +700,29 @@ scioctl(dev_t dev, u_long cmd, caddr_t data, int flag, struct proc *p)
splx(s);
return 0;
case CONS_CURSORTYPE: /* set cursor type blink/noblink */
case CONS_CURSORTYPE: /* set cursor type (obsolete) */
s = spltty();
if (!ISGRAPHSC(sc->cur_scp))
sc_remove_cursor_image(sc->cur_scp);
if ((*(int*)data) & 0x01)
sc->flags |= SC_BLINK_CURSOR;
else
sc->flags &= ~SC_BLINK_CURSOR;
if ((*(int*)data) & 0x02) {
sc->flags |= SC_CHAR_CURSOR;
} else
sc->flags &= ~SC_CHAR_CURSOR;
/*
* The cursor shape is global property; all virtual consoles
* are affected. Update the cursor in the current console...
*/
if (!ISGRAPHSC(sc->cur_scp)) {
sc_set_cursor_image(sc->cur_scp);
sc_draw_cursor_image(sc->cur_scp);
*(int *)data &= CONS_CURSOR_ATTRS;
sc_change_cursor_shape(scp, *(int *)data, -1, -1);
splx(s);
return 0;
case CONS_GETCURSORSHAPE: /* get cursor shape (new interface) */
if (((int *)data)[0] & CONS_LOCAL_CURSOR) {
((int *)data)[0] = scp->curr_curs_attr.flags;
((int *)data)[1] = scp->curr_curs_attr.base;
((int *)data)[2] = scp->curr_curs_attr.height;
} else {
((int *)data)[0] = sc->curs_attr.flags;
((int *)data)[1] = sc->curs_attr.base;
((int *)data)[2] = sc->curs_attr.height;
}
return 0;
case CONS_SETCURSORSHAPE: /* set cursor shape (new interface) */
s = spltty();
sc_change_cursor_shape(scp, ((int *)data)[0],
((int *)data)[1], ((int *)data)[2]);
splx(s);
return 0;
@ -788,12 +792,12 @@ scioctl(dev_t dev, u_long cmd, caddr_t data, int flag, struct proc *p)
scsplash_stick(FALSE);
saver_mode = *(int *)data;
s = spltty();
#if NSPLASH > 0
#ifdef DEV_SPLASH
if ((error = wait_scrn_saver_stop(NULL))) {
splx(s);
return error;
}
#endif /* NSPLASH */
#endif
run_scrn_saver = TRUE;
if (saver_mode == CONS_USR_SAVER)
scp->status |= SAVER_RUNNING;
@ -1478,8 +1482,11 @@ sccndbctl(dev_t dev, int on)
scrn_timer(NULL);
if (!cold
&& sc_console->sc->cur_scp->smode.mode == VT_AUTO
&& sc_console->smode.mode == VT_AUTO)
&& sc_console->smode.mode == VT_AUTO) {
++debugger; /* XXX */
sc_switch_scr(sc_console->sc, sc_console->index);
--debugger; /* XXX */
}
}
if (on)
++debugger;
@ -1574,11 +1581,11 @@ sccnupdate(scr_stat *scp)
if (!run_scrn_saver)
scp->sc->flags &= ~SC_SCRN_IDLE;
#if NSPLASH > 0
#ifdef DEV_SPLASH
if ((saver_mode != CONS_LKM_SAVER) || !(scp->sc->flags & SC_SCRN_IDLE))
if (scp->sc->flags & SC_SCRN_BLANKED)
stop_scrn_saver(scp->sc, current_saver);
#endif /* NSPLASH */
#endif
if (scp != scp->sc->cur_scp || scp->sc->blink_in_progress
|| scp->sc->switch_in_progress)
@ -1656,11 +1663,11 @@ scrn_timer(void *arg)
if (scrn_blank_time > 0)
run_scrn_saver = TRUE;
}
#if NSPLASH > 0
#ifdef DEV_SPLASH
if ((saver_mode != CONS_LKM_SAVER) || !(sc->flags & SC_SCRN_IDLE))
if (sc->flags & SC_SCRN_BLANKED)
stop_scrn_saver(sc, current_saver);
#endif /* NSPLASH */
#endif
/* should we just return ? */
if (sc->blink_in_progress || sc->switch_in_progress
@ -1676,12 +1683,12 @@ scrn_timer(void *arg)
if (!ISGRAPHSC(scp) && !(sc->flags & SC_SCRN_BLANKED))
scrn_update(scp, TRUE);
#if NSPLASH > 0
#ifdef DEV_SPLASH
/* should we activate the screen saver? */
if ((saver_mode == CONS_LKM_SAVER) && (sc->flags & SC_SCRN_IDLE))
if (!ISGRAPHSC(scp) || (sc->flags & SC_SCRN_BLANKED))
(*current_saver)(sc, TRUE);
#endif /* NSPLASH */
#endif
if (again)
timeout(scrn_timer, sc, hz / 25);
@ -1792,7 +1799,7 @@ scrn_update(scr_stat *scp, int show_cursor)
sc_draw_cursor_image(scp);
} else {
/* if its a blinking cursor, we may have to update it */
if (scp->sc->flags & SC_BLINK_CURSOR)
if (scp->curs_attr.flags & CONS_BLINK_CURSOR)
(*scp->rndr->blink_cursor)(scp, scp->cursor_pos,
sc_inside_cutmark(scp,
scp->cursor_pos));
@ -1829,7 +1836,7 @@ scrn_update(scr_stat *scp, int show_cursor)
--scp->sc->videoio_in_progress;
}
#if NSPLASH > 0
#ifdef DEV_SPLASH
static int
scsplash_callback(int event, void *arg)
{
@ -2036,7 +2043,8 @@ stop_scrn_saver(sc_softc_t *sc, void (*saver)(sc_softc_t *, int))
mark_all(sc->cur_scp);
if (sc->delayed_next_scr)
sc_switch_scr(sc, sc->delayed_next_scr - 1);
wakeup((caddr_t)&scrn_blanked);
if (debugger == 0)
wakeup((caddr_t)&scrn_blanked);
}
static int
@ -2057,7 +2065,7 @@ wait_scrn_saver_stop(sc_softc_t *sc)
run_scrn_saver = FALSE;
return error;
}
#endif /* NSPLASH */
#endif /* DEV_SPLASH */
void
sc_touch_scrn_saver(void)
@ -2233,7 +2241,16 @@ sc_switch_scr(sc_softc_t *sc, u_int next_scr)
sc->new_scp = SC_STAT(SC_DEV(sc, next_scr));
if (sc->new_scp == sc->old_scp) {
sc->switch_in_progress = 0;
wakeup((caddr_t)&sc->new_scp->smode);
/*
* XXX wakeup() calls mtx_lock(&sched_lock) which will hang if
* sched_lock is in an in-between state, e.g., when we stop at
* a breakpoint at fork_exit. It has always been wrong to call
* wakeup() when the debugger is active. In RELENG_4, wakeup()
* is supposed to be locked by splhigh(), but the debugger may
* be invoked at splhigh().
*/
if (debugger == 0)
wakeup((caddr_t)&sc->new_scp->smode);
splx(s);
DPRINTF(5, ("switch done (new == old)\n"));
return 0;
@ -2255,7 +2272,8 @@ sc_switch_scr(sc_softc_t *sc, u_int next_scr)
s = spltty();
/* wake up processes waiting for this vty */
wakeup((caddr_t)&sc->cur_scp->smode);
if (debugger == 0)
wakeup((caddr_t)&sc->cur_scp->smode);
/* wait for the controlling process to acknowledge, if necessary */
if (signal_vt_acq(sc->cur_scp)) {
@ -2406,7 +2424,7 @@ exchange_scr(sc_softc_t *sc)
void
sc_puts(scr_stat *scp, u_char *buf, int len)
{
#if NSPLASH > 0
#ifdef DEV_SPLASH
/* make screensaver happy */
if (!sticky_splash && scp == scp->sc->cur_scp)
run_scrn_saver = FALSE;
@ -2425,7 +2443,7 @@ sc_draw_cursor_image(scr_stat *scp)
/* assert(scp == scp->sc->cur_scp); */
++scp->sc->videoio_in_progress;
(*scp->rndr->draw_cursor)(scp, scp->cursor_pos,
scp->sc->flags & SC_BLINK_CURSOR, TRUE,
scp->curs_attr.flags & CONS_BLINK_CURSOR, TRUE,
sc_inside_cutmark(scp, scp->cursor_pos));
scp->cursor_oldpos = scp->cursor_pos;
--scp->sc->videoio_in_progress;
@ -2437,7 +2455,7 @@ sc_remove_cursor_image(scr_stat *scp)
/* assert(scp == scp->sc->cur_scp); */
++scp->sc->videoio_in_progress;
(*scp->rndr->draw_cursor)(scp, scp->cursor_oldpos,
scp->sc->flags & SC_BLINK_CURSOR, FALSE,
scp->curs_attr.flags & CONS_BLINK_CURSOR, FALSE,
sc_inside_cutmark(scp, scp->cursor_oldpos));
--scp->sc->videoio_in_progress;
}
@ -2445,45 +2463,98 @@ sc_remove_cursor_image(scr_stat *scp)
static void
update_cursor_image(scr_stat *scp)
{
int blink;
if (scp->sc->flags & SC_CHAR_CURSOR) {
scp->cursor_base = scp->sc->cursor_base;
scp->cursor_height = imin(scp->sc->cursor_height, scp->font_size);
} else {
scp->cursor_base = 0;
scp->cursor_height = scp->font_size;
}
blink = scp->sc->flags & SC_BLINK_CURSOR;
/* assert(scp == scp->sc->cur_scp); */
++scp->sc->videoio_in_progress;
(*scp->rndr->draw_cursor)(scp, scp->cursor_oldpos, blink, FALSE,
sc_inside_cutmark(scp, scp->cursor_pos));
(*scp->rndr->set_cursor)(scp, scp->cursor_base, scp->cursor_height, blink);
(*scp->rndr->draw_cursor)(scp, scp->cursor_pos, blink, TRUE,
sc_inside_cutmark(scp, scp->cursor_pos));
--scp->sc->videoio_in_progress;
sc_remove_cursor_image(scp);
sc_set_cursor_image(scp);
sc_draw_cursor_image(scp);
}
void
sc_set_cursor_image(scr_stat *scp)
{
if (scp->sc->flags & SC_CHAR_CURSOR) {
scp->cursor_base = scp->sc->cursor_base;
scp->cursor_height = imin(scp->sc->cursor_height, scp->font_size);
} else {
scp->cursor_base = 0;
scp->cursor_height = scp->font_size;
scp->curs_attr.flags = scp->curr_curs_attr.flags;
if (scp->curs_attr.flags & CONS_HIDDEN_CURSOR) {
/* hidden cursor is internally represented as zero-height underline */
scp->curs_attr.flags = CONS_CHAR_CURSOR;
scp->curs_attr.base = scp->curs_attr.height = 0;
} else if (scp->curs_attr.flags & CONS_CHAR_CURSOR) {
scp->curs_attr.base = imin(scp->curr_curs_attr.base,
scp->font_size - 1);
scp->curs_attr.height = imin(scp->curr_curs_attr.height,
scp->font_size - scp->curs_attr.base);
} else { /* block cursor */
scp->curs_attr.base = 0;
scp->curs_attr.height = scp->font_size;
}
/* assert(scp == scp->sc->cur_scp); */
++scp->sc->videoio_in_progress;
(*scp->rndr->set_cursor)(scp, scp->cursor_base, scp->cursor_height,
scp->sc->flags & SC_BLINK_CURSOR);
(*scp->rndr->set_cursor)(scp, scp->curs_attr.base, scp->curs_attr.height,
scp->curs_attr.flags & CONS_BLINK_CURSOR);
--scp->sc->videoio_in_progress;
}
static void
change_cursor_shape(scr_stat *scp, int flags, int base, int height)
{
if ((scp == scp->sc->cur_scp) && !ISGRAPHSC(scp))
sc_remove_cursor_image(scp);
if (base >= 0)
scp->curr_curs_attr.base = base;
if (height >= 0)
scp->curr_curs_attr.height = height;
if (flags & CONS_RESET_CURSOR)
scp->curr_curs_attr = scp->dflt_curs_attr;
else
scp->curr_curs_attr.flags = flags & CONS_CURSOR_ATTRS;
if ((scp == scp->sc->cur_scp) && !ISGRAPHSC(scp)) {
sc_set_cursor_image(scp);
sc_draw_cursor_image(scp);
}
}
void
sc_change_cursor_shape(scr_stat *scp, int flags, int base, int height)
{
sc_softc_t *sc;
dev_t dev;
int s;
int i;
s = spltty();
if ((flags != -1) && (flags & CONS_LOCAL_CURSOR)) {
/* local (per vty) change */
change_cursor_shape(scp, flags, base, height);
splx(s);
return;
}
/* global change */
sc = scp->sc;
if (base >= 0)
sc->curs_attr.base = base;
if (height >= 0)
sc->curs_attr.height = height;
if (flags != -1) {
if (flags & CONS_RESET_CURSOR)
sc->curs_attr = sc->dflt_curs_attr;
else
sc->curs_attr.flags = flags & CONS_CURSOR_ATTRS;
}
for (i = sc->first_vty; i < sc->first_vty + sc->vtys; ++i) {
if ((dev = SC_DEV(sc, i)) == NODEV)
continue;
if ((scp = SC_STAT(dev)) == NULL)
continue;
scp->dflt_curs_attr = sc->curs_attr;
change_cursor_shape(scp, CONS_RESET_CURSOR, -1, -1);
}
splx(s);
}
static void
scinit(int unit, int flags)
{
@ -2617,12 +2688,18 @@ scinit(int unit, int flags)
scp->xpos = col;
scp->ypos = row;
scp->cursor_pos = scp->cursor_oldpos = row*scp->xsize + col;
if (bios_value.cursor_end < scp->font_size)
sc->cursor_base = scp->font_size - bios_value.cursor_end - 1;
sc->dflt_curs_attr.base = scp->font_size -
bios_value.cursor_end - 1;
else
sc->cursor_base = 0;
sc->dflt_curs_attr.base = 0;
i = bios_value.cursor_end - bios_value.cursor_start + 1;
sc->cursor_height = imin(i, scp->font_size);
sc->dflt_curs_attr.height = imin(i, scp->font_size);
sc->dflt_curs_attr.flags = 0;
sc->curs_attr = sc->dflt_curs_attr;
scp->curr_curs_attr = scp->dflt_curs_attr = sc->curs_attr;
if (!ISGRAPHSC(scp)) {
sc_set_cursor_image(scp);
sc_draw_cursor_image(scp);
@ -2665,13 +2742,13 @@ scinit(int unit, int flags)
save_palette(sc->adp, sc->palette);
#endif
#if NSPLASH > 0
#ifdef DEV_SPLASH
if (!(sc->flags & SC_SPLASH_SCRN) && (flags & SC_KERNEL_CONSOLE)) {
/* we are ready to put up the splash image! */
splash_init(sc->adp, scsplash_callback, sc);
sc->flags |= SC_SPLASH_SCRN;
}
#endif /* NSPLASH */
#endif
}
/* the rest is not necessary, if we have done it once */
@ -2699,13 +2776,13 @@ scterm(int unit, int flags)
if (sc == NULL)
return; /* shouldn't happen */
#if NSPLASH > 0
#ifdef DEV_SPLASH
/* this console is no longer available for the splash screen */
if (sc->flags & SC_SPLASH_SCRN) {
splash_term(sc->adp);
sc->flags &= ~SC_SPLASH_SCRN;
}
#endif /* NSPLASH */
#endif
/* release the keyboard and the video card */
if (sc->keyboard >= 0)
@ -2757,16 +2834,16 @@ scshutdown(void *arg, int howto)
int
sc_clean_up(scr_stat *scp)
{
#if NSPLASH > 0
#ifdef DEV_SPLASH
int error;
#endif /* NSPLASH */
#endif
if (scp->sc->flags & SC_SCRN_BLANKED) {
sc_touch_scrn_saver();
#if NSPLASH > 0
#ifdef DEV_SPLASH
if ((error = wait_scrn_saver_stop(scp->sc)))
return error;
#endif /* NSPLASH */
#endif
}
scp->status &= ~MOUSE_VISIBLE;
sc_remove_cutmarking(scp);
@ -2884,8 +2961,7 @@ init_scp(sc_softc_t *sc, int vty, scr_stat *scp)
scp->ts = NULL;
scp->rndr = NULL;
scp->border = BG_BLACK;
scp->cursor_base = sc->cursor_base;
scp->cursor_height = imin(sc->cursor_height, scp->font_size);
scp->curr_curs_attr = scp->dflt_curs_attr = sc->curs_attr;
scp->mouse_xpos = scp->xoff*8 + scp->xsize*8/2;
scp->mouse_ypos = (scp->ysize + scp->yoff)*scp->font_size/2;
scp->mouse_cut_start = scp->xsize*scp->ysize;
@ -3112,6 +3188,12 @@ scgetc(sc_softc_t *sc, u_int flags)
}
break;
case PASTE:
#ifndef SC_NO_CUTPASTE
sc_mouse_paste(scp);
#endif
break;
/* NON-LOCKING KEYS */
case NOP:
case LSH: case RSH: case LCTR: case RCTR:
@ -3124,7 +3206,7 @@ scgetc(sc_softc_t *sc, u_int flags)
break;
case SPSC:
#if NSPLASH > 0
#ifdef DEV_SPLASH
/* force activatation/deactivation of the screen saver */
if (!(sc->flags & SC_SCRN_BLANKED)) {
run_scrn_saver = TRUE;
@ -3145,7 +3227,7 @@ scgetc(sc_softc_t *sc, u_int flags)
}
}
}
#endif /* NSPLASH */
#endif /* DEV_SPLASH */
break;
case RBT: