diff options
author | yokota <yokota@FreeBSD.org> | 1998-08-03 11:30:45 +0000 |
---|---|---|
committer | yokota <yokota@FreeBSD.org> | 1998-08-03 11:30:45 +0000 |
commit | 506dee0328f0c5179f765cc7a550341382b5d3cb (patch) | |
tree | 0726b4c71f01cb1337f1932ed61e8be8af9ab61f | |
parent | ef6d9fe5f09518eb0c43f6e464e0b0775432d278 (diff) | |
download | FreeBSD-src-506dee0328f0c5179f765cc7a550341382b5d3cb.zip FreeBSD-src-506dee0328f0c5179f765cc7a550341382b5d3cb.tar.gz |
1. Reorganized screen saver related code so that both the LKM screen
saver and splash screen can all work properly with syscons. Note that
the splash screen option (SC_SPLASH_SCREEN) does not work yet, as it
requires additional code from msmith.
- Reorganized the splash screen code to match the latest development
in this area.
- Delay screen switch in `switch_scr()' until the screen saver is
stopped, if one is running,
- Start the screen saver immediately, if any, when the `saver' key is
pressed. (There will be another commit for `kbdcontrol' to support
this keyword in the keymap file.)
- Do not always stop the screen saver when mouse-related ioctls
are called. Stop it only if the mouse is moved or buttons are
clicked; don't stop it if any other mouse ioctls are called.
2. Added provision to write userland screen savers. (Contact me if you
are interested in writing one.)
- Added CONS_IDLE, CONS_SAVERMODE, and CONS_SAVERSTART ioctls to
support userland screen savers.
3. Some code clean-ups.
-rw-r--r-- | sys/alpha/include/console.h | 12 | ||||
-rw-r--r-- | sys/dev/syscons/syscons.c | 431 | ||||
-rw-r--r-- | sys/dev/syscons/syscons.h | 15 | ||||
-rw-r--r-- | sys/i386/include/console.h | 12 | ||||
-rw-r--r-- | sys/i386/isa/syscons.c | 431 | ||||
-rw-r--r-- | sys/i386/isa/syscons.h | 15 | ||||
-rw-r--r-- | sys/isa/syscons.c | 431 | ||||
-rw-r--r-- | sys/isa/syscons.h | 15 |
8 files changed, 920 insertions, 442 deletions
diff --git a/sys/alpha/include/console.h b/sys/alpha/include/console.h index 9406441..7503746 100644 --- a/sys/alpha/include/console.h +++ b/sys/alpha/include/console.h @@ -25,7 +25,7 @@ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * - * $Id: console.h,v 1.36 1998/02/12 20:47:39 phk Exp $ + * $Id: console.h,v 1.37 1998/07/06 06:29:06 imp Exp $ */ #ifndef _MACHINE_CONSOLE_H_ @@ -73,6 +73,9 @@ #define CONS_BELLTYPE _IOW('c', 8, int) #define CONS_HISTORY _IOW('c', 9, int) #define CONS_MOUSECTL _IOWR('c', 10, mouse_info_t) +#define CONS_IDLE _IOR('c', 11, int) +#define CONS_SAVERMODE _IOW('c', 12, int) +#define CONS_SAVERSTART _IOW('c', 13, int) #define PIO_FONT8x8 _IOW('c', 64, fnt8_t) #define GIO_FONT8x8 _IOR('c', 65, fnt8_t) #define PIO_FONT8x14 _IOW('c', 66, fnt14_t) @@ -82,6 +85,10 @@ #define CONS_GETINFO _IOWR('c', 73, vid_info_t) #define CONS_GETVERS _IOR('c', 74, int) +/* CONS_SAVERMODE */ +#define CONS_LKM_SAVER 0 +#define CONS_USR_SAVER 1 + #ifdef PC98 #define ADJUST_CLOCK _IO('t',100) /* for 98note resume */ #endif @@ -157,7 +164,6 @@ struct mouse_info { #define KD_EGA 4 /* enhanced graphics adapter */ #define KD_VGA 5 /* video graphics adapter */ #define KD_PC98 6 /* PC-98 display */ -#define KD_PIXEL 7 /* Pixel based display */ #define KD_TEXT 0 /* set text mode restore fonts */ #define KD_TEXT0 0 /* ditto */ @@ -372,6 +378,8 @@ typedef struct ssaver ssaver_t; #define M_HGC_P1 0xe1 /* hercules graphics - page 1 @ B8000 */ #define M_MCA_MODE 0xff /* monochrome adapter mode */ +#define M_VESA_BASE 0x100 /* VESA mode number base */ + #define SW_PC98_80x25 _IO('S', M_PC98_80x25) #define SW_PC98_80x30 _IO('S', M_PC98_80x30) #define SW_B40x25 _IO('S', M_B40x25) diff --git a/sys/dev/syscons/syscons.c b/sys/dev/syscons/syscons.c index 25c0aa4..bb68f7f 100644 --- a/sys/dev/syscons/syscons.c +++ b/sys/dev/syscons/syscons.c @@ -25,7 +25,7 @@ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * - * $Id: syscons.c,v 1.270 1998/08/03 09:17:06 yokota Exp $ + * $Id: syscons.c,v 1.271 1998/08/03 09:18:58 yokota Exp $ */ #include "sc.h" @@ -37,6 +37,7 @@ #if NSC > 0 #include <sys/param.h> #include <sys/systm.h> +#include <sys/reboot.h> #include <sys/conf.h> #include <sys/proc.h> #include <sys/signalvar.h> @@ -47,6 +48,7 @@ #include <sys/devfsext.h> #endif +#include <machine/bootinfo.h> #include <machine/clock.h> #include <machine/cons.h> #include <machine/console.h> @@ -94,9 +96,12 @@ #define COLD 0 #define WARM 1 +#define VESA_MODE(x) ((x) >= M_VESA_BASE) + #define MODE_MAP_SIZE (M_VGA_CG320 + 1) #define MODE_PARAM_SIZE 64 +#define DEFAULT_BLANKTIME (5*60) /* 5 minutes */ #define MAX_BLANKTIME (7*24*60*60) /* 7 days!? */ /* for backward compatibility */ @@ -162,11 +167,14 @@ static const u_int n_fkey_tab = sizeof(fkey_tab) / sizeof(*fkey_tab); static int delayed_next_scr = FALSE; static long scrn_blank_time = 0; /* screen saver timeout value */ int scrn_blanked = 0; /* screen saver active flag */ -static struct timeval scrn_time_stamp; +static long scrn_time_stamp; +static int saver_mode = CONS_LKM_SAVER; /* LKM/user saver */ +static int run_scrn_saver = FALSE; /* should run the saver? */ +static int scrn_idle = FALSE; /* about to run the saver */ u_char scr_map[256]; u_char scr_rmap[256]; char *video_mode_ptr = NULL; -static int vesa_mode; +static int bios_video_mode; /* video mode # set by BIOS */ int fonts_loaded = 0 #ifdef STD8X16FONT | FONT_16 @@ -206,9 +214,12 @@ static int extra_history_size = static void none_saver(int blank) { } static void (*current_saver)(int blank) = none_saver; +static void (*default_saver)(int blank) = none_saver; int (*sc_user_ioctl)(dev_t dev, int cmd, caddr_t data, int flag, struct proc *p) = NULL; +static int sticky_splash = FALSE; + /* OS specific stuff */ #ifdef not_yet_done #define VIRTUAL_TTY(x) (sccons[x] = ttymalloc(sccons[x])) @@ -247,8 +258,8 @@ static void scmousestart(struct tty *tp); static void scinit(void); static void scshutdown(int howto, void *arg); static void map_mode_table(char *map[], char *table, int max); -static u_char map_mode_num(u_char mode); -static char *get_mode_param(scr_stat *scp, u_char mode); +static int map_mode_num(int mode); +static char *get_mode_param(scr_stat *scp, int mode); static u_int scgetc(u_int flags); #define SCGETC_CN 1 #define SCGETC_NONBLOCK 2 @@ -256,7 +267,7 @@ static void sccnupdate(scr_stat *scp); static scr_stat *get_scr_stat(dev_t dev); static scr_stat *alloc_scp(void); static void init_scp(scr_stat *scp); -static void sc_bcopy(u_short *p, int from, int to, int mark); +static void sc_bcopy(scr_stat *scp, u_short *p, int from, int to, int mark); static int get_scr_num(void); static timeout_t scrn_timer; static void scrn_update(scr_stat *scp, int show_cursor); @@ -306,7 +317,11 @@ static void save_palette(void); static void do_bell(scr_stat *scp, int pitch, int duration); static timeout_t blink_screen; #ifdef SC_SPLASH_SCREEN -static void toggle_splash_screen(scr_stat *scp); +static void scsplash_init(void); +static void scsplash(int show); +#define scsplash_stick(stick) (sticky_splash = (stick)) +#else +#define scsplash_stick(stick) #endif struct isa_driver scdriver = { @@ -336,8 +351,8 @@ draw_cursor_image(scr_stat *scp) u_short cursor_image, *ptr = Crtat + (scp->cursor_pos - scp->scr_buf); u_short prev_image; - if (vesa_mode) { - sc_bcopy(scp->scr_buf, scp->cursor_pos - scp->scr_buf, + if (VESA_MODE(scp->mode)) { + sc_bcopy(scp, scp->scr_buf, scp->cursor_pos - scp->scr_buf, scp->cursor_pos - scp->scr_buf, 1); return; } @@ -388,8 +403,8 @@ draw_cursor_image(scr_stat *scp) static void remove_cursor_image(scr_stat *scp) { - if (vesa_mode) - sc_bcopy(scp->scr_buf, scp->cursor_oldpos - scp->scr_buf, + if (VESA_MODE(scp->mode)) + sc_bcopy(scp, scp->scr_buf, scp->cursor_oldpos - scp->scr_buf, scp->cursor_oldpos - scp->scr_buf, 0); else *(Crtat + (scp->cursor_oldpos - scp->scr_buf)) = scp->cursor_saveunder; @@ -455,10 +470,12 @@ scvidprobe(int unit, int flags) cp = (u_short *)CGA_BUF; was = *cp; *cp = (u_short) 0xA55A; + bios_video_mode = *(u_char *)pa_to_va(0x449); if (bootinfo.bi_vesa == 0x102) { - vesa_mode = bootinfo.bi_vesa; + bios_video_mode = bootinfo.bi_vesa; Crtat = (u_short *)pa_to_va(0xA0000); - crtc_type = KD_PIXEL; + crtc_addr = COLOR_BASE; + crtc_type = KD_VGA; bzero(Crtat, 800*600/8); } else if (*cp == 0xA55A) { Crtat = (u_short *)CGA_BUF; @@ -476,7 +493,7 @@ scvidprobe(int unit, int flags) } *cp = was; - if (crtc_type != KD_PIXEL) { + if (!VESA_MODE(bios_video_mode)) { /* * Check rtc and BIOS date area. * XXX: don't use BIOSDATA_EQUIPMENT, it is not a dead copy @@ -717,12 +734,12 @@ scattach(struct isa_device *dev) scinit(); flags = dev->id_flags; - if (!crtc_vga) + if (crtc_type != KD_VGA || VESA_MODE(bios_video_mode)) flags &= ~CHAR_CURSOR; scp = console[0]; - if (crtc_vga) { + if (crtc_type == KD_VGA) { cut_buffer_size = scp->xsize * scp->ysize + 1; cut_buffer = (char *)malloc(cut_buffer_size, M_DEVBUF, M_NOWAIT); if (cut_buffer != NULL) @@ -754,13 +771,12 @@ scattach(struct isa_device *dev) draw_cursor_image(scp); /* get screen update going */ - scrn_timer(NULL); + scrn_timer((void *)TRUE); update_leds(scp->status); if ((crtc_type == KD_VGA) && bootverbose) { - printf("sc%d: BIOS video mode:%d\n", - dev->id_unit, *(u_char *)pa_to_va(0x449)); + printf("sc%d: BIOS video mode:%d\n", dev->id_unit, bios_video_mode); printf("sc%d: VGA registers upon power-up\n", dev->id_unit); dump_vgaregs(vgaregs); printf("sc%d: video mode:%d\n", dev->id_unit, scp->mode); @@ -775,14 +791,17 @@ scattach(struct isa_device *dev) } printf("sc%d: rows_offset:%d\n", dev->id_unit, rows_offset); } - if ((crtc_type == KD_VGA) && (video_mode_ptr == NULL)) + if ((crtc_type == KD_VGA) && !VESA_MODE(bios_video_mode) + && (video_mode_ptr == NULL)) printf("sc%d: WARNING: video mode switching is only partially supported\n", dev->id_unit); printf("sc%d: ", dev->id_unit); switch(crtc_type) { case KD_VGA: - if (crtc_addr == MONO_BASE) + if (VESA_MODE(bios_video_mode)) + printf("Graphics display (VESA mode = 0x%x)", bios_video_mode); + else if (crtc_addr == MONO_BASE) printf("VGA mono"); else printf("VGA color"); @@ -796,9 +815,6 @@ scattach(struct isa_device *dev) case KD_CGA: printf("CGA"); break; - case KD_PIXEL: - printf("Graphics display (VESA mode = 0x%x)", vesa_mode); - break; case KD_MONO: case KD_HERCULES: default: @@ -1053,9 +1069,10 @@ scioctl(dev_t dev, u_long cmd, caddr_t data, int flag, struct proc *p) case CONS_BLANKTIME: /* set screen saver timeout (0 = no saver) */ if (*(int *)data < 0 || *(int *)data > MAX_BLANKTIME) return EINVAL; + s = spltty(); scrn_blank_time = *(int *)data; - if (scrn_blank_time == 0) - getmicrouptime(&scrn_time_stamp); + run_scrn_saver = (scrn_blank_time != 0); + splx(s); return 0; case CONS_CURSORTYPE: /* set cursor type blink/noblink */ @@ -1064,7 +1081,7 @@ scioctl(dev_t dev, u_long cmd, caddr_t data, int flag, struct proc *p) else flags &= ~BLINK_CURSOR; if ((*(int*)data) & 0x02) { - if (!crtc_vga) + if (crtc_type != KD_VGA || VESA_MODE(bios_video_mode)) return ENXIO; flags |= CHAR_CURSOR; } else @@ -1154,7 +1171,7 @@ scioctl(dev_t dev, u_long cmd, caddr_t data, int flag, struct proc *p) mouse_info_t *mouse = (mouse_info_t*)data; mouse_info_t buf; - if (!crtc_vga) + if (crtc_type != KD_VGA || VESA_MODE(bios_video_mode)) return ENODEV; if (cmd == OLD_CONS_MOUSECTL) { @@ -1200,13 +1217,14 @@ scioctl(dev_t dev, u_long cmd, caddr_t data, int flag, struct proc *p) scp->mouse_proc = NULL; scp->mouse_pid = 0; } - break; + return 0; case MOUSE_SHOW: if (!(scp->status & MOUSE_ENABLED)) { scp->status |= (MOUSE_ENABLED | MOUSE_VISIBLE); scp->mouse_oldpos = scp->mouse_pos; mark_all(scp); + return 0; } else return EINVAL; @@ -1216,6 +1234,7 @@ scioctl(dev_t dev, u_long cmd, caddr_t data, int flag, struct proc *p) if (scp->status & MOUSE_ENABLED) { scp->status &= ~(MOUSE_ENABLED | MOUSE_VISIBLE); mark_all(scp); + return 0; } else return EINVAL; @@ -1238,7 +1257,7 @@ scioctl(dev_t dev, u_long cmd, caddr_t data, int flag, struct proc *p) mouse->u.data.y = scp->mouse_ypos; mouse->u.data.z = 0; mouse->u.data.buttons = scp->mouse_buttons; - break; + return 0; case MOUSE_ACTION: case MOUSE_MOTION_EVENT: @@ -1254,6 +1273,8 @@ scioctl(dev_t dev, u_long cmd, caddr_t data, int flag, struct proc *p) ((mouse->u.data.x || mouse->u.data.y || mouse->u.data.z) ? MOUSE_POSCHANGED : 0) | (mouse_status.obutton ^ mouse_status.button); + if (mouse_status.flags == 0) + return 0; if (cur_console->status & MOUSE_ENABLED) cur_console->status |= MOUSE_VISIBLE; @@ -1334,6 +1355,8 @@ scioctl(dev_t dev, u_long cmd, caddr_t data, int flag, struct proc *p) mouse_status.button &= ~mouse->u.event.id; } mouse_status.flags |= mouse_status.obutton ^ mouse_status.button; + if (mouse_status.flags == 0) + return 0; if (cur_console->status & MOUSE_ENABLED) cur_console->status |= MOUSE_VISIBLE; @@ -1411,7 +1434,8 @@ scioctl(dev_t dev, u_long cmd, caddr_t data, int flag, struct proc *p) return EINVAL; } /* make screensaver happy */ - getmicrouptime(&scrn_time_stamp); + scsplash_stick(FALSE); + run_scrn_saver = FALSE; return 0; } @@ -1542,6 +1566,37 @@ scioctl(dev_t dev, u_long cmd, caddr_t data, int flag, struct proc *p) *(int*)data = 0x200; /* version 2.0 */ return 0; + case CONS_IDLE: /* see if the screen has been idle */ + *(int *)data = (scrn_idle && !(cur_console->status & UNKNOWN_MODE)); + return 0; + + case CONS_SAVERMODE: /* set saver mode */ + switch(*(int *)data) { + case CONS_USR_SAVER: + /* if a LKM screen saver is running, it will eventually stop... */ + saver_mode = *(int *)data; + scsplash_stick(TRUE); + break; + case CONS_LKM_SAVER: + saver_mode = *(int *)data; + break; + default: + return EINVAL; + } + return 0; + + case CONS_SAVERSTART: /* immediately start/stop the screen saver */ + /* + * Note that this ioctl does not guarantee the screen saver + * actually starts or stops. It merely attempts to do so... + */ + s = spltty(); + run_scrn_saver = (*(int *)data != 0); + if (run_scrn_saver) + scrn_time_stamp -= scrn_blank_time; + splx(s); + return 0; + /* VGA TEXT MODES */ case SW_VGA_C40x25: case SW_VGA_C80x25: case SW_VGA_M80x25: @@ -1555,7 +1610,7 @@ scioctl(dev_t dev, u_long cmd, caddr_t data, int flag, struct proc *p) case SW_ENH_B80x43: case SW_ENH_C80x43: case SW_EGAMONO80x25: - if (!crtc_vga) + if (crtc_type != KD_VGA) return ENODEV; mp = get_mode_param(scp, cmd & 0xff); if (mp == NULL) @@ -1693,7 +1748,7 @@ scioctl(dev_t dev, u_long cmd, caddr_t data, int flag, struct proc *p) case SW_CG640x350: case SW_ENH_CG640: case SW_BG640x480: case SW_CG640x480: case SW_VGA_CG320: - if (!crtc_vga) + if (crtc_type != KD_VGA) return ENODEV; mp = get_mode_param(scp, cmd & 0xff); if (mp == NULL) @@ -1730,7 +1785,7 @@ scioctl(dev_t dev, u_long cmd, caddr_t data, int flag, struct proc *p) return 0; case SW_VGA_MODEX: - if (!crtc_vga) + if (crtc_type != KD_VGA) return ENODEV; mp = get_mode_param(scp, cmd & 0xff); if (mp == NULL) @@ -1869,19 +1924,21 @@ scioctl(dev_t dev, u_long cmd, caddr_t data, int flag, struct proc *p) switch (*data) { case KD_TEXT: /* switch to TEXT (known) mode */ /* restore fonts & palette ! */ - if (crtc_vga) { + if (crtc_type == KD_VGA) { + if (!VESA_MODE(scp->mode)) { #if 0 - /* - * FONT KLUDGE - * Don't load fonts for now... XXX - */ - if (fonts_loaded & FONT_8) - copy_font(LOAD, FONT_8, font_8); - if (fonts_loaded & FONT_14) - copy_font(LOAD, FONT_14, font_14); - if (fonts_loaded & FONT_16) - copy_font(LOAD, FONT_16, font_16); + /* + * FONT KLUDGE + * Don't load fonts for now... XXX + */ + if (fonts_loaded & FONT_8) + copy_font(LOAD, FONT_8, font_8); + if (fonts_loaded & FONT_14) + copy_font(LOAD, FONT_14, font_14); + if (fonts_loaded & FONT_16) + copy_font(LOAD, FONT_16, font_16); #endif + } load_palette(palette); } @@ -1904,7 +1961,7 @@ scioctl(dev_t dev, u_long cmd, caddr_t data, int flag, struct proc *p) scp->status |= UNKNOWN_MODE; splx(s); /* no restore fonts & palette */ - if (crtc_vga) + if (crtc_type == KD_VGA) set_mode(scp); scp->status &= ~UNKNOWN_MODE; clear_screen(scp); @@ -2086,7 +2143,7 @@ scioctl(dev_t dev, u_long cmd, caddr_t data, int flag, struct proc *p) return 0; case PIO_FONT8x8: /* set 8x8 dot font */ - if (!crtc_vga) + if (crtc_type != KD_VGA) return ENXIO; bcopy(data, font_8, 8*256); fonts_loaded |= FONT_8; @@ -2095,7 +2152,8 @@ scioctl(dev_t dev, u_long cmd, caddr_t data, int flag, struct proc *p) * Always use the font page #0. XXX * Don't load if the current font size is not 8x8. */ - if (!(cur_console->status & UNKNOWN_MODE) + if (!VESA_MODE(cur_console->mode) + && !(cur_console->status & UNKNOWN_MODE) && (cur_console->font_size < 14)) { copy_font(LOAD, FONT_8, font_8); if (flags & CHAR_CURSOR) @@ -2104,7 +2162,7 @@ scioctl(dev_t dev, u_long cmd, caddr_t data, int flag, struct proc *p) return 0; case GIO_FONT8x8: /* get 8x8 dot font */ - if (!crtc_vga) + if (crtc_type != KD_VGA) return ENXIO; if (fonts_loaded & FONT_8) { bcopy(font_8, data, 8*256); @@ -2114,7 +2172,7 @@ scioctl(dev_t dev, u_long cmd, caddr_t data, int flag, struct proc *p) return ENXIO; case PIO_FONT8x14: /* set 8x14 dot font */ - if (!crtc_vga) + if (crtc_type != KD_VGA) return ENXIO; bcopy(data, font_14, 14*256); fonts_loaded |= FONT_14; @@ -2123,7 +2181,8 @@ scioctl(dev_t dev, u_long cmd, caddr_t data, int flag, struct proc *p) * Always use the font page #0. XXX * Don't load if the current font size is not 8x14. */ - if (!(cur_console->status & UNKNOWN_MODE) + if (!VESA_MODE(cur_console->mode) + && !(cur_console->status & UNKNOWN_MODE) && (cur_console->font_size >= 14) && (cur_console->font_size < 16)) { copy_font(LOAD, FONT_14, font_14); if (flags & CHAR_CURSOR) @@ -2132,7 +2191,7 @@ scioctl(dev_t dev, u_long cmd, caddr_t data, int flag, struct proc *p) return 0; case GIO_FONT8x14: /* get 8x14 dot font */ - if (!crtc_vga) + if (crtc_type != KD_VGA) return ENXIO; if (fonts_loaded & FONT_14) { bcopy(font_14, data, 14*256); @@ -2142,7 +2201,7 @@ scioctl(dev_t dev, u_long cmd, caddr_t data, int flag, struct proc *p) return ENXIO; case PIO_FONT8x16: /* set 8x16 dot font */ - if (!crtc_vga && crtc_type != KD_PIXEL) + if (crtc_type != KD_VGA) return ENXIO; bcopy(data, font_16, 16*256); fonts_loaded |= FONT_16; @@ -2151,7 +2210,8 @@ scioctl(dev_t dev, u_long cmd, caddr_t data, int flag, struct proc *p) * Always use the font page #0. XXX * Don't load if the current font size is not 8x16. */ - if (crtc_vga && !(cur_console->status & UNKNOWN_MODE) + if (!VESA_MODE(cur_console->mode) + && !(cur_console->status & UNKNOWN_MODE) && (cur_console->font_size >= 16)) { copy_font(LOAD, FONT_16, font_16); if (flags & CHAR_CURSOR) @@ -2160,7 +2220,7 @@ scioctl(dev_t dev, u_long cmd, caddr_t data, int flag, struct proc *p) return 0; case GIO_FONT8x16: /* get 8x16 dot font */ - if (!crtc_vga && crtc_type != KD_PIXEL) + if (crtc_type != KD_VGA) return ENXIO; if (fonts_loaded & FONT_16) { bcopy(font_16, data, 16*256); @@ -2292,6 +2352,8 @@ sccngetc(dev_t dev) * Stop the screen saver and update the screen if necessary. * What if we have been running in the screen saver code... XXX */ + scsplash_stick(FALSE); + run_scrn_saver = FALSE; sccnupdate(cur_console); c = scgetc(SCGETC_CN); @@ -2305,7 +2367,10 @@ sccncheckc(dev_t dev) int s = spltty(); /* block scintr and scrn_timer while we poll */ int c; + scsplash_stick(FALSE); + run_scrn_saver = FALSE; sccnupdate(cur_console); + c = scgetc(SCGETC_CN | SCGETC_NONBLOCK); splx(s); return(c == NOKEY ? -1 : c); /* c == -1 can't happen */ @@ -2314,13 +2379,26 @@ sccncheckc(dev_t dev) static void sccnupdate(scr_stat *scp) { - if (scp == cur_console && !font_loading_in_progress) { + /* this is a cut-down version of scrn_timer()... */ + + if (font_loading_in_progress) + return; + + if (panicstr) { + scsplash_stick(FALSE); + run_scrn_saver = FALSE; + } + if (!run_scrn_saver) + scrn_idle = FALSE; + if ((saver_mode != CONS_LKM_SAVER) || !scrn_idle) if (scrn_blanked > 0) stop_scrn_saver(current_saver); - if (!(scp->status & UNKNOWN_MODE) && scrn_blanked <= 0 - && !blink_in_progress && !switch_in_progress) - scrn_update(scp, TRUE); - } + + if (scp != cur_console || blink_in_progress || switch_in_progress) + return; + + if ((scp->status & UNKNOWN_MODE) == 0 && scrn_blanked <= 0) + scrn_update(scp, TRUE); } static scr_stat @@ -2349,12 +2427,13 @@ static void scrn_timer(void *arg) { struct timeval tv; - scr_stat *scp = cur_console; + scr_stat *scp; int s; /* don't do anything when we are touching font */ if (font_loading_in_progress) { - timeout(scrn_timer, NULL, hz / 10); + if (arg) + timeout(scrn_timer, (void *)TRUE, hz / 10); return; } s = spltty(); @@ -2384,30 +2463,42 @@ scrn_timer(void *arg) /* should we stop the screen saver? */ getmicrouptime(&tv); - if (panicstr || shutdown_in_progress) - scrn_time_stamp = tv; - if (tv.tv_sec <= scrn_time_stamp.tv_sec + scrn_blank_time) + if (panicstr || shutdown_in_progress) { + scsplash_stick(FALSE); + run_scrn_saver = FALSE; + } + if (run_scrn_saver) { + scrn_idle = (tv.tv_sec > scrn_time_stamp + scrn_blank_time); + } else { + scrn_time_stamp = tv.tv_sec; + scrn_idle = FALSE; + if (scrn_blank_time > 0) + run_scrn_saver = TRUE; + } + if ((saver_mode != CONS_LKM_SAVER) || !scrn_idle) if (scrn_blanked > 0) stop_scrn_saver(current_saver); /* should we just return ? */ - if ((scp->status&UNKNOWN_MODE) || blink_in_progress || switch_in_progress) { - timeout(scrn_timer, NULL, hz / 10); + if (blink_in_progress || switch_in_progress) { + if (arg) + timeout(scrn_timer, (void *)TRUE, hz / 10); splx(s); return; } /* Update the screen */ scp = cur_console; - if (scrn_blanked <= 0) + if ((scp->status & UNKNOWN_MODE) == 0 && scrn_blanked <= 0) scrn_update(scp, TRUE); /* should we activate the screen saver? */ - if ((scrn_blank_time != 0) - && (tv.tv_sec > scrn_time_stamp.tv_sec + scrn_blank_time)) - (*current_saver)(TRUE); + if ((saver_mode == CONS_LKM_SAVER) && scrn_idle) + if ((scp->status & UNKNOWN_MODE) == 0 || scrn_blanked > 0) + (*current_saver)(TRUE); - timeout(scrn_timer, NULL, hz / 25); + if (arg) + timeout(scrn_timer, (void *)TRUE, hz / 25); splx(s); } @@ -2416,7 +2507,7 @@ scrn_update(scr_stat *scp, int show_cursor) { /* update screen image */ if (scp->start <= scp->end) - sc_bcopy(scp->scr_buf, scp->start, scp->end, 0); + sc_bcopy(scp, scp->scr_buf, scp->start, scp->end, 0); /* we are not to show the cursor and the mouse pointer... */ if (!show_cursor) { @@ -2483,9 +2574,18 @@ scrn_update(scr_stat *scp, int show_cursor) int add_scrn_saver(void (*this_saver)(int)) { - if (current_saver != none_saver) +#ifdef SC_SPLASH_SCREEN + if (current_saver == scsplash) { + scsplash_stick(FALSE); + stop_scrn_saver(scsplash); + } +#endif + + if (current_saver != default_saver) return EBUSY; current_saver = this_saver; + saver_mode = CONS_LKM_SAVER; + run_scrn_saver = (scrn_blank_time > 0); return 0; } @@ -2505,6 +2605,10 @@ remove_scrn_saver(void (*this_saver)(int)) if (scrn_blanked > 0) stop_scrn_saver(this_saver); + if (scrn_blanked > 0) + return EBUSY; /* XXX */ + + current_saver = default_saver; return 0; } @@ -2512,8 +2616,14 @@ static void stop_scrn_saver(void (*saver)(int)) { (*saver)(FALSE); - getmicrouptime(&scrn_time_stamp); + run_scrn_saver = FALSE; + /* the screen saver may have chosen not to stop after all... */ + if (scrn_blanked > 0) + return; + mark_all(cur_console); + if (delayed_next_scr) + switch_scr(cur_console, delayed_next_scr - 1); wakeup((caddr_t)&scrn_blanked); } @@ -2522,10 +2632,10 @@ wait_scrn_saver_stop(void) { int error = 0; - getmicrouptime(&scrn_time_stamp); + run_scrn_saver = FALSE; while (scrn_blanked > 0) { error = tsleep((caddr_t)&scrn_blanked, PZERO | PCATCH, "scrsav", 0); - getmicrouptime(&scrn_time_stamp); + run_scrn_saver = FALSE; if (error != ERESTART) break; } @@ -2546,6 +2656,14 @@ clear_screen(scr_stat *scp) static int switch_scr(scr_stat *scp, u_int next_scr) { + /* delay switch if actively updating screen */ + if (scrn_blanked > 0 || write_in_progress || blink_in_progress) { + scsplash_stick(FALSE); + run_scrn_saver = FALSE; + delayed_next_scr = next_scr+1; + return 0; + } + if (switch_in_progress && (cur_console->proc != pfind(cur_console->pid))) switch_in_progress = FALSE; @@ -2565,16 +2683,6 @@ switch_scr(scr_stat *scp, u_int next_scr) } } - /* delay switch if actively updating screen */ - if (write_in_progress || blink_in_progress) { - delayed_next_scr = next_scr+1; - return 0; - } - - /* Stop the screensaver */ - if (scrn_blanked > 0) - stop_scrn_saver(current_saver); - switch_in_progress = TRUE; old_scp = cur_console; new_scp = console[next_scr]; @@ -2614,13 +2722,13 @@ exchange_scr(void) move_crsr(old_scp, old_scp->xpos, old_scp->ypos); cur_console = new_scp; if (old_scp->mode != new_scp->mode || (old_scp->status & UNKNOWN_MODE)){ - if (crtc_vga) + if (crtc_type == KD_VGA) set_mode(new_scp); } move_crsr(new_scp, new_scp->xpos, new_scp->ypos); if (!(new_scp->status & UNKNOWN_MODE) && (flags & CHAR_CURSOR)) set_destructive_cursor(new_scp); - if ((old_scp->status & UNKNOWN_MODE) && crtc_vga) + if ((old_scp->status & UNKNOWN_MODE) && crtc_type == KD_VGA) load_palette(palette); if (old_scp->status & KBD_RAW_MODE || new_scp->status & KBD_RAW_MODE || old_scp->status & KBD_CODE_MODE || new_scp->status & KBD_CODE_MODE) @@ -2629,7 +2737,7 @@ exchange_scr(void) update_leds(new_scp->status); delayed_next_scr = FALSE; mark_all(new_scp); - if (vesa_mode == 0x102) { + if (new_scp->mode == 0x102) { bzero(Crtat, 800*600/8); } } @@ -3101,7 +3209,8 @@ scan_esc(scr_stat *scp, u_char c) flags |= BLINK_CURSOR; else flags &= ~BLINK_CURSOR; - if ((scp->term.param[0] & 0x02) && crtc_vga) + if ((scp->term.param[0] & 0x02) && + crtc_type == KD_VGA && !VESA_MODE(bios_video_mode)) flags |= CHAR_CURSOR; else flags &= ~CHAR_CURSOR; @@ -3116,7 +3225,7 @@ scan_esc(scr_stat *scp, u_char c) */ if (!(cur_console->status & UNKNOWN_MODE)) { remove_cursor_image(cur_console); - if (crtc_vga && (flags & CHAR_CURSOR)) + if (crtc_type == KD_VGA && (flags & CHAR_CURSOR)) set_destructive_cursor(cur_console); draw_cursor_image(cur_console); } @@ -3184,8 +3293,8 @@ ansi_put(scr_stat *scp, u_char *buf, int len) u_char *ptr = buf; /* make screensaver happy */ - if (scp == cur_console) - getmicrouptime(&scrn_time_stamp); + if (!sticky_splash && scp == cur_console) + run_scrn_saver = FALSE; write_in_progress++; outloop: @@ -3382,7 +3491,7 @@ scinit(void) } /* copy screen to temporary buffer */ - if (crtc_type != KD_PIXEL) + if (!VESA_MODE(console[0]->mode)) generic_bcopy(Crtat, sc_buffer, console[0]->xsize * console[0]->ysize * sizeof(u_short)); @@ -3407,30 +3516,35 @@ scinit(void) } /* Save font and palette if VGA */ - if (crtc_vga) { - if (fonts_loaded & FONT_16) { + if (crtc_type == KD_VGA) { + if (!VESA_MODE(bios_video_mode)) { + if (fonts_loaded & FONT_16) { copy_font(LOAD, FONT_16, font_16); - } else { + } else { copy_font(SAVE, FONT_16, font_16); fonts_loaded = FONT_16; + } + set_destructive_cursor(console[0]); } save_palette(); - set_destructive_cursor(console[0]); } #ifdef SC_SPLASH_SCREEN /* - * Now put up a graphics image, and maybe cycle a - * couble of palette entries for simple animation. + * If not booting verbosely, put up the splash. + * Note that the splash screen is not currently supported in + * the VESA mode. */ - toggle_splash_screen(cur_console); + if (!(boothowto & RB_VERBOSE) && !VESA_MODE(bios_video_mode)) + scsplash_init(); #endif } static void scshutdown(int howto, void *arg) { - getmicrouptime(&scrn_time_stamp); + scsplash_stick(FALSE); + run_scrn_saver = FALSE; if (!cold && cur_console->smode.mode == VT_AUTO && console[0]->smode.mode == VT_AUTO) switch_scr(cur_console, 0); @@ -3448,12 +3562,12 @@ map_mode_table(char *map[], char *table, int max) map[i] = NULL; } -static u_char -map_mode_num(u_char mode) +static int +map_mode_num(int mode) { static struct { - u_char from; - u_char to; + int from; + int to; } mode_map[] = { { M_ENH_B80x43, M_ENH_B80x25 }, { M_ENH_C80x43, M_ENH_C80x25 }, @@ -3475,7 +3589,7 @@ map_mode_num(u_char mode) } static char -*get_mode_param(scr_stat *scp, u_char mode) +*get_mode_param(scr_stat *scp, int mode) { if (mode >= MODE_MAP_SIZE) mode = map_mode_num(mode); @@ -3504,7 +3618,7 @@ static scr_stat bzero(scp->history_head, scp->history_size*sizeof(u_short)); scp->history = scp->history_head; /* SOS - if (crtc_vga && video_mode_ptr) + if (crtc_type == KD_VGA && video_mode_ptr) set_mode(scp); */ clear_screen(scp); @@ -3517,7 +3631,9 @@ init_scp(scr_stat *scp) { switch(crtc_type) { case KD_VGA: - if (crtc_addr == MONO_BASE) + if (VESA_MODE(bios_video_mode)) + scp->mode = bios_video_mode; + else if (crtc_addr == MONO_BASE) scp->mode = M_VGA_M80x25; else scp->mode = M_VGA_C80x25; @@ -3662,8 +3778,10 @@ next_code: scancode = (u_char)c; /* make screensaver happy */ - if (!(scancode & 0x80)) - getmicrouptime(&scrn_time_stamp); + if (!(scancode & 0x80)) { + scsplash_stick(FALSE); + run_scrn_saver = FALSE; + } if (!(flags & SCGETC_CN)) { /* do the /dev/random device a favour */ @@ -3940,9 +4058,6 @@ next_code: switch (action) { /* LOCKING KEYS */ case NLK: -#ifdef SC_SPLASH_SCREEN - toggle_splash_screen(cur_console); /* SOS XXX */ -#endif if (!nlkcnt) { nlkcnt++; if (cur_console->status & NLKED) @@ -4009,9 +4124,28 @@ next_code: case NOP: break; case SPSC: -#ifdef SC_SPLASH_SCREEN + /* force activatation/deactivation of the screen saver */ accents = 0; - toggle_splash_screen(cur_console); + if (scrn_blanked <= 0) { + run_scrn_saver = TRUE; + scrn_time_stamp -= scrn_blank_time; + } +#ifdef SC_SPLASH_SCREEN + if (cold) { + /* + * While devices are being probed, the screen saver need + * to be invoked explictly. XXX + */ + if (scrn_blanked > 0) { + scsplash_stick(FALSE); + stop_scrn_saver(current_saver); + } else { + if ((cur_console->status & UNKNOWN_MODE) == 0) { + scsplash_stick(TRUE); + (*current_saver)(TRUE); + } + } + } #endif break; case RBT: @@ -4037,6 +4171,12 @@ next_code: case DBG: #ifdef DDB /* try to switch to console 0 */ accents = 0; + /* + * TRY to make sure the screen saver is stopped, + * and the screen is updated before switching to + * the vty0. + */ + scrn_timer((void *)FALSE); if (cur_console->smode.mode == VT_AUTO && console[0]->smode.mode == VT_AUTO) switch_scr(cur_console, 0); @@ -5193,11 +5333,11 @@ blink_screen(void *arg) } void -sc_bcopy(u_short *p, int from, int to, int mark) +sc_bcopy(scr_stat *scp, u_short *p, int from, int to, int mark) { - if (!vesa_mode) { + if (!VESA_MODE(scp->mode)) { generic_bcopy(p+from, Crtat+from, (to-from+1)*sizeof (u_short)); - } else if (vesa_mode == 0x102) { + } else if (scp->mode == 0x102) { u_char *d, *e; int i,j; @@ -5219,33 +5359,38 @@ sc_bcopy(u_short *p, int from, int to, int mark) } #ifdef SC_SPLASH_SCREEN + static void -toggle_splash_screen(scr_stat *scp) +scsplash_init(void) { - static int toggle = 0; - static u_char save_mode; - int s; - - if (video_mode_ptr == NULL) + /* + * We currently assume the splash screen always use + * VGA_CG320 mode and abort installation if this mode is not + * supported with this video card. XXX + */ + if (crtc_type != KD_VGA || get_mode_param(cur_console, M_VGA_CG320) == NULL) return; - s = splhigh(); - if (toggle) { - scp->mode = save_mode; - scp->status &= ~UNKNOWN_MODE; - set_mode(scp); - load_palette(palette); - toggle = 0; - } - else { - save_mode = scp->mode; - scp->mode = M_VGA_CG320; - scp->status |= UNKNOWN_MODE; - set_mode(scp); - /* load image */ - toggle = 1; + if (splash_load() == 0 && add_scrn_saver(scsplash) == 0) { + default_saver = scsplash; + scrn_blank_time = DEFAULT_BLANKTIME; + run_scrn_saver = TRUE; + if (!(boothowto & RB_CONFIG)) { + scsplash_stick(TRUE); + scsplash(TRUE); + } } - splx(s); } -#endif + +static void +scsplash(int show) +{ + if (show) + splash(TRUE); + else if (!sticky_splash) + splash(FALSE); +} + +#endif /* SC_SPLASH_SCREEN */ + #endif /* NSC */ diff --git a/sys/dev/syscons/syscons.h b/sys/dev/syscons/syscons.h index e65aff4..b23a2ae 100644 --- a/sys/dev/syscons/syscons.h +++ b/sys/dev/syscons/syscons.h @@ -25,7 +25,7 @@ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * - * $Id: syscons.h,v 1.37 1998/02/12 22:05:08 phk Exp $ + * $Id: syscons.h,v 1.38 1998/08/03 09:09:35 yokota Exp $ */ #ifndef _I386_ISA_SYSCONS_H_ @@ -174,8 +174,8 @@ typedef struct scr_stat { u_short bell_duration; u_short bell_pitch; u_char border; /* border color */ - u_char initial_mode; /* initial mode */ - u_char mode; /* mode */ + int initial_mode; /* initial mode */ + int mode; /* mode */ pid_t pid; /* pid of controlling proc */ struct proc *proc; /* proc* of controlling proc */ struct vt_mode smode; /* switch mode */ @@ -185,6 +185,9 @@ typedef struct scr_stat { u_short *history_save; /* save area index */ int history_size; /* size of history buffer */ struct apmhook r_hook; /* reconfiguration support */ +#ifdef SC_SPLASH_SCREEN + u_char splash_save_mode; /* saved mode for splash screen */ +#endif } scr_stat; typedef struct default_attr { @@ -200,4 +203,10 @@ void load_palette(char *palette); int add_scrn_saver(void (*this)(int)); int remove_scrn_saver(void (*this)(int)); +#ifdef SC_SPLASH_SCREEN +void splash(int); +int splash_load(void); +int splash_unload(void); +#endif + #endif /* !_I386_ISA_SYSCONS_H_ */ diff --git a/sys/i386/include/console.h b/sys/i386/include/console.h index 9406441..7503746 100644 --- a/sys/i386/include/console.h +++ b/sys/i386/include/console.h @@ -25,7 +25,7 @@ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * - * $Id: console.h,v 1.36 1998/02/12 20:47:39 phk Exp $ + * $Id: console.h,v 1.37 1998/07/06 06:29:06 imp Exp $ */ #ifndef _MACHINE_CONSOLE_H_ @@ -73,6 +73,9 @@ #define CONS_BELLTYPE _IOW('c', 8, int) #define CONS_HISTORY _IOW('c', 9, int) #define CONS_MOUSECTL _IOWR('c', 10, mouse_info_t) +#define CONS_IDLE _IOR('c', 11, int) +#define CONS_SAVERMODE _IOW('c', 12, int) +#define CONS_SAVERSTART _IOW('c', 13, int) #define PIO_FONT8x8 _IOW('c', 64, fnt8_t) #define GIO_FONT8x8 _IOR('c', 65, fnt8_t) #define PIO_FONT8x14 _IOW('c', 66, fnt14_t) @@ -82,6 +85,10 @@ #define CONS_GETINFO _IOWR('c', 73, vid_info_t) #define CONS_GETVERS _IOR('c', 74, int) +/* CONS_SAVERMODE */ +#define CONS_LKM_SAVER 0 +#define CONS_USR_SAVER 1 + #ifdef PC98 #define ADJUST_CLOCK _IO('t',100) /* for 98note resume */ #endif @@ -157,7 +164,6 @@ struct mouse_info { #define KD_EGA 4 /* enhanced graphics adapter */ #define KD_VGA 5 /* video graphics adapter */ #define KD_PC98 6 /* PC-98 display */ -#define KD_PIXEL 7 /* Pixel based display */ #define KD_TEXT 0 /* set text mode restore fonts */ #define KD_TEXT0 0 /* ditto */ @@ -372,6 +378,8 @@ typedef struct ssaver ssaver_t; #define M_HGC_P1 0xe1 /* hercules graphics - page 1 @ B8000 */ #define M_MCA_MODE 0xff /* monochrome adapter mode */ +#define M_VESA_BASE 0x100 /* VESA mode number base */ + #define SW_PC98_80x25 _IO('S', M_PC98_80x25) #define SW_PC98_80x30 _IO('S', M_PC98_80x30) #define SW_B40x25 _IO('S', M_B40x25) diff --git a/sys/i386/isa/syscons.c b/sys/i386/isa/syscons.c index 25c0aa4..bb68f7f 100644 --- a/sys/i386/isa/syscons.c +++ b/sys/i386/isa/syscons.c @@ -25,7 +25,7 @@ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * - * $Id: syscons.c,v 1.270 1998/08/03 09:17:06 yokota Exp $ + * $Id: syscons.c,v 1.271 1998/08/03 09:18:58 yokota Exp $ */ #include "sc.h" @@ -37,6 +37,7 @@ #if NSC > 0 #include <sys/param.h> #include <sys/systm.h> +#include <sys/reboot.h> #include <sys/conf.h> #include <sys/proc.h> #include <sys/signalvar.h> @@ -47,6 +48,7 @@ #include <sys/devfsext.h> #endif +#include <machine/bootinfo.h> #include <machine/clock.h> #include <machine/cons.h> #include <machine/console.h> @@ -94,9 +96,12 @@ #define COLD 0 #define WARM 1 +#define VESA_MODE(x) ((x) >= M_VESA_BASE) + #define MODE_MAP_SIZE (M_VGA_CG320 + 1) #define MODE_PARAM_SIZE 64 +#define DEFAULT_BLANKTIME (5*60) /* 5 minutes */ #define MAX_BLANKTIME (7*24*60*60) /* 7 days!? */ /* for backward compatibility */ @@ -162,11 +167,14 @@ static const u_int n_fkey_tab = sizeof(fkey_tab) / sizeof(*fkey_tab); static int delayed_next_scr = FALSE; static long scrn_blank_time = 0; /* screen saver timeout value */ int scrn_blanked = 0; /* screen saver active flag */ -static struct timeval scrn_time_stamp; +static long scrn_time_stamp; +static int saver_mode = CONS_LKM_SAVER; /* LKM/user saver */ +static int run_scrn_saver = FALSE; /* should run the saver? */ +static int scrn_idle = FALSE; /* about to run the saver */ u_char scr_map[256]; u_char scr_rmap[256]; char *video_mode_ptr = NULL; -static int vesa_mode; +static int bios_video_mode; /* video mode # set by BIOS */ int fonts_loaded = 0 #ifdef STD8X16FONT | FONT_16 @@ -206,9 +214,12 @@ static int extra_history_size = static void none_saver(int blank) { } static void (*current_saver)(int blank) = none_saver; +static void (*default_saver)(int blank) = none_saver; int (*sc_user_ioctl)(dev_t dev, int cmd, caddr_t data, int flag, struct proc *p) = NULL; +static int sticky_splash = FALSE; + /* OS specific stuff */ #ifdef not_yet_done #define VIRTUAL_TTY(x) (sccons[x] = ttymalloc(sccons[x])) @@ -247,8 +258,8 @@ static void scmousestart(struct tty *tp); static void scinit(void); static void scshutdown(int howto, void *arg); static void map_mode_table(char *map[], char *table, int max); -static u_char map_mode_num(u_char mode); -static char *get_mode_param(scr_stat *scp, u_char mode); +static int map_mode_num(int mode); +static char *get_mode_param(scr_stat *scp, int mode); static u_int scgetc(u_int flags); #define SCGETC_CN 1 #define SCGETC_NONBLOCK 2 @@ -256,7 +267,7 @@ static void sccnupdate(scr_stat *scp); static scr_stat *get_scr_stat(dev_t dev); static scr_stat *alloc_scp(void); static void init_scp(scr_stat *scp); -static void sc_bcopy(u_short *p, int from, int to, int mark); +static void sc_bcopy(scr_stat *scp, u_short *p, int from, int to, int mark); static int get_scr_num(void); static timeout_t scrn_timer; static void scrn_update(scr_stat *scp, int show_cursor); @@ -306,7 +317,11 @@ static void save_palette(void); static void do_bell(scr_stat *scp, int pitch, int duration); static timeout_t blink_screen; #ifdef SC_SPLASH_SCREEN -static void toggle_splash_screen(scr_stat *scp); +static void scsplash_init(void); +static void scsplash(int show); +#define scsplash_stick(stick) (sticky_splash = (stick)) +#else +#define scsplash_stick(stick) #endif struct isa_driver scdriver = { @@ -336,8 +351,8 @@ draw_cursor_image(scr_stat *scp) u_short cursor_image, *ptr = Crtat + (scp->cursor_pos - scp->scr_buf); u_short prev_image; - if (vesa_mode) { - sc_bcopy(scp->scr_buf, scp->cursor_pos - scp->scr_buf, + if (VESA_MODE(scp->mode)) { + sc_bcopy(scp, scp->scr_buf, scp->cursor_pos - scp->scr_buf, scp->cursor_pos - scp->scr_buf, 1); return; } @@ -388,8 +403,8 @@ draw_cursor_image(scr_stat *scp) static void remove_cursor_image(scr_stat *scp) { - if (vesa_mode) - sc_bcopy(scp->scr_buf, scp->cursor_oldpos - scp->scr_buf, + if (VESA_MODE(scp->mode)) + sc_bcopy(scp, scp->scr_buf, scp->cursor_oldpos - scp->scr_buf, scp->cursor_oldpos - scp->scr_buf, 0); else *(Crtat + (scp->cursor_oldpos - scp->scr_buf)) = scp->cursor_saveunder; @@ -455,10 +470,12 @@ scvidprobe(int unit, int flags) cp = (u_short *)CGA_BUF; was = *cp; *cp = (u_short) 0xA55A; + bios_video_mode = *(u_char *)pa_to_va(0x449); if (bootinfo.bi_vesa == 0x102) { - vesa_mode = bootinfo.bi_vesa; + bios_video_mode = bootinfo.bi_vesa; Crtat = (u_short *)pa_to_va(0xA0000); - crtc_type = KD_PIXEL; + crtc_addr = COLOR_BASE; + crtc_type = KD_VGA; bzero(Crtat, 800*600/8); } else if (*cp == 0xA55A) { Crtat = (u_short *)CGA_BUF; @@ -476,7 +493,7 @@ scvidprobe(int unit, int flags) } *cp = was; - if (crtc_type != KD_PIXEL) { + if (!VESA_MODE(bios_video_mode)) { /* * Check rtc and BIOS date area. * XXX: don't use BIOSDATA_EQUIPMENT, it is not a dead copy @@ -717,12 +734,12 @@ scattach(struct isa_device *dev) scinit(); flags = dev->id_flags; - if (!crtc_vga) + if (crtc_type != KD_VGA || VESA_MODE(bios_video_mode)) flags &= ~CHAR_CURSOR; scp = console[0]; - if (crtc_vga) { + if (crtc_type == KD_VGA) { cut_buffer_size = scp->xsize * scp->ysize + 1; cut_buffer = (char *)malloc(cut_buffer_size, M_DEVBUF, M_NOWAIT); if (cut_buffer != NULL) @@ -754,13 +771,12 @@ scattach(struct isa_device *dev) draw_cursor_image(scp); /* get screen update going */ - scrn_timer(NULL); + scrn_timer((void *)TRUE); update_leds(scp->status); if ((crtc_type == KD_VGA) && bootverbose) { - printf("sc%d: BIOS video mode:%d\n", - dev->id_unit, *(u_char *)pa_to_va(0x449)); + printf("sc%d: BIOS video mode:%d\n", dev->id_unit, bios_video_mode); printf("sc%d: VGA registers upon power-up\n", dev->id_unit); dump_vgaregs(vgaregs); printf("sc%d: video mode:%d\n", dev->id_unit, scp->mode); @@ -775,14 +791,17 @@ scattach(struct isa_device *dev) } printf("sc%d: rows_offset:%d\n", dev->id_unit, rows_offset); } - if ((crtc_type == KD_VGA) && (video_mode_ptr == NULL)) + if ((crtc_type == KD_VGA) && !VESA_MODE(bios_video_mode) + && (video_mode_ptr == NULL)) printf("sc%d: WARNING: video mode switching is only partially supported\n", dev->id_unit); printf("sc%d: ", dev->id_unit); switch(crtc_type) { case KD_VGA: - if (crtc_addr == MONO_BASE) + if (VESA_MODE(bios_video_mode)) + printf("Graphics display (VESA mode = 0x%x)", bios_video_mode); + else if (crtc_addr == MONO_BASE) printf("VGA mono"); else printf("VGA color"); @@ -796,9 +815,6 @@ scattach(struct isa_device *dev) case KD_CGA: printf("CGA"); break; - case KD_PIXEL: - printf("Graphics display (VESA mode = 0x%x)", vesa_mode); - break; case KD_MONO: case KD_HERCULES: default: @@ -1053,9 +1069,10 @@ scioctl(dev_t dev, u_long cmd, caddr_t data, int flag, struct proc *p) case CONS_BLANKTIME: /* set screen saver timeout (0 = no saver) */ if (*(int *)data < 0 || *(int *)data > MAX_BLANKTIME) return EINVAL; + s = spltty(); scrn_blank_time = *(int *)data; - if (scrn_blank_time == 0) - getmicrouptime(&scrn_time_stamp); + run_scrn_saver = (scrn_blank_time != 0); + splx(s); return 0; case CONS_CURSORTYPE: /* set cursor type blink/noblink */ @@ -1064,7 +1081,7 @@ scioctl(dev_t dev, u_long cmd, caddr_t data, int flag, struct proc *p) else flags &= ~BLINK_CURSOR; if ((*(int*)data) & 0x02) { - if (!crtc_vga) + if (crtc_type != KD_VGA || VESA_MODE(bios_video_mode)) return ENXIO; flags |= CHAR_CURSOR; } else @@ -1154,7 +1171,7 @@ scioctl(dev_t dev, u_long cmd, caddr_t data, int flag, struct proc *p) mouse_info_t *mouse = (mouse_info_t*)data; mouse_info_t buf; - if (!crtc_vga) + if (crtc_type != KD_VGA || VESA_MODE(bios_video_mode)) return ENODEV; if (cmd == OLD_CONS_MOUSECTL) { @@ -1200,13 +1217,14 @@ scioctl(dev_t dev, u_long cmd, caddr_t data, int flag, struct proc *p) scp->mouse_proc = NULL; scp->mouse_pid = 0; } - break; + return 0; case MOUSE_SHOW: if (!(scp->status & MOUSE_ENABLED)) { scp->status |= (MOUSE_ENABLED | MOUSE_VISIBLE); scp->mouse_oldpos = scp->mouse_pos; mark_all(scp); + return 0; } else return EINVAL; @@ -1216,6 +1234,7 @@ scioctl(dev_t dev, u_long cmd, caddr_t data, int flag, struct proc *p) if (scp->status & MOUSE_ENABLED) { scp->status &= ~(MOUSE_ENABLED | MOUSE_VISIBLE); mark_all(scp); + return 0; } else return EINVAL; @@ -1238,7 +1257,7 @@ scioctl(dev_t dev, u_long cmd, caddr_t data, int flag, struct proc *p) mouse->u.data.y = scp->mouse_ypos; mouse->u.data.z = 0; mouse->u.data.buttons = scp->mouse_buttons; - break; + return 0; case MOUSE_ACTION: case MOUSE_MOTION_EVENT: @@ -1254,6 +1273,8 @@ scioctl(dev_t dev, u_long cmd, caddr_t data, int flag, struct proc *p) ((mouse->u.data.x || mouse->u.data.y || mouse->u.data.z) ? MOUSE_POSCHANGED : 0) | (mouse_status.obutton ^ mouse_status.button); + if (mouse_status.flags == 0) + return 0; if (cur_console->status & MOUSE_ENABLED) cur_console->status |= MOUSE_VISIBLE; @@ -1334,6 +1355,8 @@ scioctl(dev_t dev, u_long cmd, caddr_t data, int flag, struct proc *p) mouse_status.button &= ~mouse->u.event.id; } mouse_status.flags |= mouse_status.obutton ^ mouse_status.button; + if (mouse_status.flags == 0) + return 0; if (cur_console->status & MOUSE_ENABLED) cur_console->status |= MOUSE_VISIBLE; @@ -1411,7 +1434,8 @@ scioctl(dev_t dev, u_long cmd, caddr_t data, int flag, struct proc *p) return EINVAL; } /* make screensaver happy */ - getmicrouptime(&scrn_time_stamp); + scsplash_stick(FALSE); + run_scrn_saver = FALSE; return 0; } @@ -1542,6 +1566,37 @@ scioctl(dev_t dev, u_long cmd, caddr_t data, int flag, struct proc *p) *(int*)data = 0x200; /* version 2.0 */ return 0; + case CONS_IDLE: /* see if the screen has been idle */ + *(int *)data = (scrn_idle && !(cur_console->status & UNKNOWN_MODE)); + return 0; + + case CONS_SAVERMODE: /* set saver mode */ + switch(*(int *)data) { + case CONS_USR_SAVER: + /* if a LKM screen saver is running, it will eventually stop... */ + saver_mode = *(int *)data; + scsplash_stick(TRUE); + break; + case CONS_LKM_SAVER: + saver_mode = *(int *)data; + break; + default: + return EINVAL; + } + return 0; + + case CONS_SAVERSTART: /* immediately start/stop the screen saver */ + /* + * Note that this ioctl does not guarantee the screen saver + * actually starts or stops. It merely attempts to do so... + */ + s = spltty(); + run_scrn_saver = (*(int *)data != 0); + if (run_scrn_saver) + scrn_time_stamp -= scrn_blank_time; + splx(s); + return 0; + /* VGA TEXT MODES */ case SW_VGA_C40x25: case SW_VGA_C80x25: case SW_VGA_M80x25: @@ -1555,7 +1610,7 @@ scioctl(dev_t dev, u_long cmd, caddr_t data, int flag, struct proc *p) case SW_ENH_B80x43: case SW_ENH_C80x43: case SW_EGAMONO80x25: - if (!crtc_vga) + if (crtc_type != KD_VGA) return ENODEV; mp = get_mode_param(scp, cmd & 0xff); if (mp == NULL) @@ -1693,7 +1748,7 @@ scioctl(dev_t dev, u_long cmd, caddr_t data, int flag, struct proc *p) case SW_CG640x350: case SW_ENH_CG640: case SW_BG640x480: case SW_CG640x480: case SW_VGA_CG320: - if (!crtc_vga) + if (crtc_type != KD_VGA) return ENODEV; mp = get_mode_param(scp, cmd & 0xff); if (mp == NULL) @@ -1730,7 +1785,7 @@ scioctl(dev_t dev, u_long cmd, caddr_t data, int flag, struct proc *p) return 0; case SW_VGA_MODEX: - if (!crtc_vga) + if (crtc_type != KD_VGA) return ENODEV; mp = get_mode_param(scp, cmd & 0xff); if (mp == NULL) @@ -1869,19 +1924,21 @@ scioctl(dev_t dev, u_long cmd, caddr_t data, int flag, struct proc *p) switch (*data) { case KD_TEXT: /* switch to TEXT (known) mode */ /* restore fonts & palette ! */ - if (crtc_vga) { + if (crtc_type == KD_VGA) { + if (!VESA_MODE(scp->mode)) { #if 0 - /* - * FONT KLUDGE - * Don't load fonts for now... XXX - */ - if (fonts_loaded & FONT_8) - copy_font(LOAD, FONT_8, font_8); - if (fonts_loaded & FONT_14) - copy_font(LOAD, FONT_14, font_14); - if (fonts_loaded & FONT_16) - copy_font(LOAD, FONT_16, font_16); + /* + * FONT KLUDGE + * Don't load fonts for now... XXX + */ + if (fonts_loaded & FONT_8) + copy_font(LOAD, FONT_8, font_8); + if (fonts_loaded & FONT_14) + copy_font(LOAD, FONT_14, font_14); + if (fonts_loaded & FONT_16) + copy_font(LOAD, FONT_16, font_16); #endif + } load_palette(palette); } @@ -1904,7 +1961,7 @@ scioctl(dev_t dev, u_long cmd, caddr_t data, int flag, struct proc *p) scp->status |= UNKNOWN_MODE; splx(s); /* no restore fonts & palette */ - if (crtc_vga) + if (crtc_type == KD_VGA) set_mode(scp); scp->status &= ~UNKNOWN_MODE; clear_screen(scp); @@ -2086,7 +2143,7 @@ scioctl(dev_t dev, u_long cmd, caddr_t data, int flag, struct proc *p) return 0; case PIO_FONT8x8: /* set 8x8 dot font */ - if (!crtc_vga) + if (crtc_type != KD_VGA) return ENXIO; bcopy(data, font_8, 8*256); fonts_loaded |= FONT_8; @@ -2095,7 +2152,8 @@ scioctl(dev_t dev, u_long cmd, caddr_t data, int flag, struct proc *p) * Always use the font page #0. XXX * Don't load if the current font size is not 8x8. */ - if (!(cur_console->status & UNKNOWN_MODE) + if (!VESA_MODE(cur_console->mode) + && !(cur_console->status & UNKNOWN_MODE) && (cur_console->font_size < 14)) { copy_font(LOAD, FONT_8, font_8); if (flags & CHAR_CURSOR) @@ -2104,7 +2162,7 @@ scioctl(dev_t dev, u_long cmd, caddr_t data, int flag, struct proc *p) return 0; case GIO_FONT8x8: /* get 8x8 dot font */ - if (!crtc_vga) + if (crtc_type != KD_VGA) return ENXIO; if (fonts_loaded & FONT_8) { bcopy(font_8, data, 8*256); @@ -2114,7 +2172,7 @@ scioctl(dev_t dev, u_long cmd, caddr_t data, int flag, struct proc *p) return ENXIO; case PIO_FONT8x14: /* set 8x14 dot font */ - if (!crtc_vga) + if (crtc_type != KD_VGA) return ENXIO; bcopy(data, font_14, 14*256); fonts_loaded |= FONT_14; @@ -2123,7 +2181,8 @@ scioctl(dev_t dev, u_long cmd, caddr_t data, int flag, struct proc *p) * Always use the font page #0. XXX * Don't load if the current font size is not 8x14. */ - if (!(cur_console->status & UNKNOWN_MODE) + if (!VESA_MODE(cur_console->mode) + && !(cur_console->status & UNKNOWN_MODE) && (cur_console->font_size >= 14) && (cur_console->font_size < 16)) { copy_font(LOAD, FONT_14, font_14); if (flags & CHAR_CURSOR) @@ -2132,7 +2191,7 @@ scioctl(dev_t dev, u_long cmd, caddr_t data, int flag, struct proc *p) return 0; case GIO_FONT8x14: /* get 8x14 dot font */ - if (!crtc_vga) + if (crtc_type != KD_VGA) return ENXIO; if (fonts_loaded & FONT_14) { bcopy(font_14, data, 14*256); @@ -2142,7 +2201,7 @@ scioctl(dev_t dev, u_long cmd, caddr_t data, int flag, struct proc *p) return ENXIO; case PIO_FONT8x16: /* set 8x16 dot font */ - if (!crtc_vga && crtc_type != KD_PIXEL) + if (crtc_type != KD_VGA) return ENXIO; bcopy(data, font_16, 16*256); fonts_loaded |= FONT_16; @@ -2151,7 +2210,8 @@ scioctl(dev_t dev, u_long cmd, caddr_t data, int flag, struct proc *p) * Always use the font page #0. XXX * Don't load if the current font size is not 8x16. */ - if (crtc_vga && !(cur_console->status & UNKNOWN_MODE) + if (!VESA_MODE(cur_console->mode) + && !(cur_console->status & UNKNOWN_MODE) && (cur_console->font_size >= 16)) { copy_font(LOAD, FONT_16, font_16); if (flags & CHAR_CURSOR) @@ -2160,7 +2220,7 @@ scioctl(dev_t dev, u_long cmd, caddr_t data, int flag, struct proc *p) return 0; case GIO_FONT8x16: /* get 8x16 dot font */ - if (!crtc_vga && crtc_type != KD_PIXEL) + if (crtc_type != KD_VGA) return ENXIO; if (fonts_loaded & FONT_16) { bcopy(font_16, data, 16*256); @@ -2292,6 +2352,8 @@ sccngetc(dev_t dev) * Stop the screen saver and update the screen if necessary. * What if we have been running in the screen saver code... XXX */ + scsplash_stick(FALSE); + run_scrn_saver = FALSE; sccnupdate(cur_console); c = scgetc(SCGETC_CN); @@ -2305,7 +2367,10 @@ sccncheckc(dev_t dev) int s = spltty(); /* block scintr and scrn_timer while we poll */ int c; + scsplash_stick(FALSE); + run_scrn_saver = FALSE; sccnupdate(cur_console); + c = scgetc(SCGETC_CN | SCGETC_NONBLOCK); splx(s); return(c == NOKEY ? -1 : c); /* c == -1 can't happen */ @@ -2314,13 +2379,26 @@ sccncheckc(dev_t dev) static void sccnupdate(scr_stat *scp) { - if (scp == cur_console && !font_loading_in_progress) { + /* this is a cut-down version of scrn_timer()... */ + + if (font_loading_in_progress) + return; + + if (panicstr) { + scsplash_stick(FALSE); + run_scrn_saver = FALSE; + } + if (!run_scrn_saver) + scrn_idle = FALSE; + if ((saver_mode != CONS_LKM_SAVER) || !scrn_idle) if (scrn_blanked > 0) stop_scrn_saver(current_saver); - if (!(scp->status & UNKNOWN_MODE) && scrn_blanked <= 0 - && !blink_in_progress && !switch_in_progress) - scrn_update(scp, TRUE); - } + + if (scp != cur_console || blink_in_progress || switch_in_progress) + return; + + if ((scp->status & UNKNOWN_MODE) == 0 && scrn_blanked <= 0) + scrn_update(scp, TRUE); } static scr_stat @@ -2349,12 +2427,13 @@ static void scrn_timer(void *arg) { struct timeval tv; - scr_stat *scp = cur_console; + scr_stat *scp; int s; /* don't do anything when we are touching font */ if (font_loading_in_progress) { - timeout(scrn_timer, NULL, hz / 10); + if (arg) + timeout(scrn_timer, (void *)TRUE, hz / 10); return; } s = spltty(); @@ -2384,30 +2463,42 @@ scrn_timer(void *arg) /* should we stop the screen saver? */ getmicrouptime(&tv); - if (panicstr || shutdown_in_progress) - scrn_time_stamp = tv; - if (tv.tv_sec <= scrn_time_stamp.tv_sec + scrn_blank_time) + if (panicstr || shutdown_in_progress) { + scsplash_stick(FALSE); + run_scrn_saver = FALSE; + } + if (run_scrn_saver) { + scrn_idle = (tv.tv_sec > scrn_time_stamp + scrn_blank_time); + } else { + scrn_time_stamp = tv.tv_sec; + scrn_idle = FALSE; + if (scrn_blank_time > 0) + run_scrn_saver = TRUE; + } + if ((saver_mode != CONS_LKM_SAVER) || !scrn_idle) if (scrn_blanked > 0) stop_scrn_saver(current_saver); /* should we just return ? */ - if ((scp->status&UNKNOWN_MODE) || blink_in_progress || switch_in_progress) { - timeout(scrn_timer, NULL, hz / 10); + if (blink_in_progress || switch_in_progress) { + if (arg) + timeout(scrn_timer, (void *)TRUE, hz / 10); splx(s); return; } /* Update the screen */ scp = cur_console; - if (scrn_blanked <= 0) + if ((scp->status & UNKNOWN_MODE) == 0 && scrn_blanked <= 0) scrn_update(scp, TRUE); /* should we activate the screen saver? */ - if ((scrn_blank_time != 0) - && (tv.tv_sec > scrn_time_stamp.tv_sec + scrn_blank_time)) - (*current_saver)(TRUE); + if ((saver_mode == CONS_LKM_SAVER) && scrn_idle) + if ((scp->status & UNKNOWN_MODE) == 0 || scrn_blanked > 0) + (*current_saver)(TRUE); - timeout(scrn_timer, NULL, hz / 25); + if (arg) + timeout(scrn_timer, (void *)TRUE, hz / 25); splx(s); } @@ -2416,7 +2507,7 @@ scrn_update(scr_stat *scp, int show_cursor) { /* update screen image */ if (scp->start <= scp->end) - sc_bcopy(scp->scr_buf, scp->start, scp->end, 0); + sc_bcopy(scp, scp->scr_buf, scp->start, scp->end, 0); /* we are not to show the cursor and the mouse pointer... */ if (!show_cursor) { @@ -2483,9 +2574,18 @@ scrn_update(scr_stat *scp, int show_cursor) int add_scrn_saver(void (*this_saver)(int)) { - if (current_saver != none_saver) +#ifdef SC_SPLASH_SCREEN + if (current_saver == scsplash) { + scsplash_stick(FALSE); + stop_scrn_saver(scsplash); + } +#endif + + if (current_saver != default_saver) return EBUSY; current_saver = this_saver; + saver_mode = CONS_LKM_SAVER; + run_scrn_saver = (scrn_blank_time > 0); return 0; } @@ -2505,6 +2605,10 @@ remove_scrn_saver(void (*this_saver)(int)) if (scrn_blanked > 0) stop_scrn_saver(this_saver); + if (scrn_blanked > 0) + return EBUSY; /* XXX */ + + current_saver = default_saver; return 0; } @@ -2512,8 +2616,14 @@ static void stop_scrn_saver(void (*saver)(int)) { (*saver)(FALSE); - getmicrouptime(&scrn_time_stamp); + run_scrn_saver = FALSE; + /* the screen saver may have chosen not to stop after all... */ + if (scrn_blanked > 0) + return; + mark_all(cur_console); + if (delayed_next_scr) + switch_scr(cur_console, delayed_next_scr - 1); wakeup((caddr_t)&scrn_blanked); } @@ -2522,10 +2632,10 @@ wait_scrn_saver_stop(void) { int error = 0; - getmicrouptime(&scrn_time_stamp); + run_scrn_saver = FALSE; while (scrn_blanked > 0) { error = tsleep((caddr_t)&scrn_blanked, PZERO | PCATCH, "scrsav", 0); - getmicrouptime(&scrn_time_stamp); + run_scrn_saver = FALSE; if (error != ERESTART) break; } @@ -2546,6 +2656,14 @@ clear_screen(scr_stat *scp) static int switch_scr(scr_stat *scp, u_int next_scr) { + /* delay switch if actively updating screen */ + if (scrn_blanked > 0 || write_in_progress || blink_in_progress) { + scsplash_stick(FALSE); + run_scrn_saver = FALSE; + delayed_next_scr = next_scr+1; + return 0; + } + if (switch_in_progress && (cur_console->proc != pfind(cur_console->pid))) switch_in_progress = FALSE; @@ -2565,16 +2683,6 @@ switch_scr(scr_stat *scp, u_int next_scr) } } - /* delay switch if actively updating screen */ - if (write_in_progress || blink_in_progress) { - delayed_next_scr = next_scr+1; - return 0; - } - - /* Stop the screensaver */ - if (scrn_blanked > 0) - stop_scrn_saver(current_saver); - switch_in_progress = TRUE; old_scp = cur_console; new_scp = console[next_scr]; @@ -2614,13 +2722,13 @@ exchange_scr(void) move_crsr(old_scp, old_scp->xpos, old_scp->ypos); cur_console = new_scp; if (old_scp->mode != new_scp->mode || (old_scp->status & UNKNOWN_MODE)){ - if (crtc_vga) + if (crtc_type == KD_VGA) set_mode(new_scp); } move_crsr(new_scp, new_scp->xpos, new_scp->ypos); if (!(new_scp->status & UNKNOWN_MODE) && (flags & CHAR_CURSOR)) set_destructive_cursor(new_scp); - if ((old_scp->status & UNKNOWN_MODE) && crtc_vga) + if ((old_scp->status & UNKNOWN_MODE) && crtc_type == KD_VGA) load_palette(palette); if (old_scp->status & KBD_RAW_MODE || new_scp->status & KBD_RAW_MODE || old_scp->status & KBD_CODE_MODE || new_scp->status & KBD_CODE_MODE) @@ -2629,7 +2737,7 @@ exchange_scr(void) update_leds(new_scp->status); delayed_next_scr = FALSE; mark_all(new_scp); - if (vesa_mode == 0x102) { + if (new_scp->mode == 0x102) { bzero(Crtat, 800*600/8); } } @@ -3101,7 +3209,8 @@ scan_esc(scr_stat *scp, u_char c) flags |= BLINK_CURSOR; else flags &= ~BLINK_CURSOR; - if ((scp->term.param[0] & 0x02) && crtc_vga) + if ((scp->term.param[0] & 0x02) && + crtc_type == KD_VGA && !VESA_MODE(bios_video_mode)) flags |= CHAR_CURSOR; else flags &= ~CHAR_CURSOR; @@ -3116,7 +3225,7 @@ scan_esc(scr_stat *scp, u_char c) */ if (!(cur_console->status & UNKNOWN_MODE)) { remove_cursor_image(cur_console); - if (crtc_vga && (flags & CHAR_CURSOR)) + if (crtc_type == KD_VGA && (flags & CHAR_CURSOR)) set_destructive_cursor(cur_console); draw_cursor_image(cur_console); } @@ -3184,8 +3293,8 @@ ansi_put(scr_stat *scp, u_char *buf, int len) u_char *ptr = buf; /* make screensaver happy */ - if (scp == cur_console) - getmicrouptime(&scrn_time_stamp); + if (!sticky_splash && scp == cur_console) + run_scrn_saver = FALSE; write_in_progress++; outloop: @@ -3382,7 +3491,7 @@ scinit(void) } /* copy screen to temporary buffer */ - if (crtc_type != KD_PIXEL) + if (!VESA_MODE(console[0]->mode)) generic_bcopy(Crtat, sc_buffer, console[0]->xsize * console[0]->ysize * sizeof(u_short)); @@ -3407,30 +3516,35 @@ scinit(void) } /* Save font and palette if VGA */ - if (crtc_vga) { - if (fonts_loaded & FONT_16) { + if (crtc_type == KD_VGA) { + if (!VESA_MODE(bios_video_mode)) { + if (fonts_loaded & FONT_16) { copy_font(LOAD, FONT_16, font_16); - } else { + } else { copy_font(SAVE, FONT_16, font_16); fonts_loaded = FONT_16; + } + set_destructive_cursor(console[0]); } save_palette(); - set_destructive_cursor(console[0]); } #ifdef SC_SPLASH_SCREEN /* - * Now put up a graphics image, and maybe cycle a - * couble of palette entries for simple animation. + * If not booting verbosely, put up the splash. + * Note that the splash screen is not currently supported in + * the VESA mode. */ - toggle_splash_screen(cur_console); + if (!(boothowto & RB_VERBOSE) && !VESA_MODE(bios_video_mode)) + scsplash_init(); #endif } static void scshutdown(int howto, void *arg) { - getmicrouptime(&scrn_time_stamp); + scsplash_stick(FALSE); + run_scrn_saver = FALSE; if (!cold && cur_console->smode.mode == VT_AUTO && console[0]->smode.mode == VT_AUTO) switch_scr(cur_console, 0); @@ -3448,12 +3562,12 @@ map_mode_table(char *map[], char *table, int max) map[i] = NULL; } -static u_char -map_mode_num(u_char mode) +static int +map_mode_num(int mode) { static struct { - u_char from; - u_char to; + int from; + int to; } mode_map[] = { { M_ENH_B80x43, M_ENH_B80x25 }, { M_ENH_C80x43, M_ENH_C80x25 }, @@ -3475,7 +3589,7 @@ map_mode_num(u_char mode) } static char -*get_mode_param(scr_stat *scp, u_char mode) +*get_mode_param(scr_stat *scp, int mode) { if (mode >= MODE_MAP_SIZE) mode = map_mode_num(mode); @@ -3504,7 +3618,7 @@ static scr_stat bzero(scp->history_head, scp->history_size*sizeof(u_short)); scp->history = scp->history_head; /* SOS - if (crtc_vga && video_mode_ptr) + if (crtc_type == KD_VGA && video_mode_ptr) set_mode(scp); */ clear_screen(scp); @@ -3517,7 +3631,9 @@ init_scp(scr_stat *scp) { switch(crtc_type) { case KD_VGA: - if (crtc_addr == MONO_BASE) + if (VESA_MODE(bios_video_mode)) + scp->mode = bios_video_mode; + else if (crtc_addr == MONO_BASE) scp->mode = M_VGA_M80x25; else scp->mode = M_VGA_C80x25; @@ -3662,8 +3778,10 @@ next_code: scancode = (u_char)c; /* make screensaver happy */ - if (!(scancode & 0x80)) - getmicrouptime(&scrn_time_stamp); + if (!(scancode & 0x80)) { + scsplash_stick(FALSE); + run_scrn_saver = FALSE; + } if (!(flags & SCGETC_CN)) { /* do the /dev/random device a favour */ @@ -3940,9 +4058,6 @@ next_code: switch (action) { /* LOCKING KEYS */ case NLK: -#ifdef SC_SPLASH_SCREEN - toggle_splash_screen(cur_console); /* SOS XXX */ -#endif if (!nlkcnt) { nlkcnt++; if (cur_console->status & NLKED) @@ -4009,9 +4124,28 @@ next_code: case NOP: break; case SPSC: -#ifdef SC_SPLASH_SCREEN + /* force activatation/deactivation of the screen saver */ accents = 0; - toggle_splash_screen(cur_console); + if (scrn_blanked <= 0) { + run_scrn_saver = TRUE; + scrn_time_stamp -= scrn_blank_time; + } +#ifdef SC_SPLASH_SCREEN + if (cold) { + /* + * While devices are being probed, the screen saver need + * to be invoked explictly. XXX + */ + if (scrn_blanked > 0) { + scsplash_stick(FALSE); + stop_scrn_saver(current_saver); + } else { + if ((cur_console->status & UNKNOWN_MODE) == 0) { + scsplash_stick(TRUE); + (*current_saver)(TRUE); + } + } + } #endif break; case RBT: @@ -4037,6 +4171,12 @@ next_code: case DBG: #ifdef DDB /* try to switch to console 0 */ accents = 0; + /* + * TRY to make sure the screen saver is stopped, + * and the screen is updated before switching to + * the vty0. + */ + scrn_timer((void *)FALSE); if (cur_console->smode.mode == VT_AUTO && console[0]->smode.mode == VT_AUTO) switch_scr(cur_console, 0); @@ -5193,11 +5333,11 @@ blink_screen(void *arg) } void -sc_bcopy(u_short *p, int from, int to, int mark) +sc_bcopy(scr_stat *scp, u_short *p, int from, int to, int mark) { - if (!vesa_mode) { + if (!VESA_MODE(scp->mode)) { generic_bcopy(p+from, Crtat+from, (to-from+1)*sizeof (u_short)); - } else if (vesa_mode == 0x102) { + } else if (scp->mode == 0x102) { u_char *d, *e; int i,j; @@ -5219,33 +5359,38 @@ sc_bcopy(u_short *p, int from, int to, int mark) } #ifdef SC_SPLASH_SCREEN + static void -toggle_splash_screen(scr_stat *scp) +scsplash_init(void) { - static int toggle = 0; - static u_char save_mode; - int s; - - if (video_mode_ptr == NULL) + /* + * We currently assume the splash screen always use + * VGA_CG320 mode and abort installation if this mode is not + * supported with this video card. XXX + */ + if (crtc_type != KD_VGA || get_mode_param(cur_console, M_VGA_CG320) == NULL) return; - s = splhigh(); - if (toggle) { - scp->mode = save_mode; - scp->status &= ~UNKNOWN_MODE; - set_mode(scp); - load_palette(palette); - toggle = 0; - } - else { - save_mode = scp->mode; - scp->mode = M_VGA_CG320; - scp->status |= UNKNOWN_MODE; - set_mode(scp); - /* load image */ - toggle = 1; + if (splash_load() == 0 && add_scrn_saver(scsplash) == 0) { + default_saver = scsplash; + scrn_blank_time = DEFAULT_BLANKTIME; + run_scrn_saver = TRUE; + if (!(boothowto & RB_CONFIG)) { + scsplash_stick(TRUE); + scsplash(TRUE); + } } - splx(s); } -#endif + +static void +scsplash(int show) +{ + if (show) + splash(TRUE); + else if (!sticky_splash) + splash(FALSE); +} + +#endif /* SC_SPLASH_SCREEN */ + #endif /* NSC */ diff --git a/sys/i386/isa/syscons.h b/sys/i386/isa/syscons.h index e65aff4..b23a2ae 100644 --- a/sys/i386/isa/syscons.h +++ b/sys/i386/isa/syscons.h @@ -25,7 +25,7 @@ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * - * $Id: syscons.h,v 1.37 1998/02/12 22:05:08 phk Exp $ + * $Id: syscons.h,v 1.38 1998/08/03 09:09:35 yokota Exp $ */ #ifndef _I386_ISA_SYSCONS_H_ @@ -174,8 +174,8 @@ typedef struct scr_stat { u_short bell_duration; u_short bell_pitch; u_char border; /* border color */ - u_char initial_mode; /* initial mode */ - u_char mode; /* mode */ + int initial_mode; /* initial mode */ + int mode; /* mode */ pid_t pid; /* pid of controlling proc */ struct proc *proc; /* proc* of controlling proc */ struct vt_mode smode; /* switch mode */ @@ -185,6 +185,9 @@ typedef struct scr_stat { u_short *history_save; /* save area index */ int history_size; /* size of history buffer */ struct apmhook r_hook; /* reconfiguration support */ +#ifdef SC_SPLASH_SCREEN + u_char splash_save_mode; /* saved mode for splash screen */ +#endif } scr_stat; typedef struct default_attr { @@ -200,4 +203,10 @@ void load_palette(char *palette); int add_scrn_saver(void (*this)(int)); int remove_scrn_saver(void (*this)(int)); +#ifdef SC_SPLASH_SCREEN +void splash(int); +int splash_load(void); +int splash_unload(void); +#endif + #endif /* !_I386_ISA_SYSCONS_H_ */ diff --git a/sys/isa/syscons.c b/sys/isa/syscons.c index 25c0aa4..bb68f7f 100644 --- a/sys/isa/syscons.c +++ b/sys/isa/syscons.c @@ -25,7 +25,7 @@ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * - * $Id: syscons.c,v 1.270 1998/08/03 09:17:06 yokota Exp $ + * $Id: syscons.c,v 1.271 1998/08/03 09:18:58 yokota Exp $ */ #include "sc.h" @@ -37,6 +37,7 @@ #if NSC > 0 #include <sys/param.h> #include <sys/systm.h> +#include <sys/reboot.h> #include <sys/conf.h> #include <sys/proc.h> #include <sys/signalvar.h> @@ -47,6 +48,7 @@ #include <sys/devfsext.h> #endif +#include <machine/bootinfo.h> #include <machine/clock.h> #include <machine/cons.h> #include <machine/console.h> @@ -94,9 +96,12 @@ #define COLD 0 #define WARM 1 +#define VESA_MODE(x) ((x) >= M_VESA_BASE) + #define MODE_MAP_SIZE (M_VGA_CG320 + 1) #define MODE_PARAM_SIZE 64 +#define DEFAULT_BLANKTIME (5*60) /* 5 minutes */ #define MAX_BLANKTIME (7*24*60*60) /* 7 days!? */ /* for backward compatibility */ @@ -162,11 +167,14 @@ static const u_int n_fkey_tab = sizeof(fkey_tab) / sizeof(*fkey_tab); static int delayed_next_scr = FALSE; static long scrn_blank_time = 0; /* screen saver timeout value */ int scrn_blanked = 0; /* screen saver active flag */ -static struct timeval scrn_time_stamp; +static long scrn_time_stamp; +static int saver_mode = CONS_LKM_SAVER; /* LKM/user saver */ +static int run_scrn_saver = FALSE; /* should run the saver? */ +static int scrn_idle = FALSE; /* about to run the saver */ u_char scr_map[256]; u_char scr_rmap[256]; char *video_mode_ptr = NULL; -static int vesa_mode; +static int bios_video_mode; /* video mode # set by BIOS */ int fonts_loaded = 0 #ifdef STD8X16FONT | FONT_16 @@ -206,9 +214,12 @@ static int extra_history_size = static void none_saver(int blank) { } static void (*current_saver)(int blank) = none_saver; +static void (*default_saver)(int blank) = none_saver; int (*sc_user_ioctl)(dev_t dev, int cmd, caddr_t data, int flag, struct proc *p) = NULL; +static int sticky_splash = FALSE; + /* OS specific stuff */ #ifdef not_yet_done #define VIRTUAL_TTY(x) (sccons[x] = ttymalloc(sccons[x])) @@ -247,8 +258,8 @@ static void scmousestart(struct tty *tp); static void scinit(void); static void scshutdown(int howto, void *arg); static void map_mode_table(char *map[], char *table, int max); -static u_char map_mode_num(u_char mode); -static char *get_mode_param(scr_stat *scp, u_char mode); +static int map_mode_num(int mode); +static char *get_mode_param(scr_stat *scp, int mode); static u_int scgetc(u_int flags); #define SCGETC_CN 1 #define SCGETC_NONBLOCK 2 @@ -256,7 +267,7 @@ static void sccnupdate(scr_stat *scp); static scr_stat *get_scr_stat(dev_t dev); static scr_stat *alloc_scp(void); static void init_scp(scr_stat *scp); -static void sc_bcopy(u_short *p, int from, int to, int mark); +static void sc_bcopy(scr_stat *scp, u_short *p, int from, int to, int mark); static int get_scr_num(void); static timeout_t scrn_timer; static void scrn_update(scr_stat *scp, int show_cursor); @@ -306,7 +317,11 @@ static void save_palette(void); static void do_bell(scr_stat *scp, int pitch, int duration); static timeout_t blink_screen; #ifdef SC_SPLASH_SCREEN -static void toggle_splash_screen(scr_stat *scp); +static void scsplash_init(void); +static void scsplash(int show); +#define scsplash_stick(stick) (sticky_splash = (stick)) +#else +#define scsplash_stick(stick) #endif struct isa_driver scdriver = { @@ -336,8 +351,8 @@ draw_cursor_image(scr_stat *scp) u_short cursor_image, *ptr = Crtat + (scp->cursor_pos - scp->scr_buf); u_short prev_image; - if (vesa_mode) { - sc_bcopy(scp->scr_buf, scp->cursor_pos - scp->scr_buf, + if (VESA_MODE(scp->mode)) { + sc_bcopy(scp, scp->scr_buf, scp->cursor_pos - scp->scr_buf, scp->cursor_pos - scp->scr_buf, 1); return; } @@ -388,8 +403,8 @@ draw_cursor_image(scr_stat *scp) static void remove_cursor_image(scr_stat *scp) { - if (vesa_mode) - sc_bcopy(scp->scr_buf, scp->cursor_oldpos - scp->scr_buf, + if (VESA_MODE(scp->mode)) + sc_bcopy(scp, scp->scr_buf, scp->cursor_oldpos - scp->scr_buf, scp->cursor_oldpos - scp->scr_buf, 0); else *(Crtat + (scp->cursor_oldpos - scp->scr_buf)) = scp->cursor_saveunder; @@ -455,10 +470,12 @@ scvidprobe(int unit, int flags) cp = (u_short *)CGA_BUF; was = *cp; *cp = (u_short) 0xA55A; + bios_video_mode = *(u_char *)pa_to_va(0x449); if (bootinfo.bi_vesa == 0x102) { - vesa_mode = bootinfo.bi_vesa; + bios_video_mode = bootinfo.bi_vesa; Crtat = (u_short *)pa_to_va(0xA0000); - crtc_type = KD_PIXEL; + crtc_addr = COLOR_BASE; + crtc_type = KD_VGA; bzero(Crtat, 800*600/8); } else if (*cp == 0xA55A) { Crtat = (u_short *)CGA_BUF; @@ -476,7 +493,7 @@ scvidprobe(int unit, int flags) } *cp = was; - if (crtc_type != KD_PIXEL) { + if (!VESA_MODE(bios_video_mode)) { /* * Check rtc and BIOS date area. * XXX: don't use BIOSDATA_EQUIPMENT, it is not a dead copy @@ -717,12 +734,12 @@ scattach(struct isa_device *dev) scinit(); flags = dev->id_flags; - if (!crtc_vga) + if (crtc_type != KD_VGA || VESA_MODE(bios_video_mode)) flags &= ~CHAR_CURSOR; scp = console[0]; - if (crtc_vga) { + if (crtc_type == KD_VGA) { cut_buffer_size = scp->xsize * scp->ysize + 1; cut_buffer = (char *)malloc(cut_buffer_size, M_DEVBUF, M_NOWAIT); if (cut_buffer != NULL) @@ -754,13 +771,12 @@ scattach(struct isa_device *dev) draw_cursor_image(scp); /* get screen update going */ - scrn_timer(NULL); + scrn_timer((void *)TRUE); update_leds(scp->status); if ((crtc_type == KD_VGA) && bootverbose) { - printf("sc%d: BIOS video mode:%d\n", - dev->id_unit, *(u_char *)pa_to_va(0x449)); + printf("sc%d: BIOS video mode:%d\n", dev->id_unit, bios_video_mode); printf("sc%d: VGA registers upon power-up\n", dev->id_unit); dump_vgaregs(vgaregs); printf("sc%d: video mode:%d\n", dev->id_unit, scp->mode); @@ -775,14 +791,17 @@ scattach(struct isa_device *dev) } printf("sc%d: rows_offset:%d\n", dev->id_unit, rows_offset); } - if ((crtc_type == KD_VGA) && (video_mode_ptr == NULL)) + if ((crtc_type == KD_VGA) && !VESA_MODE(bios_video_mode) + && (video_mode_ptr == NULL)) printf("sc%d: WARNING: video mode switching is only partially supported\n", dev->id_unit); printf("sc%d: ", dev->id_unit); switch(crtc_type) { case KD_VGA: - if (crtc_addr == MONO_BASE) + if (VESA_MODE(bios_video_mode)) + printf("Graphics display (VESA mode = 0x%x)", bios_video_mode); + else if (crtc_addr == MONO_BASE) printf("VGA mono"); else printf("VGA color"); @@ -796,9 +815,6 @@ scattach(struct isa_device *dev) case KD_CGA: printf("CGA"); break; - case KD_PIXEL: - printf("Graphics display (VESA mode = 0x%x)", vesa_mode); - break; case KD_MONO: case KD_HERCULES: default: @@ -1053,9 +1069,10 @@ scioctl(dev_t dev, u_long cmd, caddr_t data, int flag, struct proc *p) case CONS_BLANKTIME: /* set screen saver timeout (0 = no saver) */ if (*(int *)data < 0 || *(int *)data > MAX_BLANKTIME) return EINVAL; + s = spltty(); scrn_blank_time = *(int *)data; - if (scrn_blank_time == 0) - getmicrouptime(&scrn_time_stamp); + run_scrn_saver = (scrn_blank_time != 0); + splx(s); return 0; case CONS_CURSORTYPE: /* set cursor type blink/noblink */ @@ -1064,7 +1081,7 @@ scioctl(dev_t dev, u_long cmd, caddr_t data, int flag, struct proc *p) else flags &= ~BLINK_CURSOR; if ((*(int*)data) & 0x02) { - if (!crtc_vga) + if (crtc_type != KD_VGA || VESA_MODE(bios_video_mode)) return ENXIO; flags |= CHAR_CURSOR; } else @@ -1154,7 +1171,7 @@ scioctl(dev_t dev, u_long cmd, caddr_t data, int flag, struct proc *p) mouse_info_t *mouse = (mouse_info_t*)data; mouse_info_t buf; - if (!crtc_vga) + if (crtc_type != KD_VGA || VESA_MODE(bios_video_mode)) return ENODEV; if (cmd == OLD_CONS_MOUSECTL) { @@ -1200,13 +1217,14 @@ scioctl(dev_t dev, u_long cmd, caddr_t data, int flag, struct proc *p) scp->mouse_proc = NULL; scp->mouse_pid = 0; } - break; + return 0; case MOUSE_SHOW: if (!(scp->status & MOUSE_ENABLED)) { scp->status |= (MOUSE_ENABLED | MOUSE_VISIBLE); scp->mouse_oldpos = scp->mouse_pos; mark_all(scp); + return 0; } else return EINVAL; @@ -1216,6 +1234,7 @@ scioctl(dev_t dev, u_long cmd, caddr_t data, int flag, struct proc *p) if (scp->status & MOUSE_ENABLED) { scp->status &= ~(MOUSE_ENABLED | MOUSE_VISIBLE); mark_all(scp); + return 0; } else return EINVAL; @@ -1238,7 +1257,7 @@ scioctl(dev_t dev, u_long cmd, caddr_t data, int flag, struct proc *p) mouse->u.data.y = scp->mouse_ypos; mouse->u.data.z = 0; mouse->u.data.buttons = scp->mouse_buttons; - break; + return 0; case MOUSE_ACTION: case MOUSE_MOTION_EVENT: @@ -1254,6 +1273,8 @@ scioctl(dev_t dev, u_long cmd, caddr_t data, int flag, struct proc *p) ((mouse->u.data.x || mouse->u.data.y || mouse->u.data.z) ? MOUSE_POSCHANGED : 0) | (mouse_status.obutton ^ mouse_status.button); + if (mouse_status.flags == 0) + return 0; if (cur_console->status & MOUSE_ENABLED) cur_console->status |= MOUSE_VISIBLE; @@ -1334,6 +1355,8 @@ scioctl(dev_t dev, u_long cmd, caddr_t data, int flag, struct proc *p) mouse_status.button &= ~mouse->u.event.id; } mouse_status.flags |= mouse_status.obutton ^ mouse_status.button; + if (mouse_status.flags == 0) + return 0; if (cur_console->status & MOUSE_ENABLED) cur_console->status |= MOUSE_VISIBLE; @@ -1411,7 +1434,8 @@ scioctl(dev_t dev, u_long cmd, caddr_t data, int flag, struct proc *p) return EINVAL; } /* make screensaver happy */ - getmicrouptime(&scrn_time_stamp); + scsplash_stick(FALSE); + run_scrn_saver = FALSE; return 0; } @@ -1542,6 +1566,37 @@ scioctl(dev_t dev, u_long cmd, caddr_t data, int flag, struct proc *p) *(int*)data = 0x200; /* version 2.0 */ return 0; + case CONS_IDLE: /* see if the screen has been idle */ + *(int *)data = (scrn_idle && !(cur_console->status & UNKNOWN_MODE)); + return 0; + + case CONS_SAVERMODE: /* set saver mode */ + switch(*(int *)data) { + case CONS_USR_SAVER: + /* if a LKM screen saver is running, it will eventually stop... */ + saver_mode = *(int *)data; + scsplash_stick(TRUE); + break; + case CONS_LKM_SAVER: + saver_mode = *(int *)data; + break; + default: + return EINVAL; + } + return 0; + + case CONS_SAVERSTART: /* immediately start/stop the screen saver */ + /* + * Note that this ioctl does not guarantee the screen saver + * actually starts or stops. It merely attempts to do so... + */ + s = spltty(); + run_scrn_saver = (*(int *)data != 0); + if (run_scrn_saver) + scrn_time_stamp -= scrn_blank_time; + splx(s); + return 0; + /* VGA TEXT MODES */ case SW_VGA_C40x25: case SW_VGA_C80x25: case SW_VGA_M80x25: @@ -1555,7 +1610,7 @@ scioctl(dev_t dev, u_long cmd, caddr_t data, int flag, struct proc *p) case SW_ENH_B80x43: case SW_ENH_C80x43: case SW_EGAMONO80x25: - if (!crtc_vga) + if (crtc_type != KD_VGA) return ENODEV; mp = get_mode_param(scp, cmd & 0xff); if (mp == NULL) @@ -1693,7 +1748,7 @@ scioctl(dev_t dev, u_long cmd, caddr_t data, int flag, struct proc *p) case SW_CG640x350: case SW_ENH_CG640: case SW_BG640x480: case SW_CG640x480: case SW_VGA_CG320: - if (!crtc_vga) + if (crtc_type != KD_VGA) return ENODEV; mp = get_mode_param(scp, cmd & 0xff); if (mp == NULL) @@ -1730,7 +1785,7 @@ scioctl(dev_t dev, u_long cmd, caddr_t data, int flag, struct proc *p) return 0; case SW_VGA_MODEX: - if (!crtc_vga) + if (crtc_type != KD_VGA) return ENODEV; mp = get_mode_param(scp, cmd & 0xff); if (mp == NULL) @@ -1869,19 +1924,21 @@ scioctl(dev_t dev, u_long cmd, caddr_t data, int flag, struct proc *p) switch (*data) { case KD_TEXT: /* switch to TEXT (known) mode */ /* restore fonts & palette ! */ - if (crtc_vga) { + if (crtc_type == KD_VGA) { + if (!VESA_MODE(scp->mode)) { #if 0 - /* - * FONT KLUDGE - * Don't load fonts for now... XXX - */ - if (fonts_loaded & FONT_8) - copy_font(LOAD, FONT_8, font_8); - if (fonts_loaded & FONT_14) - copy_font(LOAD, FONT_14, font_14); - if (fonts_loaded & FONT_16) - copy_font(LOAD, FONT_16, font_16); + /* + * FONT KLUDGE + * Don't load fonts for now... XXX + */ + if (fonts_loaded & FONT_8) + copy_font(LOAD, FONT_8, font_8); + if (fonts_loaded & FONT_14) + copy_font(LOAD, FONT_14, font_14); + if (fonts_loaded & FONT_16) + copy_font(LOAD, FONT_16, font_16); #endif + } load_palette(palette); } @@ -1904,7 +1961,7 @@ scioctl(dev_t dev, u_long cmd, caddr_t data, int flag, struct proc *p) scp->status |= UNKNOWN_MODE; splx(s); /* no restore fonts & palette */ - if (crtc_vga) + if (crtc_type == KD_VGA) set_mode(scp); scp->status &= ~UNKNOWN_MODE; clear_screen(scp); @@ -2086,7 +2143,7 @@ scioctl(dev_t dev, u_long cmd, caddr_t data, int flag, struct proc *p) return 0; case PIO_FONT8x8: /* set 8x8 dot font */ - if (!crtc_vga) + if (crtc_type != KD_VGA) return ENXIO; bcopy(data, font_8, 8*256); fonts_loaded |= FONT_8; @@ -2095,7 +2152,8 @@ scioctl(dev_t dev, u_long cmd, caddr_t data, int flag, struct proc *p) * Always use the font page #0. XXX * Don't load if the current font size is not 8x8. */ - if (!(cur_console->status & UNKNOWN_MODE) + if (!VESA_MODE(cur_console->mode) + && !(cur_console->status & UNKNOWN_MODE) && (cur_console->font_size < 14)) { copy_font(LOAD, FONT_8, font_8); if (flags & CHAR_CURSOR) @@ -2104,7 +2162,7 @@ scioctl(dev_t dev, u_long cmd, caddr_t data, int flag, struct proc *p) return 0; case GIO_FONT8x8: /* get 8x8 dot font */ - if (!crtc_vga) + if (crtc_type != KD_VGA) return ENXIO; if (fonts_loaded & FONT_8) { bcopy(font_8, data, 8*256); @@ -2114,7 +2172,7 @@ scioctl(dev_t dev, u_long cmd, caddr_t data, int flag, struct proc *p) return ENXIO; case PIO_FONT8x14: /* set 8x14 dot font */ - if (!crtc_vga) + if (crtc_type != KD_VGA) return ENXIO; bcopy(data, font_14, 14*256); fonts_loaded |= FONT_14; @@ -2123,7 +2181,8 @@ scioctl(dev_t dev, u_long cmd, caddr_t data, int flag, struct proc *p) * Always use the font page #0. XXX * Don't load if the current font size is not 8x14. */ - if (!(cur_console->status & UNKNOWN_MODE) + if (!VESA_MODE(cur_console->mode) + && !(cur_console->status & UNKNOWN_MODE) && (cur_console->font_size >= 14) && (cur_console->font_size < 16)) { copy_font(LOAD, FONT_14, font_14); if (flags & CHAR_CURSOR) @@ -2132,7 +2191,7 @@ scioctl(dev_t dev, u_long cmd, caddr_t data, int flag, struct proc *p) return 0; case GIO_FONT8x14: /* get 8x14 dot font */ - if (!crtc_vga) + if (crtc_type != KD_VGA) return ENXIO; if (fonts_loaded & FONT_14) { bcopy(font_14, data, 14*256); @@ -2142,7 +2201,7 @@ scioctl(dev_t dev, u_long cmd, caddr_t data, int flag, struct proc *p) return ENXIO; case PIO_FONT8x16: /* set 8x16 dot font */ - if (!crtc_vga && crtc_type != KD_PIXEL) + if (crtc_type != KD_VGA) return ENXIO; bcopy(data, font_16, 16*256); fonts_loaded |= FONT_16; @@ -2151,7 +2210,8 @@ scioctl(dev_t dev, u_long cmd, caddr_t data, int flag, struct proc *p) * Always use the font page #0. XXX * Don't load if the current font size is not 8x16. */ - if (crtc_vga && !(cur_console->status & UNKNOWN_MODE) + if (!VESA_MODE(cur_console->mode) + && !(cur_console->status & UNKNOWN_MODE) && (cur_console->font_size >= 16)) { copy_font(LOAD, FONT_16, font_16); if (flags & CHAR_CURSOR) @@ -2160,7 +2220,7 @@ scioctl(dev_t dev, u_long cmd, caddr_t data, int flag, struct proc *p) return 0; case GIO_FONT8x16: /* get 8x16 dot font */ - if (!crtc_vga && crtc_type != KD_PIXEL) + if (crtc_type != KD_VGA) return ENXIO; if (fonts_loaded & FONT_16) { bcopy(font_16, data, 16*256); @@ -2292,6 +2352,8 @@ sccngetc(dev_t dev) * Stop the screen saver and update the screen if necessary. * What if we have been running in the screen saver code... XXX */ + scsplash_stick(FALSE); + run_scrn_saver = FALSE; sccnupdate(cur_console); c = scgetc(SCGETC_CN); @@ -2305,7 +2367,10 @@ sccncheckc(dev_t dev) int s = spltty(); /* block scintr and scrn_timer while we poll */ int c; + scsplash_stick(FALSE); + run_scrn_saver = FALSE; sccnupdate(cur_console); + c = scgetc(SCGETC_CN | SCGETC_NONBLOCK); splx(s); return(c == NOKEY ? -1 : c); /* c == -1 can't happen */ @@ -2314,13 +2379,26 @@ sccncheckc(dev_t dev) static void sccnupdate(scr_stat *scp) { - if (scp == cur_console && !font_loading_in_progress) { + /* this is a cut-down version of scrn_timer()... */ + + if (font_loading_in_progress) + return; + + if (panicstr) { + scsplash_stick(FALSE); + run_scrn_saver = FALSE; + } + if (!run_scrn_saver) + scrn_idle = FALSE; + if ((saver_mode != CONS_LKM_SAVER) || !scrn_idle) if (scrn_blanked > 0) stop_scrn_saver(current_saver); - if (!(scp->status & UNKNOWN_MODE) && scrn_blanked <= 0 - && !blink_in_progress && !switch_in_progress) - scrn_update(scp, TRUE); - } + + if (scp != cur_console || blink_in_progress || switch_in_progress) + return; + + if ((scp->status & UNKNOWN_MODE) == 0 && scrn_blanked <= 0) + scrn_update(scp, TRUE); } static scr_stat @@ -2349,12 +2427,13 @@ static void scrn_timer(void *arg) { struct timeval tv; - scr_stat *scp = cur_console; + scr_stat *scp; int s; /* don't do anything when we are touching font */ if (font_loading_in_progress) { - timeout(scrn_timer, NULL, hz / 10); + if (arg) + timeout(scrn_timer, (void *)TRUE, hz / 10); return; } s = spltty(); @@ -2384,30 +2463,42 @@ scrn_timer(void *arg) /* should we stop the screen saver? */ getmicrouptime(&tv); - if (panicstr || shutdown_in_progress) - scrn_time_stamp = tv; - if (tv.tv_sec <= scrn_time_stamp.tv_sec + scrn_blank_time) + if (panicstr || shutdown_in_progress) { + scsplash_stick(FALSE); + run_scrn_saver = FALSE; + } + if (run_scrn_saver) { + scrn_idle = (tv.tv_sec > scrn_time_stamp + scrn_blank_time); + } else { + scrn_time_stamp = tv.tv_sec; + scrn_idle = FALSE; + if (scrn_blank_time > 0) + run_scrn_saver = TRUE; + } + if ((saver_mode != CONS_LKM_SAVER) || !scrn_idle) if (scrn_blanked > 0) stop_scrn_saver(current_saver); /* should we just return ? */ - if ((scp->status&UNKNOWN_MODE) || blink_in_progress || switch_in_progress) { - timeout(scrn_timer, NULL, hz / 10); + if (blink_in_progress || switch_in_progress) { + if (arg) + timeout(scrn_timer, (void *)TRUE, hz / 10); splx(s); return; } /* Update the screen */ scp = cur_console; - if (scrn_blanked <= 0) + if ((scp->status & UNKNOWN_MODE) == 0 && scrn_blanked <= 0) scrn_update(scp, TRUE); /* should we activate the screen saver? */ - if ((scrn_blank_time != 0) - && (tv.tv_sec > scrn_time_stamp.tv_sec + scrn_blank_time)) - (*current_saver)(TRUE); + if ((saver_mode == CONS_LKM_SAVER) && scrn_idle) + if ((scp->status & UNKNOWN_MODE) == 0 || scrn_blanked > 0) + (*current_saver)(TRUE); - timeout(scrn_timer, NULL, hz / 25); + if (arg) + timeout(scrn_timer, (void *)TRUE, hz / 25); splx(s); } @@ -2416,7 +2507,7 @@ scrn_update(scr_stat *scp, int show_cursor) { /* update screen image */ if (scp->start <= scp->end) - sc_bcopy(scp->scr_buf, scp->start, scp->end, 0); + sc_bcopy(scp, scp->scr_buf, scp->start, scp->end, 0); /* we are not to show the cursor and the mouse pointer... */ if (!show_cursor) { @@ -2483,9 +2574,18 @@ scrn_update(scr_stat *scp, int show_cursor) int add_scrn_saver(void (*this_saver)(int)) { - if (current_saver != none_saver) +#ifdef SC_SPLASH_SCREEN + if (current_saver == scsplash) { + scsplash_stick(FALSE); + stop_scrn_saver(scsplash); + } +#endif + + if (current_saver != default_saver) return EBUSY; current_saver = this_saver; + saver_mode = CONS_LKM_SAVER; + run_scrn_saver = (scrn_blank_time > 0); return 0; } @@ -2505,6 +2605,10 @@ remove_scrn_saver(void (*this_saver)(int)) if (scrn_blanked > 0) stop_scrn_saver(this_saver); + if (scrn_blanked > 0) + return EBUSY; /* XXX */ + + current_saver = default_saver; return 0; } @@ -2512,8 +2616,14 @@ static void stop_scrn_saver(void (*saver)(int)) { (*saver)(FALSE); - getmicrouptime(&scrn_time_stamp); + run_scrn_saver = FALSE; + /* the screen saver may have chosen not to stop after all... */ + if (scrn_blanked > 0) + return; + mark_all(cur_console); + if (delayed_next_scr) + switch_scr(cur_console, delayed_next_scr - 1); wakeup((caddr_t)&scrn_blanked); } @@ -2522,10 +2632,10 @@ wait_scrn_saver_stop(void) { int error = 0; - getmicrouptime(&scrn_time_stamp); + run_scrn_saver = FALSE; while (scrn_blanked > 0) { error = tsleep((caddr_t)&scrn_blanked, PZERO | PCATCH, "scrsav", 0); - getmicrouptime(&scrn_time_stamp); + run_scrn_saver = FALSE; if (error != ERESTART) break; } @@ -2546,6 +2656,14 @@ clear_screen(scr_stat *scp) static int switch_scr(scr_stat *scp, u_int next_scr) { + /* delay switch if actively updating screen */ + if (scrn_blanked > 0 || write_in_progress || blink_in_progress) { + scsplash_stick(FALSE); + run_scrn_saver = FALSE; + delayed_next_scr = next_scr+1; + return 0; + } + if (switch_in_progress && (cur_console->proc != pfind(cur_console->pid))) switch_in_progress = FALSE; @@ -2565,16 +2683,6 @@ switch_scr(scr_stat *scp, u_int next_scr) } } - /* delay switch if actively updating screen */ - if (write_in_progress || blink_in_progress) { - delayed_next_scr = next_scr+1; - return 0; - } - - /* Stop the screensaver */ - if (scrn_blanked > 0) - stop_scrn_saver(current_saver); - switch_in_progress = TRUE; old_scp = cur_console; new_scp = console[next_scr]; @@ -2614,13 +2722,13 @@ exchange_scr(void) move_crsr(old_scp, old_scp->xpos, old_scp->ypos); cur_console = new_scp; if (old_scp->mode != new_scp->mode || (old_scp->status & UNKNOWN_MODE)){ - if (crtc_vga) + if (crtc_type == KD_VGA) set_mode(new_scp); } move_crsr(new_scp, new_scp->xpos, new_scp->ypos); if (!(new_scp->status & UNKNOWN_MODE) && (flags & CHAR_CURSOR)) set_destructive_cursor(new_scp); - if ((old_scp->status & UNKNOWN_MODE) && crtc_vga) + if ((old_scp->status & UNKNOWN_MODE) && crtc_type == KD_VGA) load_palette(palette); if (old_scp->status & KBD_RAW_MODE || new_scp->status & KBD_RAW_MODE || old_scp->status & KBD_CODE_MODE || new_scp->status & KBD_CODE_MODE) @@ -2629,7 +2737,7 @@ exchange_scr(void) update_leds(new_scp->status); delayed_next_scr = FALSE; mark_all(new_scp); - if (vesa_mode == 0x102) { + if (new_scp->mode == 0x102) { bzero(Crtat, 800*600/8); } } @@ -3101,7 +3209,8 @@ scan_esc(scr_stat *scp, u_char c) flags |= BLINK_CURSOR; else flags &= ~BLINK_CURSOR; - if ((scp->term.param[0] & 0x02) && crtc_vga) + if ((scp->term.param[0] & 0x02) && + crtc_type == KD_VGA && !VESA_MODE(bios_video_mode)) flags |= CHAR_CURSOR; else flags &= ~CHAR_CURSOR; @@ -3116,7 +3225,7 @@ scan_esc(scr_stat *scp, u_char c) */ if (!(cur_console->status & UNKNOWN_MODE)) { remove_cursor_image(cur_console); - if (crtc_vga && (flags & CHAR_CURSOR)) + if (crtc_type == KD_VGA && (flags & CHAR_CURSOR)) set_destructive_cursor(cur_console); draw_cursor_image(cur_console); } @@ -3184,8 +3293,8 @@ ansi_put(scr_stat *scp, u_char *buf, int len) u_char *ptr = buf; /* make screensaver happy */ - if (scp == cur_console) - getmicrouptime(&scrn_time_stamp); + if (!sticky_splash && scp == cur_console) + run_scrn_saver = FALSE; write_in_progress++; outloop: @@ -3382,7 +3491,7 @@ scinit(void) } /* copy screen to temporary buffer */ - if (crtc_type != KD_PIXEL) + if (!VESA_MODE(console[0]->mode)) generic_bcopy(Crtat, sc_buffer, console[0]->xsize * console[0]->ysize * sizeof(u_short)); @@ -3407,30 +3516,35 @@ scinit(void) } /* Save font and palette if VGA */ - if (crtc_vga) { - if (fonts_loaded & FONT_16) { + if (crtc_type == KD_VGA) { + if (!VESA_MODE(bios_video_mode)) { + if (fonts_loaded & FONT_16) { copy_font(LOAD, FONT_16, font_16); - } else { + } else { copy_font(SAVE, FONT_16, font_16); fonts_loaded = FONT_16; + } + set_destructive_cursor(console[0]); } save_palette(); - set_destructive_cursor(console[0]); } #ifdef SC_SPLASH_SCREEN /* - * Now put up a graphics image, and maybe cycle a - * couble of palette entries for simple animation. + * If not booting verbosely, put up the splash. + * Note that the splash screen is not currently supported in + * the VESA mode. */ - toggle_splash_screen(cur_console); + if (!(boothowto & RB_VERBOSE) && !VESA_MODE(bios_video_mode)) + scsplash_init(); #endif } static void scshutdown(int howto, void *arg) { - getmicrouptime(&scrn_time_stamp); + scsplash_stick(FALSE); + run_scrn_saver = FALSE; if (!cold && cur_console->smode.mode == VT_AUTO && console[0]->smode.mode == VT_AUTO) switch_scr(cur_console, 0); @@ -3448,12 +3562,12 @@ map_mode_table(char *map[], char *table, int max) map[i] = NULL; } -static u_char -map_mode_num(u_char mode) +static int +map_mode_num(int mode) { static struct { - u_char from; - u_char to; + int from; + int to; } mode_map[] = { { M_ENH_B80x43, M_ENH_B80x25 }, { M_ENH_C80x43, M_ENH_C80x25 }, @@ -3475,7 +3589,7 @@ map_mode_num(u_char mode) } static char -*get_mode_param(scr_stat *scp, u_char mode) +*get_mode_param(scr_stat *scp, int mode) { if (mode >= MODE_MAP_SIZE) mode = map_mode_num(mode); @@ -3504,7 +3618,7 @@ static scr_stat bzero(scp->history_head, scp->history_size*sizeof(u_short)); scp->history = scp->history_head; /* SOS - if (crtc_vga && video_mode_ptr) + if (crtc_type == KD_VGA && video_mode_ptr) set_mode(scp); */ clear_screen(scp); @@ -3517,7 +3631,9 @@ init_scp(scr_stat *scp) { switch(crtc_type) { case KD_VGA: - if (crtc_addr == MONO_BASE) + if (VESA_MODE(bios_video_mode)) + scp->mode = bios_video_mode; + else if (crtc_addr == MONO_BASE) scp->mode = M_VGA_M80x25; else scp->mode = M_VGA_C80x25; @@ -3662,8 +3778,10 @@ next_code: scancode = (u_char)c; /* make screensaver happy */ - if (!(scancode & 0x80)) - getmicrouptime(&scrn_time_stamp); + if (!(scancode & 0x80)) { + scsplash_stick(FALSE); + run_scrn_saver = FALSE; + } if (!(flags & SCGETC_CN)) { /* do the /dev/random device a favour */ @@ -3940,9 +4058,6 @@ next_code: switch (action) { /* LOCKING KEYS */ case NLK: -#ifdef SC_SPLASH_SCREEN - toggle_splash_screen(cur_console); /* SOS XXX */ -#endif if (!nlkcnt) { nlkcnt++; if (cur_console->status & NLKED) @@ -4009,9 +4124,28 @@ next_code: case NOP: break; case SPSC: -#ifdef SC_SPLASH_SCREEN + /* force activatation/deactivation of the screen saver */ accents = 0; - toggle_splash_screen(cur_console); + if (scrn_blanked <= 0) { + run_scrn_saver = TRUE; + scrn_time_stamp -= scrn_blank_time; + } +#ifdef SC_SPLASH_SCREEN + if (cold) { + /* + * While devices are being probed, the screen saver need + * to be invoked explictly. XXX + */ + if (scrn_blanked > 0) { + scsplash_stick(FALSE); + stop_scrn_saver(current_saver); + } else { + if ((cur_console->status & UNKNOWN_MODE) == 0) { + scsplash_stick(TRUE); + (*current_saver)(TRUE); + } + } + } #endif break; case RBT: @@ -4037,6 +4171,12 @@ next_code: case DBG: #ifdef DDB /* try to switch to console 0 */ accents = 0; + /* + * TRY to make sure the screen saver is stopped, + * and the screen is updated before switching to + * the vty0. + */ + scrn_timer((void *)FALSE); if (cur_console->smode.mode == VT_AUTO && console[0]->smode.mode == VT_AUTO) switch_scr(cur_console, 0); @@ -5193,11 +5333,11 @@ blink_screen(void *arg) } void -sc_bcopy(u_short *p, int from, int to, int mark) +sc_bcopy(scr_stat *scp, u_short *p, int from, int to, int mark) { - if (!vesa_mode) { + if (!VESA_MODE(scp->mode)) { generic_bcopy(p+from, Crtat+from, (to-from+1)*sizeof (u_short)); - } else if (vesa_mode == 0x102) { + } else if (scp->mode == 0x102) { u_char *d, *e; int i,j; @@ -5219,33 +5359,38 @@ sc_bcopy(u_short *p, int from, int to, int mark) } #ifdef SC_SPLASH_SCREEN + static void -toggle_splash_screen(scr_stat *scp) +scsplash_init(void) { - static int toggle = 0; - static u_char save_mode; - int s; - - if (video_mode_ptr == NULL) + /* + * We currently assume the splash screen always use + * VGA_CG320 mode and abort installation if this mode is not + * supported with this video card. XXX + */ + if (crtc_type != KD_VGA || get_mode_param(cur_console, M_VGA_CG320) == NULL) return; - s = splhigh(); - if (toggle) { - scp->mode = save_mode; - scp->status &= ~UNKNOWN_MODE; - set_mode(scp); - load_palette(palette); - toggle = 0; - } - else { - save_mode = scp->mode; - scp->mode = M_VGA_CG320; - scp->status |= UNKNOWN_MODE; - set_mode(scp); - /* load image */ - toggle = 1; + if (splash_load() == 0 && add_scrn_saver(scsplash) == 0) { + default_saver = scsplash; + scrn_blank_time = DEFAULT_BLANKTIME; + run_scrn_saver = TRUE; + if (!(boothowto & RB_CONFIG)) { + scsplash_stick(TRUE); + scsplash(TRUE); + } } - splx(s); } -#endif + +static void +scsplash(int show) +{ + if (show) + splash(TRUE); + else if (!sticky_splash) + splash(FALSE); +} + +#endif /* SC_SPLASH_SCREEN */ + #endif /* NSC */ diff --git a/sys/isa/syscons.h b/sys/isa/syscons.h index e65aff4..b23a2ae 100644 --- a/sys/isa/syscons.h +++ b/sys/isa/syscons.h @@ -25,7 +25,7 @@ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * - * $Id: syscons.h,v 1.37 1998/02/12 22:05:08 phk Exp $ + * $Id: syscons.h,v 1.38 1998/08/03 09:09:35 yokota Exp $ */ #ifndef _I386_ISA_SYSCONS_H_ @@ -174,8 +174,8 @@ typedef struct scr_stat { u_short bell_duration; u_short bell_pitch; u_char border; /* border color */ - u_char initial_mode; /* initial mode */ - u_char mode; /* mode */ + int initial_mode; /* initial mode */ + int mode; /* mode */ pid_t pid; /* pid of controlling proc */ struct proc *proc; /* proc* of controlling proc */ struct vt_mode smode; /* switch mode */ @@ -185,6 +185,9 @@ typedef struct scr_stat { u_short *history_save; /* save area index */ int history_size; /* size of history buffer */ struct apmhook r_hook; /* reconfiguration support */ +#ifdef SC_SPLASH_SCREEN + u_char splash_save_mode; /* saved mode for splash screen */ +#endif } scr_stat; typedef struct default_attr { @@ -200,4 +203,10 @@ void load_palette(char *palette); int add_scrn_saver(void (*this)(int)); int remove_scrn_saver(void (*this)(int)); +#ifdef SC_SPLASH_SCREEN +void splash(int); +int splash_load(void); +int splash_unload(void); +#endif + #endif /* !_I386_ISA_SYSCONS_H_ */ |